def int2Rational(num, den): assert isinstance(num, int) assert isinstance(den, int) if den < 0: # expects den to be an unsigned long int num, den = (-1) * num, (-1) * den result = Rational() c_mpq_set_si(result.value, rffi.r_long(num), rffi.r_ulong(den)) c_mpq_canonicalize(result.value) return result
def same(self, other): if not isinstance(other, Real): return False # Approximate numbers with machine precision or higher are considered # equal if they differ in at most their last seven binary digits prec = min(self.prec, other.prec) - 7 # TODO: # For numbers below machine precision the required tolerance is reduced # in proportion to the precision of the numbers. return c_mpf_eq(self.value, other.value, rffi.r_ulong(prec)) != 0
def from_object(obj): if as_i(obj.getitem(space.String(u"version"))) != 0: raise space.unwind(space.LError(u"bytecode version=0 required")) sources = as_list(obj.getitem(space.String(u"sources"))) constants = as_list(obj.getitem(space.String(u"constants"))) functions = [] for function_list in as_list(obj.getitem(space.String(u"functions"))): flags = as_i( function_list.getitem(space.String(u"flags"))) regc = as_i( function_list.getitem(space.String(u"regc"))) argc = rffi.r_ulong(as_i( function_list.getitem(space.String(u"argc")))) topc = rffi.r_ulong(as_i( function_list.getitem(space.String(u"topc")))) localc = as_i( function_list.getitem(space.String(u"localc"))) block_list = as_u8a(function_list.getitem(space.String(u"code"))) sourcemap = function_list.getitem(space.String(u"sourcemap")) exc_table = as_list(function_list.getitem(space.String(u"exceptions"))) block = lltype.malloc(u16_array, block_list.length/2) for i in range(block_list.length/2): a = rffi.r_long(block_list.uint8data[i*2+0]) b = rffi.r_long(block_list.uint8data[i*2+1]) block[i] = rffi.r_ushort((a << 8) | b) excs = [] for n in exc_table: excs.append(Exc( rffi.r_ulong(as_i(n.getitem(space.Integer(0)))), rffi.r_ulong(as_i(n.getitem(space.Integer(1)))), rffi.r_ulong(as_i(n.getitem(space.Integer(2)))), rffi.r_ulong(as_i(n.getitem(space.Integer(3)))), )) functions.append(Function(flags, regc, argc, topc, localc, block, sourcemap, excs[:])) return Program(Unit(constants[:], functions[:], sources[:]))
def from_object(obj): constants_list = obj.getitem(space.String(u"constants")) assert isinstance(constants_list, space.List) constants = constants_list.contents functions = [] functions_list = obj.getitem(space.String(u"functions")) assert isinstance(functions_list, space.List) for function_list in functions_list.contents: flags = as_i( function_list.getitem(space.Integer(0)) ) regc = as_i( function_list.getitem(space.Integer(1)) ) argc = rffi.r_ulong(as_i( function_list.getitem(space.Integer(2)))) topc = rffi.r_ulong(as_i( function_list.getitem(space.Integer(3)))) localc = as_i( function_list.getitem(space.Integer(4)) ) block_list = function_list.getitem(space.Integer(5)) sourcemap = function_list.getitem(space.Integer(6)) exc_table = function_list.getitem(space.Integer(7)) assert isinstance(exc_table, space.List) assert isinstance(block_list, space.List) block = lltype.malloc(u16_array, len(block_list.contents)) i = 0 for n in block_list.contents: block[i] = rffi.r_ushort( as_i(n) ) i += 1 excs = [] for n in exc_table.contents: excs.append(Exc( rffi.r_ulong(as_i(n.getitem(space.Integer(0)))), rffi.r_ulong(as_i(n.getitem(space.Integer(1)))), rffi.r_ulong(as_i(n.getitem(space.Integer(2)))), rffi.r_ulong(as_i(n.getitem(space.Integer(3)))), )) functions.append(Function(flags, regc, argc, topc, localc, block, sourcemap, excs[:])) return Program(Unit(constants[:], functions[:]))
def from_object(obj): if as_i(obj.getitem(space.String(u"version"))) != 0: raise space.unwind(space.LError(u"bytecode version=0 required")) sources = as_list(obj.getitem(space.String(u"sources"))) constants = as_list(obj.getitem(space.String(u"constants"))) functions = [] for function_list in as_list(obj.getitem(space.String(u"functions"))): flags = as_i(function_list.getitem(space.String(u"flags"))) regc = as_i(function_list.getitem(space.String(u"regc"))) argc = rffi.r_ulong(as_i(function_list.getitem(space.String(u"argc")))) topc = rffi.r_ulong(as_i(function_list.getitem(space.String(u"topc")))) localc = as_i(function_list.getitem(space.String(u"localc"))) block_list = as_u8a(function_list.getitem(space.String(u"code"))) sourcemap = function_list.getitem(space.String(u"sourcemap")) exc_table = as_list(function_list.getitem(space.String(u"exceptions"))) block = lltype.malloc(u16_array, block_list.length / 2) for i in range(block_list.length / 2): a = rffi.r_long(block_list.uint8data[i * 2 + 0]) b = rffi.r_long(block_list.uint8data[i * 2 + 1]) block[i] = rffi.r_ushort((a << 8) | b) excs = [] for n in exc_table: excs.append( Exc( rffi.r_ulong(as_i(n.getitem(space.Integer(0)))), rffi.r_ulong(as_i(n.getitem(space.Integer(1)))), rffi.r_ulong(as_i(n.getitem(space.Integer(2)))), rffi.r_ulong(as_i(n.getitem(space.Integer(3)))), )) functions.append( Function(flags, regc, argc, topc, localc, block, sourcemap, excs[:])) return Program(Unit(constants[:], functions[:], sources[:]))
def from_object(obj, path): if as_i(obj.getitem(space.String(u"version"))) != 0: raise space.unwind(space.LError(u"bytecode version=0 required")) sources = as_list(obj.getitem(space.String(u"sources"))) constants = as_list(obj.getitem(space.String(u"constants"))) functions = [] for function_list in as_list(obj.getitem(space.String(u"functions"))): flags = as_i(function_list.getitem(space.String(u"flags"))) regc = as_i(function_list.getitem(space.String(u"regc"))) argc = rffi.r_ulong(as_i(function_list.getitem(space.String(u"argc")))) topc = rffi.r_ulong(as_i(function_list.getitem(space.String(u"topc")))) localc = as_i(function_list.getitem(space.String(u"localc"))) block_list = as_u8a(function_list.getitem(space.String(u"code"))) sourcemap = function_list.getitem(space.String(u"sourcemap")) exc_table = as_list(function_list.getitem(space.String(u"exceptions"))) block = [ getindex_u16(block_list, i) for i in range(block_list.length / 2) ] #block = lltype.malloc(u16_array, block_list.length/2) #for i in range(block_list.length/2): # a = rffi.r_long(block_list.uint8data[i*2+0]) # b = rffi.r_long(block_list.uint8data[i*2+1]) # block[i] = rffi.r_ushort((a << 8) | b) excs = [ Exc(rffi.r_ulong(as_i(n.getitem(space.Integer(0)))), rffi.r_ulong(as_i(n.getitem(space.Integer(1)))), rffi.r_ulong(as_i(n.getitem(space.Integer(2)))), rffi.r_ulong(as_i(n.getitem(space.Integer(3))))) for n in exc_table ] varnames = space.null # Backwards compatible approach. if function_list.contains(space.String( u"varnames")): # Consider improvements in the major release. varnames = function_list.getitem(space.String(u"varnames")) functions.append( Function(flags, regc, argc, topc, localc, block, sourcemap, excs[:], varnames)) return Program(Unit(constants[:], functions[:], sources[:], path))
def from_object(obj): constants_list = obj.getitem(space.String(u"constants")) assert isinstance(constants_list, space.List) constants = constants_list.contents functions = [] functions_list = obj.getitem(space.String(u"functions")) assert isinstance(functions_list, space.List) for function_list in functions_list.contents: flags = as_i(function_list.getitem(space.Integer(0))) regc = as_i(function_list.getitem(space.Integer(1))) argc = rffi.r_ulong(as_i(function_list.getitem(space.Integer(2)))) topc = rffi.r_ulong(as_i(function_list.getitem(space.Integer(3)))) localc = as_i(function_list.getitem(space.Integer(4))) block_list = function_list.getitem(space.Integer(5)) sourcemap = function_list.getitem(space.Integer(6)) exc_table = function_list.getitem(space.Integer(7)) assert isinstance(exc_table, space.List) assert isinstance(block_list, space.List) block = lltype.malloc(u16_array, len(block_list.contents)) i = 0 for n in block_list.contents: block[i] = rffi.r_ushort(as_i(n)) i += 1 excs = [] for n in exc_table.contents: excs.append( Exc( rffi.r_ulong(as_i(n.getitem(space.Integer(0)))), rffi.r_ulong(as_i(n.getitem(space.Integer(1)))), rffi.r_ulong(as_i(n.getitem(space.Integer(2)))), rffi.r_ulong(as_i(n.getitem(space.Integer(3)))), )) functions.append( Function(flags, regc, argc, topc, localc, block, sourcemap, excs[:])) return Program(Unit(constants[:], functions[:]))
def interpret(pc, block, frame): function = jit.promote(frame.function) module = jit.promote(frame.module) unit = jit.promote(frame.unit) excs = jit.promote(frame.excs) try: while pc < len(block): try: jitdriver.jit_merge_point(pc=pc, block=block, module=module, unit=unit, excs=excs, function=function, frame=frame) #ec=ec, regv=regv, opcode = rffi.r_ulong(block[pc]) >> 8 ix = pc + 1 pc = ix + (rffi.r_ulong(block[pc]) & 255) # Not sure.. #if ec.debug_hook is not None: # hook, ec.debug_hook = ec.debug_hook, None # res = ec.debug_hook.call([DebugContext(rffi.r_long(ix), unit, frame)]) # if res != space.null: # ec.debug_hook = res #print optable.dec[opcode][0] regv = frame # from now on.. if opcode == opcode_of('assert'): obj = regv.load(block[ix + 0]) raise space.unwind(space.LAssertionError(obj)) elif opcode == opcode_of('raise'): obj = regv.load(block[ix + 0]) traceback = obj.getattr(u"traceback") if traceback is space.null: traceback = space.List([]) obj.setattr(u"traceback", traceback) elif not isinstance(traceback, space.List): raise space.unwind( space.LError( u"Expected null or list as .traceback: %s" % obj.repr())) raise space.Unwinder(obj, traceback) elif opcode == opcode_of('constant'): regv.store(block[ix + 0], unit.constants[block[ix + 1]]) elif opcode == opcode_of('list'): contents = [] for i in range(ix + 1, pc): contents.append(regv.load(block[i])) regv.store(block[ix], space.List(contents)) elif opcode == opcode_of('move'): regv.store(block[ix + 0], regv.load(block[ix + 1])) elif opcode == opcode_of('call'): op_call(regv, block, ix, pc) elif opcode == opcode_of('callv'): op_callv(regv, block, ix, pc) elif opcode == opcode_of('return'): return regv.load(block[ix + 0]) elif opcode == opcode_of('yield'): result = regv.load(block[ix + 0]) jit.hint(frame, force_virtualizable=True) raise Yield(pc, result) elif opcode == opcode_of('jump'): pc = rffi.r_ulong(block[ix + 0]) elif opcode == opcode_of('cond'): if space.is_false(regv.load(block[ix + 0])): pc = rffi.r_ulong(block[ix + 2]) else: pc = rffi.r_ulong(block[ix + 1]) elif opcode == opcode_of('func'): regv.store(block[ix + 0], Closure(frame, unit.functions[block[ix + 1]])) elif opcode == opcode_of('iter'): regv.store(block[ix + 0], regv.load(block[ix + 1]).iter()) elif opcode == opcode_of('next'): try: regv.store( block[ix + 0], regv.load(block[ix + 1]).callattr(u'next', [])) except StopIteration as _: pc = rffi.r_ulong(block[ix + 2]) elif opcode == opcode_of('getattr'): name = get_string(unit, block, ix + 2) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.getattr(name)) elif opcode == opcode_of('setattr'): value = regv.load(block[ix + 3]) name = get_string(unit, block, ix + 2) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.setattr(name, value)) elif opcode == opcode_of('getitem'): index = regv.load(block[ix + 2]) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.getitem(index)) elif opcode == opcode_of('setitem'): item = regv.load(block[ix + 3]) index = regv.load(block[ix + 2]) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.setitem(index, item)) elif opcode == opcode_of('getloc'): regv.store(block[ix + 0], frame.load_local(block[ix + 1])) elif opcode == opcode_of('setloc'): value = regv.load(block[ix + 2]) frame.store_local(block[ix + 1], value) regv.store(block[ix + 0], value) elif opcode == opcode_of('getupv'): value = get_upframe(frame, block[ix + 1]).load_local( block[ix + 2]) regv.store(block[ix + 0], value) elif opcode == opcode_of('setupv'): value = regv.load(block[ix + 3]) get_upframe(frame, block[ix + 1]).store_local( block[ix + 2], value) regv.store(block[ix + 0], value) elif opcode == opcode_of('getglob'): regv.store(block[ix + 0], module.getattr(get_string(unit, block, ix + 1))) elif opcode == opcode_of('setglob'): regv.store( block[ix + 0], module.setattr(get_string(unit, block, ix + 1), regv.load(block[ix + 2]))) elif opcode == opcode_of('loglob'): src_module = regv.load(block[ix + 0]) assert isinstance(src_module, space.Module) for name in src_module.list_locals(): module.setattr(name, src_module.getattr(name)) elif opcode == opcode_of('not'): if space.is_false(regv.load(block[ix + 1])): regv.store(block[ix + 0], space.true) else: regv.store(block[ix + 0], space.false) elif opcode == opcode_of('isnull'): if regv.load(block[ix + 1]) is space.null: regv.store(block[ix + 0], space.true) else: regv.store(block[ix + 0], space.false) elif opcode == opcode_of('contains'): v0 = regv.load(block[ix + 1]) v1 = regv.load(block[ix + 2]) if v0.contains(v1): regv.store(block[ix + 0], space.true) else: regv.store(block[ix + 0], space.false) else: raise space.unwind( space.LInstructionError( optable.names.get(opcode, str(opcode)).decode('utf-8'), opcode)) except space.Unwinder as unwinder: #print "exception detected, doing unwinds", pc, unwinder.exception.repr() for exc in excs: #print exc.start, exc.stop, exc.label, exc.reg if exc.start < pc <= exc.stop: frame.store(exc.reg, unwinder.exception) pc = exc.label #print "exception handler found" break else: raise except StopIteration as stop: # Doing an exception check to see if .next() was called in try block. unwinder = space.unwind(space.LUncatchedStopIteration()) for exc in excs: if exc.start < pc <= exc.stop: frame.store(exc.reg, unwinder.exception) pc = exc.label break else: raise unwinder except space.Unwinder as unwinder: unwinder.traceback.contents.append( TraceEntry(rffi.r_long(pc), unit.sources, frame.sourcemap, unit.path)) raise return space.null
def get_printable_location(pc, block, module, unit, excs, function): # ,ec opcode = rffi.r_ulong(block[pc]) >> 8 name = optable.names[opcode] return "pc=%d %s module=%s" % (pc, name, module.repr().encode('utf-8'))
def interpret(pc, block, regv, frame): module = jit.promote(frame.module) unit = jit.promote(frame.unit) excs = jit.promote(frame.excs) try: while pc < len(block): try: jitdriver.jit_merge_point( pc=pc, block=block, module=module, unit=unit, excs=excs, regv=regv, frame=frame) opcode = rffi.r_ulong(block[pc])>>8 ix = pc+1 pc = ix+(rffi.r_ulong(block[pc])&255) #print optable.dec[opcode][0] if opcode == opcode_of('assert'): obj = regv.load(block[ix+0]) raise space.unwind(space.LAssertionError(obj)) elif opcode == opcode_of('raise'): obj = regv.load(block[ix+0]) traceback = obj.getattr(u"traceback") if traceback is space.null: traceback = space.List([]) obj.setattr(u"traceback", traceback) elif not isinstance(traceback, space.List): raise space.unwind(space.LError(u"Expected null or list as .traceback: %s" % obj.repr())) raise space.Unwinder(obj, traceback) elif opcode == opcode_of('constant'): regv.store(block[ix+0], unit.constants[block[ix+1]]) elif opcode == opcode_of('list'): contents = [] for i in range(ix+1, pc): contents.append(regv.load(block[i])) regv.store(block[ix], space.List(contents)) elif opcode == opcode_of('move'): regv.store(block[ix+0], regv.load(block[ix+1])) elif opcode == opcode_of('call'): op_call(regv, block, ix, pc) elif opcode == opcode_of('callv'): op_callv(regv, block, ix, pc) elif opcode == opcode_of('return'): return regv.load(block[ix+0]) elif opcode == opcode_of('jump'): pc = rffi.r_ulong(block[ix+0]) elif opcode == opcode_of('cond'): if space.is_false(regv.load(block[ix+0])): pc = rffi.r_ulong(block[ix+2]) else: pc = rffi.r_ulong(block[ix+1]) elif opcode == opcode_of('func'): regv.store(block[ix+0], Closure(frame, unit.functions[block[ix+1]])) elif opcode == opcode_of('iter'): regv.store(block[ix+0], regv.load(block[ix+1]).iter()) elif opcode == opcode_of('next'): try: regv.store(block[ix+0], regv.load(block[ix+1]).callattr(u'next', [])) except StopIteration as _: pc = rffi.r_ulong(block[ix+2]) # this is missing. #elif isinstance(op, Yield): # raise YieldIteration(op.block, loop_break, op.i, regv.load(op.value.i)) elif opcode == opcode_of('getattr'): name = get_string(unit, block, ix+2) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.getattr(name)) elif opcode == opcode_of('setattr'): value = regv.load(block[ix+3]) name = get_string(unit, block, ix+2) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.setattr(name, value)) elif opcode == opcode_of('getitem'): index = regv.load(block[ix+2]) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.getitem(index)) elif opcode == opcode_of('setitem'): item = regv.load(block[ix+3]) index = regv.load(block[ix+2]) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.setitem(index, item)) elif opcode == opcode_of('getloc'): regv.store(block[ix+0], frame.local[block[ix+1]]) elif opcode == opcode_of('setloc'): value = regv.load(block[ix+2]) frame.local[block[ix+1]] = value regv.store(block[ix+0], value) elif opcode == opcode_of('getupv'): value = get_upframe(frame, block[ix+1]).local[block[ix+2]] regv.store(block[ix+0], value) elif opcode == opcode_of('setupv'): value = regv.load(block[ix+3]) get_upframe(frame, block[ix+1]).local[block[ix+2]] = value regv.store(block[ix+0], value) elif opcode == opcode_of('getglob'): regv.store(block[ix+0], module.getattr(get_string(unit, block, ix+1))) elif opcode == opcode_of('setglob'): regv.store(block[ix+0], module.setattr( get_string(unit, block, ix+1), regv.load(block[ix+2]))) elif opcode == opcode_of('not'): if space.is_false(regv.load(block[ix+1])): regv.store(block[ix+0], space.true) else: regv.store(block[ix+0], space.false) elif opcode == opcode_of('contains'): v0 = regv.load(block[ix+1]) v1 = regv.load(block[ix+2]) if v0.contains(v1): regv.store(block[ix+0], space.true) else: regv.store(block[ix+0], space.false) else: raise space.unwind(space.LInstructionError( optable.names.get(opcode, str(opcode)).decode('utf-8'), opcode)) except space.Unwinder as unwinder: #print "exception detected, doing unwinds", pc, unwinder.exception.repr() for exc in excs: #print exc.start, exc.stop, exc.label, exc.reg if exc.start < pc <= exc.stop: regv.store(exc.reg, unwinder.exception) pc = exc.label #print "exception handler found" break else: raise except StopIteration as stop: unwinder = space.unwind(space.LUncatchedStopIteration()) unwinder.traceback.contents.append(TraceEntry(rffi.r_long(pc), unit.sources, frame.sourcemap)) raise unwinder except space.Unwinder as unwinder: unwinder.traceback.contents.append(TraceEntry(rffi.r_long(pc), unit.sources, frame.sourcemap)) raise return space.null
def new_register_array(regc): regs = [] for i in range(regc): regs.append(space.null) return RegisterArray(regs) def get_printable_location(pc, iterstop, block, module, unit): return "pc=%d module=%s" % (pc, module.repr().encode('utf-8')) jitdriver = jit.JitDriver( greens=['pc', 'iterstop', 'block', 'module', 'unit'], reds=['regv', 'frame'], virtualizables = ['regv'], get_printable_location=get_printable_location) LARGE_PC = rffi.r_ulong(0xFFFFFFFF) def interpret(pc, block, regv, frame, iterstop=LARGE_PC): module = jit.promote(frame.module) unit = jit.promote(frame.unit) try: while pc < len(block): jitdriver.jit_merge_point( pc=pc, block=block, module=module, unit=unit, iterstop=iterstop, regv=regv, frame=frame) opcode = rffi.r_ulong(block[pc])>>8 ix = pc+1 pc = ix+(rffi.r_ulong(block[pc])&255) if opcode == opcode_of('assert'): if space.is_false(regv.load(block[ix+0])): raise space.Error(u"Assertion error")
def __init__(self, prec): Number.__init__(self) self.prec = prec self.value = lltype.malloc(MPF_STRUCT, flavor='raw') c_mpf_init2(self.value, rffi.r_ulong(prec))
def get_printable_location(pc, block, module, unit, excs, function): # ,ec opcode = rffi.r_ulong(block[pc]) >> 8 name = optable.names[opcode] lno = raw_pc_location(function.sourcemap, rffi.r_long(pc))[2] return "pc=%d %s module=%s:%d" % (pc, name, module.repr().encode('utf-8'), lno)
def interpret(pc, block, regv, frame): module = jit.promote(frame.module) unit = jit.promote(frame.unit) excs = jit.promote(frame.excs) try: while pc < len(block): try: jitdriver.jit_merge_point(pc=pc, block=block, module=module, unit=unit, excs=excs, regv=regv, frame=frame) opcode = rffi.r_ulong(block[pc]) >> 8 ix = pc + 1 pc = ix + (rffi.r_ulong(block[pc]) & 255) if opcode == opcode_of('assert'): obj = regv.load(block[ix + 0]) raise space.unwind(space.LAssertionError(obj)) elif opcode == opcode_of('raise'): obj = regv.load(block[ix + 0]) traceback = obj.getattr(u"traceback") if traceback is space.null: traceback = space.List([]) obj.setattr(u"traceback", traceback) elif not isinstance(traceback, space.List): raise space.unwind( space.LError( u"Expected null or list as .traceback: %s" % obj.repr())) raise space.Unwinder(obj, traceback) elif opcode == opcode_of('constant'): regv.store(block[ix + 0], unit.constants[block[ix + 1]]) elif opcode == opcode_of('list'): contents = [] for i in range(ix + 1, pc): contents.append(regv.load(block[i])) regv.store(block[ix], space.List(contents)) elif opcode == opcode_of('move'): regv.store(block[ix + 0], regv.load(block[ix + 1])) elif opcode == opcode_of('call'): op_call(regv, block, ix, pc) elif opcode == opcode_of('callv'): op_callv(regv, block, ix, pc) elif opcode == opcode_of('return'): return regv.load(block[ix + 0]) elif opcode == opcode_of('jump'): pc = rffi.r_ulong(block[ix + 0]) elif opcode == opcode_of('cond'): if space.is_false(regv.load(block[ix + 0])): pc = rffi.r_ulong(block[ix + 2]) else: pc = rffi.r_ulong(block[ix + 1]) elif opcode == opcode_of('func'): regv.store(block[ix + 0], Closure(frame, unit.functions[block[ix + 1]])) elif opcode == opcode_of('iter'): regv.store(block[ix + 0], regv.load(block[ix + 1]).iter()) elif opcode == opcode_of('next'): try: regv.store( block[ix + 0], regv.load(block[ix + 1]).callattr(u'next', [])) except StopIteration as _: pc = rffi.r_ulong(block[ix + 2]) # this is missing. #elif isinstance(op, Yield): # raise YieldIteration(op.block, loop_break, op.i, regv.load(op.value.i)) elif opcode == opcode_of('getattr'): name = get_string(unit, block, ix + 2) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.getattr(name)) elif opcode == opcode_of('setattr'): value = regv.load(block[ix + 3]) name = get_string(unit, block, ix + 2) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.setattr(name, value)) elif opcode == opcode_of('getitem'): index = regv.load(block[ix + 2]) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.getitem(index)) elif opcode == opcode_of('setitem'): item = regv.load(block[ix + 3]) index = regv.load(block[ix + 2]) obj = regv.load(block[ix + 1]) regv.store(block[ix + 0], obj.setitem(index, item)) elif opcode == opcode_of('getloc'): regv.store(block[ix + 0], frame.local[block[ix + 1]]) elif opcode == opcode_of('setloc'): value = regv.load(block[ix + 2]) frame.local[block[ix + 1]] = value regv.store(block[ix + 0], value) elif opcode == opcode_of('getupv'): value = get_upframe(frame, block[ix + 1]).local[block[ix + 2]] regv.store(block[ix + 0], value) elif opcode == opcode_of('setupv'): value = regv.load(block[ix + 3]) get_upframe(frame, block[ix + 1]).local[block[ix + 2]] = value regv.store(block[ix + 0], value) elif opcode == opcode_of('getglob'): regv.store(block[ix + 0], module.getattr(get_string(unit, block, ix + 1))) elif opcode == opcode_of('setglob'): regv.store( block[ix + 0], module.setattr(get_string(unit, block, ix + 1), regv.load(block[ix + 2]))) elif opcode == opcode_of('not'): if space.is_false(regv.load(block[ix + 1])): regv.store(block[ix + 0], space.true) else: regv.store(block[ix + 0], space.false) elif opcode == opcode_of('contains'): v0 = regv.load(block[ix + 1]) v1 = regv.load(block[ix + 2]) if v0.contains(v1): regv.store(block[ix + 0], space.true) else: regv.store(block[ix + 0], space.false) else: raise space.unwind( space.LInstructionError( optable.names.get(opcode, str(opcode)).decode('utf-8'), opcode)) except space.Unwinder as unwinder: for exc in excs: if exc.start < pc <= exc.stop: regv.store(exc.reg, unwinder.exception) pc = exc.label break else: raise except StopIteration as stop: unwinder = space.unwind(space.LUncatchedStopIteration()) unwinder.traceback.contents.append( TraceEntry(rffi.r_long(pc), unit.constants, frame.sourcemap)) raise unwinder except space.Unwinder as unwinder: unwinder.traceback.contents.append( TraceEntry(rffi.r_long(pc), unit.constants, frame.sourcemap)) raise return space.null
def interpret(pc, block, regv, frame, iterstop=LARGE_PC): module = jit.promote(frame.module) unit = jit.promote(frame.unit) try: while pc < len(block): jitdriver.jit_merge_point( pc=pc, block=block, module=module, unit=unit, iterstop=iterstop, regv=regv, frame=frame) opcode = rffi.r_ulong(block[pc])>>8 ix = pc+1 pc = ix+(rffi.r_ulong(block[pc])&255) if opcode == opcode_of('assert'): if space.is_false(regv.load(block[ix+0])): raise space.Error(u"Assertion error") elif opcode == opcode_of('constant'): regv.store(block[ix+0], unit.constants[block[ix+1]]) elif opcode == opcode_of('list'): contents = [] for i in range(ix+1, pc): contents.append(regv.load(block[i])) regv.store(block[ix], space.List(contents)) elif opcode == opcode_of('move'): regv.store(block[ix+0], regv.load(block[ix+1])) elif opcode == opcode_of('call'): op_call(regv, block, ix, pc) elif opcode == opcode_of('return'): return regv.load(block[ix+0]) elif opcode == opcode_of('jump'): pc = rffi.r_ulong(block[ix+0]) elif opcode == opcode_of('cond'): if space.is_false(regv.load(block[ix+0])): pc = rffi.r_ulong(block[ix+2]) else: pc = rffi.r_ulong(block[ix+1]) elif opcode == opcode_of('func'): regv.store(block[ix+0], Closure(frame, unit.functions[block[ix+1]])) elif opcode == opcode_of('iter'): regv.store(block[ix+0], regv.load(block[ix+1]).iter()) elif opcode == opcode_of('iterstop'): iterstop = rffi.r_ulong(block[ix+0]) elif opcode == opcode_of('next'): regv.store(block[ix+0], regv.load(block[ix+1]).callattr(u'next', [])) # this is missing. #elif isinstance(op, Yield): # raise YieldIteration(op.block, loop_break, op.i, regv.load(op.value.i)) elif opcode == opcode_of('getattr'): name = get_string(unit, block, ix+2) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.getattr(name)) elif opcode == opcode_of('setattr'): value = regv.load(block[ix+3]) name = get_string(unit, block, ix+2) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.setattr(name, value)) elif opcode == opcode_of('getitem'): index = regv.load(block[ix+2]) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.getitem(index)) elif opcode == opcode_of('setitem'): item = regv.load(block[ix+3]) index = regv.load(block[ix+2]) obj = regv.load(block[ix+1]) regv.store(block[ix+0], obj.setitem(index, item)) elif opcode == opcode_of('getloc'): regv.store(block[ix+0], frame.local[block[ix+1]]) elif opcode == opcode_of('setloc'): value = regv.load(block[ix+2]) frame.local[block[ix+1]] = value regv.store(block[ix+0], value) elif opcode == opcode_of('getupv'): value = get_upframe(frame, block[ix+1]).local[block[ix+2]] regv.store(block[ix+0], value) elif opcode == opcode_of('setupv'): value = regv.load(block[ix+3]) get_upframe(frame, block[ix+1]).local[block[ix+2]] = value regv.store(block[ix+0], value) elif opcode == opcode_of('getglob'): regv.store(block[ix+0], module.getattr(get_string(unit, block, ix+1))) elif opcode == opcode_of('setglob'): regv.store(block[ix+0], module.setattr( get_string(unit, block, ix+1), regv.load(block[ix+2]))) else: raise space.Error(u"unexpected instruction: " + optable.names.get(opcode, str(opcode)).decode('utf-8')) except StopIteration as stop: if iterstop != LARGE_PC: return interpret(iterstop, block, regv, frame) else: raise space.Error(u"StopIteration") return space.null
def read_u64(self): return rffi.r_ulong(self.read_uint() << 0 | self.read_uint() << 32)