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)))
 def push_to_stack(self, out):
     # out-of-bounds stack path
     out.write(c.DataModifyFrom(c.GlobalNBT(self.namespace),
                                c.StackPath(None), 'append', self.storage,
                                self.root_path))
Exemple #5
0
 def get_cmd(self, func):
     storage = c.GlobalNBT(func.namespace)
     return c.DataRemove(storage, c.StackPath(STACK_HEAD))
Exemple #6
0
 def apply(self, out, func):
     out.write(
         _zt.cmd_set_from(c.StackPath(STACK_HEAD, None),
                          c.GlobalNBT(func.namespace)))
     out.write(_zt.clear_last_exec())
Exemple #7
0
 def get_cmd(self, func):
     storage = c.GlobalNBT(func.namespace)
     return _ut.cmd_set_from(c.StackPath(STACK_HEAD, None), storage)
 def push_to_stack(self, out):
     # out-of-bounds stack path
     out.write(
         c.DataModifyFrom(c.GlobalEntity.ref, c.StackPath(None), 'append',
                          self.entity.ref, self.root_path))
 def get_cmd(self):
     return c.DataRemove(c.GlobalEntity.ref, c.StackPath(STACK_HEAD))
 def get_cmd(self):
     return c.DataModifyFrom(c.UtilBlockPos.ref, c.NbtPath('Command'),
                             'set', c.GlobalEntity.ref,
                             c.StackPath(STACK_HEAD, 'cmd'))
 def apply(self, out, func):
     out.write(
         _zt.cmd_set_from(c.StackPath(STACK_HEAD, None), c.GlobalEntity))
     out.write(_zt.clear_last_exec())
 def get_cmd(self):
     return _ut.cmd_set_from(c.StackPath(STACK_HEAD, None), c.GlobalEntity)