Beispiel #1
0
 def eval_arithmetic(self, engine):
     from prolog.interpreter.arithmetic import get_arithmetic_function
     func = get_arithmetic_function(self.signature())
     jit.promote(func)
     if func is None:
         error.throw_type_error("evaluable", self.get_prolog_signature())
     return func(engine, self)
Beispiel #2
0
 def pop_n(self, n):
     #assert n == 0 or self._stack_ptr - n >= self.tempsize()
     jit.promote(self._stack_ptr)
     while n > 0:
         n -= 1
         self._stack_ptr -= 1
         self.stack_put(self._stack_ptr, self.space.w_nil)
Beispiel #3
0
 def pop_n(self, n):
     #assert n == 0 or self._stack_ptr - n >= self.tempsize()
     jit.promote(self._stack_ptr)
     while n > 0:
         n -= 1
         self._stack_ptr -= 1
         self._temps_and_stack[self._stack_ptr] = None
Beispiel #4
0
 def getbytecode(self):
     jit.promote(self._pc)
     assert self._pc >= 0
     bytecode = self.s_method().getbytecode(self._pc)
     currentBytecode = ord(bytecode)
     self._pc += 1
     return currentBytecode
Beispiel #5
0
 def constr_proc_wrapper_cont(self, field_values, struct_type_name, issuper,
     app, env, cont, _vals):
     from pycket.interpreter import return_multi_vals, jump
     guard_values = _vals.get_all_values()
     type = jit.promote(self.type)
     if guard_values:
         field_values = guard_values
     super_type = jit.promote(type.super)
     if isinstance(super_type, W_StructType):
         split_position = len(field_values) - type.init_field_cnt
         super_auto = super_type.constr.type.auto_values
         assert split_position >= 0
         field_values = self._splice(field_values, len(field_values),\
             split_position, super_auto, len(super_auto))
         if issuper:
             return super_type.constr.code(field_values[:split_position],
                 struct_type_name, True, env, cont, app)
         else:
             return super_type.constr.code(field_values[:split_position],
                 struct_type_name, True,
                 env, self.constr_proc_cont(field_values, env, cont), app)
     else:
         if issuper:
             return return_multi_vals(values.Values.make(field_values), env, cont)
         else:
             return jump(env, self.constr_proc_cont(field_values, env, cont))
 def pop_n(self, n):
     jit.promote(self.stack_ptr())
     while n > 0:
         n -= 1
         assert self.stack_ptr() >= 1, "stack pointer reduced to < 1 in pop_n"
         self.store_stack_ptr(self.stack_ptr() - 1)
         self.stack_put(self.stack_ptr(), self.space.w_nil)
Beispiel #7
0
    def descr_call(self, space, __args__):
        promote(self)
        # invoke the __new__ of the type
        if not we_are_jitted():
            # note that the annotator will figure out that self.w_new_function
            # can only be None if the newshortcut config option is not set
            w_newfunc = self.w_new_function
        else:
            # for the JIT it is better to take the slow path because normal lookup
            # is nicely optimized, but the self.w_new_function attribute is not
            # known to the JIT
            w_newfunc = None
        if w_newfunc is None:
            w_newtype, w_newdescr = self.lookup_where('__new__')
            w_newfunc = space.get(w_newdescr, self)
            if (space.config.objspace.std.newshortcut and
                not we_are_jitted() and
                isinstance(w_newtype, W_TypeObject)):
                self.w_new_function = w_newfunc
        w_newobject = space.call_obj_args(w_newfunc, self, __args__)
        call_init = space.isinstance_w(w_newobject, self)

        # maybe invoke the __init__ of the type
        if (call_init and not (space.is_w(self, space.w_type) and
            not __args__.keywords and len(__args__.arguments_w) == 1)):
            w_descr = space.lookup(w_newobject, '__init__')
            w_result = space.get_and_call_args(w_descr, w_newobject, __args__)
            if not space.is_w(w_result, space.w_None):
                raise oefmt(space.w_TypeError, "__init__() should return None")
        return w_newobject
Beispiel #8
0
 def mutate(self, struct, field, val, env, cont, app):
     assert isinstance(struct, W_RootStruct)
     jit.promote(self)
     offset = struct.struct_type().get_offset(self.type)
     if offset == -1:
         raise SchemeException("cannot reference an identifier before its definition")
     return struct.set_with_extra_info(field + offset, val, app, env, cont)
def impl_functor(engine, heap, t, functor, arity):
    if helper.is_atomic(t):
        functor.unify(t, heap)
        arity.unify(term.Number(0), heap)
    elif helper.is_term(t):
        assert isinstance(t, term.Callable)
        sig = t.signature()
        atom = term.Callable.build(t.name(), signature=sig.atom_signature)
        functor.unify(atom, heap)
        arity.unify(term.Number(t.argument_count()), heap)
    elif isinstance(t, term.Var):
        if isinstance(functor, term.Var):
            error.throw_instantiation_error()
        a = helper.unwrap_int(arity)
        jit.promote(a)
        if a < 0:
            error.throw_domain_error("not_less_than_zero", arity)
        else:
            functor = helper.ensure_atomic(functor)
            if a == 0:
                t.unify(functor, heap)
            else:
                jit.promote(functor)
                name = helper.unwrap_atom(functor)
                t.unify(
                    term.Callable.build(name, [heap.newvar() for i in range(a)]),
                    heap)
Beispiel #10
0
 def make_cont(self, env, prev, i=0):
     jit.promote(self)
     jit.promote(i)
     if i == len(self.body) - 1:
         return self.body[i], env, prev
     else:
         return self.body[i], env, SequenceContinuation(self, i+1, env, prev)
Beispiel #11
0
 def toplevel_lookup(self, sym):
     from pycket.values import W_Cell
     jit.promote(self)
     w_res = self._lookup(sym, jit.promote(self.version))
     if isinstance(w_res, W_Cell):
         w_res = w_res.get_val()
     return w_res
Beispiel #12
0
 def fn(n):
     a1 = (n, )
     g.a = a1
     a2 = (n - 1, )
     g.a = a2
     jit.promote(n)
     return a1[0] + a2[0] + gn(a1, a2)
Beispiel #13
0
 def plug_reduce(self, v):
     assert isinstance(v, MultiValue)
     new_env_s = create_new_env_structure(self.let_ast.top_env_s, self.env_s)
     jit.promote(new_env_s)
     return ExpState(self.let_ast.body,
                     new_env_s, EnvironmentValues(v.values, self.env_v),
                     self.k)
Beispiel #14
0
    def __init__(self, func, names, args, env, strict=False):
        from js.object_space import _w
        W__Object.__init__(self)
        self.strict = strict
        _len = len(args)
        put_property(self, u'length', _w(_len), writable=True, enumerable=False, configurable=True)

        from js.object_space import object_space
        _map = object_space.new_obj()
        mapped_names = new_map()
        jit.promote(_len)
        indx = _len - 1
        while indx >= 0:
            val = args[indx]
            put_property(self, unicode(str(indx)), val, writable=True, enumerable=True, configurable=True)
            if indx < len(names):
                name = names[indx]
                if strict is False and not mapped_names.contains(name):
                    mapped_names = mapped_names.add(name)
                    g = make_arg_getter(name, env)
                    p = make_arg_setter(name, env)
                    desc = PropertyDescriptor(setter=p, getter=g, configurable=True)
                    _map.define_own_property(unicode(str(indx)), desc, False)
            indx = indx - 1

        if not mapped_names.empty():
            self._paramenter_map_ = _map

        if strict is False:
            put_property(self, u'callee', _w(func), writable=True, enumerable=False, configurable=True)
        else:
            # 10.6 14 thrower
            pass
Beispiel #15
0
 def next(self, state, mutate=False):
     assert state.iterator is self
     index = state.index
     if self.track_index:
         index += 1
     indices = state._indices
     offset = state.offset
     if self.contiguous:
         elsize = self.array.dtype.elsize
         jit.promote(elsize)
         offset += elsize
     elif self.ndim_m1 == 0:
         stride = self.strides[0]
         jit.promote(stride)
         offset += stride
     else:
         for i in xrange(self.ndim_m1, -1, -1):
             idx = indices[i]
             if idx < self.shape_m1[i]:
                 indices[i] = idx + 1
                 offset += self.strides[i]
                 break
             else:
                 indices[i] = 0
                 offset -= self.backstrides[i]
     if not mutate:
         return IterState(self, index, indices, offset)
     state.index = index
     state.offset = offset
Beispiel #16
0
 def fn(n):
     jit.promote(n)
     try:
         n = ovfcheck(n + 1)
     except OverflowError:
         return 12
     else:
         return n
Beispiel #17
0
 def __init__(self, closure, k, env_s, prev_env_v):
     assert isinstance(closure, Closure)
     self.closure = closure
     self.k = k
     self.env_s = env_s
     jit.promote(self.env_s)
     self.prev_env_v = prev_env_v
     self.plug_loop = False
Beispiel #18
0
def make_arity_list(arity, extra=None):
    jit.promote(arity)
    acc = values.w_null
    if extra is not None:
        acc = values.W_Cons.make(extra, acc)
    for item in reversed(arity.arity_list):
        i = values.W_Fixnum(item)
        acc = values.W_Cons.make(i, acc)
    return acc
Beispiel #19
0
 def get_global(self, name):
     # Return the global with the given name if it's in the dictionary of globals
     # if not, return None
     jit.promote(self)
     assoc = self._get_global(name)
     if assoc:
         return assoc.get_value()
     else:
         return None
Beispiel #20
0
 def lookup(self, sym, env_structure):
     jit.promote(env_structure)
     for i, s in enumerate(env_structure.elems):
         if s is sym:
             v = self._get_list(i)
             assert v is not None
             return v
     prev = self.get_prev(env_structure)
     return prev.lookup(sym, env_structure.prev)
Beispiel #21
0
    def __init__(self, code, frame, globals):
        self.code = code
        self.env = Environment(frame, globals, self.code.localSize(),
                               promote(self.code.maxDepth),
                               promote(self.code.maxHandlerDepth))

        # For vat checkpointing.
        from typhon.vats import currentVat
        self.vat = currentVat.get()
Beispiel #22
0
 def code(self, field_values, issuper, env, cont):
     from pycket.interpreter import jump
     if self.type.guard is values.w_false:
         return jump(env, self.constr_proc_wrapper_cont(field_values, issuper, env, cont))
     else:
         guard_args = field_values + [values.W_Symbol.make(self.type.name)]
         jit.promote(self)
         return self.type.guard.call(guard_args, env,
             self.constr_proc_wrapper_cont(field_values, issuper, env, cont))
Beispiel #23
0
 def mutate(self, struct, field, val, env, cont, app):
     self = jit.promote(self)
     st = jit.promote(struct.struct_type())
     if st is None:
         raise SchemeException("%s got %s" % (self.tostring(), struct.tostring()))
     offset = st.get_offset(self.type)
     if offset == -1:
         raise SchemeException("cannot reference an identifier before its definition")
     return struct.set_with_extra_info(field + offset, val, app, env, cont)
Beispiel #24
0
 def eq(self, other):
     # slightly evil
     if jit.isconstant(self):
         jit.promote(other)
     elif jit.isconstant(other):
         jit.promote(self)
     return self is other or (
             self.numargs == other.numargs and
             self.name == other.name)
Beispiel #25
0
 def invoke_Ef(self, args):
     new_env = self._env
     x = 0
     arg_names = jit.promote(self._arg_names)
     while x < args.arg_count():
         new_env = new_env.with_locals(arg_names[x], args.get_arg(x))
         x += 1
     new_env = new_env.with_locals(jit.promote(self._name), self)
     ast = self._w_code
     return thunk_tailcall_Ef(ast, new_env)
Beispiel #26
0
 def fn(n, i):
     res = 0
     obj = A()
     while i > 0:
         myjitdriver.can_enter_jit(i=i, obj=obj)
         myjitdriver.jit_merge_point(i=i, obj=obj)
         promote(obj)
         res = obj.foo()
         i-=1
     return res
Beispiel #27
0
 def issubtype(w_self, w_type):
     promote(w_self)
     promote(w_type)
     if w_self.space.config.objspace.std.withtypeversion and we_are_jitted():
         version_tag1 = w_self.version_tag()
         version_tag2 = w_type.version_tag()
         if version_tag1 is not None and version_tag2 is not None:
             res = _pure_issubtype(w_self, w_type, version_tag1, version_tag2)
             return res
     return _issubtype(w_self, w_type)
Beispiel #28
0
 def fn(i):
     if i < 0:
         g.a1 = [7, 8, 9]
         g.a2 = [7, 8, 9, 10]
     jit.promote(i)
     a1 = g.a1
     a1[i + 1] = 15 # make lists mutable
     a2 = g.a2
     a2[i + 1] = 19
     return a1[i] + a2[i] + a1[i] + a2[i]
Beispiel #29
0
    def prep_exb(self, args):
        size = jit.promote(self._cd.exchange_size)
        exb = rffi.cast(rffi.VOIDP, lltype.malloc(rffi.CCHARP.TO, size, flavor="raw"))
        tokens = [None] * len(args)

        for i, tp in enumerate(self._arg_types):
            offset_p = rffi.ptradd(exb, jit.promote(self._cd.exchange_args[i]))
            tokens[i] = tp.ffi_set_value(offset_p, args[i])

        return exb, tokens
Beispiel #30
0
 def f(n, a, i):
     stufflist = StuffList()
     stufflist.lst = [Stuff(a), Stuff(3)]
     while n > 0:
         myjitdriver.can_enter_jit(n=n, i=i, stufflist=stufflist)
         myjitdriver.jit_merge_point(n=n, i=i, stufflist=stufflist)
         promote(i)
         v = Stuff(i)
         n -= stufflist.lst[v.x].x
     return n
Beispiel #31
0
 def call_with_extra_info(self, args, env, cont, calling_app):
     jit.promote(self)
     return self.closure.call_with_extra_info(args, env, cont, calling_app)
Beispiel #32
0
 def _stack_pointer(self):
     return jit.promote(self._stack_pointer_)
Beispiel #33
0
 def getclass(self, space):
     return jit.promote(self.map).find(mapdict.ClassNode).getclass()
Beispiel #34
0
 def find_instance_var(self, space, name):
     node = jit.promote(self.map).find(mapdict.AttributeNode, name)
     if node is None:
         return None
     return node.read(space, self)
Beispiel #35
0
 def unset_flag(self, space, name):
     node = jit.promote(self.map).find(mapdict.FlagNode, name)
     # Flags are by default unset, no need to add if unsetting
     if node is not None:
         node.write(space, self, space.w_false)
Beispiel #36
0
 def set_instance_var(self, space, name, w_value):
     idx = jit.promote(self.map).find_set_attr(space, name)
     if idx == -1:
         idx = self.map.add_attr(space, self, name)
     self.storage[idx] = w_value
Beispiel #37
0
 def set_instance_var(self, space, name, w_value):
     node = jit.promote(self.map).find(mapdict.AttributeNode, name)
     if node is None:
         self.map = node = self.map.add(space, mapdict.AttributeNode.select_type(space, w_value), name, self)
     node.write(space, self, w_value)
Beispiel #38
0
 def find_instance_var(self, space, name):
     idx = jit.promote(self.map).find_attr(space, name)
     if idx == -1:
         return None
     return self.storage[idx]
Beispiel #39
0
 def get_flag(self, space, name):
     node = jit.promote(self.map).find(mapdict.FlagNode, name)
     return space.w_false if node is None else node.read(space, self)
Beispiel #40
0
 def test(a, b):
     a = promote(a)
     b = promote(b)
     return compare(a, b)
Beispiel #41
0
def equal_func_unroll_n(a, b, info, env, cont, n):
    # n says how many times to call equal_func before going through loop label
    if n > 0:
        jit.promote(n)
        return equal_func_impl(a, b, info, env, cont, n - 1)
    return equal_func_loop(a, b, info, env, cont)
Beispiel #42
0
 def unset_flag(self, space, name):
     idx = jit.promote(self.map).find_flag(space, name)
     if idx != -1:
         # Flags are by default unset, no need to add if unsetting
         self.storage[idx] = space.w_false
Beispiel #43
0
 def getclass(self, space):
     return jit.promote(self.w_class)
Beispiel #44
0
    def callAtom(self, atom, arguments, namedArgsMap):
        """
        This method is used to reuse atoms without having to rebuild them.
        """
        from typhon.objects.collections.maps import EMPTY_MAP
        # Promote the atom, on the basis that atoms are generally reused.
        atom = promote(atom)
        # Log the atom to the JIT log. Don't do this if the atom's not
        # promoted; it'll be slow.
        jit_debug(atom.repr)

        try:
            return self.recvNamed(atom, arguments, namedArgsMap)
        except Refused as r:
            # This block of method implementations is Typhon's Miranda
            # protocol. ~ C.

            if atom is _CONFORMTO_1:
                # Welcome to _conformTo/1.
                # to _conformTo(_): return self
                return self

            if atom is _GETALLEGEDINTERFACE_0:
                # Welcome to _getAllegedInterface/0.
                interface = self.optInterface()
                if interface is None:
                    from typhon.objects.interfaces import ComputedInterface
                    interface = ComputedInterface(self)
                return interface

            if atom is _PRINTON_1:
                # Welcome to _printOn/1.
                from typhon.objects.constants import NullObject
                self.printOn(arguments[0])
                return NullObject

            if atom is _RESPONDSTO_2:
                from typhon.objects.constants import wrapBool
                from typhon.objects.data import unwrapInt, unwrapStr
                verb = unwrapStr(arguments[0])
                arity = unwrapInt(arguments[1])
                atom = getAtom(verb, arity)
                result = (atom in self.respondingAtoms()
                          or atom in mirandaAtoms)
                return wrapBool(result)

            if atom is _SEALEDDISPATCH_1:
                # to _sealedDispatch(_): return null
                from typhon.objects.constants import NullObject
                return NullObject

            if atom is _UNCALL_0:
                from typhon.objects.constants import NullObject
                return NullObject

            if atom is _WHENMORERESOLVED_1:
                # Welcome to _whenMoreResolved.
                # This method's implementation, in Monte, should be:
                # to _whenMoreResolved(callback): callback<-(self)
                from typhon.vats import currentVat
                vat = currentVat.get()
                vat.sendOnly(arguments[0], RUN_1, [self], EMPTY_MAP)
                from typhon.objects.constants import NullObject
                return NullObject

            addTrail(r, self, atom, arguments)
            raise

        except UserException as ue:
            addTrail(ue, self, atom, arguments)
            raise
        except MemoryError:
            ue = userError(u"Memory corruption or exhausted heap")
            addTrail(ue, self, atom, arguments)
            raise ue
        except StackOverflow:
            check_stack_overflow()
            ue = userError(u"Stack overflow")
            addTrail(ue, self, atom, arguments)
            raise ue
Beispiel #45
0
 def class_shadow(self, space):
     """Return internal representation of Squeak class."""
     w_class = jit.promote(self.getclass(space))
     return w_class.as_class_get_shadow(space)
Beispiel #46
0
 def invoke(self, args):
     self = jit.promote(self)
     return self._invoke(args)
Beispiel #47
0
 def call(self, args, env, cont):
     jit.promote(self)
     return self.closure.call(args, env, cont)
Beispiel #48
0
def interpret(bytecode, args):
    """The interpreter's entry point and portal function.
    """
    # ------------------------------
    # First a lot of JIT hints...
    #
    # A portal needs a "global merge point" at the beginning, for
    # technical reasons, if it uses promotion hints:
    hint(None, global_merge_point=True)

    # An important hint: 'bytecode' is a list, which is in theory
    # mutable.  Let's tell the JIT compiler that it can assume that the
    # list is entirely frozen, i.e. immutable and only containing immutable
    # objects.  Otherwise, it cannot do anything - it would have to assume
    # that the list can unpredictably change at runtime.
    bytecode = hint(bytecode, deepfreeze=True)

    # Now some strange code that makes a copy of the 'args' list in
    # a complicated way...  this is a workaround forcing the whole 'args'
    # list to be virtual.  It is a way to tell the JIT compiler that it
    # doesn't have to worry about the 'args' list being unpredictably
    # modified.
    oldargs = args
    argcount = promote(len(oldargs))
    args = []
    n = 0
    while n < argcount:
        hint(n, concrete=True)
        args.append(oldargs[n])
        n += 1
    # ------------------------------
    # the real code starts here
    loops = []
    stack = []
    pos = 0
    while pos < len(bytecode):
        # It is a good idea to put another 'global merge point' at the
        # start of each iteration in the interpreter's main loop.  The
        # JIT compiler keeps a table of all the times it passed through
        # the global merge point.  It allows it to detect when it can
        # stop compiling and generate a jump back to some machine code
        # that was already generated earlier.
        hint(None, global_merge_point=True)

        opcode = bytecode[pos]
        hint(opcode, concrete=True)  # same as in tiny1.py
        pos += 1
        if opcode == 'ADD': op2(stack, func_add_int, func_add_str)
        elif opcode == 'SUB': op2(stack, func_sub_int, func_sub_str)
        elif opcode == 'MUL': op2(stack, func_mul_int, func_mul_str)
        elif opcode[0] == '#':
            n = myint(opcode, start=1)
            stack.append(args[n - 1])
        elif opcode.startswith('->#'):
            n = myint(opcode, start=3)
            if n > len(args):
                raise IndexError
            args[n - 1] = stack.pop()
        elif opcode == '{':
            loops.append(pos)
        elif opcode == '}':
            if stack.pop().as_int() == 0:
                loops.pop()
            else:
                pos = loops[-1]
                # A common problem when interpreting loops or jumps: the 'pos'
                # above is read out of a list, so the hint-annotator thinks
                # it must be red (not a compile-time constant).  But the
                # hint(opcode, concrete=True) in the next iteration of the
                # loop requires all variables the 'opcode' depends on to be
                # green, including this 'pos'.  We promote 'pos' to a green
                # here, as early as possible.  Note that in practice the 'pos'
                # read out of the 'loops' list will be a compile-time constant
                # because it was pushed as a compile-time constant by the '{'
                # case above into 'loops', which is a virtual list, so the
                promote(pos)
        else:
            stack.append(StrBox(opcode))
    return stack
Beispiel #49
0
 def get_prev(self, env_structure):
     jit.promote(env_structure)
     if env_structure.elems:
         return self._prev
     return self
Beispiel #50
0
 def get_w_globals(self):
     debugdata = self.getdebug()
     if debugdata is not None:
         return debugdata.w_globals
     return jit.promote(self.pycode).w_globals
Beispiel #51
0
 def get_method(self):
     return jit.promote(self._method)
Beispiel #52
0
 def set_flag(self, space, name):
     node = jit.promote(self.map).find(mapdict.FlagNode, name)
     if node is None:
         self.map = node = self.map.add(space, mapdict.FlagNode, name, self)
     node.write(space, self, space.w_true)
Beispiel #53
0
 def get_ret_val_from_buffer(self, exb):
     cd = self._c_fn_type.get_cd()
     offset_p = rffi.ptradd(exb, jit.promote(cd.exchange_result))
     ret_val = self._c_fn_type._ret_type.ffi_get_value(offset_p)
     return ret_val
Beispiel #54
0
 def set_flag(self, space, name):
     idx = jit.promote(self.map).find_flag(space, name)
     if idx == -1:
         self.map.add_flag(space, self, name)
     else:
         self.storage[idx] = space.w_true
Beispiel #55
0
 def getcode(self):
     if jit.we_are_jitted():
         if not self.can_change_code:
             return _get_immutable_code(self)
         return jit.promote(self.code)
     return self.code
Beispiel #56
0
 def call_with_extra_info(self, args, env, cont, extra_call_info):
     jit.promote(self)
     return self.code(args, env, cont, extra_call_info)
Beispiel #57
0
 def getclass(self, space):
     return jit.promote(self.map).get_class()
Beispiel #58
0
 def get_flag(self, space, name):
     idx = jit.promote(self.map).find_flag(space, name)
     if idx == -1:
         return space.w_false
     return self.storage[idx]
Beispiel #59
0
def equal_func_impl(a, b, info, env, cont, n):
    from pycket.interpreter import return_value

    for_chaperone = jit.promote(info.for_chaperone)
    if a.eqv(b):
        return return_value(values.w_true, env, cont)

    if (for_chaperone >= EqualInfo.CHAPERONE and b.is_non_interposing_chaperone()):
        return equal_func_unroll_n(a, b.get_proxied(), info, env, cont, n)

    # Enter into chaperones/impersonators if we have permission to do so
    if ((for_chaperone == EqualInfo.CHAPERONE and a.is_chaperone()) or
        (for_chaperone == EqualInfo.IMPERSONATOR and a.is_impersonator())):
        return equal_func_unroll_n(a.get_proxied(), b, info, env, cont, n)

    # If we are doing a chaperone/impersonator comparison, then we do not have
    # a chaperone-of/impersonator-of relation if `a` is not a proxy and
    # `b` is a proxy.
    if for_chaperone != EqualInfo.BASIC and not a.is_proxy() and b.is_proxy():
        return return_value(values.w_false, env, cont)

    if isinstance(a, values_string.W_String) and isinstance(b, values_string.W_String):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return return_value(values.W_Bool.make(a.equal(b)), env, cont)

    if isinstance(a, values.W_Bytes) and isinstance(b, values.W_Bytes):
        is_chaperone = info.for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return return_value(values.W_Bool.make(a.equal(b)), env, cont)

    if isinstance(a, values.W_Cons) and isinstance(b, values.W_Cons):
        cont = equal_car_cont(a.cdr(), b.cdr(), info, env, cont)
        return equal_func_unroll_n(a.car(), b.car(), info, env, cont, n)

    if isinstance(a, values.W_MCons) and isinstance(b, values.W_MCons):
        cont = equal_car_cont(a.cdr(), b.cdr(), info, env, cont)
        return equal_func_unroll_n(a.car(), b.car(), info, env, cont, n)

    if isinstance(a, values.W_Box) and isinstance(b, values.W_Box):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return a.unbox(env, equal_unbox_right_cont(b, info, env, cont))

    if isinstance(a, values.W_MVector) and isinstance(b, values.W_MVector):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        if a.length() != b.length():
            return return_value(values.w_false, env, cont)
        return equal_vec_func(a, b, values.W_Fixnum(0), info, env, cont)

    if isinstance(a, values_struct.W_RootStruct) and isinstance(b, values_struct.W_RootStruct):
        a_type = a.struct_type()
        b_type = b.struct_type()
        w_prop = a_type.read_prop(values_struct.w_prop_equal_hash)
        if w_prop:
            w_prop = b_type.read_prop(values_struct.w_prop_equal_hash)
            if w_prop:
                w_equal_proc, w_hash_proc, w_hash2_proc = equal_hash_args(w_prop)
                # FIXME: it should work with cycles properly and be an equal?-recur
                w_equal_recur = equalp.w_prim
                return w_equal_proc.call([a, b, w_equal_recur], env, cont)
        if not a.struct_type().isopaque and not b.struct_type().isopaque:
            # This is probably not correct even if struct2vector were done
            # correct, due to side effects, but it is close enough for now.
            # Though the racket documentation says that `equal?` can elide
            # impersonator/chaperone handlers.
            a_imm = len(a_type.immutables) == a_type.total_field_cnt
            b_imm = len(b_type.immutables) == b_type.total_field_cnt
            a = values_struct.struct2vector(a, immutable=a_imm)
            b = values_struct.struct2vector(b, immutable=b_imm)
            return equal_func_unroll_n(a, b, info, env, cont, n)

    if a.equal(b):
        return return_value(values.w_true, env, cont)

    return return_value(values.w_false, env, cont)
Beispiel #60
0
 def get_fn(self, tp1, tp2, _rev):
     d1 = self._dict.get(tp1, None)
     if d1 is None:
         return self._default_fn
     fn = d1.get(tp2, self._default_fn)
     return promote(fn)