예제 #1
0
    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 '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
        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)
예제 #2
0
 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))
예제 #3
0
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)
예제 #4
0
 def __init__(self):
     super(ExtendedAssembler, self).__init__()
     self.instructions.update({
         'MOVIND': self.handle_mov_ind,
         'MOVINDD': self.handle_mov_ind_d,
         'MOVINDS': self.handle_mov_ind_s
     })
     self.use_mem = False
     self.mem_get = self.top.generate_name('mem_get', FunctionRef('mem_get'))
     self.mem_set = self.top.generate_name('mem_set', FunctionRef('mem_set'))
     self.mem_addr = self.top.create_global('mem_addr', VarType.i32)
     self.mem_buf = self.top.create_global('mem_buf', VarType.i32)
     self.mem_addr.set_proxy(GlobalScoreVariable(VarType.i32,
                                                 c.Var('memory_address')))
     self.mem_buf.set_proxy(GlobalScoreVariable(VarType.i32,
                                                c.Var('memory_buffer')))
예제 #5
0
 def __enter__(self):
     self.ref = self.var._direct_ref()
     if self.ref is None:
         self.using_temp = self.out.allocate_temp()
         self.ref = c.Var(self.using_temp)
         if self.read:
             self.var._write_to_reference(self.ref, self.out)
     return self.ref
예제 #6
0
 def scale_down(self, ref, out):
     if self.type.scale != 1:
         # TODO extract to constant reference
         tmp = out.allocate_temp()
         scaleparam = c.Var(tmp)
         out.write(c.SetConst(scaleparam, self.type.scale))
         out.write(c.OpDiv(ref, scaleparam))
         out.free_temp(tmp)
예제 #7
0
 def scale_other_to_this(self, other, otherref, out):
     factor = self.type.scale / other.type.scale
     op = c.OpMul
     if factor < 1:
         factor = 1 / factor
         op = c.OpDiv
     factor = int(factor)
     if factor == 1:
         return otherref
     newvar = out.allocate_temp()
     scaled = c.Var(newvar)
     out.write(c.OpAssign(scaled, otherref))
     # TODO extract to constant reference
     tmp = out.allocate_temp()
     scaleparam = c.Var(tmp)
     out.write(c.SetConst(scaleparam, factor))
     out.write(op(scaled, scaleparam))
     out.free_temp(tmp)
     return newvar
def _branch_apply(out, if_true, if_false, apply):
    inverted = not if_true
    if inverted:
        if_true, if_false = if_false, if_true
    have_false = if_false is not None
    if have_false:
        # Workaround: execute store doesn't set success to 0 if failed
        # See MC-125058
        # Can't use execute store anyway because it locks the success
        # tracker. See MC-125145
        out.write(c.SetConst(c.Var('success_tracker'), 0))
    true_fn = c.Function(if_true.global_name)
    out.write(
        apply(c.ExecuteChain().cond('unless' if inverted else 'if')).run(
            true_fn))
    if have_false:
        false_fn = c.Function(if_false.global_name)
        out.write(c.ExecuteChain().cond('if').score_range(
            c.Var('success_tracker'), c.ScoreRange(0, 0)).run(false_fn))
예제 #9
0
 def apply(self, out, func):
     # Possible optimisation where scope exit ("put back" value) is applied
     # directly to operation i.e. store result ... scoreboard add ...
     with self.dest.open_for_write(out, read=True) as ref:
         if isinstance(self.src, Variable):
             with self.src.open_for_read(out) as srcref:
                 scaled = self.dest.scale_other_to_this(
                     self.src, srcref, out)
                 if scaled != srcref:
                     # TODO this is a hack because a temp is allocated
                     srcref = c.Var(scaled)
                 out.write(self.with_ref(ref, srcref))
                 if scaled != srcref:
                     out.free_temp(scaled)
         else:
             self.apply_const_src(ref, self.dest.to_int(self.src), out)
         if not self.is_additive:
             self.dest.scale_down(ref, out)
예제 #10
0
 def extended_setup(self, up, down):
     for i in range(self.page_size):
         slot = c.Var('memory_slot_%d' % i)
         up.append(c.SetConst(slot, 0).resolve(self.scope))
예제 #11
0
 def allocate_temp(self):
     return c.Var('dummy')
예제 #12
0
 def apply_const_src(self, ref, val, out):
     tmp = out.allocate_temp()
     srcref = c.Var(tmp)
     out.write(c.SetConst(srcref, val))
     out.write(self.with_ref(ref, srcref))
     out.free_temp(tmp)