def apply(self, out, func):
        # Validate arguments and return type
        self.func.validate_args(self.fnargs, self.retvars)

        # See also: IRFunction.configure_parameters
        # Build invocation frame
        # list of:
        #  - arguments
        #  - return variable pointers
        #  - saved registers
        allargs = []

        # Arguments
        args_start = 0
        if self.fnargs:
            allargs.extend(self.fnargs)

        # Returns
        ret_start = len(allargs)
        if self.retvars:
            # default return variable = default for the type
            allargs.extend([var.type for var in self.retvars])

        # Save registers
        reg_start = len(allargs)
        registers = func.get_registers()
        # Optimization - don't save registers used as return pointers
        if self.retvars:
            registers = [var for var in registers if var not in self.retvars]
        allargs.extend(registers)

        if allargs:
            make_stack_frame_from(allargs, out)
        out.write(c.Function(self.func.global_name))

        # Restore registers
        if registers:
            for i, reg in enumerate(registers):
                src = LocalStackVariable(reg.type, reg_start + i)
                # shouldn't need to realign because they're registers,
                # but just to be safe
                reg.realign_frame(1)
                src.clone_to(reg, out)
                reg.realign_frame(-1)

        # Copy return values into return variables
        if self.retvars:
            for i, var in enumerate(self.retvars):
                if var is None:
                    continue
                src = LocalStackVariable(var.type, ret_start + i)
                var.realign_frame(1)
                src.clone_to(var, out)
                var.realign_frame(-1)

        # Pop invocation frame
        if allargs:
            out.write(c.DataRemove(c.GlobalEntity.ref,
                                   c.StackPath(STACK_HEAD)))
Exemple #2
0
    def destroy_frame(self, out, func, frame):
        registers, reg_start, args_start, ret_start, allargs = frame
        destns = self.func.namespace
        stack_move = out.namespace == destns or destns is None

        # Restore registers
        if registers:
            for i, reg in enumerate(registers):
                src = LocalStackVariable(reg.type, destns, reg_start + i)
                if stack_move:
                    # shouldn't need to realign because they're registers,
                    # but just to be safe
                    reg.realign_frame(1)
                src.clone_to(reg, out)
                if stack_move:
                    reg.realign_frame(-1)

        # Mutate pass-by-reference arguments
        if self.fnargs:
            for i, (ptype, ppass) in enumerate(self.func.params):
                if ppass == 'byref':
                    src = LocalStackVariable(ptype, destns, args_start + i)
                    arg = self.fnargs[i]
                    assert isinstance(arg,
                                      Variable), "%s passed by value!" % arg
                    # The mutated arguments are on frame 0
                    # We want to copy them to where they were from (now frame 1)
                    if stack_move:
                        arg.realign_frame(1)
                    src.clone_to(arg, out)
                    if stack_move:
                        arg.realign_frame(-1)

        # Copy return values into return variables
        if self.retvars:
            for i, var in enumerate(self.retvars):
                if var is None:
                    continue
                src = LocalStackVariable(var.type, destns, ret_start + i)
                if stack_move:
                    var.realign_frame(1)
                src.clone_to(var, out)
                if stack_move:
                    var.realign_frame(-1)

        # Pop invocation frame
        if allargs:
            out.write(
                c.DataRemove(c.GlobalNBT(destns), c.StackPath(STACK_HEAD)))
    def destroy_frame(self, out, frame):
        registers, reg_start, args_start, ret_start, allargs = frame

        # Restore registers
        if registers:
            for i, reg in enumerate(registers):
                src = LocalStackVariable(reg.type, reg_start + i)
                # shouldn't need to realign because they're registers,
                # but just to be safe
                reg.realign_frame(1)
                src.clone_to(reg, out)
                reg.realign_frame(-1)

        # Mutate pass-by-reference arguments
        if self.fnargs:
            for i, (ptype, ppass) in enumerate(self.func.params):
                if ppass == 'byref':
                    src = LocalStackVariable(ptype, args_start + i)
                    arg = self.fnargs[i]
                    assert isinstance(arg,
                                      Variable), "%s passed by value!" % arg
                    src.realign_frame(1)
                    src.clone_to(arg, out)
                    src.realign_frame(-1)

        # Copy return values into return variables
        if self.retvars:
            for i, var in enumerate(self.retvars):
                if var is None:
                    continue
                src = LocalStackVariable(var.type, ret_start + i)
                var.realign_frame(1)
                src.clone_to(var, out)
                var.realign_frame(-1)

        # Pop invocation frame
        if allargs:
            out.write(c.DataRemove(c.GlobalEntity.ref,
                                   c.StackPath(STACK_HEAD)))
Exemple #4
0
 def get_cmd(self, func):
     storage = c.GlobalNBT(func.namespace)
     return c.DataRemove(storage, c.StackPath(STACK_HEAD))
Exemple #5
0
 def clear(self):
     return c.DataRemove(self.block, c.NbtPath('Command'))
 def get_cmd(self):
     return c.DataRemove(c.GlobalEntity.ref, c.StackPath(STACK_HEAD))
 def get_cmd(self):
     return c.DataRemove(c.UtilBlockPos.ref, c.NbtPath('Command'))
Exemple #8
0
 def get_cmd(self, func):
     direct = self.nbtvar._direct_nbt()
     assert direct is not None
     path, storage = direct
     return c.DataRemove(storage, path)