def signature(*argtypes, **keywords): topc = argc = len(argtypes) argc -= keywords.get("optional", 0) variadic = keywords.get("variadic", False) argi = unroll.unrolling_iterable(range(argc)) argj = unroll.unrolling_iterable(range(argc, topc)) def signature_decorator(func): def fancy_frame(argv): args = () L = len(argv) if L < argc or (L > topc and not variadic): raise space.unwind(space.LCallError(argc, topc, variadic, L)) for i in argi: arg = argv[i] if isinstance(arg, argtypes[i]): args += (arg,) else: raise expectations_error(i, argtypes[i].interface.name) for j in argj: if j < L: arg = argv[j] if arg is null: arg = None elif not isinstance(arg, argtypes[j]): raise expectations_error(j, argtypes[j].interface.name) else: arg = None args += (arg,) if variadic: args += (argv[min(topc, L):],) return func(*args) fancy_frame.__name__ = func.__name__ return fancy_frame return signature_decorator
def generate_fixed_immutable_subclass(n_storage): """ Generate `W_PointersObject` subclass with immutable storage of fixed size. :param n_storage: Number of storage slots. :returns: Immutable `W_PointersObject` subclass with fixed slots. """ storage_iter = unrolling_iterable(range(n_storage)) cls_name = '%s_Immutable_%s' % (W_PointersObject.repr_classname, n_storage) class W_FixedImmutable_PointersObject(W_AbstractImmutable_PointersObject): """`W_PointersObject` subclass with immutable storage of fixed size.""" _storages_ = [(STORAGE_ATTR_TEMPLATE % x) for x in storage_iter] _attrs_ = _storages_ _immutable_fields_ = _storages_ repr_classname = cls_name def __init__(self, space, w_cls, pointers_w): W_AbstractImmutable_PointersObject.__init__(self, space, w_cls) for x in storage_iter: setattr(self, STORAGE_ATTR_TEMPLATE % x, pointers_w[x]) def size(self): return n_storage def fetch(self, space, n0): for x in storage_iter: if x == n0: return getattr(self, STORAGE_ATTR_TEMPLATE % x) raise IndexError return self.storage[n0] W_FixedImmutable_PointersObject.__name__ = cls_name return W_FixedImmutable_PointersObject
def make_list_eater(name): """ For generating car, cdr, caar, cadr, etc... """ spec = name[1:-1] unrolled = unroll.unrolling_iterable(reversed(spec)) contract = "pair?" for letter in spec[1::-1]: if letter == 'a': contract = "(cons/c %s any/c)" % contract elif letter == 'd': contract = "(cons/c any/c %s)" % contract else: assert False, "Bad list eater specification" @expose(name, [values.W_Object]) def process_list(_lst): lst = _lst for letter in unrolled: if not isinstance(lst, values.W_Cons): raise SchemeException("%s: expected %s given %s" % (name, contract, _lst)) if letter == 'a': lst = lst.car() elif letter == 'd': lst = lst.cdr() else: assert False, "Bad list eater specification" return lst process_list.__name__ = "do_" + name return process_list
def inner(f): name = f.__name__.decode("utf-8") doc = f.__doc__.decode("utf-8") if f.__doc__ else None if singleAtom is None: arity = len(inspect.getargspec(f).args) theAtom = getAtom(name, arity) else: arity = singleAtom.arity theAtom = singleAtom unrolledArity = unrolling_iterable(range(arity)) class runnableObject(Object): def toString(self): return u"<%s>" % name def auditorStamps(self): return _stamps def docString(self): return doc def respondingAtoms(self): return {theAtom: doc} def recv(self, atom, listArgs): if atom is theAtom: args = () for i in unrolledArity: args += (listArgs[i], ) return f(*args) else: raise Refused(self, atom, listArgs) return runnableObject
def _make_arg_unwrapper(func, argstypes, funcname, has_self=False, simple=False): argtype_tuples = [] min_arg = 0 isdefault = False for i, typ in enumerate(argstypes): default_value = None if isinstance(typ, default): isdefault = True default_value = typ.default typ = typ.typ else: assert not isdefault, "non-default argument %s after default argument" % typ min_arg += 1 unwrapper, errorname = typ.make_unwrapper() type_errormsg = "expected %s as argument %s to %s, got " % ( errorname, i, funcname) argtype_tuples.append((i, unwrapper, isdefault, default_value, type_errormsg)) unroll_argtypes = unroll.unrolling_iterable(argtype_tuples) max_arity = len(argstypes) if min_arg == max_arity: aritystring = max_arity else: aritystring = "%s to %s" % (min_arg, max_arity) errormsg_arity = "expected %s arguments to %s, got " % ( aritystring, funcname) if min_arg == max_arity and not has_self and min_arg in (1, 2) and simple: func_arg_unwrap, call1, call2 = make_direct_arg_unwrapper( func, min_arg, unroll_argtypes, errormsg_arity) else: func_arg_unwrap = make_list_arg_unwrapper( func, has_self, min_arg, max_arity, unroll_argtypes, errormsg_arity) call1 = call2 = None _arity = Arity(range(min_arg, max_arity+1), -1) return func_arg_unwrap, _arity, call1, call2
def make_methods(size): attrs = ["_%s_%s" % (attrname, i) for i in range(size)] unrolling_enumerate_attrs = unrolling_iterable(enumerate(attrs)) def _get_size_list(self): return size def _get_list(self, i): for j, attr in unrolling_enumerate_attrs: if j == i: return getattr(self, attr) raise IndexError def _get_full_list(self): res = [None] * size for i, attr in unrolling_enumerate_attrs: res[i] = getattr(self, attr) return res def _set_list(self, i, val): for j, attr in unrolling_enumerate_attrs: if j == i: setattr(self, attr, val) return raise IndexError def _init(self, elems, *args): assert len(elems) == size for i, attr in unrolling_enumerate_attrs: setattr(self, attr, elems[i]) cls.__init__(self, *args) meths = {"_get_list": _get_list, "_get_size_list": _get_size_list, "_get_full_list": _get_full_list, "_set_list": _set_list, "__init__" : _init} if immutable: meths["_immutable_fields_"] = attrs return meths
def wrapper(cls): """ This attempts to produce a method which will copy the immutable contents of a given data type from the '_immutable_fields_' annotation of the class. The methods employed here will only work for certain types of class specifications (i.e. only works if all the desired fields are present in the '_immutable_fields_' annotation of the class definition). The mutable fields of the class must be copied separately as well. """ field_names = [] for base in inspect.getmro(cls): if base is object: continue fields = getattr(base, "_immutable_fields_", []) field_names.extend(map(strip_immutable_field_name, fields)) field_names = unrolling_iterable(field_names) def copy(self): result = objectmodel.instantiate(cls) for attr in field_names: val = getattr(self, attr) setattr(result, attr, val) return result setattr(cls, copy_method, copy) return cls
def _generate_replace_method(cls): child_fields = unrolling_iterable(_get_all_child_fields(cls)) def _replace_child_with(parent_node, old_child, new_child): was_replaced = False for child_slot in child_fields: if child_slot.endswith('[*]'): slot_name = child_slot[:-3] nodes = getattr(parent_node, slot_name) if nodes and old_child in nodes: # update old list, because iterators might have a copy of it for i, n in enumerate(nodes): if n is old_child: nodes[i] = new_child setattr(parent_node, slot_name, nodes[:]) # TODO: figure out whether we need the copy of the list here was_replaced = True else: current = getattr(parent_node, child_slot) if current is old_child: setattr(parent_node, child_slot, new_child) was_replaced = True # TODO: method recursion is a problem causing specialization more than # once of a node if the containing method is already on the stack # if not was_replaced: # raise ValueError("%s was not a direct child node of %s" % ( # old_child, parent_node)) return new_child cls._replace_child_with = _replace_child_with
def make_execute_function(name, func): # Make a wrapper for 'func'. The func is a simple bhimpl_xxx function # from the BlackholeInterpreter class. The wrapper is a new function # that receives boxed values (but returns a non-boxed value). for argtype in func.argtypes: if argtype not in ('i', 'r', 'f', 'd', 'cpu'): return None if list(func.argtypes).count('d') > 1: return None argtypes = unrolling_iterable(func.argtypes) # def do(cpu, _, *argboxes): newargs = () for argtype in argtypes: if argtype == 'cpu': value = cpu elif argtype == 'd': value = argboxes[-1] assert isinstance(value, AbstractDescr) argboxes = argboxes[:-1] else: argbox = argboxes[0] argboxes = argboxes[1:] if argtype == 'i': value = argbox.getint() elif argtype == 'r': value = argbox.getref_base() elif argtype == 'f': value = argbox.getfloatstorage() newargs = newargs + (value, ) assert not argboxes # return func(*newargs) # do.func_name = 'do_' + name return do
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 side_effect_arguments(self): # if an item in array p0 is modified or a call contains an argument # it can modify it is returned in the destroyed list. args = [] op = self.op if self.modifies_complex_object(): for opnum, i, j in unrolling_iterable(MODIFY_COMPLEX_OBJ): if op.getopnum() == opnum: op_args = op.getarglist() if j == -1: args.append((op.getarg(i), None, True)) for j in range(i+1,len(op_args)): args.append((op.getarg(j), None, False)) else: args.append((op.getarg(i), op.getarg(j), True)) for x in range(j+1,len(op_args)): args.append((op.getarg(x), None, False)) return args # assume this destroys every argument... can be enhanced by looking # at the effect info of a call for instance for arg in op.getarglist(): # if it is a constant argument it cannot be destroyed. # neither can a box float be destroyed. BoxInt can # contain a reference thus it is assumed to be destroyed if arg.is_constant() or arg.type == 'f': args.append((arg, None, False)) else: args.append((arg, None, True)) return args
def _make_arg_unwrapper(func, argstypes, funcname, has_self=False, simple=False): argtype_tuples = [] min_arg = 0 isdefault = False for i, typ in enumerate(argstypes): default_value = None if isinstance(typ, default): isdefault = True default_value = typ.default typ = typ.typ else: assert not isdefault, "non-default argument %s after default argument" % typ min_arg += 1 unwrapper, errorname = typ.make_unwrapper() type_errormsg = "expected %s as argument %s to %s, got " % ( errorname, i, funcname) argtype_tuples.append((i, unwrapper, isdefault, default_value, type_errormsg)) unroll_argtypes = unroll.unrolling_iterable(argtype_tuples) max_arity = len(argstypes) if min_arg == max_arity: aritystring = max_arity else: aritystring = "%s to %s" % (min_arg, max_arity) errormsg_arity = "expected %s arguments to %s, got " % ( aritystring, funcname) if min_arg == max_arity and not has_self and min_arg in (1, 2) and simple: func_arg_unwrap, call1, call2 = make_direct_arg_unwrapper( func, min_arg, unroll_argtypes, errormsg_arity) else: func_arg_unwrap = make_list_arg_unwrapper( func, has_self, min_arg, max_arity, unroll_argtypes, errormsg_arity) call1 = call2 = None _arity = Arity.oneof(*range(min_arg, max_arity+1)) return func_arg_unwrap, _arity, call1, call2
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, 'bool': 6, 'lt': 1, 'le': 1, 'eq': 1, 'ne': 1, 'gt': 1, 'ge': 1 }
def generate_call_class(n_arguments): arguments_iter = unrolling_iterable(range(n_arguments)) class call_class(W_Call): _immutable_fields_ = [(ARG_ATTR_TEMPLATE % x) for x in arguments_iter] def _init_arguments(self, arguments): for x in arguments_iter: setattr(self, ARG_ATTR_TEMPLATE % x, arguments[x]) def get_arguments(self): result = [None] * n_arguments for x in arguments_iter: result[x] = getattr(self, ARG_ATTR_TEMPLATE % x) return result def get_argument(self, index): for x in arguments_iter: if x == index: return getattr(self, ARG_ATTR_TEMPLATE % x) raise IndexError def get_number_of_arguments(self): return n_arguments call_class.__name__ = call_class_name(n_arguments) return call_class
def _make_args_class(base, argnames): unroll_argnames = unroll.unrolling_iterable(enumerate(argnames)) class Args(base): _attrs_ = _immutable_fields_ = argnames def _init_args(self, *args): for i, name in unroll_argnames: setattr(self, name, args[i]) def _copy_args(self, other): for _, name in unroll_argnames: val = getattr(self, name) setattr(other, name, val) def _get_args(self): args = () for i, name in unroll_argnames: args += (getattr(self, name), ) return args def tostring(self): return "%s%s" % (self.__class__.__name__, len(self._get_args())) return Args
def build(tag, constructor, pieces): ipieces = unrolling_iterable(enumerate(pieces + [['span', None]])) class Constructor(NT): _immutable_ = True _immutable_fields_ = ( ["_constructorTag", "span"] + [freezeField(field, ty) for field, ty in pieces]) _constructorTag = tag def __init__(self, *args): for i, (piece, _) in ipieces: setattr(self, piece, args[i]) def asTree(self): "NOT_RPYTHON" l = [constructor] for i, (piece, ty) in ipieces: if ty is None: l.append(getattr(self, piece)) elif ty.endswith("*"): l.append( [tryAsTree(x) for x in getattr(self, piece)]) else: l.append(tryAsTree(getattr(self, piece))) return l Constructor.__name__ = name + "~" + constructor + str(increment()) irAttrs[constructor] = Constructor
def get_native_fmtstr(self, fmt): lenfmt = len(fmt) nat = False if lenfmt == 0: return None elif lenfmt == 1: format = fmt[0] # fine! elif lenfmt == 2: if fmt[0] == '@': nat = True format = fmt[1] else: return None else: return None chars = [ 'c', 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N', 'f', 'd', '?', 'P' ] for c in unrolling_iterable(chars): if c == format: if nat: return '@' + c else: return c return None
def wrapper(fn): if argtypes is None: wrapped = fn else: unroll_argtypes = unroll.unrolling_iterable(argtypes) def wrapped(otree, *etc): args_tuple = () rest = otree for type_ in unroll_argtypes: assert isinstance(rest, kt.Pair) arg = rest.car rest = rest.cdr kt.check_type(arg, type_) assert isinstance(arg, type_) args_tuple += (arg,) assert kt.is_nil(rest) args_tuple += etc return fn(*args_tuple) if simple: comb = kt.SimplePrimitive(wrapped, name) else: comb = kt.Primitive(wrapped, name) if not operative: comb = kt.Applicative(comb) _exports[name] = comb return wrapped
def _rebuild_action_dispatcher(self): periodic_actions = unrolling_iterable(self._periodic_actions) @jit.unroll_safe @objectmodel.dont_inline def action_dispatcher(ec, frame): # periodic actions (first reset the bytecode counter) self.reset_ticker(self.checkinterval_scaled) for action in periodic_actions: action.perform(ec, frame) # nonperiodic actions action = self._fired_actions_first if action: self._fired_actions_reset() # NB. in case there are several actions, we reset each # 'action._fired' to false only when we're about to call # 'action.perform()'. This means that if # 'action.fire()' happens to be called any time before # the corresponding perform(), the fire() has no # effect---which is the effect we want, because # perform() will be called anyway. All such pending # actions with _fired == True are still inside the old # chained list. As soon as we reset _fired to False, # we also reset _next to None and we are ready for # another fire(). while action is not None: next_action = action._next action._next = None action._fired = False action.perform(ec, frame) action = next_action self.action_dispatcher = action_dispatcher
def make_execute_function(name, func): # Make a wrapper for 'func'. The func is a simple bhimpl_xxx function # from the BlackholeInterpreter class. The wrapper is a new function # that receives boxed values (but returns a non-boxed value). for argtype in func.argtypes: if argtype not in ('i', 'r', 'f', 'd', 'cpu'): return None if list(func.argtypes).count('d') > 1: return None argtypes = unrolling_iterable(func.argtypes) # def do(cpu, _, *argboxes): newargs = () for argtype in argtypes: if argtype == 'cpu': value = cpu elif argtype == 'd': value = argboxes[-1] assert isinstance(value, AbstractDescr) argboxes = argboxes[:-1] else: argbox = argboxes[0] argboxes = argboxes[1:] if argtype == 'i': value = argbox.getint() elif argtype == 'r': value = argbox.getref_base() elif argtype == 'f': value = argbox.getfloatstorage() newargs = newargs + (value,) assert not argboxes # return func(*newargs) # do.func_name = 'do_' + name return do
def wrapper(fn): if argtypes is None: wrapped = fn else: unroll_argtypes = unroll.unrolling_iterable(argtypes) def wrapped(otree, *etc): args_tuple = () rest = otree for type_ in unroll_argtypes: if isinstance(rest, kt.Pair): arg = rest.car rest = rest.cdr kt.check_type(arg, type_) if isinstance(arg, type_): args_tuple += (arg,) else: kt.signal_type_error(type_, arg) else: kt.signal_arity_mismatch(str(len(argtypes)), otree) if kt.is_nil(rest): args_tuple += etc return fn(*args_tuple) else: kt.signal_arity_mismatch(str(len(argtypes)), otree) if simple: comb = kt.SimplePrimitive(wrapped, name) else: comb = kt.Primitive(wrapped, name) if not operative: comb = kt.Applicative(comb) _exports[name] = comb return wrapped
def _rebuild_action_dispatcher(self): periodic_actions = unrolling_iterable(self._periodic_actions) @jit.unroll_safe @objectmodel.dont_inline def action_dispatcher(ec, frame): # periodic actions (first reset the bytecode counter) self.reset_ticker(self.checkinterval_scaled) for action in periodic_actions: action.perform(ec, frame) # nonperiodic actions list = self.fired_actions if list is not None: self.fired_actions = None # NB. in case there are several actions, we reset each # 'action._fired' to false only when we're about to call # 'action.perform()'. This means that if # 'action.fire()' happens to be called any time before # the corresponding perform(), the fire() has no # effect---which is the effect we want, because # perform() will be called anyway. for action in list: action._fired = False action.perform(ec, frame) self.action_dispatcher = action_dispatcher
def test_cutoff(self): py.test.skip("cutoff: disabled") from rpython.rlib.unroll import unrolling_iterable cutoff = 20 attrs = unrolling_iterable(["s%s" % i for i in range(cutoff + 5)]) class A(object): def __init__(self, y): for attr in attrs: setattr(self, attr, y) def f(self): self.x = 1 res = 0 for attr in attrs: res += getattr(self, attr) return res def h(flag): obj = A(flag) return obj.f() t, wa = self.translate(h, [int]) wa.cutoff = cutoff hgraph = graphof(t, h) op_call_f = hgraph.startblock.operations[-1] # check that we fished the expected ops assert op_call_f.opname == "direct_call" assert op_call_f.args[0].value._obj._name == 'A.f' result = wa.analyze(op_call_f) assert result is top_set
def _make_args_class(base, argnames): unroll_argnames = unroll.unrolling_iterable(enumerate(argnames)) class Args(base): _immutable_fields_ = getattr(base, "_immutable_fields_", []) + argnames def _init_args(self, *args): for i, name in unroll_argnames: setattr(self, name, args[i]) def _copy_args(self, other): for _, name in unroll_argnames: val = getattr(self, name) setattr(other, name, val) def _get_args(self): args = () for i, name in unroll_argnames: args += (getattr(self, name),) return args def tostring(self): return "%s%s" % (self.__class__.__name__, len(self._get_args())) return Args
def decorator(func): len_unwrap_spec = len(unwrap_spec) assert len_unwrap_spec == len(inspect.getargspec(func)[0]), "wrong number of arguments" unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(*c_arguments): assert len_unwrap_spec == len(c_arguments) args = () if IProxy.trace_proxy.is_set(): print 'Called InterpreterProxy >> %s' % func.func_name, assert IProxy.s_frame is not None and IProxy.space is not None and IProxy.interp is not None try: for i, spec in unrolling_unwrap_spec: c_arg = c_arguments[i] if spec is oop: args += (IProxy.oop_to_object(c_arg), ) elif spec is str: args += (rffi.charp2str(c_arg), ) else: args += (c_arg, ) result = func(*args) if IProxy.trace_proxy.is_set(): print '\t-> %s' % result if result_type is oop: assert isinstance(result, model.W_Object) return IProxy.object_to_oop(result) elif result_type in (int, float): assert isinstance(result, result_type) return result elif result_type is bool: assert isinstance(result, bool) if result: return 1 else: return 0 else: return result except error.PrimitiveFailedError: if IProxy.trace_proxy.is_set(): print '\t-> failed' IProxy.failed() from rpython.rlib.objectmodel import we_are_translated if not we_are_translated(): import pdb; pdb.set_trace() if mapping[result_type] is sqInt: return 0 elif mapping[result_type] is sqDouble: return 0.0 elif mapping[result_type] is sqIntArrayPtr: return rffi.cast(sqIntArrayPtr, 0) elif mapping[result_type] is sqLong: # XXX: how to return a long 0? return 0 elif mapping[result_type] is sqStr: return rffi.cast(sqStr, "") else: raise NotImplementedError( "InterpreterProxy: unknown result_type %s" % (result_type, )) wrapped.func_name = "wrapped_ipf_" + func.func_name functions.append((func.func_name, f_ptr, wrapped)) return wrapped
def _rebuild_action_dispatcher(self): periodic_actions = unrolling_iterable(self._periodic_actions) @jit.unroll_safe @objectmodel.dont_inline def action_dispatcher(ec, frame): # periodic actions (first reset the bytecode counter) self.reset_ticker(self.checkinterval_scaled) for action in periodic_actions: action.perform(ec, frame) # nonperiodic actions list = self.fired_actions if list is not None: self.fired_actions = None # NB. in case there are several actions, we reset each # 'action._fired' to false only when we're about to call # 'action.perform()'. This means that if # 'action.fire()' happens to be called any time before # the corresponding perform(), the fire() has no # effect---which is the effect we want, because # perform() will be called anyway. for action in list: action._fired = False action.perform(ec, frame) self.action_dispatcher = action_dispatcher
def side_effect_arguments(self): # if an item in array p0 is modified or a call contains an argument # it can modify it is returned in the destroyed list. args = [] op = self.op if self.modifies_complex_object(): for opnum, i, j in unrolling_iterable(MODIFY_COMPLEX_OBJ): if op.getopnum() == opnum: op_args = op.getarglist() if j == -1: args.append((op.getarg(i), None, True)) for j in range(i+1,len(op_args)): args.append((op.getarg(j), None, False)) else: args.append((op.getarg(i), op.getarg(j), True)) for x in range(j+1,len(op_args)): args.append((op.getarg(x), None, False)) return args # assume this destroys every argument... can be enhanced by looking # at the effect info of a call for instance for arg in op.getarglist(): # if it is a constant argument it cannot be destroyed. # neither can a box float be destroyed. BoxInt can # contain a reference thus it is assumed to be destroyed if arg.is_constant() or arg.type == 'f': args.append((arg, None, False)) else: args.append((arg, None, True)) return args
def generate_fixed_immutable_subclass(n_storage): """ Generate `W_PointersObject` subclass with immutable storage of fixed size. :param n_storage: Number of storage slots. :returns: Immutable `W_PointersObject` subclass with fixed slots. """ storage_iter = unrolling_iterable(range(n_storage)) cls_name = '%s_Immutable_%s' % (W_PointersObject.repr_classname, n_storage) class W_FixedImmutable_PointersObject(W_AbstractImmutable_PointersObject): """`W_PointersObject` subclass with immutable storage of fixed size.""" _storages_ = [(STORAGE_ATTR_TEMPLATE % x) for x in storage_iter] _attrs_ = _storages_ _immutable_fields_ = _storages_ repr_classname = cls_name def __init__(self, space, w_cls, pointers_w): W_AbstractImmutable_PointersObject.__init__(self, space, w_cls) for x in storage_iter: setattr(self, STORAGE_ATTR_TEMPLATE % x, pointers_w[x]) def size(self): return n_storage def fetch(self, space, n0): for x in storage_iter: if x == n0: return getattr(self, STORAGE_ATTR_TEMPLATE % x) raise IndexError return self.storage[n0] W_FixedImmutable_PointersObject.__name__ = cls_name return W_FixedImmutable_PointersObject
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 decorator(func): len_unwrap_spec = len(unwrap_spec) assert len_unwrap_spec == len(inspect.getargspec(func)[0]), "wrong number of arguments" unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(*c_arguments): assert len_unwrap_spec == len(c_arguments) args = () if IProxy.trace_proxy.is_set(): print 'Called InterpreterProxy >> %s' % func.func_name, assert IProxy.s_frame is not None and IProxy.space is not None and IProxy.interp is not None try: for i, spec in unrolling_unwrap_spec: c_arg = c_arguments[i] if spec is oop: args += (IProxy.oop_to_object(c_arg), ) elif spec is str: args += (rffi.charp2str(c_arg), ) else: args += (c_arg, ) result = func(*args) if IProxy.trace_proxy.is_set(): print '\t-> %s' % result if result_type is oop: assert isinstance(result, model.W_Object) return IProxy.object_to_oop(result) elif result_type in (int, float): assert isinstance(result, result_type) return result elif result_type is bool: assert isinstance(result, bool) if result: return 1 else: return 0 else: return result except error.PrimitiveFailedError: if IProxy.trace_proxy.is_set(): print '\t-> failed' IProxy.failed() from rpython.rlib.objectmodel import we_are_translated if not we_are_translated(): import pdb; pdb.set_trace() if mapping[result_type] is sqInt: return 0 elif mapping[result_type] is sqDouble: return 0.0 elif mapping[result_type] is sqIntArrayPtr: return rffi.cast(sqIntArrayPtr, 0) elif mapping[result_type] is sqLong: # XXX: how to return a long 0? return 0 elif mapping[result_type] is sqStr: return rffi.cast(sqStr, "") else: raise NotImplementedError( "InterpreterProxy: unknown result_type %s" % (result_type, )) wrapped.func_name = "wrapped_ipf_" + func.func_name functions.append((func.func_name, f_ptr, wrapped)) return wrapped
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 generate_class(cname, fname, n_args): from rpython.rlib.unroll import unrolling_iterable arg_iter = unrolling_iterable(range(n_args)) parent = callables['Abstract', n_args] assert parent is not None signature = Signature.getsignature(fname, n_args) class specific_class(parent): if n_args == 0: TYPE_STANDARD_ORDER = Atom.TYPE_STANDARD_ORDER else: TYPE_STANDARD_ORDER = Term.TYPE_STANDARD_ORDER def __init__(self, term_name, args, signature): parent._init_values(self, args) assert self.name() == term_name assert args is None or len(args) == n_args def name(self): return fname def signature(self): return signature def _make_new(self, name, signature): cls = specific_class return cls(name, None, signature) specific_class.__name__ = cname return specific_class
def make_int_packer(size, signed, _memo={}): key = size, signed try: return _memo[key] except KeyError: pass min, max, accept_method = min_max_acc_method(size, signed) if size > 1: plural = "s" else: plural = "" errormsg = "argument out of range for %d-byte%s integer format" % (size, plural) unroll_revrange_size = unrolling_iterable(range(size-1, -1, -1)) def pack_int(fmtiter): method = getattr(fmtiter, accept_method) value = method() if not min <= value <= max: raise StructError(errormsg) if fmtiter.bigendian: for i in unroll_revrange_size: x = (value >> (8*i)) & 0xff fmtiter.result.append(chr(x)) else: for i in unroll_revrange_size: fmtiter.result.append(chr(value & 0xff)) value >>= 8 _memo[key] = pack_int return pack_int
def gen_str_function(tuplerepr): items_r = tuplerepr.items_r key = tuple([r_item.ll_str for r_item in items_r]) try: return _gen_str_function_cache[key] except KeyError: autounrolling_funclist = unrolling_iterable(enumerate(key)) constant = LLHelpers.ll_constant start = LLHelpers.ll_build_start push = LLHelpers.ll_build_push finish = LLHelpers.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 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 _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 is_valid_int(value) and value != 0 result.append((value, getattr(OptString, name))) return unrolling_iterable(result)
def make_execute_token(self, *ARGS): """Build and return a function for executing the given JIT token. Each chunk of compiled code is represented by an integer "function id". We need to look up the id, build the necessary frame, and then call the helper function "jitInvoke" to execute the compiled function. """ # This is mostly copied from llsupport/llmodel.py, but with changes # to invoke the external javascript helper thingy. lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] kinds = unrolling_iterable(lst) def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert isinstance(clt, CompiledLoopTokenASMJS) funcid = clt.func.compiled_funcid loopid = clt.compiled_loopid frame_info = clt.func.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = clt._ll_initial_locs if SANITYCHECK: assert len(locs) == len(args) if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: # Store each argument into the frame. for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) llop.gc_writebarrier(lltype.Void, ll_frame) # Send the threadlocaladdr. if self.translate_support_code: ll_tlref = llop.threadlocalref_addr(llmemory.Address) else: ll_tlref = rffi.cast(llmemory.Address, self._debug_errno_container) # Invoke it via the helper. ll_frameadr = self.cast_ptr_to_int(ll_frame) ll_tladdr = self.cast_adr_to_int(ll_tlref) ll_frameadr = support.jitInvoke(funcid, ll_frameadr, ll_tladdr, loopid) ll_frame = self.cast_int_to_ptr(ll_frameadr, llmemory.GCREF) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter return ll_frame return execute_token
def make_wrapper(space, callable, gil=None): "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() gil_acquire = (gil == "acquire" or gil == "around") gil_release = (gil == "release" or gil == "around") assert gil is None or gil_acquire or gil_release @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 if gil_acquire: after = rffi.aroundstate.after if after: after() rffi.stackcounter.stacks_counter += 1 llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py 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_execute_token(self, *ARGS): """Build and return a function for executing the given JIT token. Each chunk of compiled code is represented by an integer "function id". We need to look up the id, build the necessary frame, and then call the helper function "jitInvoke" to execute the compiled function. """ # This is mostly copied from llsupport/llmodel.py, but with changes # to invoke the external javascript helper thingy. lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] kinds = unrolling_iterable(lst) def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert isinstance(clt, CompiledLoopTokenASMJS) funcid = clt.func.compiled_funcid loopid = clt.compiled_loopid frame_info = clt.func.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = clt._ll_initial_locs if SANITYCHECK: assert len(locs) == len(args) if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: # Store each argument into the frame. for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) llop.gc_writebarrier(lltype.Void, ll_frame) # Send the threadlocaladdr. if self.translate_support_code: ll_tlref = llop.threadlocalref_addr( llmemory.Address) else: ll_tlref = rffi.cast(llmemory.Address, self._debug_errno_container) # Invoke it via the helper. ll_frameadr = self.cast_ptr_to_int(ll_frame) ll_tladdr = self.cast_adr_to_int(ll_tlref) ll_frameadr = support.jitInvoke(funcid, ll_frameadr, ll_tladdr, loopid) ll_frame = self.cast_int_to_ptr(ll_frameadr, llmemory.GCREF) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter return ll_frame return execute_token
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 is_valid_int(value) and value != 0 result.append((value, getattr(OptString, name))) return unrolling_iterable(result)
def make_execute_token(self, *ARGS): # The JIT backend must generate functions with the following # signature: it takes the jitframe and the threadlocal_addr # as arguments, and it returns the (possibly reallocated) jitframe. # The backend can optimize OS_THREADLOCALREF_GET calls to return a # field of this threadlocal_addr, but only if 'translate_support_code': # in untranslated tests, threadlocal_addr is a dummy container # for errno tests only. FUNCPTR = lltype.Ptr( lltype.FuncType([llmemory.GCREF, llmemory.Address], llmemory.GCREF)) lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] kinds = unrolling_iterable(lst) def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert len(args) == clt._debug_nbargs # addr = executable_token._ll_function_addr func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) if self.translate_support_code: ll_threadlocal_addr = llop.threadlocalref_addr( llmemory.Address) else: ll_threadlocal_addr = rffi.cast( llmemory.Address, self._debug_errno_container) llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame, ll_threadlocal_addr) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter #llop.debug_print(lltype.Void, "<<<< Back") return ll_frame return execute_token
def make_class(size): attrs = ["_%s_%s" % (attrname, i) for i in range(size)] unrolling_enumerate_attrs = unrolling_iterable(enumerate(attrs)) def _get_size_list(self): return size def _get_list(self, i): for j, attr in unrolling_enumerate_attrs: if j == i: return getattr(self, attr) raise IndexError def _get_full_list(self): res = [None] * size for i, attr in unrolling_enumerate_attrs: res[i] = getattr(self, attr) return res def _set_list(self, i, val): for j, attr in unrolling_enumerate_attrs: if j == i: if nonull: assert val is not None setattr(self, attr, val) return raise IndexError def _init(self, elems, *args): assert len(elems) == size for i, attr in unrolling_enumerate_attrs: val = elems[i] if nonull: assert val is not None setattr(self, attr, elems[i]) cls.__init__(self, *args) # Methods for the new class being built methods = { gettername : _get_list, listsizename : _get_size_list, listgettername : _get_full_list, settername : _set_list, "__init__" : _init, } newcls = type(cls)("%sSize%s" % (cls.__name__, size), (cls, ), methods) if _immutable_: setattr(newcls, "_immutable_", True) newcls = add_clone_method(newcls) if immutable: setattr(newcls, "_immutable_fields_", attrs) newcls = add_clone_method(newcls) if "_attrs_" in cls.__dict__: setattr(newcls, "_attrs_", attrs) return newcls
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 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 make_class(size): attrs = ["_%s_%s" % (attrname, i) for i in range(size)] unrolling_enumerate_attrs = unrolling_iterable(enumerate(attrs)) def _get_size_list(self): return size def _get_list(self, i): for j, attr in unrolling_enumerate_attrs: if j == i: return getattr(self, attr) raise IndexError def _get_full_list(self): res = [None] * size for i, attr in unrolling_enumerate_attrs: res[i] = getattr(self, attr) return res def _set_list(self, i, val): for j, attr in unrolling_enumerate_attrs: if j == i: if nonull: assert val is not None setattr(self, attr, val) return raise IndexError def _init(self, elems, *args): assert len(elems) == size for i, attr in unrolling_enumerate_attrs: val = elems[i] if nonull: assert val is not None setattr(self, attr, elems[i]) cls.__init__(self, *args) def _clone(self): # Allocate and fill in small list values result = objectmodel.instantiate(newcls) for _, attr in unrolling_enumerate_attrs: value = getattr(self, attr) setattr(result, attr, value) return result # Methods for the new class being built methods = { gettername : _get_list, listsizename : _get_size_list, listgettername : _get_full_list, settername : _set_list, "__init__" : _init, "_clone_small_list" : _clone, } if immutable: methods["_immutable_fields_"] = attrs newcls = type(cls)("%sSize%s" % (cls.__name__, size), (cls, ), methods) return newcls
def signature(*argtypes, **keywords): topc = argc = len(argtypes) argc -= keywords.get("optional", 0) variadic = keywords.get("variadic", False) argi = unroll.unrolling_iterable(range(argc)) argj = unroll.unrolling_iterable(range(argc, topc)) def signature_decorator(func): def fancy_frame(argv): args = () L = len(argv) if L < argc or (L > topc and not variadic): raise space.unwind(space.LCallError(argc, topc, variadic, L)) for i in argi: arg = argv[i] if isinstance(arg, argtypes[i]): args += (arg, ) else: args += (space.cast(arg, argtypes[i], u"arg:%d" % i), ) for j in argj: if j < L: arg = argv[j] if arg is null: arg = None elif not isinstance(arg, argtypes[j]): arg = space.cast(arg, argtypes[j], u"arg:%d" % j) else: arg = None args += (arg, ) if variadic: args += (argv[min(topc, L):], ) return func(*args) fancy_frame.__name__ = func.__name__ spec_table[fancy_frame] = spec_table[func] = ( argc, topc - argc, variadic, list(inspect.getargspec(func)[0]), [t.interface for t in argtypes]) source_table[fancy_frame] = source_table[func] = get_source_location( func) return fancy_frame return signature_decorator
def decorator(func): if unwrap_spec is None: assert num_args is not None def wrapped(w_arguments): assert len(w_arguments) == num_args w_result = func(w_arguments) return w_result return wrapped # unwrap_spec not None. len_unwrap_spec = len(unwrap_spec) assert num_args is None or num_args == len_unwrap_spec actual_arglen = len(inspect.getargspec(func)[0]) assert (len_unwrap_spec == actual_arglen), \ "wrong number of unwrap arguments (%d for %d) in %r" % ( len_unwrap_spec, actual_arglen, func) unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec)) def wrapped(w_arguments): assert len(w_arguments) == len_unwrap_spec args = () for i, spec in unrolling_unwrap_spec: w_arg = w_arguments[i] if False: pass elif spec is generic: assert isinstance(w_arg, model.W_Object) args += (w_arg, ) elif spec is int: assert isinstance(w_arg, model.W_Integer) args += (w_arg.value(), ) elif spec is float: assert isinstance(w_arg, model.W_Float) args += (w_arg.value(), ) elif spec is long: assert isinstance(w_arg, model.W_Bignumber) args += (w_arg.value(), ) elif spec is str: assert isinstance(w_arg, model.W_String) args += (w_arg.value(), ) elif spec is list: assert isinstance(w_arg, model.W_Constructor) t = w_arg.get_tag() assert t.arity() == 2 args += (plist(w_arg), ) else: raise NotImplementedError("unknown unwrap_spec %s" % (spec, )) w_result = func(*args) return w_result return wrapped
def make_execute_token(self, *ARGS): # The JIT backend must generate functions with the following # signature: it takes the jitframe and the threadlocal_addr # as arguments, and it returns the (possibly reallocated) jitframe. # The backend can optimize OS_THREADLOCALREF_GET calls to return a # field of this threadlocal_addr, but only if 'translate_support_code': # in untranslated tests, threadlocal_addr is a dummy container # for errno tests only. FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.Address], llmemory.GCREF)) lst = [(i, history.getkind(ARG)[0]) for i, ARG in enumerate(ARGS)] kinds = unrolling_iterable(lst) def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert len(args) == clt._debug_nbargs # addr = executable_token._ll_function_addr func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) if self.translate_support_code: ll_threadlocal_addr = llop.threadlocalref_addr( llmemory.Address) else: ll_threadlocal_addr = rffi.cast(llmemory.Address, self._debug_errno_container) llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame, ll_threadlocal_addr) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter #llop.debug_print(lltype.Void, "<<<< Back") return ll_frame return execute_token
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_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 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 build(constructor, pieces): ipieces = unrolling_iterable(enumerate(pieces)) class Constructor(NT): _immutable_ = True _immutable_fields_ = [freezeField(field, ty) for field, ty in pieces] def __init__(self, *args): for i, (piece, _) in ipieces: setattr(self, piece, args[i]) Constructor.__name__ = constructor + str(increment()) irAttrs[constructor] = Constructor