def read_shared_object(file): dp = zipfile.ZipFile(file, 'r') with dp.open('__mcc__.json', 'r') as f: meta = json.load(f) dp.close() top = TopLevel() table = meta['symbol_table'] for name, props in table['functions'].items(): params = [(vt(p['t']), p['p']) for p in props['params']] returns = [vt(r) for r in props['returns']] flags = props['flags'] pure = flags.get('pure', False) func = DynLinkFunction(c.NSName(props['_name']), params, returns, pure) top.store(name, func) for name, vardesc in table['variables'].items(): var = ExternVariable(vt(vardesc['type'])) ns = vardesc['namespace'] top.store(name, var) if 'nbt' in vardesc: proxy = GlobalNbtVariable(var.type, ns, vardesc['nbt']) elif 'score' in vardesc: proxy = GlobalScoreVariable(var.type, c.Var(vardesc['score'], ns)) else: assert False var.set_proxy(proxy) top.end() funcs = set(map(c.NSName, meta['reserved_funcs'])) return SharedObject(top, funcs)
def pair_name(fn, pair): return c.NSName('memory/%s_%d_%d' % (fn, pair.min, pair.max))
def add_page(self): mbr = c.Var('memory_buffer') mar = c.Var('memory_address') self.define_objective('memory_buffer', None) self.define_objective('memory_address', None) def pair_name(fn, pair): return c.NSName('memory/%s_%d_%d' % (fn, pair.min, pair.max)) def create_function(pair, force=False): getter = [] setter = [] def gen_fn(fn, p): return c.ExecuteChain() \ .cond('if') \ .score_range(mar, c.ScoreRange(p.min, p.max)) \ .run(c.Function(pair_name(fn, p))) def gen_assign(n, g=True): slot = c.Var('memory_slot_%d' % n) self.define_objective('memory_slot_%d' % n, None) return c.ExecuteChain() \ .cond('if') \ .score_range(mar, c.ScoreRange(n, n)) \ .run(c.OpAssign(mbr if g else slot, slot if g else mbr)) if pair.left and pair.left.left: getter.append(gen_fn('mem_get', pair.left)) setter.append(gen_fn('mem_set', pair.left)) if pair.right and pair.right.right: getter.append(gen_fn('mem_get', pair.right)) setter.append(gen_fn('mem_set', pair.right)) if not pair.left and not pair.right and not force: # Don't do anything here, it's done in the next level up return if pair.left and not pair.left.left or force: getter.append(gen_assign(pair.min)) setter.append(gen_assign(pair.min, False)) if pair.right and not pair.right.right: getter.append(gen_assign(pair.max)) setter.append(gen_assign(pair.max, False)) name_get = pair_name('mem_get', pair) name_set = pair_name('mem_set', pair) self.scope.add_function_names((name_get, name_set)) self.add_function(name_get, getter) self.add_function(name_set, setter) entry_point = self.generate_bin_tree(self.page_size, create_function) if not entry_point.left and not entry_point.right: create_function(entry_point, force=True) # Redirect mem_get and mem_set to the actual entry point mem_get = c.NSName('mem_get') mem_set = c.NSName('mem_set') getter = [c.Function(pair_name('mem_get', entry_point))] setter = [c.Function(pair_name('mem_set', entry_point))] self.scope.add_function_names((mem_get, mem_set)) self.add_function(mem_get, getter) self.add_function(mem_set, setter)
def as_cmd(self, func): return c.Function(c.NSName(self.name))
def get_cmd(self, func): return c.FunctionTag(c.NSName(self.event.name))