def parse_float_(string): value = 0.0 inv_scale = 1 divider = 1 exponent = 0.0 exponent_sign = +1.0 mode = 0 for ch in string.string: if mode == 0: if u'0' <= ch and ch <= u'9': digit = ord(ch) - ord(u'0') value = value * 10.0 + digit inv_scale *= divider elif u'.' == ch: divider = 10 elif u'e' == ch or u'E' == ch: mode = 1 else: raise space.unwind(space.LError(u"invalid digit char: " + ch)) elif mode == 1: mode = 2 if u'+' == ch: exponent_sign = +1.0 continue if u'-' == ch: exponent_sign = -1.0 continue else: # mode == 2 if u'0' <= ch and ch <= u'9': digit = ord(ch) - ord(u'0') exponent = exponent * 10.0 + digit else: raise space.unwind(space.LError(u"invalid digit char: " + ch)) exponent = exponent_sign * exponent return (value / inv_scale) * math.pow(10.0, exponent)
def Integer_to_string(integer, base): base = 10 if base is None else base.value if base >= len(digits): raise space.unwind(space.LError(u"not enough digits to represent this base %d" % base)) if base < 0: raise space.unwind(space.LError(u"negative base not supported")) return space.String(integer_to_string(integer.value, base))
def parse_int_(string, base): base = 10 if base is None else base.value value = 0 for ch in string.string: if u'0' <= ch and ch <= u'9': digit = ord(ch) - ord('0') elif u'a' <= ch and ch <= u'z': digit = ord(ch) - ord('a') + 10 elif u'A' <= ch and ch <= u'Z': digit = ord(ch) - ord('A') + 10 else: raise space.unwind(space.LError(u"invalid digit char: " + ch)) if digit >= base: raise space.unwind(space.LError(u"invalid digit char: " + ch)) value = value * base + digit return value
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 Uint8Data_memcpy(self, src, size): size = src.length if size is None else size.value if size > self.length or size > src.length: raise space.unwind(space.LError(u"memcpy range error")) rffi.c_memcpy(rffi.cast(rffi.VOIDP, self.uint8data), rffi.cast(rffi.VOIDP, src.uint8data), size) return space.null
def utf8_decoder_operate(decoder, newdata, final): data = decoder.buffer + newdata try: string, pos = str_decode_utf_8(data, len(data), '', final=final) except UnicodeDecodeError as error: raise space.unwind(space.LError(u"unicode decode failed")) decoder.buffer = data[pos:] return string
def max_default(argv): if len(argv) == 2 and argv[1] is null: return argv[0] if len(argv) == 2 and argv[0] is null: return argv[1] args = coerce.call(argv) if not isinstance(args, List): raise space.unwind(space.LError(u"coerce should return list")) return max_.call_suppressed(args.contents)
def String_count(self, ch): if len(ch.string) != 1: raise space.unwind(space.LError(u"str.count expected char")) count = 0 x = ch.string[0] for ch in self.string: if ch == x: count += 1 return Integer(count)
def utf8_decoder_operate(decoder, newdata, final): data = decoder.buffer + newdata try: string, pos = str_decode_utf_8(data, len(data), '', final=final) except UnicodeDecodeError as error: raise space.unwind(space.LError(u"unicode decode failed")) assert 0 <= pos <= len(data) # Added to satisfy PyPy 5.7 # The implementation of str_decode_utf_8 perhaps changed? decoder.buffer = data[pos:] return string
def String_is_digit(string, base): base = 10 if base is None else base.value if not 0 <= base <= 36: raise space.unwind(space.LError(u"is_digit base not in range .:36")) for ch in string.string: if not 0 <= as_alphadigit_i(ord(ch)) < base: return space.false if len(string.string) == 0: return space.false return space.true
def call(self, argv): if len(argv) != 1: raise space.unwind(space.LCallError(1, 1, False, len(argv))) module = argv[0] if not isinstance(module, space.Module): raise space.unwind( space.LError(u"Argument to program must be a module")) entry = self.unit.functions[0] frame = Frame(entry, module, None, entry.regc) #regv = new_register_array(entry.regc) return interpret(0, entry.block, frame)
def int_shl(a, b): a_v = int(a.value) b_v = int(b.value) if b_v < LONG_BIT: # 0 <= b < LONG_BIT c = ovfcheck(a_v << b_v) return Integer(rffi.r_long(c)) if b_v < 0: raise space.unwind(space.LError(u"negative shift count")) # b_v >= LONG_BIT if a_v == 0: return a raise OverflowError
def setitem(self, index, value): index = space.cast(index, space.List, u"Multimethod.setitem") vec = [ space.cast(item, space.Interface, u"Multimethod expects interface list").weakref for item in index.contents ] if vec in self.multimethod_table: raise space.unwind( space.LError(u"Multimethod table is not overwritable.")) record = MultimethodRecord(self, vec, value) self.register_record(record) return value
def int_shr(a, b): a_v = a.value b_v = b.value if b_v >= LONG_BIT: # not (0 <= b < LONG_BIT) if b_v < 0: raise space.unwind(space.LError(u"negative shift count")) # b >= LONG_BIT if a_v == 0: return a a_v = -1 if a_v < 0 else 0 else: a_v = a_v >> b_v return Integer(a_v)
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 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, 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 hate_them(argv): raise space.unwind(space.LError(u"hate them"))
def default(argv): args = coerce.call(argv) if not isinstance(args, List): raise space.unwind(space.LError(u"coerce should return list")) return method.call_suppressed(args.contents)