def _rebuild_action_dispatcher(self): periodic_actions = unrolling_iterable(self._periodic_actions) nonperiodic_actions = unrolling_iterable(self._nonperiodic_actions) has_bytecode_counter = self.has_bytecode_counter @jit.dont_look_inside def action_dispatcher(ec, frame): # periodic actions if has_bytecode_counter: ticker = self.get() if ticker & self.BYTECODE_COUNTER_OVERFLOW_BIT: # We must run the periodic actions now, but first # reset the bytecode counter (the following line # works by assuming that we just overflowed the # counter, i.e. BYTECODE_COUNTER_OVERFLOW_BIT is # set but none of the BYTECODE_COUNTER_MASK bits # are). ticker -= ec.space.sys.checkinterval self.set(ticker) for action in periodic_actions: action.perform(ec, frame) # nonperiodic actions for action, bitmask in nonperiodic_actions: ticker = self.get() if ticker & bitmask: self.set(ticker & ~bitmask) action.perform(ec, frame) action_dispatcher._dont_inline_ = True self.action_dispatcher = action_dispatcher
def _rebuild_action_dispatcher(self): periodic_actions = unrolling_iterable(self._periodic_actions) nonperiodic_actions = unrolling_iterable(self._nonperiodic_actions) has_bytecode_counter = self.has_bytecode_counter def action_dispatcher(ec, frame): # periodic actions if has_bytecode_counter: ticker = self.get() if ticker & self.BYTECODE_COUNTER_OVERFLOW_BIT: # We must run the periodic actions now, but first # reset the bytecode counter (the following line # works by assuming that we just overflowed the # counter, i.e. BYTECODE_COUNTER_OVERFLOW_BIT is # set but none of the BYTECODE_COUNTER_MASK bits # are). ticker -= ec.space.sys.checkinterval self.set(ticker) for action in periodic_actions: action.perform(ec, frame) # nonperiodic actions for action, bitmask in nonperiodic_actions: ticker = self.get() if ticker & bitmask: self.set(ticker & ~ bitmask) action.perform(ec, frame) action_dispatcher._dont_inline_ = True self.action_dispatcher = action_dispatcher
def ARRAY_ITER(ARRAY, INDEXARRAY, ITEM): ndim = dim_of_ARRAY(ARRAY) unroll_ndim = unrolling_iterable(range(ndim)) def ll_iter_reset(it, dataptr): it.index = 0 it.dataptr = dataptr for i in unroll_ndim: it.coordinates[i] = 0 ll_iter_reset._always_inline_ = True unroll_ndim_rev = unrolling_iterable(reversed(range(ndim))) def ll_iter_next(it): it.index += 1 for i in unroll_ndim_rev: if it.coordinates[i] < it.dims_m1[i]: it.coordinates[i] += 1 it.dataptr = direct_ptradd(it.dataptr, it.strides[i]) break it.coordinates[i] = 0 it.dataptr = direct_ptradd(it.dataptr, -it.backstrides[i]) ll_iter_next._always_inline_ = True DATA_PTR = Ptr(FixedSizeArray(ITEM, 1)) ADTIIter = ADTInterface(None, { 'll_reset': (['self', DATA_PTR], Void), 'll_next': (['self'], Void), }) ITER = Ptr( GcStruct( "array_iter", ("nd_m1", Signed), # number of dimensions - 1 ("index", NPY_INTP), ("size", NPY_INTP), ("coordinates", INDEXARRAY), ("dims_m1", INDEXARRAY), # array of dimensions - 1 ("strides", INDEXARRAY), ("backstrides", INDEXARRAY), #("factors", INDEXARRAY), #("ao", ARRAY), # not needed.. ("dataptr", DATA_PTR), # pointer to current item #("contiguous", Bool), adtmeths=ADTIIter({ 'll_next': ll_iter_next, 'll_reset': ll_iter_reset, }), )) return ITER
def ARRAY_ITER(ARRAY, INDEXARRAY, ITEM): ndim = dim_of_ARRAY(ARRAY) unroll_ndim = unrolling_iterable(range(ndim)) def ll_iter_reset(it, dataptr): it.index = 0 it.dataptr = dataptr for i in unroll_ndim: it.coordinates[i] = 0 ll_iter_reset._always_inline_ = True unroll_ndim_rev = unrolling_iterable(reversed(range(ndim))) def ll_iter_next(it): it.index += 1 for i in unroll_ndim_rev: if it.coordinates[i] < it.dims_m1[i]: it.coordinates[i] += 1 it.dataptr = direct_ptradd(it.dataptr, it.strides[i]) break it.coordinates[i] = 0 it.dataptr = direct_ptradd(it.dataptr, -it.backstrides[i]) ll_iter_next._always_inline_ = True DATA_PTR = Ptr(FixedSizeArray(ITEM, 1)) ADTIIter = ADTInterface(None, { 'll_reset': (['self', DATA_PTR], Void), 'll_next': (['self'], Void), }) ITER = Ptr( GcStruct("array_iter", ("nd_m1", Signed), # number of dimensions - 1 ("index", NPY_INTP), ("size", NPY_INTP), ("coordinates", INDEXARRAY), ("dims_m1", INDEXARRAY), # array of dimensions - 1 ("strides", INDEXARRAY), ("backstrides", INDEXARRAY), #("factors", INDEXARRAY), #("ao", ARRAY), # not needed.. ("dataptr", DATA_PTR), # pointer to current item #("contiguous", Bool), adtmeths = ADTIIter({ 'll_next': ll_iter_next, 'll_reset': ll_iter_reset, }), )) return ITER
def make_set_future_values(self): "NOT_RPYTHON" if hasattr(self, 'set_future_values'): return self.set_future_values warmrunnerdesc = self.warmrunnerdesc jitdriver_sd = self.jitdriver_sd cpu = self.cpu vinfo = jitdriver_sd.virtualizable_info red_args_types = unrolling_iterable(jitdriver_sd._red_args_types) # def set_future_values(*redargs): i = 0 for typecode in red_args_types: set_future_value(cpu, i, redargs[i], typecode) i = i + 1 if vinfo is not None: set_future_values_from_vinfo(*redargs) # if vinfo is not None: i0 = len(jitdriver_sd._red_args_types) num_green_args = jitdriver_sd.num_green_args index_of_virtualizable = jitdriver_sd.index_of_virtualizable vable_static_fields = unrolling_iterable( zip(vinfo.static_extra_types, vinfo.static_fields)) vable_array_fields = unrolling_iterable( zip(vinfo.arrayitem_extra_types, vinfo.array_fields)) getlength = cpu.ts.getlength getarrayitem = cpu.ts.getarrayitem # def set_future_values_from_vinfo(*redargs): i = i0 virtualizable = redargs[index_of_virtualizable] virtualizable = vinfo.cast_to_vtype(virtualizable) for typecode, fieldname in vable_static_fields: x = getattr(virtualizable, fieldname) set_future_value(cpu, i, x, typecode) i = i + 1 for typecode, fieldname in vable_array_fields: lst = getattr(virtualizable, fieldname) for j in range(getlength(lst)): x = getarrayitem(lst, j) set_future_value(cpu, i, x, typecode) i = i + 1 else: set_future_values_from_vinfo = None # self.set_future_values = set_future_values return set_future_values
def make_set_future_values(self): "NOT_RPYTHON" if hasattr(self, 'set_future_values'): return self.set_future_values warmrunnerdesc = self.warmrunnerdesc cpu = warmrunnerdesc.cpu vinfo = warmrunnerdesc.metainterp_sd.virtualizable_info red_args_types = unrolling_iterable(warmrunnerdesc.red_args_types) # def set_future_values(*redargs): i = 0 for typecode in red_args_types: set_future_value(cpu, i, redargs[i], typecode) i = i + 1 if vinfo is not None: set_future_values_from_vinfo(*redargs) # if vinfo is not None: i0 = len(warmrunnerdesc.red_args_types) num_green_args = warmrunnerdesc.num_green_args vable_static_fields = unrolling_iterable( zip(vinfo.static_extra_types, vinfo.static_fields)) vable_array_fields = unrolling_iterable( zip(vinfo.arrayitem_extra_types, vinfo.array_fields)) getlength = cpu.ts.getlength getarrayitem = cpu.ts.getarrayitem # def set_future_values_from_vinfo(*redargs): i = i0 virtualizable = redargs[vinfo.index_of_virtualizable - num_green_args] virtualizable = vinfo.cast_to_vtype(virtualizable) for typecode, fieldname in vable_static_fields: x = getattr(virtualizable, fieldname) set_future_value(cpu, i, x, typecode) i = i + 1 for typecode, fieldname in vable_array_fields: lst = getattr(virtualizable, fieldname) for j in range(getlength(lst)): x = getarrayitem(lst, j) set_future_value(cpu, i, x, typecode) i = i + 1 else: set_future_values_from_vinfo = None # self.set_future_values = set_future_values return set_future_values
def postprocess_timeshifting(self): annhelper = self.hrtyper.annhelper convert_result = getattr(self.main, 'convert_result', str) annotator = self.rtyper.annotator args_s = [annmodel.lltype_to_annotation(v.concretetype) for v in self.maingraph.getargs()] retvar = self.maingraph.getreturnvar() s_result = annmodel.lltype_to_annotation(retvar.concretetype) main_fnptr = self.rtyper.type_system.getcallable(self.maingraph) main = PseudoHighLevelCallable(main_fnptr, args_s, s_result) if hasattr(self.main, 'convert_arguments'): decoders = self.main.convert_arguments assert len(decoders) == len(args_s) else: decoders = [int] * len(args_s) decoders = unrolling_iterable(decoders) def ll_main(argv): args = () i = 1 for decoder in decoders: args += (decoder(argv[i]),) i = i + 1 try: res = main(*args) except Exception, e: os.write(1, 'EXCEPTION: %s\n' % (e,)) return 0 os.write(1, convert_result(res) + '\n') return 0
def insn(*encoding): def encode(mc, *args): rexbyte = 0 if mc.WORD == 8: # compute the REX byte, if any for encode_step, arg, extra, rex_step in encoding_steps: if rex_step: if arg is not None: arg = args[arg - 1] rexbyte |= rex_step(mc, arg, extra) args = (rexbyte, ) + args # emit the bytes of the instruction orbyte = 0 for encode_step, arg, extra, rex_step in encoding_steps: if arg is not None: arg = args[arg] orbyte = encode_step(mc, arg, extra, orbyte) assert orbyte == 0 # encoding_steps = [] for step in encoding: if isinstance(step, str): for c in step: encoding_steps.append((encode_char, None, ord(c), None)) else: assert type(step) is tuple and len(step) == 4 encoding_steps.append(step) encoding_steps = unrolling_iterable(encoding_steps) return encode
def make_interior_getter(fielddescs, _cache={}): # returns a 'getinterior(jitstate, argbox, *indexboxes)' function key = tuple(fielddescs) try: return _cache[key] except KeyError: unroll_fielddescs = unrolling_iterable([ (fielddesc, isinstance(fielddesc, ArrayFieldDesc)) for fielddesc in fielddescs ]) def getinterior(jitstate, argbox, *indexboxes): i = 0 for fielddesc, is_array in unroll_fielddescs: if is_array: # array substruct indexbox = indexboxes[i] i += 1 genvar = jitstate.curbuilder.genop_getarraysubstruct( fielddesc.arraytoken, argbox.getgenvar(jitstate), indexbox.getgenvar(jitstate)) argbox = fielddesc.makebox(jitstate, genvar) else: # getsubstruct argbox = argbox.op_getsubstruct(jitstate, fielddesc) assert isinstance(argbox, rvalue.PtrRedBox) return argbox _cache[key] = getinterior return getinterior
def _define_collect_residual_args(self): my_redirected_names = unrolling_iterable(self.my_redirected_names) TOPPTR = self.access_desc.PTRTYPE if TOPPTR == self.PTRTYPE: _super_collect = None else: _super_collect = self.firstsubstructdesc._collect_residual_args def _collect_residual_args(v): if _super_collect is None: assert not v.vable_access # xxx need to use access ? t = () else: t = _super_collect(v.super) for name in my_redirected_names: t = t + (getattr(v, name), ) return t self._collect_residual_args = _collect_residual_args def collect_residual_args(v): t = (v, ) + _collect_residual_args(v) return t self.collect_residual_args = collect_residual_args
def get_operrcls2(valuefmt): strings, formats = decompose_valuefmt(valuefmt) assert len(strings) == len(formats) + 1 try: OpErrFmt = _fmtcache2[formats] except KeyError: from pypy.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) # class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) assert len(args) == len(strings) - 1 self.xstrings = strings for i, attr in entries: setattr(self, attr, args[i]) if not we_are_translated() and w_type is None: from pypy.tool.error import FlowingError raise FlowingError(self._compute_value()) def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: string = self.xstrings[i] value = getattr(self, attr) lst[i + i] = string lst[i + i + 1] = str(value) lst[-1] = self.xstrings[-1] return ''.join(lst) # _fmtcache2[formats] = OpErrFmt return OpErrFmt, strings
def make_arg_subclass(n, base): rangen = unroll.unrolling_iterable(range(n)) class cls(base): _immutable_fields_ = ["arg%s" % i for i in rangen] def __init__(self, function, args): base.__init__(self, function) for i in rangen: setattr(self, "arg%s" % i, args[i]) assert len(args) == n def numargs(self): return n def getarg(self, i): assert i < n for j in rangen: if i == j: return getattr(self, "arg%s" % j) assert 0 cls.__name__ = "%s%s" % (base.__name__, n) return cls
def get_operrcls2(valuefmt): strings, formats = decompose_valuefmt(valuefmt) assert len(strings) == len(formats) + 1 try: OpErrFmt = _fmtcache2[formats] except KeyError: from pypy.rlib.unroll import unrolling_iterable attrs = ['x%d' % i for i in range(len(formats))] entries = unrolling_iterable(enumerate(attrs)) # class OpErrFmt(OperationError): def __init__(self, w_type, strings, *args): self.setup(w_type) assert len(args) == len(strings) - 1 self.xstrings = strings for i, attr in entries: setattr(self, attr, args[i]) if not we_are_translated() and w_type is None: from pypy.tool.error import FlowingError raise FlowingError(self._compute_value()) def _compute_value(self): lst = [None] * (len(formats) + len(formats) + 1) for i, attr in entries: string = self.xstrings[i] value = getattr(self, attr) lst[i+i] = string lst[i+i+1] = str(value) lst[-1] = self.xstrings[-1] return ''.join(lst) # _fmtcache2[formats] = OpErrFmt return OpErrFmt, strings
def proxymaker(space, name, parentfn): arity = nb_forcing_args[name] indices = unrolling_iterable(range(arity)) if name in RegularMethods: def proxy(*args_w): newargs_w = () tainted = False for i in indices: w_arg = args_w[i] if isinstance(w_arg, W_Tainted): tainted = True w_arg = w_arg.w_obj elif isinstance(w_arg, W_TaintBomb): return w_arg newargs_w += (w_arg,) newargs_w += args_w[arity:] try: w_res = parentfn(*newargs_w) except OperationError, operr: if not tainted: raise return W_TaintBomb(space, operr) if tainted: w_res = taint(w_res) return w_res
def _make_jitcell_getter_default(self): "NOT_RPYTHON" jitdriver_sd = self.jitdriver_sd green_args_spec = unrolling_iterable(jitdriver_sd._green_args_spec) # def comparekey(greenargs1, greenargs2): i = 0 for TYPE in green_args_spec: if not equal_whatever(TYPE, greenargs1[i], greenargs2[i]): return False i = i + 1 return True # def hashkey(greenargs): x = 0x345678 i = 0 for TYPE in green_args_spec: item = greenargs[i] y = hash_whatever(TYPE, item) x = intmask((1000003 * x) ^ y) i = i + 1 return x # jitcell_dict = r_dict(comparekey, hashkey) # def get_jitcell(build, *greenargs): try: cell = jitcell_dict[greenargs] except KeyError: if not build: return None cell = JitCell() jitcell_dict[greenargs] = cell return cell return get_jitcell
def _make_jitcell_getter_default(self, JitCell): "NOT_RPYTHON" warmrunnerdesc = self.warmrunnerdesc green_args_spec = unrolling_iterable(warmrunnerdesc.green_args_spec) # def comparekey(greenargs1, greenargs2): i = 0 for TYPE in green_args_spec: if not equal_whatever(TYPE, greenargs1[i], greenargs2[i]): return False i = i + 1 return True # def hashkey(greenargs): x = 0x345678 i = 0 for TYPE in green_args_spec: item = greenargs[i] y = hash_whatever(TYPE, item) x = intmask((1000003 * x) ^ y) i = i + 1 return x # jitcell_dict = r_dict(comparekey, hashkey) # def get_jitcell(*greenargs): try: cell = jitcell_dict[greenargs] except KeyError: cell = JitCell() jitcell_dict[greenargs] = cell return cell return get_jitcell
def gen_str_function(tuplerepr): items_r = tuplerepr.items_r str_funcs = [r_item.ll_str for r_item in items_r] key = tuplerepr.rstr_ll, tuple(str_funcs) try: return _gen_str_function_cache[key] except KeyError: autounrolling_funclist = unrolling_iterable(enumerate(str_funcs)) constant = tuplerepr.rstr_ll.ll_constant start = tuplerepr.rstr_ll.ll_build_start push = tuplerepr.rstr_ll.ll_build_push finish = tuplerepr.rstr_ll.ll_build_finish length = len(items_r) def ll_str(t): if length == 0: return constant("()") buf = start(2 * length + 1) push(buf, constant("("), 0) for i, str_func in autounrolling_funclist: attrname = 'item%d' % i item = getattr(t, attrname) if i > 0: push(buf, constant(", "), 2 * i) push(buf, str_func(item), 2 * i + 1) if length == 1: push(buf, constant(",)"), 2 * length) else: push(buf, constant(")"), 2 * length) return finish(buf) _gen_str_function_cache[key] = ll_str return ll_str
def test_unroll_ifs(self): operations = unrolling_iterable([ operator.lt, operator.le, operator.eq, operator.ne, operator.gt, operator.ge ]) def accept(n): "stub" def f(x, y): for op in operations: if accept(op): op(x, y) graph = self.codetest(f) ops = self.all_operations(graph) assert ops == { 'simple_call': 6, 'is_true': 6, 'lt': 1, 'le': 1, 'eq': 1, 'ne': 1, 'gt': 1, 'ge': 1 }
def gen_cmp_function(items_r, op_funcs, eq_funcs, strict): """generates <= and >= comparison ll_op for tuples cmp_funcs is a tuple of (strict_comp, equality) functions works for != with strict==True """ cmp_funcs = zip(op_funcs,eq_funcs) autounrolling_funclist = unrolling_iterable(enumerate(cmp_funcs)) key = tuple(cmp_funcs), strict try: return _gen_cmp_function_cache[key] except KeyError: def ll_cmp(t1, t2): cmp_res = True for i, (cmpfn, eqfn) in autounrolling_funclist: attrname = 'item%d' % i item1 = getattr(t1, attrname) item2 = getattr(t2, attrname) cmp_res = cmpfn(item1, item2) if cmp_res: # a strict compare is true we shortcut return True eq_res = eqfn(item1, item2) if not eq_res: # not strict and not equal we fail return False # Everything's equal here if strict: return False else: return True _gen_cmp_function_cache[key] = ll_cmp return ll_cmp
def proxymaker(space, name, parentfn): arity = nb_forcing_args[name] indices = unrolling_iterable(range(arity)) if name in RegularMethods: def proxy(*args_w): newargs_w = () tainted = False for i in indices: w_arg = args_w[i] if isinstance(w_arg, W_Tainted): tainted = True w_arg = w_arg.w_obj elif isinstance(w_arg, W_TaintBomb): return w_arg newargs_w += (w_arg, ) newargs_w += args_w[arity:] try: w_res = parentfn(*newargs_w) except OperationError, operr: if not tainted: raise return W_TaintBomb(space, operr) if tainted: w_res = taint(w_res) return w_res
def make_interior_getter(fielddescs, _cache={}): # returns a 'getinterior(jitstate, argbox, *indexboxes)' function key = tuple(fielddescs) try: return _cache[key] except KeyError: unroll_fielddescs = unrolling_iterable([ (fielddesc, isinstance(fielddesc, ArrayFieldDesc)) for fielddesc in fielddescs]) def getinterior(jitstate, argbox, *indexboxes): i = 0 for fielddesc, is_array in unroll_fielddescs: if is_array: # array substruct indexbox = indexboxes[i] i += 1 genvar = jitstate.curbuilder.genop_getarraysubstruct( fielddesc.arraytoken, argbox.getgenvar(jitstate), indexbox.getgenvar(jitstate)) argbox = fielddesc.makebox(jitstate, genvar) else: # getsubstruct argbox = argbox.op_getsubstruct(jitstate, fielddesc) assert isinstance(argbox, rvalue.PtrRedBox) return argbox _cache[key] = getinterior return getinterior
def _define_collect_residual_args(self): my_redirected_names = unrolling_iterable(self.my_redirected_names) TOPPTR = self.access_desc.PTRTYPE if TOPPTR == self.PTRTYPE: _super_collect = None else: _super_collect = self.firstsubstructdesc._collect_residual_args def _collect_residual_args(v): if _super_collect is None: assert not v.vable_access # xxx need to use access ? t = () else: t = _super_collect(v.super) for name in my_redirected_names: t = t + (getattr(v, name),) return t self._collect_residual_args = _collect_residual_args def collect_residual_args(v): t = (v,) + _collect_residual_args(v) return t self.collect_residual_args = collect_residual_args
def insn(*encoding): def encode(mc, *args): rexbyte = 0 if mc.WORD == 8: # compute the REX byte, if any for encode_step, arg, extra, rex_step in encoding_steps: if rex_step: if arg is not None: arg = args[arg-1] rexbyte |= rex_step(mc, arg, extra) args = (rexbyte,) + args # emit the bytes of the instruction orbyte = 0 for encode_step, arg, extra, rex_step in encoding_steps: if arg is not None: arg = args[arg] orbyte = encode_step(mc, arg, extra, orbyte) assert orbyte == 0 # encoding_steps = [] for step in encoding: if isinstance(step, str): for c in step: encoding_steps.append((encode_char, None, ord(c), None)) else: assert type(step) is tuple and len(step) == 4 encoding_steps.append(step) encoding_steps = unrolling_iterable(encoding_steps) return encode
def make_specialized_class(n): iter_n = unrolling_iterable(range(n)) class cls(W_SmallTupleObject): def __init__(self, values): assert len(values) == n for i in iter_n: setattr(self, 'w_value%s' % i, values[i]) def tolist(self): l = [None] * n for i in iter_n: l[i] = getattr(self, 'w_value%s' % i) return l # same source code, but builds and returns a resizable list getitems_copy = func_with_new_name(tolist, 'getitems_copy') def length(self): return n def getitem(self, index): for i in iter_n: if index == i: return getattr(self, 'w_value%s' % i) raise IndexError def setitem(self, index, w_item): for i in iter_n: if index == i: setattr(self, 'w_value%s' % i, w_item) return raise IndexError def eq(self, space, w_other): if n != w_other.length(): return space.w_False for i in iter_n: item1 = getattr(self, 'w_value%s' % i) item2 = w_other.getitem(i) if not space.eq_w(item1, item2): return space.w_False return space.w_True def hash(self, space): mult = 1000003 x = 0x345678 z = n for i in iter_n: w_item = getattr(self, 'w_value%s' % i) y = space.int_w(space.hash(w_item)) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return space.wrap(intmask(x)) cls.__name__ = "W_SmallTupleObject%s" % n return cls
def make_specialized_class(n): iter_n = unrolling_iterable(range(n)) class cls(W_SmallTupleObject): def __init__(self, values): assert len(values) == n for i in iter_n: setattr(self, 'w_value%s' % i, values[i]) def tolist(self): l = [None] * n for i in iter_n: l[i] = getattr(self, 'w_value%s' % i) return l # same source code, but builds and returns a resizable list getitems_copy = func_with_new_name(tolist, 'getitems_copy') def length(self): return n def getitem(self, index): for i in iter_n: if index == i: return getattr(self,'w_value%s' % i) raise IndexError def setitem(self, index, w_item): for i in iter_n: if index == i: setattr(self, 'w_value%s' % i, w_item) return raise IndexError def eq(self, space, w_other): if n != w_other.length(): return space.w_False for i in iter_n: item1 = getattr(self,'w_value%s' % i) item2 = w_other.getitem(i) if not space.eq_w(item1, item2): return space.w_False return space.w_True def hash(self, space): mult = 1000003 x = 0x345678 z = n for i in iter_n: w_item = getattr(self, 'w_value%s' % i) y = space.int_w(space.hash(w_item)) x = (x ^ y) * mult z -= 1 mult += 82520 + z + z x += 97531 return space.wrap(intmask(x)) cls.__name__ = "W_SmallTupleObject%s" % n return cls
def __init__(self): self.heap = Heap() self.signature2function = {} self.parser = None self.operations = None #XXX circular imports hack from pypy.lang.prolog.builtin import builtins_list globals()['unrolling_builtins'] = unrolling_iterable(builtins_list)
def __init__(self, ctype): CTypeController.__init__(self, ctype) # Map the field names to their controllers controllers = [] fields = [] for name, field_ctype in ctype._fields_: controller = getcontroller(field_ctype) setattr(self, 'fieldcontroller_' + name, controller) controllers.append((name, controller)) fields.append((name, controller.knowntype)) external = getattr(ctype, '_external_', False) self.knowntype = rctypesobject.RStruct(ctype.__name__, fields, c_external = external) self.fieldcontrollers = controllers # Build a custom new() method where the setting of the fields # is unrolled unrolled_controllers = unrolling_iterable(controllers) def structnew(*args): obj = self.knowntype.allocate() if len(args) > len(fields): raise ValueError("too many arguments for this structure") for name, controller in unrolled_controllers: if args: value = args[0] args = args[1:] if controller.is_box(value): structsetboxattr(obj, name, value) else: structsetattr(obj, name, value) return obj self.new = structnew # Build custom getter and setter methods def structgetattr(obj, attr): controller = getattr(self, 'fieldcontroller_' + attr) itemobj = getattr(obj, 'ref_' + attr)() return controller.return_value(itemobj) structgetattr._annspecialcase_ = 'specialize:arg(1)' def structsetattr(obj, attr, value): controller = getattr(self, 'fieldcontroller_' + attr) itemobj = getattr(obj, 'ref_' + attr)() controller.store_value(itemobj, value) structsetattr._annspecialcase_ = 'specialize:arg(1)' def structsetboxattr(obj, attr, valuebox): controller = getattr(self, 'fieldcontroller_' + attr) itemobj = getattr(obj, 'ref_' + attr)() controller.store_box(itemobj, valuebox) structsetboxattr._annspecialcase_ = 'specialize:arg(1)' self.getattr = structgetattr self.setattr = structsetattr self.setboxattr = structsetboxattr
def decorator(func): assert code not in prim_table func.func_name = "prim_" + name if unwrap_spec is None: def wrapped(interp, argument_count_m1): w_result = func(interp, argument_count_m1) if not no_result: assert w_result is not None interp.s_active_context().push(w_result) return w_result else: len_unwrap_spec = len(unwrap_spec) assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1, "wrong number of arguments") unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(interp, argument_count_m1): argument_count = argument_count_m1 + 1 # to account for the rcvr frame = interp.w_active_context() s_frame = frame.as_context_get_shadow(interp.space) assert argument_count == len_unwrap_spec if len(s_frame.stack()) < len_unwrap_spec: raise PrimitiveFailedError() args = () for i, spec in unrolling_unwrap_spec: index = len_unwrap_spec - 1 - i w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) elif spec is index1_0: args += (interp.space.unwrap_int(w_arg) - 1, ) elif spec is float: args += (interp.space.unwrap_float(w_arg), ) elif spec is object: args += (w_arg, ) elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) elif spec is char: args += (unwrap_char(w_arg), ) else: raise NotImplementedError("unknown unwrap_spec %s" % (spec, )) w_result = func(interp, *args) # After calling primitive, reload context-shadow in case it # needs to be updated new_s_frame = interp.s_active_context() frame.as_context_get_shadow(interp.space).pop_n( len_unwrap_spec) # only if no exception occurs! if not no_result: assert w_result is not None new_s_frame.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) return func
def _findall_call_oopspec(): prefix = 'opt_call_stroruni_' result = [] for name in dir(OptString): if name.startswith(prefix): value = getattr(EffectInfo, 'OS_' + name[len(prefix):]) assert isinstance(value, int) and value != 0 result.append((value, getattr(OptString, name))) return unrolling_iterable(result)
def test_unroll_setattrs(self): values_names = unrolling_iterable(enumerate(['a', 'b', 'c'])) def f(x): for v, name in values_names: setattr(x, name, v) graph = self.codetest(f) ops = self.all_operations(graph) assert ops == {'setattr': 3}
def gen_get_shape(ndim): unrolling_dims = unrolling_iterable(range(ndim)) def ll_get_shape(ARRAY, TUPLE, array): shape = malloc(TUPLE) for i in unrolling_dims: size = array.shape[i] attr = 'item%d'%i setattr(shape, attr, size) return shape return ll_get_shape
def gen_get_view(r_array, r_tuple, hop): # XX method on the pair type ? ndim = get_view_ndim(r_array, r_tuple) unroll_r_tuple = unrolling_iterable(enumerate(r_tuple.items_r)) rslice = hop.rtyper.type_system.rslice def ll_get_view(ARRAY, ao, tpl): array = ARRAY.ll_allocate(ndim) dataptr = direct_arrayitems(ao.data) src_i = 0 tgt_i = 0 for src_i, r_key in unroll_r_tuple: if isinstance(r_key, IntegerRepr): dataptr = direct_ptradd( dataptr, getattr(tpl, 'item%d' % src_i) * ao.strides[src_i]) elif r_key == rslice.startonly_slice_repr: start = getattr(tpl, 'item%d' % src_i) size = ao.shape[src_i] if start > size: start = size size -= start dataptr = direct_ptradd(dataptr, start * ao.strides[src_i]) array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 elif r_key == rslice.startstop_slice_repr: start = getattr(tpl, 'item%d' % src_i).start stop = getattr(tpl, 'item%d' % src_i).stop size = ao.shape[src_i] if start > size: start = size dataptr = direct_ptradd(dataptr, start * ao.strides[src_i]) if stop < size: size = stop size -= start if size < 0: size = 0 array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 else: assert 0 src_i += 1 # consume the rest of ndim as if we found more slices while tgt_i < ndim: array.shape[tgt_i] = ao.shape[src_i] array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 src_i += 1 ll_assert(tgt_i == ndim, "tgt_i == ndim") array.dataptr = dataptr array.data = ao.data # keep a ref return array return ll_get_view
def test_unroll_twice(self): operations = unrolling_iterable([1, 2, 3]) def f(x): for num1 in operations: for num2 in operations: x = x + (num1 + num2) return x graph = self.codetest(f) ops = self.all_operations(graph) assert ops['add'] == 9
def test_unroller(self): l = unrolling_iterable(range(10)) def f(tot): for v in l: tot += v return tot*3 assert f(0) == sum(l)*3 graph = self.codetest(f) ops = self.all_operations(graph) assert ops == {'inplace_add': 10, 'mul': 1}
def decorator(func): assert code not in prim_table func.func_name = "prim_" + name if unwrap_spec is None: def wrapped(interp, argument_count_m1): w_result = func(interp, argument_count_m1) if not no_result: assert w_result is not None interp.s_active_context().push(w_result) return w_result else: len_unwrap_spec = len(unwrap_spec) assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1, "wrong number of arguments") unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(interp, argument_count_m1): argument_count = argument_count_m1 + 1 # to account for the rcvr frame = interp.w_active_context() s_frame = frame.as_context_get_shadow(interp.space) assert argument_count == len_unwrap_spec if len(s_frame.stack()) < len_unwrap_spec: raise PrimitiveFailedError() args = () for i, spec in unrolling_unwrap_spec: index = len_unwrap_spec - 1 - i w_arg = s_frame.peek(index) if spec is int: args += (interp.space.unwrap_int(w_arg), ) elif spec is index1_0: args += (interp.space.unwrap_int(w_arg)-1, ) elif spec is float: args += (interp.space.unwrap_float(w_arg), ) elif spec is object: args += (w_arg, ) elif spec is str: assert isinstance(w_arg, model.W_BytesObject) args += (w_arg.as_string(), ) elif spec is char: args += (unwrap_char(w_arg), ) else: raise NotImplementedError( "unknown unwrap_spec %s" % (spec, )) w_result = func(interp, *args) # After calling primitive, reload context-shadow in case it # needs to be updated new_s_frame = interp.s_active_context() frame.as_context_get_shadow(interp.space).pop_n(len_unwrap_spec) # only if no exception occurs! if not no_result: assert w_result is not None new_s_frame.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) return func
def install_marshaller((tag, s_tuple)): def dump_tuple(buf, x): buf.append(TYPE_TUPLE) w_long(buf, len(x)) for i, itemdumper in unroll_item_dumpers: itemdumper(buf, x[i]) itemdumpers = [get_marshaller(s_item) for s_item in s_tuple.items] unroll_item_dumpers = unrolling_iterable(enumerate(itemdumpers)) dumper_annotations = [get_dumper_annotation(itemdumper) for itemdumper in itemdumpers] s_general_tuple = annmodel.SomeTuple(dumper_annotations) add_dumper(s_general_tuple, dump_tuple)
def gen_get_shape(ndim): unrolling_dims = unrolling_iterable(range(ndim)) def ll_get_shape(ARRAY, TUPLE, array): shape = malloc(TUPLE) for i in unrolling_dims: size = array.shape[i] attr = 'item%d' % i setattr(shape, attr, size) return shape return ll_get_shape
def make_wrapper(space, callable): "NOT_RPYTHON" names = callable.api_func.argnames argtypes_enum_ui = unrolling_iterable( enumerate(zip(callable.api_func.argtypes, [name.startswith("w_") for name in names])) ) fatal_value = callable.api_func.restype._defl() @specialize.ll() def wrapper(*args): from pypy.module.cpyext.pyobject import make_ref, from_ref from pypy.module.cpyext.pyobject import Reference # we hope that malloc removal removes the newtuple() that is # inserted exactly here by the varargs specializer llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py rffi.stackcounter.stacks_counter += 1 retval = fatal_value boxed_args = () try: if not we_are_translated() and DEBUG_WRAPPER: print >> sys.stderr, callable, assert len(args) == len(callable.api_func.argtypes) for i, (typ, is_wrapped) in argtypes_enum_ui: arg = args[i] if is_PyObject(typ) and is_wrapped: if arg: arg_conv = from_ref(space, rffi.cast(PyObject, arg)) else: arg_conv = None else: arg_conv = arg boxed_args += (arg_conv,) state = space.fromcache(State) try: result = callable(space, *boxed_args) if not we_are_translated() and DEBUG_WRAPPER: print >> sys.stderr, " DONE" except OperationError, e: failed = True state.set_exception(e) except BaseException, e: failed = True if not we_are_translated(): message = repr(e) import traceback traceback.print_exc() else: message = str(e) state.set_exception(OperationError(space.w_SystemError, space.wrap(message))) else:
def decorator(func): assert code not in prim_table func.func_name = "prim_" + name if unwrap_spec is None: def wrapped(interp, argument_count_m1): w_result = func(interp, argument_count_m1) if not no_result: assert w_result is not None interp.w_active_context.push(w_result) return w_result else: len_unwrap_spec = len(unwrap_spec) assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1, "wrong number of arguments") unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(interp, argument_count_m1): argument_count = argument_count_m1 + 1 # to account for the rcvr frame = interp.w_active_context assert argument_count == len_unwrap_spec if len(frame.stack) < len_unwrap_spec: raise PrimitiveFailedError() args = () for i, spec in unrolling_unwrap_spec: index = -len_unwrap_spec + i w_arg = frame.stack[index] if spec is int: args += (utility.unwrap_int(w_arg), ) elif spec is index1_0: args += (utility.unwrap_int(w_arg) - 1, ) elif spec is float: args += (utility.unwrap_float(w_arg), ) elif spec is object: args += (w_arg, ) elif spec is str: args += (w_arg.as_string(), ) elif spec is char: args += (unwrap_char(w_arg), ) else: raise NotImplementedError("unknown unwrap_spec %s" % (spec, )) w_result = func(interp, *args) frame.pop_n(len_unwrap_spec) # only if no exception occurs! if not no_result: assert w_result is not None interp.w_active_context.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) return func
def make_wrapper(space, callable): "NOT_RPYTHON" names = callable.api_func.argnames argtypes_enum_ui = unrolling_iterable( enumerate( zip(callable.api_func.argtypes, [name.startswith("w_") for name in names]))) fatal_value = callable.api_func.restype._defl() @specialize.ll() def wrapper(*args): from pypy.module.cpyext.pyobject import make_ref, from_ref from pypy.module.cpyext.pyobject import Reference # we hope that malloc removal removes the newtuple() that is # inserted exactly here by the varargs specializer llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py rffi.stackcounter.stacks_counter += 1 retval = fatal_value boxed_args = () try: if not we_are_translated() and DEBUG_WRAPPER: print >> sys.stderr, callable, assert len(args) == len(callable.api_func.argtypes) for i, (typ, is_wrapped) in argtypes_enum_ui: arg = args[i] if is_PyObject(typ) and is_wrapped: if arg: arg_conv = from_ref(space, rffi.cast(PyObject, arg)) else: arg_conv = None else: arg_conv = arg boxed_args += (arg_conv, ) state = space.fromcache(State) try: result = callable(space, *boxed_args) if not we_are_translated() and DEBUG_WRAPPER: print >> sys.stderr, " DONE" except OperationError, e: failed = True state.set_exception(e) except BaseException, e: failed = True if not we_are_translated(): message = repr(e) import traceback traceback.print_exc() else: message = str(e) state.set_exception( OperationError(space.w_SystemError, space.wrap(message))) else:
def make_choice(*methodnames): from pypy.rlib.unroll import unrolling_iterable unrolling_methodnames = unrolling_iterable(methodnames) def choice(self): c = self.i, self.last_i last = None for func in unrolling_methodnames: try: return getattr(self, func)() except ParseError, e: last = combine_errors(last, e.errorinformation) self.i, self.last_i = c raise ParseError(self.tokens[self.i].source_pos, last, self.source)
def _findall(Class, name_prefix, op_prefix=None): result = [] for name in dir(Class): if name.startswith(name_prefix): opname = name[len(name_prefix):] if opname.isupper(): assert hasattr(resoperation.rop, opname) for value, name in resoperation.opname.items(): if op_prefix and not name.startswith(op_prefix): continue if hasattr(Class, name_prefix + name): result.append((value, getattr(Class, name_prefix + name))) return unrolling_iterable(result)
def gen_get_view(r_array, r_tuple, hop): # XX method on the pair type ? ndim = get_view_ndim(r_array, r_tuple) unroll_r_tuple = unrolling_iterable(enumerate(r_tuple.items_r)) rslice = hop.rtyper.type_system.rslice def ll_get_view(ARRAY, ao, tpl): array = ARRAY.ll_allocate(ndim) dataptr = direct_arrayitems(ao.data) src_i = 0 tgt_i = 0 for src_i, r_key in unroll_r_tuple: if isinstance(r_key, IntegerRepr): dataptr = direct_ptradd(dataptr, getattr(tpl, 'item%d'%src_i)*ao.strides[src_i]) elif r_key == rslice.startonly_slice_repr: start = getattr(tpl, 'item%d'%src_i) size = ao.shape[src_i] if start > size: start = size size -= start dataptr = direct_ptradd(dataptr, start*ao.strides[src_i]) array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 elif r_key == rslice.startstop_slice_repr: start = getattr(tpl, 'item%d'%src_i).start stop = getattr(tpl, 'item%d'%src_i).stop size = ao.shape[src_i] if start > size: start = size dataptr = direct_ptradd(dataptr, start*ao.strides[src_i]) if stop < size: size = stop size -= start if size < 0: size = 0 array.shape[tgt_i] = size array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 else: assert 0 src_i += 1 # consume the rest of ndim as if we found more slices while tgt_i < ndim: array.shape[tgt_i] = ao.shape[src_i] array.strides[tgt_i] = ao.strides[src_i] tgt_i += 1 src_i += 1 ll_assert(tgt_i == ndim, "tgt_i == ndim") array.dataptr = dataptr array.data = ao.data # keep a ref return array return ll_get_view
def test_methodtable(self): space = self.space for fixed_arity in [1, 2, 3, 4]: # methodtable = [name for (name, _, arity, _) in space.MethodTable if arity == fixed_arity] methodtable = unrolling_iterable(methodtable) args_w = (W_Root(),) * fixed_arity # def f(): for name in methodtable: getattr(space, name)(*args_w) # space.translates(f)
def install_marshaller((tag, s_tuple)): def dump_tuple(buf, x): buf.append(TYPE_TUPLE) w_long(buf, len(x)) for i, itemdumper in unroll_item_dumpers: itemdumper(buf, x[i]) itemdumpers = [get_marshaller(s_item) for s_item in s_tuple.items] unroll_item_dumpers = unrolling_iterable(enumerate(itemdumpers)) dumper_annotations = [ get_dumper_annotation(itemdumper) for itemdumper in itemdumpers ] s_general_tuple = annmodel.SomeTuple(dumper_annotations) add_dumper(s_general_tuple, dump_tuple)
def dict_to_switch(d): """Convert of dictionary with integer keys to a switch statement.""" def lookup(query): if we_are_translated(): for key, value in unrolling_iteritems: if key == query: return value else: raise KeyError else: return d[query] lookup._always_inline_ = True unrolling_iteritems = unrolling_iterable(d.iteritems()) return lookup
def decorator(func): assert code not in prim_table func.func_name = "prim_" + name if unwrap_spec is None: def wrapped(interp, argument_count_m1): w_result = func(interp, argument_count_m1) if not no_result: assert w_result is not None interp.w_active_context.push(w_result) return w_result else: len_unwrap_spec = len(unwrap_spec) assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1, "wrong number of arguments") unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(interp, argument_count_m1): argument_count = argument_count_m1 + 1 # to account for the rcvr frame = interp.w_active_context assert argument_count == len_unwrap_spec if len(frame.stack) < len_unwrap_spec: raise PrimitiveFailedError() args = () for i, spec in unrolling_unwrap_spec: index = -len_unwrap_spec + i w_arg = frame.stack[index] if spec is int: args += (utility.unwrap_int(w_arg), ) elif spec is index1_0: args += (utility.unwrap_int(w_arg)-1, ) elif spec is float: args += (utility.unwrap_float(w_arg), ) elif spec is object: args += (w_arg, ) elif spec is str: args += (w_arg.as_string(), ) elif spec is char: args += (unwrap_char(w_arg), ) else: raise NotImplementedError( "unknown unwrap_spec %s" % (spec, )) w_result = func(interp, *args) frame.pop_n(len_unwrap_spec) # only if no exception occurs! if not no_result: assert w_result is not None interp.w_active_context.push(w_result) wrapped.func_name = "wrap_prim_" + name prim_table[code] = wrapped prim_table_implemented_only.append((code, wrapped)) return func
def install_unmarshaller((tag, s_tuple)): def load_tuple(loader): if readchr(loader) != TYPE_TUPLE: raise ValueError("expected a tuple") if readlong(loader) != expected_length: raise ValueError("wrong tuple length") result = () for i, itemloader in unroll_item_loaders: result += (itemloader(loader), ) return result itemloaders = [get_loader(s_item) for s_item in s_tuple.items] expected_length = len(itemloaders) unroll_item_loaders = unrolling_iterable(enumerate(itemloaders)) add_loader(s_tuple, load_tuple)
def _define_materialize(self): TYPE = self.TYPE descs = unrolling_iterable(self.fielddescs) def materialize(rgenop, boxes): s = lltype.malloc(TYPE) i = 0 for desc in descs: v = rvalue.ll_getvalue(boxes[i], desc.RESTYPE) tgt = lltype.cast_pointer(desc.PTRTYPE, s) setattr(tgt, desc.fieldname, v) i = i + 1 return rgenop.genconst(s) self.materialize = materialize
def _findall(Class, name_prefix, op_prefix=None): result = [] for name in dir(Class): if name.startswith(name_prefix): opname = name[len(name_prefix):] if opname.isupper(): assert hasattr(resoperation.rop, opname) for value, name in resoperation.opname.items(): if op_prefix and not name.startswith(op_prefix): continue if hasattr(Class, name_prefix + name): opclass = resoperation.opclasses[getattr(rop, name)] assert name in opclass.__name__ result.append((value, opclass, getattr(Class, name_prefix + name))) return unrolling_iterable(result)
def make_getargs(ARGS): argsiter = unrolling_iterable(ARGS) args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void]) def getargs(argboxes): funcargs = () assert len(argboxes) == args_n i = 0 for ARG in argsiter: if ARG is ootype.Void: funcargs += (None,) else: box = argboxes[i] i+=1 funcargs += (unwrap(ARG, box),) return funcargs return getargs