Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from pypy.translator.avm2.util import serialize_u32 as u32, Avm2Label
- from pypy.translator.avm2.constants import METHODFLAG_Activation, METHODFLAG_SetsDxns
- from decorator import decorator
- INSTRUCTIONS = {}
- @decorator
- def needs_specialized(fn, self, *args, **kwargs):
- if not self.specialized:
- raise ValueError, "Instruction needs to be specialized"
- return fn(self, *args, **kwargs)
- class _Avm2SpecializedInstruction(object):
- pass
- class _Avm2ShortInstruction(object):
- specialized=False
- def __init__(self, opcode, name, stack=0, scope=0, flags=0):
- self.opcode = opcode
- self.name = name
- self.stack = stack
- self.scope = scope
- self.flags = flags
- INSTRUCTIONS[opcode] = self
- def _repr(self):
- return "%s (0x%H)" % (self.name, self.opcode)
- def _set_assembler_props(self, asm):
- asm.flags |= self.flags
- asm.stack_depth += self.stack
- asm.scope_depth += self.scope
- def _serialize(self):
- return chr(self.opcode)
- serialize = _serialize
- set_assembler_props = _set_assembler_props
- __repr__ = _repr
- def specialize(self, **kwargs):
- return type("_Avm2_Instruction_%s" % self.name,
- (_Avm2SpecializedInstruction, self.__class__),
- dict(kwargs.items(),
- specialized=True,
- set_assembler_props=self._set_assembler_props,
- serialize=self._serialize,
- __repr__=self._repr,
- opcode=self.opcode, name=self.name, stack=self.stack, scope=self.scope,
- ))()
- def __call__(self):
- return self.specialize()
- class _Avm2DebugInstruction(_Avm2ShortInstruction):
- @needs_specialized
- def _serialize(self):
- return chr(self.opcode) + \
- chr(self.debug_type & 0xFF) + \
- u32(self.index) + \
- chr(self.reg & 0xFF) + \
- u32(self.extra)
- def __call__(self, debug_type, index, reg, extra):
- return self.specialize(debug_type=debug_type, index=index, reg=reg, extra=extra)
- class _Avm2U8Instruction(_Avm2ShortInstruction):
- @needs_specialized
- def _serialize(self):
- return chr(self.opcode) + chr(self.argument)
- def __call__(self, argument):
- return self.specialize(argument=argument)
- class _Avm2U30Instruction(_Avm2U8Instruction):
- @needs_specialized
- def _serialize(self):
- if hasattr(self.argument, "__iter__"):
- return chr(self.opcode) + ''.join(u32(i) for i in self.argument)
- else:
- return chr(self.opcode) + u32(self.argument)
- def __call__(self, argument, *arguments):
- if arguments:
- self.argument = [argument] + list(arguments)
- else:
- self.argument = argument
- class _Avm2KillInstruction(_Avm2U30Instruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- super(_Avm2KillInstruction, self)._set_assembler_props(asm)
- asm.kill_local(self.argument)
- class _Avm2NamespaceInstruction(_Avm2U30Instruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- super(_Avm2NamespaceInstruction, self)._set_assembler_props(asm)
- has_rtns = asm.constants.has_RTNS(self.multiname)
- has_rtname = asm.constants.has_RTName(self.multiname)
- self.argument = asm.constants.multiname_pool.index_for(self.multiname)
- asm.stack_depth -= int(has_rtns) + int(has_rtname)
- def __call__(self, multiname):
- return self.specialize(multiname=multiname)
- class _Avm2SetLocalInstruction(_Avm2U30Instruction):
- @needs_specialized
- def __call__(self, index):
- _speed = {0: setlocal_0, 1: setlocal_1, 2: setlocal_2, 3: setlocal_3}
- if index in _speed:
- return _speed[index]
- return self.specialize(index=index)
- class _Avm2GetLocalInstruction(_Avm2ShortInstruction):
- def __call__(self, index):
- _speed = {0: getlocal_0, 1: getlocal_1, 2: getlocal_2, 3: getlocal_3}
- if index in _speed:
- return _speed[index]
- return self.specialize(index=index)
- class _Avm2OffsetInstruction(_Avm2ShortInstruction):
- @needs_specialized
- def _repr(self):
- return repr(super(_Avm2OffsetInstruction, self))[:-2] + " lbl=%r)>" % self.lbl
- @needs_specialized
- def _set_assembler_props(self, asm):
- super(_Avm2OffsetInstruction, self)._set_assembler_props
- if self.lbl is None:
- self.lbl = Avm2Label(asm)
- self.asm = asm
- @needs_specialized
- def _serialize(self):
- code = chr(self.opcode)
- code += self.lbl.write_relative_offset(len(self.asm) + 4, len(self.asm) + 1)
- return code
- def __call__(self, lbl=None):
- return self.specialize(lbl=lbl)
- class _Avm2LookupSwitchInstruction(_Avm2ShortInstruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- super(_Avm2LookupSwitchInstruction, self)._set_assembler_props(asm)
- self.asm = asm
- if self.default_label is None:
- self.default_label = Avm2Label(asm)
- if isinstance(self.case_labels, int):
- self.case_labels = [Avm2Label(asm) for i in xrange(self.case_labels)]
- @needs_specialized
- def _serialize(self):
- code = chr(self.opcode)
- base = len(self.asm)
- code += self.default_label.write_relative_offset(base, base+1)
- code += u32(len(self.case_labels) - 1)
- for lbl in self.case_labels:
- location = base + len(code)
- code += lbl.write_relative_offset(base, location)
- return code
- def __call__(self, default_label=None, case_labels=None):
- return self.specialize(default_label=default_label, case_labels=case_labels)
- class _Avm2LabelInstruction(_Avm2ShortInstruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- super(_Avm2LabelInstruction, self)._set_assembler_props(asm)
- if self.lbl == None:
- self.define = True
- self.lbl = Avm2Label(asm)
- else:
- assert self.lbl.address == -1
- asm.stack_depth = self.lbl.stack_depth
- asm.scope_depth = self.lbl.scope_depth
- self.lbl.address = len(asm)
- @needs_specialized
- def _serialize(self):
- if self.define:
- return label_internal.serialize()
- return ""
- def __call__(self, lbl=None):
- return self.specialize(lbl=lbl, define=False)
- class _Avm2Call(_Avm2U30Instruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- asm.stack_depth += 1 - (self.argument + 2) # push function/receiver/args; push result
- class _Avm2Construct(_Avm2U30Instruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- asm.stack_depth += 1 - (self.argument + 1) # push object/args; push result
- class _Avm2ConstructSuper(_Avm2U30Instruction):
- @needs_specialized
- def _set_assembler_props(self, asm):
- asm.stack_depth += self.argument + 1 # pop receiver/args
- class _Avm2CallIDX(_Avm2U30Instruction):
- @needs_specialized
- def _serialize(self):
- return chr(self.opcode) + u32(self.index) + u32(self.argument)
- @needs_specialized
- def _set_assembler_props(self, asm):
- self.index = asm.constants.multiname_pool.index_for(self.multiname)
- asm.stack_depth += 1 - (self.argument + 1) # push object/args; push result
- def __call__(self, multiname, num_args):
- return self.specialize(multiname=multiname, argument=num_args)
- class _Avm2CallMN(_Avm2CallIDX):
- is_void = False
- @needs_specialized
- def _set_assembler_props(self, asm):
- has_rtns = asm.constants.has_RTNS(self.multiname)
- has_rtname = asm.constants.has_RTName(self.multiname)
- asm.stack_depth += int(self.is_void) - (1 + int(has_rtns) + int(has_rtname) + self.argument)
- def __call__(self, multiname, num_args):
- return self.specialize(multiname=multiname, argument=num_args)
Add Comment
Please, Sign In to add comment