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_file(path): stream = bincode.decoder.open_file(path) assert stream.read(8) == bincode.common.header functions = [] for i in range(stream.read_u16()): flags = stream.read_u16() regc = stream.read_u16() argc = stream.read_u16() localc = stream.read_u16() blocklen = stream.read_u16() block = lltype.malloc(u16_array, blocklen) for i in range(blocklen): block[i] = rffi.r_ushort(stream.read_u16()) functions.append(Function(flags, regc, argc, localc, block)) constants = [] for i in range(stream.read_u16()): klass = stream.read_ubyte() if klass == 1: constants.append(space.String(stream.read_string())) elif klass == 2: constants.append(space.Integer(rffi.r_long(stream.read_u64()))) elif klass == 3: constants.append(space.Integer(-rffi.r_long(stream.read_u64()))) elif klass == 4: constants.append(space.Float(stream.read_double())) else: assert False, klass return Program(Unit(constants[:], functions[:]))
def getattr(self, name): if name == u"doc": return self.doc elif name == u"loc": source, start, stop = self.source_location obj = space.Exnihilo() obj.setattr(u"source", space.String(source)) obj.setattr(u"start", space.Integer(start)) obj.setattr(u"stop", space.Integer(stop)) return obj elif name == u"spec": argc, optional, variadic, varnames, argtypes = self.spec varnames = [ space.String(name.decode('utf-8')) for name in varnames ] spec = space.Exnihilo() spec.setattr(u'argc', space.Integer(rffi.r_long(argc))) spec.setattr(u'optional', space.Integer(rffi.r_long(optional))) spec.setattr(u'is_variadic', space.boolean(variadic)) spec.setattr(u'varnames', space.List(list(varnames))) if argtypes is not None: spec.setattr(u'argtypes', space.List(list(argtypes))) else: spec.setattr(u'argtypes', space.null) return spec else: return Object.getattr(self, name)
def excs_introspection(excs): out = [] for exc in excs: o = space.Exnihilo() o.setattr(u"start", space.Integer(rffi.r_long(exc.start))) o.setattr(u"stop", space.Integer(rffi.r_long(exc.stop))) o.setattr(u"label", space.Integer(rffi.r_long(exc.label))) o.setattr(u"reg", space.Integer(rffi.r_long(exc.reg))) out.append(o) return space.List(out)
def configured_stringify(obj, config): if config is None: ub = UnicodeBuilder() quick_stringify(ub, obj) return ub.build() margin = space.to_int(get_config(config, u"margin", space.Integer(80))) scan = Scanner(Printer(margin)) scan.indent = space.to_int(get_config(config, u"indent", space.Integer(2))) scan.sort_keys = space.is_true( get_config(config, u"sort_keys", space.false)) stringify(scan, obj) scan.finish() return scan.printer.result.build()
def sourceloc_introspection(pc, function): trace = TraceEntry(pc, function.unit.sources, function.sourcemap, function.unit.path) name, col0, lno0, col1, lno1 = trace.pc_location() start = space.Exnihilo() start.setattr(u"col", space.Integer(col0)) start.setattr(u"lno", space.Integer(lno0)) stop = space.Exnihilo() stop.setattr(u"col", space.Integer(col1)) stop.setattr(u"lno", space.Integer(lno1)) obj = space.Exnihilo() obj.setattr(u"source", name) obj.setattr(u"start", start) obj.setattr(u"stop", stop) return obj
def getattr(self, name): if name == u"closure": return self.closure elif name == u"is_generator": return space.boolean(self.closure.function.flags & 2 != 0) elif name == u"excs": return self.excs_l elif name == u"regc": return space.Integer(rffi.r_long(self.closure.function.regc)) elif name == u"localc": return space.Integer(rffi.r_long(self.closure.function.localc)) elif name == u"length": return space.Integer(len(self.closure.function.block)) elif name == u"module": return self.closure.frame.module return space.Object.getattr(self, name)
def Uint8Iterator_next(self): if self.index < self.length: res = self.uint8data[self.index] self.index += 1 return space.Integer(rffi.r_long(res)) else: raise StopIteration()
def List_pop(self, index): if index: index = index.value else: index = len(self.contents) - 1 if not 0 <= index < len(self.contents): raise space.unwind(space.LKeyError(self, space.Integer(index))) return self.contents.pop(index)
def decode(stream): stream.skipspace() if stream.shift(u'{'): dct = space.Dict() if stream.shift(u'}'): return dct decode_pair(stream, dct) while stream.shift(u','): decode_pair(stream, dct) stream.skipspace() stream.skipspace() stream.expect(u'}') return dct if stream.shift(u'['): lst = [] if stream.shift(u']'): return space.List(lst) lst.append(decode(stream)) while stream.shift(u','): lst.append(decode(stream)) stream.skipspace() stream.skipspace() stream.expect(u']') return space.List(lst) if stream.get() == u'"': return decode_string(stream) if stream.shift(u'f'): stream.expect(u'a') stream.expect(u'l') stream.expect(u's') stream.expect(u'e') return space.false if stream.shift(u't'): stream.expect(u'r') stream.expect(u'u') stream.expect(u'e') return space.true if stream.shift(u'n'): stream.expect(u'u') stream.expect(u'l') stream.expect(u'l') return space.null if stream.shift(u'-'): sign = -1 else: sign = +1 num = digits(stream) if stream.shift(u'.'): num += u'.' + digits(stream) if stream.get() in u'eE': raise space.OldError(u"XXX") return space.Float(float(num.encode('utf-8'))) else: if stream.get() in u'eE': raise space.OldError(u"XXX") return space.Integer(sign*int(num.encode('utf-8'))) raise space.OldError(u"JSON decode error at %s" % stream.get())
def getattr(self, index): if index == u"arity": return space.Integer(self.arity) if index == u"default": return self.default if index == u"doc": return self.doc if index == u"size": # Used for ensuring that the gc+sleep can a = len(self.multimethod_table) # bite into the weak references. return Integer(a) return Object.getattr(self, index)
def getattr(self, name): if name == u"doc": return self.doc elif name == u"loc": return sourceloc_introspection(0, self.function) elif name == u"spec": spec = space.Exnihilo() spec.setattr(u'argc', space.Integer(rffi.r_long(self.function.argc))) spec.setattr( u'optional', space.Integer( rffi.r_long(self.function.topc - self.function.argc))) spec.setattr(u'is_variadic', space.boolean(self.function.flags & 1 == 1)) spec.setattr(u'varnames', self.function.varnames) return spec elif name == u"code": return Introspection(self) else: return space.Object.getattr(self, name)
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 getattr(self, name): if name == u"doc": return self.doc elif name == u"loc": unit = self.function.unit trace = TraceEntry(0, unit.sources, self.function.sourcemap, unit.path) name, col0, lno0, col1, lno1 = trace.pc_location() start = space.Exnihilo() start.setattr(u"col", space.Integer(col0)) start.setattr(u"lno", space.Integer(lno0)) stop = space.Exnihilo() stop.setattr(u"col", space.Integer(col1)) stop.setattr(u"lno", space.Integer(lno1)) obj = space.Exnihilo() obj.setattr(u"source", name) obj.setattr(u"start", start) obj.setattr(u"stop", stop) return obj elif name == u"spec": spec = space.Exnihilo() spec.setattr(u'argc', space.Integer(rffi.r_long(self.function.argc))) spec.setattr( u'optional', space.Integer( rffi.r_long(self.function.topc - self.function.argc))) spec.setattr(u'is_variadic', space.boolean(self.function.flags & 1 == 1)) spec.setattr(u'varnames', self.function.varnames) return spec else: return space.Object.getattr(self, name)
def decode_json(action, ch, ctx): if action == 0x1: # push list ctx.ds.append(space.List([])) # Push object to ds elif action == 0x2: # push object ctx.ds.append(space.Dict()) elif action == 0x3: # pop & append val = ctx.ds.pop() top = ctx.ds[len(ctx.ds) - 1] assert isinstance(top, List) # we can trust this. top.contents.append(val) elif action == 0x4: # pop pop & setitem val = ctx.ds.pop() key = ctx.ds.pop() top = ctx.ds[len(ctx.ds) - 1] assert isinstance(top, Dict) # again.. top.data[key] = val elif action == 0x5: # push null ctx.ds.append(space.null) elif action == 0x6: # push true ctx.ds.append(space.true) elif action == 0x7: # push false ctx.ds.append(space.false) elif action == 0x8: # push string val = ctx.ss.build() ctx.ds.append(space.String(val)) ctx.ss = UnicodeBuilder() ctx.es = UnicodeBuilder() elif action == 0x9: val = int(ctx.ss.build().encode('utf-8')) # push int ctx.ds.append(space.Integer(val)) ctx.ss = UnicodeBuilder() elif action == 0xA: val = float(ctx.ss.build().encode('utf-8')) # push float ctx.ds.append(space.Float(val)) ctx.ss = UnicodeBuilder() elif action == 0xB: # push ch to ss ctx.ss.append(ch) elif action == 0xC: # push ch to es ctx.es.append(ch) elif action == 0xD: # push escape ctx.ss.append(unichr(escape_characters[ch])) elif action == 0xE: # push unicode point ctx.ss.append(unichr(int(ctx.es.build().encode('utf-8'), 16))) ctx.es = UnicodeBuilder() else: # This is very unlikely to happen. assert False, "JSON decoder bug"
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 SliceStep_next(self): i = self.current self.current += self.step return space.Integer(i)
def SliceRange_next(self): if self.current * self.sign < self.stop * self.sign: i = self.current self.current += self.step return space.Integer(i) raise StopIteration()
def Slice_inst(start, stop, step): if step is None: step = space.Integer(1) return Slice(start, stop, step)
def getitem(self, index): pc = space.cast(index, space.Integer, u"[index]").value if pc < len(self.closure.function.block): return space.Integer(rffi.r_long(self.closure.function.block[pc])) raise space.OldError(u"pc out of range")
def getitem_int(cell, index): item = cell.getitem(space.Integer(index)) if isinstance(item, space.Integer): return item.value raise space.OldError(u"invalid sourcemap format")
def translate_(env, exp): if isinstance(exp, reader.Literal): if exp.name == u'string': return env.add(Constant(space.from_ustring(exp.value))) elif exp.name == u'int': return env.add( Constant(space.Integer(int(exp.value.encode('utf-8'))))) elif exp.name == u'hex': return env.add( Constant(space.Integer(int(exp.value[2:].encode('utf-8'), 16)))) elif exp.name == u'float': return env.add( Constant(space.Float(float(exp.value.encode('utf-8'))))) elif exp.name == u'symbol': return env.add(Variable(exp.value)) raise space.Error(u"no translation for " + exp.name) assert isinstance(exp, reader.Expr), exp.__class__.__name__ if exp.name == u'form' and len(exp.exps) > 0: if macro_name(exp) in macros: cc = env.capture_catch if len(exp.capture) > 0: env.capture_catch = exp.capture res = macros[macro_name(exp)](env, exp) if len(exp.capture) > 0 and len(env.capture_catch) > 0: raise space.Error(u"%s: capture without receiver" % exp.start.repr()) env.capture_catch = cc return res # callattr goes here, if it'll be needed args = translate_map(env, exp.exps) callee = args.pop(0) args.extend(translate_map(env, exp.capture)) return env.add(Call(callee, args)) elif exp.name == u'list': return env.add(MakeList(translate_map(env, exp.exps))) elif exp.name == u'attr' and len(exp.exps) == 2: lhs, name = exp.exps lhs = translate(env, lhs) if not isinstance(name, reader.Literal): raise space.Error(u"%s: bad attribute expr" % exp.repr()) return env.add(GetAttr(lhs, name.value)) sym.value elif exp.name == u'index' and len(exp.exps) == 2: lhs, rhs = exp.exps lhs = translate(env, lhs) rhs = translate(env, rhs) return env.add(GetItem(lhs, rhs)) elif exp.name == u'let' or exp.name == u'set': lhs, rhs = exp.exps rhs = translate(env, rhs) return store_value(env, lhs, rhs, exp.name == u'set') elif exp.name == u'aug' and len(exp.exps) == 3: aug, lhs, rhs = exp.exps if not isinstance(aug, reader.Literal): raise space.Error(u"%s: bad augmented expr" % exp.repr()) rhs = translate(env, rhs) return store_aug_value(env, aug, lhs, rhs) elif exp.name == u'chain': return syntax_chain(env, exp) raise space.Error(u"no translation for " + exp.name)