def __str__(self): self.check() instrnamestr = self.name if self._opcode <= 17 else "illegal{0}".format(self._opcode) instrstr = None if self._opcode > 17: return ''.join([labelstr, "illegal{0}\t{1}, {2}, {3}".format(self._opcode, self._subOpcode, self._parameter)]) elif self._opcode in (0, 8, 15): # nop, return, exit instrstr = "{0}".format((self._subOpcode, self._parameter)) if\ not (self._subOpcode, self._parameter) == (0, 0) else "" elif self._opcode == 1: # operator instrstr = FunctionInfo.getOperatorName(self._subOpcode) elif self._opcode == 2: # ldimm if self._subOpcode == 0: instrstr = 'none_t, ={0}'.format('None' if self.ctx is None or self.ctx.sections["CODE"].instructions[self._position + 1] == 0 else self.ctx.sections["CODE"].instructions[self._position + 1]) elif self._subOpcode == 1: instrstr = 'int, ={0}'.format("" if self.ctx is None else str(self.ctx.sections["CODE"].instructions[self._position + 1])) elif self._subOpcode == 2: if self.ctx is None: instrstr = 'float, =' else: fstr = '{0:.7g}'.format(self.ctx.sections["CODE"].instructions[self._position + 1])#.rstrip('0') fstr = fstr if fstr else "0." instrstr = 'float, ={0}'.format(fstr) elif self._subOpcode == 3: instrstr = 'str, ={0}'.format(self._parameter if self.ctx is None or self.ctx.sections.get("STRG") is None else '"{0}"'.format(self.ctx.sections["STRG"].getString(self._parameter))) elif self._subOpcode == 4: instrstr = "vector, ={0}".format(self._parameter if self.ctx is None or self.ctx.sections.get("VECT") is None else "<{0}, {1}, {2}>".format(*self.ctx.sections["VECT"].vectors[self._parameter]) ) elif self._subOpcode == 0x2c: instrstr = "type44, {0}".format(self._parameter & 0xffff) # unsigned parameter elif self._subOpcode == 0x35: typestr = "codeptr_t" valuestr = "={0}".format(hex(self.ctx.sections["CODE"].instructions[self._position + 1])\ if self.ctx is not None else "") else: instrstr = "{0}, {1}".format(self._subOpcode, self._parameter & 0xffff) elif self._opcode in (3, 4, 17): # ldvar, setvar, ldncpvar instrstr = self.variableName elif self._opcode == 5: # setvector instrstr = "{0}, {1}".format(self.__class__.vectorCoordNames[self.subSubOpcodes[0]], self.variableName) elif self._opcode in (6, 13, 14): # pop, reserve, release instrstr = "{0}{1}".format(self._subOpcode, "" if self._parameter == 0 else\ "(, {0})".format(self._parameter)) elif self._opcode in (7, 10, 11, 12): # call/jmptrue/jmpfalse/jmp instrID = self.instructionID instrstr = hex(instrID) if (self.ctx is None or instrID >= len(self.ctx.sections["CODE"].instructions))\ else self.ctx.sections["CODE"].labels[instrID] elif self._opcode == 9: # callstd instrstr = FunctionInfo.getStdFunctionName(self._subOpcode, self._parameter) elif self._opcode == 16: # setline instrstr = str(self._parameter) ret = ''.join([instrnamestr, (14 - len(instrnamestr)) * ' ', instrstr]) return ret
def __str__(self): self.check() instrnamestr = self.name if self._opcode <= 17 else "illegal{0}".format( self._opcode) instrstr = None if self._opcode > 17: return ''.join([ labelstr, "illegal{0}\t{1}, {2}, {3}".format(self._opcode, self._subOpcode, self._parameter) ]) elif self._opcode in (0, 8, 15): # nop, return, exit instrstr = "{0}".format((self._subOpcode, self._parameter)) if\ not (self._subOpcode, self._parameter) == (0, 0) else "" elif self._opcode == 1: # operator instrstr = FunctionInfo.getOperatorName(self._subOpcode) elif self._opcode == 2: # ldimm if self._subOpcode == 0: instrstr = 'none_t, ={0}'.format( 'None' if self.ctx is None or self.ctx.sections["CODE"]. instructions[self._position + 1] == 0 else self.ctx. sections["CODE"].instructions[self._position + 1]) elif self._subOpcode == 1: instrstr = 'int, ={0}'.format("" if self.ctx is None else str( self.ctx.sections["CODE"].instructions[self._position + 1])) elif self._subOpcode == 2: if self.ctx is None: instrstr = 'float, =' else: fstr = '{0:.7g}'.format( self.ctx.sections["CODE"].instructions[ self._position + 1]) #.rstrip('0') fstr = fstr if fstr else "0." instrstr = 'float, ={0}'.format(fstr) elif self._subOpcode == 3: instrstr = 'str, ={0}'.format( self._parameter if self.ctx is None or self.ctx.sections.get("STRG") is None else '"{0}"'.format( self.ctx.sections["STRG"].getString(self._parameter))) elif self._subOpcode == 4: instrstr = "vector, ={0}".format( self._parameter if self.ctx is None or self.ctx.sections. get("VECT") is None else "<{0}, {1}, {2}>".format( *self.ctx.sections["VECT"].vectors[self._parameter])) elif self._subOpcode == 0x2c: instrstr = "type44, {0}".format(self._parameter & 0xffff) # unsigned parameter elif self._subOpcode == 0x35: typestr = "codeptr_t" valuestr = "={0}".format(hex(self.ctx.sections["CODE"].instructions[self._position + 1])\ if self.ctx is not None else "") else: instrstr = "{0}, {1}".format(self._subOpcode, self._parameter & 0xffff) elif self._opcode in (3, 4, 17): # ldvar, setvar, ldncpvar instrstr = self.variableName elif self._opcode == 5: # setvector instrstr = "{0}, {1}".format( self.__class__.vectorCoordNames[self.subSubOpcodes[0]], self.variableName) elif self._opcode in (6, 13, 14): # pop, reserve, release instrstr = "{0}{1}".format(self._subOpcode, "" if self._parameter == 0 else\ "(, {0})".format(self._parameter)) elif self._opcode in (7, 10, 11, 12): # call/jmptrue/jmpfalse/jmp instrID = self.instructionID instrstr = hex(instrID) if (self.ctx is None or instrID >= len(self.ctx.sections["CODE"].instructions))\ else self.ctx.sections["CODE"].labels[instrID] elif self._opcode == 9: # callstd instrstr = FunctionInfo.getStdFunctionName(self._subOpcode, self._parameter) elif self._opcode == 16: # setline instrstr = str(self._parameter) ret = ''.join([instrnamestr, (14 - len(instrnamestr)) * ' ', instrstr]) return ret
def check(self): self._nextPosition = self._position + 1 instrID = self.instructionID if self._opcode > 17: warnings.warn("illegal opcode encountered (opcode {0} \ at instruction #{1})".format(self._opcode, hex(self.position))) elif self._opcode == 1: if FunctionInfo.getOperatorName(self._subOpcode) == str(self._subOpcode): warnings.warn("invalid operator encountered (operator '{0}' \ at instruction #{1})".format(FunctionInfo.getOperatorName(self._subOpcode), hex(self.position))) elif self._opcode == 2: if self.ctx is not None: packed = None if self._subOpcode in (0, 1, 2, 0x35): assert not isinstance(self.ctx.sections["CODE"].instructions[self._position + 1], self.__class__) packed = struct.pack(">f", self.ctx.sections["CODE"].instructions[self._position + 1]) if\ type(self.ctx.sections["CODE"].instructions[self._position + 1]) is float else\ struct.pack(">I", self.ctx.sections["CODE"].instructions[self._position + 1] & 0xffffffff) if self._subOpcode in (0, 0x35): # none_t/codeptr_t self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack(">I", packed)[0] self._nextPosition = self._position + 2 if self._subOpcode == 1: # int self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack(">i", packed)[0] self._nextPosition = self._position + 2 elif self._subOpcode == 2: # float self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack(">f", packed)[0] self._nextPosition = self._position + 2 if self._subOpcode == 3: if self._parameter < 0: warnings.warn("negative string offset encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) elif self._subOpcode == 4: if self._parameter < 0: warnings.warn("negative vector ID encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) elif self._subOpcode not in (0, 1, 2, 3, 4, 0x35, 0x2c): warnings.warn("ldimm does not support this type ({0} \ at instruction #{1})".format(self._subOpcode, hex(self.position))) elif self._opcode in (3, 4, 17): # ldvar, setvar, ldncpvar self.checkVariable() if self.subSubOpcodes[1] == 3 and self._opcode == 4: warnings.warn("cannot change immutable reference (instruction #{0})".format(hex(self.position))) elif self._opcode == 5: # setvector vecindex, veclevel = self.subSubOpcodes if vecindex == 4: warnings.warn("out-of-range vector coordinate index encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) if veclevel == 3: warnings.warn("Invalid vector storage type encountered \ (instruction #{0})".format(hex(self.position))) elif self._opcode in (7, 10, 11, 12): # call/jmptrue/jmpfalse/jmp if self.ctx is not None: if instrID >= len(self.ctx.sections["CODE"].instructions): warnings.warn("out-of-range destination \ instruction encountered in jump/call instruction \ (at instruction #{0}: {1}\t{2})".format(hex(self.position), self.name, hex(instrID))) else: if self._opcode == 7 and instrID not in self.ctx.sections["HEAD"].functionOffsets: warnings.warn("call to unreferenced function ({0} \ at instruction #{1})".format(instrID, hex(self.position))) lbl = ''.join(["sub_" if self._opcode == 7 else "loc_", hex(instrID)[2:]]) if not self.ctx.sections["CODE"].labels[instrID]: self.ctx.sections["CODE"].labels[instrID] = lbl if self._opcode != 7 and (True if self.ctx is None else self.position+1 < len(self.ctx.sections["CODE"].instructions)) : lbl2 = ''.join(["loc_", hex(self.position+1)[2:]]) if not self.ctx.sections["CODE"].labels[self.position+1]: self.ctx.sections["CODE"].labels[self.position+1] = lbl2 elif self._opcode == 9: # callstd if FunctionInfo.stdfunctions_name_dict.get(self._subOpcode) is None: warnings.warn("invalid class id encountered ({0} \ at instruction #{1})".format(self._subOpcode, hex(self.position)))
def check(self): self._nextPosition = self._position + 1 instrID = self.instructionID if self._opcode > 17: warnings.warn("illegal opcode encountered (opcode {0} \ at instruction #{1})".format(self._opcode, hex(self.position))) elif self._opcode == 1: if FunctionInfo.getOperatorName(self._subOpcode) == str( self._subOpcode): warnings.warn("invalid operator encountered (operator '{0}' \ at instruction #{1})".format(FunctionInfo.getOperatorName(self._subOpcode), hex(self.position))) elif self._opcode == 2: if self.ctx is not None: packed = None if self._subOpcode in (0, 1, 2, 0x35): assert not isinstance( self.ctx.sections["CODE"].instructions[self._position + 1], self.__class__) packed = struct.pack(">f", self.ctx.sections["CODE"].instructions[self._position + 1]) if\ type(self.ctx.sections["CODE"].instructions[self._position + 1]) is float else\ struct.pack(">I", self.ctx.sections["CODE"].instructions[self._position + 1] & 0xffffffff) if self._subOpcode in (0, 0x35): # none_t/codeptr_t self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack( ">I", packed)[0] self._nextPosition = self._position + 2 if self._subOpcode == 1: # int self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack( ">i", packed)[0] self._nextPosition = self._position + 2 elif self._subOpcode == 2: # float self.ctx.sections["CODE"].instructions[self._position + 1] = struct.unpack( ">f", packed)[0] self._nextPosition = self._position + 2 if self._subOpcode == 3: if self._parameter < 0: warnings.warn("negative string offset encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) elif self._subOpcode == 4: if self._parameter < 0: warnings.warn("negative vector ID encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) elif self._subOpcode not in (0, 1, 2, 3, 4, 0x35, 0x2c): warnings.warn("ldimm does not support this type ({0} \ at instruction #{1})".format(self._subOpcode, hex(self.position))) elif self._opcode in (3, 4, 17): # ldvar, setvar, ldncpvar self.checkVariable() if self.subSubOpcodes[1] == 3 and self._opcode == 4: warnings.warn( "cannot change immutable reference (instruction #{0})". format(hex(self.position))) elif self._opcode == 5: # setvector vecindex, veclevel = self.subSubOpcodes if vecindex == 4: warnings.warn( "out-of-range vector coordinate index encountered ({0} \ at instruction #{1})".format(self._parameter, hex(self.position))) if veclevel == 3: warnings.warn("Invalid vector storage type encountered \ (instruction #{0})".format(hex(self.position))) elif self._opcode in (7, 10, 11, 12): # call/jmptrue/jmpfalse/jmp if self.ctx is not None: if instrID >= len(self.ctx.sections["CODE"].instructions): warnings.warn("out-of-range destination \ instruction encountered in jump/call instruction \ (at instruction #{0}: {1}\t{2})".format(hex(self.position), self.name, hex(instrID))) else: if self._opcode == 7 and instrID not in self.ctx.sections[ "HEAD"].functionOffsets: warnings.warn("call to unreferenced function ({0} \ at instruction #{1})".format(instrID, hex(self.position))) lbl = ''.join([ "sub_" if self._opcode == 7 else "loc_", hex(instrID)[2:] ]) if not self.ctx.sections["CODE"].labels[instrID]: self.ctx.sections["CODE"].labels[instrID] = lbl if self._opcode != 7 and ( True if self.ctx is None else self.position + 1 < len(self.ctx.sections["CODE"].instructions)): lbl2 = ''.join(["loc_", hex(self.position + 1)[2:]]) if not self.ctx.sections["CODE"].labels[self.position + 1]: self.ctx.sections["CODE"].labels[self.position + 1] = lbl2 elif self._opcode == 9: # callstd if FunctionInfo.stdfunctions_name_dict.get( self._subOpcode) is None: warnings.warn("invalid class id encountered ({0} \ at instruction #{1})".format(self._subOpcode, hex(self.position)))