Exemple #1
0
def loop(iterable, consumer):
    """
    Perform an iterative loop.
    """

    # If the consumer is *not* a ScriptObject, then damn them to the slow
    # path. In order for the consumer to not be ScriptObject, though, the
    # compiler and optimizer must have decided that an object could be
    # directly passed to _loop(), which is currently impossible to do without
    # manual effort. It's really not a common pathway at all.
    if not isinstance(consumer, ScriptObject):
        return slowLoop(iterable, consumer)

    # Rarer path: If the consumer doesn't actually have RUN_2, then they're
    # not going to be JIT'd. Again, the compiler and optimizer won't ever do
    # this to us; it has to be intentional.
    code = consumer.codeScript.strategy.lookupMethod(RUN_2)
    if code is None:
        return slowLoop(iterable, consumer)

    iterator = iterable.call(u"_makeIterator", [])

    ej = Ejector()
    try:
        while True:
            # JIT merge point.
            loopDriver.jit_merge_point(code=code,
                                       consumer=consumer,
                                       ejector=ej,
                                       iterator=iterator)
            globals = promote(consumer.globals)
            if isinstance(consumer, BusyObject):
                machine = SmallCaps(code, consumer.closure, globals)
            else:
                machine = SmallCaps(code, None, globals)
            values = unwrapList(iterator.call(u"next", [ej]))
            # Push the arguments onto the stack, backwards.
            values.reverse()
            for arg in values:
                machine.push(arg)
                machine.push(NullObject)
            machine.push(EMPTY_MAP)
            machine.run()
    except Ejecting as e:
        if e.ejector is not ej:
            raise
    finally:
        ej.disable()

    return NullObject
Exemple #2
0
def listFromIterable(obj):
    rv = []
    iterator = obj.call(u"_makeIterator", [])
    ej = Ejector()
    while True:
        try:
            l = unwrapList(iterator.call(u"next", [ej]))
            if len(l) != 2:
                raise userError(u"makeList.fromIterable/1: Invalid iterator")
            rv.append(l[1])
        except Ejecting as ex:
            if ex.ejector is ej:
                ej.disable()
                return rv
            raise
Exemple #3
0
def listFromIterable(obj):
    rv = []
    iterator = obj.call(u"_makeIterator", [])
    ej = Ejector()
    while True:
        try:
            l = unwrapList(iterator.call(u"next", [ej]))
            if len(l) != 2:
                raise userError(u"makeList.fromIterable/1: Invalid iterator")
            rv.append(l[1])
        except Ejecting as ex:
            if ex.ejector is ej:
                ej.disable()
                return rv[:]
            raise
Exemple #4
0
def loop(iterable, consumer):
    """
    Perform an iterative loop.
    """

    # If the consumer is *not* a ScriptObject, then damn them to the slow
    # path. In order for the consumer to not be ScriptObject, though, the
    # compiler and optimizer must have decided that an object could be
    # directly passed to _loop(), which is currently impossible to do without
    # manual effort. It's really not a common pathway at all.
    if not isinstance(consumer, ScriptObject):
        return slowLoop(iterable, consumer)

    # Rarer path: If the consumer doesn't actually have RUN_2, then they're
    # not going to be JIT'd. Again, the compiler and optimizer won't ever do
    # this to us; it has to be intentional.
    code = consumer.codeScript.strategy.lookupMethod(RUN_2)
    if code is None:
        return slowLoop(iterable, consumer)

    iterator = iterable.call(u"_makeIterator", [])

    ej = Ejector()
    try:
        while True:
            # JIT merge point.
            loopDriver.jit_merge_point(code=code, consumer=consumer,
                                       ejector=ej, iterator=iterator)
            globals = promote(consumer.globals)
            if isinstance(consumer, BusyObject):
                machine = SmallCaps(code, consumer.closure, globals)
            else:
                machine = SmallCaps(code, None, globals)
            values = unwrapList(iterator.call(u"next", [ej]))
            # Push the arguments onto the stack, backwards.
            values.reverse()
            for arg in values:
                machine.push(arg)
                machine.push(NullObject)
            machine.push(EMPTY_MAP)
            machine.run()
    except Ejecting as e:
        if e.ejector is not ej:
            raise
    finally:
        ej.disable()

    return NullObject
Exemple #5
0
def isDeepFrozen(obj):
    with Ejector() as ej:
        try:
            deepFrozenGuard.coerce(obj, ej)
            return True
        except Ejecting as ex:
            if ex.ejector is not ej:
                raise
    return False
Exemple #6
0
 def coerce(self, specimen, ej):
     for g in self.subguards:
         with Ejector() as cont:
             try:
                 return g.call(u"coerce", [specimen, cont])
             except Ejecting as e:
                 if e.ejector is cont:
                     continue
     throwStr(ej, u"No subguards matched")
Exemple #7
0
def loop(iterable, consumer):
    """
    Perform an iterative loop.
    """

    # If the consumer is *not* an InterpObject, then damn them to the slow
    # path. In order for the consumer to not be InterpObject, though, the
    # compiler and optimizer must have decided that an object could be
    # directly passed to _loop(), which is currently impossible to do without
    # manual effort. It's really not a common pathway at all.
    if not isinstance(consumer, InterpObject):
        return slowLoop(iterable, consumer)
    displayName = consumer.getDisplayName().encode("utf-8")

    # Rarer path: If the consumer doesn't actually have a method for run/2,
    # then they're not going to be JIT'd. Again, the compiler and optimizer
    # won't ever do this to us; it has to be intentional.
    method = consumer.getMethod(RUN_2)
    if method is None:
        return slowLoop(iterable, consumer)

    iterator = iterable.call(u"_makeIterator", [])

    # XXX We want to use a with-statement here, but we cannot because of
    # something weird about the merge point.
    ej = Ejector()
    try:
        while True:
            # JIT merge point.
            loopDriver.jit_merge_point(method=method, displayName=displayName,
                    consumer=consumer, ejector=ej, iterator=iterator)
            values = unwrapList(iterator.call(u"next", [ej]))
            consumer.runMethod(method, values, EMPTY_MAP)
    except Ejecting as e:
        if e.ejector is not ej:
            raise
    finally:
        ej.disable()

    return NullObject
Exemple #8
0
def loop(iterable, consumer):
    """
    Perform an iterative loop.
    """

    # If the consumer is *not* an InterpObject, then damn them to the slow
    # path. In order for the consumer to not be InterpObject, though, the
    # compiler and optimizer must have decided that an object could be
    # directly passed to _loop(), which is currently impossible to do without
    # manual effort. It's really not a common pathway at all.
    if not isinstance(consumer, InterpObject):
        return slowLoop(iterable, consumer)
    displayName = consumer.getDisplayName().encode("utf-8")

    # Rarer path: If the consumer doesn't actually have a method for run/2,
    # then they're not going to be JIT'd. Again, the compiler and optimizer
    # won't ever do this to us; it has to be intentional.
    method = consumer.getMethod(RUN_2)
    if method is None:
        return slowLoop(iterable, consumer)

    iterator = iterable.call(u"_makeIterator", [])

    ej = Ejector()
    try:
        while True:
            # JIT merge point.
            loopDriver.jit_merge_point(method=method, displayName=displayName,
                    consumer=consumer, ejector=ej, iterator=iterator)
            values = unwrapList(iterator.call(u"next", [ej]))
            consumer.runMethod(method, values, EMPTY_MAP)
    except Ejecting as e:
        if e.ejector is not ej:
            raise
    finally:
        ej.disable()

    return NullObject
Exemple #9
0
def slowLoop(iterable, consumer):
    iterator = iterable.call(u"_makeIterator", [])

    with Ejector() as ej:
        while True:
            try:
                values = iterator.call(u"next", [ej])
                consumer.call(u"run", unwrapList(values))
            except Ejecting as e:
                if e.ejector is ej:
                    break
                else:
                    raise

    return NullObject
Exemple #10
0
    def runMatchers(self, atom, args, namedArgs):
        message = ConstList([StrObject(atom.verb), ConstList(args), namedArgs])
        for matcher in self.codeScript.strategy.getMatchers():
            with Ejector() as ej:
                try:
                    return self.runMatcher(matcher, message, ej)
                except Ejecting as e:
                    if e.ejector is ej:
                        # Looks like unification failed. On to the next
                        # matcher!
                        continue
                    else:
                        # It's not ours, cap'n.
                        raise

        raise Refused(self, atom, args)
Exemple #11
0
    def testMakeIterator(self):
        """
        Strings are iterable.
        """

        s = StrObject(u"cs")
        iterator = s.call(u"_makeIterator", [])
        with Ejector() as ej:
            result = iterator.call(u"next", [ej])
            objs = unwrapList(result)
            self.assertEqual(objs[0].getInt(), 0)
            self.assertEqual(objs[1]._c, u'c')
            result = iterator.call(u"next", [ej])
            objs = unwrapList(result)
            self.assertEqual(objs[0].getInt(), 1)
            self.assertEqual(objs[1]._c, u's')
            self.assertRaises(Ejecting, iterator.call, u"next", [ej])
Exemple #12
0
    def recv(self, atom, args):
        if atom is COERCE_2:
            for g in self.subguards:
                with Ejector() as ej:
                    try:
                        return g.call(u"coerce", [args[0], ej])
                    except Ejecting as e:
                        if e.ejector is ej:
                            continue
            throw(args[1], StrObject(u"No subguards matched"))
        if atom is SUPERSETOF_1:
            for g in self.subguards:
                if not unwrapBool(g.call(u"supersetOf", [args[0]])):
                    return wrapBool(False)
            return wrapBool(True)

        if atom is _UNCALL_0:
            from typhon.objects.collections.maps import EMPTY_MAP
            return ConstList([
                anyGuard,
                StrObject(u"get"),
                ConstList(self.subguards), EMPTY_MAP
            ])
        raise Refused(self, atom, args)
Exemple #13
0
    def runInstruction(self, instruction, pc):
        index = self.code.index(pc)
        # jit_debug(self.code.disAt(pc))

        if instruction.asInt == ops.DUP.asInt:
            self.push(self.peek())
            return pc + 1
        elif instruction.asInt == ops.ROT.asInt:
            z = self.pop()
            y = self.pop()
            x = self.pop()
            self.push(y)
            self.push(z)
            self.push(x)
            return pc + 1
        elif instruction.asInt == ops.POP.asInt:
            self.pop()
            return pc + 1
        elif instruction.asInt == ops.SWAP.asInt:
            y = self.pop()
            x = self.pop()
            self.push(y)
            self.push(x)
            return pc + 1
        elif instruction.asInt == ops.ASSIGN_GLOBAL.asInt:
            value = self.pop()
            self.env.putValueGlobal(index, value)
            return pc + 1
        elif instruction.asInt == ops.ASSIGN_FRAME.asInt:
            value = self.pop()
            self.env.putValueFrame(index, value)
            return pc + 1
        elif instruction.asInt == ops.ASSIGN_LOCAL.asInt:
            value = self.pop()
            self.env.putValueLocal(index, value)
            return pc + 1
        elif instruction.asInt == ops.BIND.asInt:
            binding = self.pop()
            self.env.createBindingLocal(index, binding)
            return pc + 1
        elif instruction.asInt == ops.BINDFINALSLOT.asInt:
            guard = self.pop()
            ej = self.pop()
            specimen = self.pop()
            val = guard.call(u"coerce", [specimen, ej])
            self.env.createBindingLocal(index, finalBinding(val, guard))
            return pc + 1
        elif instruction.asInt == ops.BINDVARSLOT.asInt:
            guard = self.pop()
            ej = self.pop()
            specimen = self.pop()
            val = guard.call(u"coerce", [specimen, ej])
            self.env.createBindingLocal(index, varBinding(val, guard))
            return pc + 1
        elif instruction.asInt == ops.SLOT_GLOBAL.asInt:
            self.push(self.env.getSlotGlobal(index))
            return pc + 1
        elif instruction.asInt == ops.SLOT_FRAME.asInt:
            self.push(self.env.getSlotFrame(index))
            return pc + 1
        elif instruction.asInt == ops.SLOT_LOCAL.asInt:
            self.push(self.env.getSlotLocal(index))
            return pc + 1
        elif instruction.asInt == ops.NOUN_GLOBAL.asInt:
            self.push(self.env.getValueGlobal(index))
            return pc + 1
        elif instruction.asInt == ops.NOUN_FRAME.asInt:
            self.push(self.env.getValueFrame(index))
            return pc + 1
        elif instruction.asInt == ops.NOUN_LOCAL.asInt:
            self.push(self.env.getValueLocal(index))
            return pc + 1
        elif instruction.asInt == ops.BINDING_GLOBAL.asInt:
            self.push(self.env.getBindingGlobal(index))
            return pc + 1
        elif instruction.asInt == ops.BINDING_FRAME.asInt:
            self.push(self.env.getBindingFrame(index))
            return pc + 1
        elif instruction.asInt == ops.BINDING_LOCAL.asInt:
            self.push(self.env.getBindingLocal(index))
            return pc + 1
        elif instruction.asInt == ops.LIST_PATT.asInt:
            self.listPattern(index)
            return pc + 1
        elif instruction.asInt == ops.LITERAL.asInt:
            self.push(self.code.literal(index))
            return pc + 1
        elif instruction.asInt == ops.BINDOBJECT.asInt:
            self.bindObject(index)
            return pc + 1
        elif instruction.asInt == ops.EJECTOR.asInt:
            # Look carefully at the order of operations. The handler captures
            # the depth of the stack, so it's important to create it *before*
            # pushing the ejector onto the stack. Otherwise, the handler
            # thinks that the stack started off with an extra level of depth.
            ej = Ejector()
            handler = Eject(self, ej, index)
            self.push(ej)
            self.env.pushHandler(handler)
            return pc + 1
        elif instruction.asInt == ops.TRY.asInt:
            self.env.pushHandler(Catch(self, index))
            return pc + 1
        elif instruction.asInt == ops.UNWIND.asInt:
            self.env.pushHandler(Unwind(self, index))
            return pc + 1
        elif instruction.asInt == ops.END_HANDLER.asInt:
            handler = self.env.popHandler()
            return handler.drop(self, pc, index)
        elif instruction.asInt == ops.BRANCH.asInt:
            cond = unwrapBool(self.pop())
            if cond:
                return pc + 1
            else:
                return index
        elif instruction.asInt == ops.CALL.asInt:
            self.call(index, withMap=False)
            return pc + 1
        elif instruction.asInt == ops.CALL_MAP.asInt:
            self.call(index, withMap=True)
            return pc + 1
        elif instruction.asInt == ops.BUILD_MAP.asInt:
            self.buildMap(index)
            return pc + 1
        elif instruction.asInt == ops.NAMEDARG_EXTRACT.asInt:
            k = self.pop()
            d = unwrapMap(self.pop())
            if k not in d:
                raise userError(u"Named arg %s missing in call" %
                                (k.toString(), ))
            self.push(d[k])
            return pc + 1
        elif instruction.asInt == ops.NAMEDARG_EXTRACT_OPTIONAL.asInt:
            k = self.pop()
            d = unwrapMap(self.pop())
            if k not in d:
                self.push(NullObject)
                return pc + 1
            self.push(d[k])
            return index
        elif instruction.asInt == ops.JUMP.asInt:
            return index
        else:
            raise RuntimeError("Unknown instruction %s" %
                               instruction.repr.encode("utf-8"))
Exemple #14
0
def deepFrozenSupersetOf(guard):
    from typhon.objects.collections.helpers import monteMap
    from typhon.objects.collections.lists import unwrapList
    from typhon.objects.constants import wrapBool
    from typhon.objects.ejectors import Ejector
    from typhon.objects.refs import Promise
    from typhon.objects.guards import (AnyOfGuard, BoolGuard, BytesGuard,
                                       CharGuard, DoubleGuard, FinalSlotGuard,
                                       IntGuard, SameGuard, StrGuard,
                                       SubrangeGuard, VoidGuard)
    from typhon.prelude import getGlobalValue
    if guard is deepFrozenGuard:
        return True
    if guard is deepFrozenStamp:
        return True
    if isinstance(guard, Promise):
        guard = guard.resolution()
    if isinstance(guard, BoolGuard):
        return True
    if isinstance(guard, BytesGuard):
        return True
    if isinstance(guard, CharGuard):
        return True
    if isinstance(guard, DoubleGuard):
        return True
    if isinstance(guard, IntGuard):
        return True
    if isinstance(guard, StrGuard):
        return True
    if isinstance(guard, VoidGuard):
        return True

    if isinstance(guard, SameGuard):
        with Ejector() as ej:
            try:
                v = guard.value
                checkDeepFrozen(v, monteMap(), ej, v)
                return True
            except Ejecting:
                return False

    if isinstance(guard, FinalSlotGuard):
        return deepFrozenSupersetOf(guard.valueGuard)
    for superGuardName in [u"List", u"NullOk", u"Set"]:
        superGuard = getGlobalValue(superGuardName)
        if superGuard is None:
            continue
        with Ejector() as ej:
            try:
                subGuard = superGuard.call(u"extractGuard", [guard, ej])
                return deepFrozenSupersetOf(subGuard)
            except Ejecting as e:
                # Just keep going.
                if e.ejector is not ej:
                    raise
    for pairGuardName in [u"Map", u"Pair"]:
        pairGuard = getGlobalValue(pairGuardName)
        if pairGuard is None:
            continue
        with Ejector() as ej:
            try:
                guardPair = pairGuard.call(u"extractGuards", [guard, ej])
                l = unwrapList(guardPair, ej)
                if len(l) == 2:
                    return deepFrozenSupersetOf(l[0]) and deepFrozenSupersetOf(
                        l[1])
            except Ejecting as e:
                if e.ejector is not ej:
                    raise
    if (SubrangeGuard(deepFrozenGuard).call(u"passes", [guard]) is
            wrapBool(True)):
        return True
    if isinstance(guard, AnyOfGuard):
        for g in guard.subguards:
            if not deepFrozenSupersetOf(g):
                return False
        return True
    return False
Exemple #15
0
def deepFrozenSupersetOf(guard):
    from typhon.objects.collections.helpers import monteMap
    from typhon.objects.collections.lists import ConstList
    from typhon.objects.constants import wrapBool
    from typhon.objects.ejectors import Ejector
    from typhon.objects.refs import Promise
    from typhon.objects.guards import (
        AnyOfGuard, BoolGuard, BytesGuard, CharGuard, DoubleGuard,
        FinalSlotGuard, IntGuard, SameGuard, StrGuard, SubrangeGuard,
        VoidGuard)
    from typhon.prelude import getGlobalValue
    if guard is deepFrozenGuard:
        return True
    if guard is deepFrozenStamp:
        return True
    if isinstance(guard, Promise):
        guard = guard.resolution()
    if isinstance(guard, BoolGuard):
        return True
    if isinstance(guard, BytesGuard):
        return True
    if isinstance(guard, CharGuard):
        return True
    if isinstance(guard, DoubleGuard):
        return True
    if isinstance(guard, IntGuard):
        return True
    if isinstance(guard, StrGuard):
        return True
    if isinstance(guard, VoidGuard):
        return True

    if isinstance(guard, SameGuard):
        ej = Ejector()
        try:
            v = guard.value
            checkDeepFrozen(v, monteMap(), ej, v)
            return True
        except Ejecting:
            return False

    if isinstance(guard, FinalSlotGuard):
        return deepFrozenSupersetOf(guard.valueGuard)
    for superGuardName in [u"List", u"NullOk", u"Set"]:
        superGuard = getGlobalValue(superGuardName)
        if superGuard is None:
            continue
        ej = Ejector()
        try:
            subGuard = superGuard.call(u"extractGuard", [guard, ej])
            return deepFrozenSupersetOf(subGuard)
        except Ejecting:
            # XXX lets other ejectors get through
            pass
    for pairGuardName in [u"Map", u"Pair"]:
        pairGuard = getGlobalValue(pairGuardName)
        if pairGuard is None:
            continue
        ej = Ejector()
        try:
            guardPair = pairGuard.call(u"extractGuards", [guard, ej])
            if isinstance(guardPair, ConstList) and guardPair.size() == 2:
                return (
                    (deepFrozenSupersetOf(guardPair.strategy.fetch(
                        guardPair, 0))) and
                    (deepFrozenSupersetOf(guardPair.strategy.fetch(
                        guardPair, 1))))
        except Ejecting:
            # XXX lets other ejectors get through
            pass
    if (SubrangeGuard(deepFrozenGuard).call(u"passes", [guard])
            is wrapBool(True)):
        return True
    if isinstance(guard, AnyOfGuard):
        for g in guard.subguards:
            if not deepFrozenSupersetOf(g):
                return False
        return True
    return False
Exemple #16
0
 def testDisable(self):
     ej = Ejector()
     ej.disable()
     self.assertFalse(ej.active)