コード例 #1
0
ファイル: test_collections.py プロジェクト: washort/typhon
 def testSurprisingMapCorruption(self):
     d = monteMap()
     d[IntObject(1)] = IntObject(2)
     m = ConstMap(d)
     f = m.call(u"diverge", [])
     f.call(u"removeKey", [IntObject(1)])
     result = m.call(u"get", [IntObject(1)])
     self.assertEqual(result.getInt(), 2)
コード例 #2
0
 def testSurprisingMapCorruption(self):
     d = monteMap()
     d[IntObject(1)] = IntObject(2)
     m = ConstMap(d)
     f = m.call(u"diverge", [])
     f.call(u"removeKey", [IntObject(1)])
     result = m.call(u"get", [IntObject(1)])
     self.assertEqual(result.getInt(), 2)
コード例 #3
0
 def buildMap(self, index):
     # XXX monteMap()
     d = monteMap()
     for i in range(index):
         # Yikes, the order of operations here is dangerous.
         d[self.pop()] = self.pop()
     self.push(ConstMap(d))
コード例 #4
0
def packLocalNamedRefs(namedArgs, targetVat, originVat):
    from typhon.objects.collections.maps import ConstMap, monteMap
    # XXX monteMap()
    namedRefs = monteMap()
    for k, v in namedArgs.objectMap.items():
        namedRefs[packLocalRef(k, targetVat, originVat)] = packLocalRef(
            v, targetVat, originVat)
    return ConstMap(namedRefs)
コード例 #5
0
ファイル: importing.py プロジェクト: washort/typhon
 def recv(self, atom, args):
     if atom is IMPORT_1:
         path = unwrapStr(args[0])
         # this is a hack, but the whole class is a hack :)
         if path == u"unittest":
             d = monteMap()
             d[args[0]] = self.importList.call(u"get", args)
             return ConstMap(d)
         return self.importer.performModule(path, self.importList)
     raise Refused(self, atom, args)
コード例 #6
0
def tieMirandaKnot():
    """
    Tie a knot needed for Miranda named arguments.
    """

    global MIRANDA_ARGS
    global MIRANDA_MAP

    from typhon.objects.collections.maps import ConstMap
    MIRANDA_ARGS = makeMirandaArgs()
    MIRANDA_MAP = ConstMap(MIRANDA_ARGS)
コード例 #7
0
    def callAtom(self, atom, arguments, namedArgsMap=None, span=None):
        """
        This method is used to reuse atoms without having to rebuild them.

        This is the correct method to call if you have an atom.
        """

        # 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)

        if namedArgsMap is None or namedArgsMap.isEmpty():
            namedArgsMap = MIRANDA_MAP
        else:
            from typhon.objects.collections.maps import ConstMap
            namedArgsMap = ConstMap(namedArgsMap._or(MIRANDA_ARGS))

        try:
            return self.recvNamed(atom, arguments, namedArgsMap)
        except Refused as r:
            r.addTrail(self, atom, arguments, span)
            raise
        except UserException as ue:
            ue.addTrail(self, atom, arguments, span)
            raise
        except MemoryError:
            ue = userError(u"Memory corruption or exhausted heap")
            ue.addTrail(self, atom, arguments, span)
            raise ue
        except StackOverflow:
            check_stack_overflow()
            ue = userError(u"Stack overflow")
            ue.addTrail(self, atom, arguments, span)
            raise ue
コード例 #8
0
def evalToPair(code, topLocals, envMap, bindingNames=False):
    environment = {}
    if bindingNames:
        for k, v in unwrapMap(envMap).items():
            s = unwrapStr(k)
            if not s.startswith("&&"):
                raise userError(u"evalMonteFile scope map must be of the "
                                "form '[\"&&name\" => binding]'")
            environment[s[2:]] = v
    else:
        for k, v in unwrapMap(envMap).items():
            environment[unwrapStr(k)] = v
    # Don't catch user exceptions; on traceback, we'll have a trail
    # auto-added that indicates that the exception came through
    # eval() or whatnot.
    result, newEnv = evaluateRaise([code], environment)
    if newEnv is not None:
        # XXX monteMap()
        d = monteMap()
        for k, vi in topLocals.items():
            d[StrObject(k)] = newEnv.local[vi]
        addendum = ConstMap(d)
        envMap = addendum._or(envMap)
    return result, envMap
コード例 #9
0
ファイル: boot.py プロジェクト: markrwilliams/typhon
def evalToPair(code, topLocals, envMap, bindingNames=False):
    environment = {}
    if bindingNames:
        for k, v in unwrapMap(envMap).items():
            s = unwrapStr(k)
            if not s.startswith("&&"):
                raise userError(u"evalMonteFile scope map must be of the "
                                "form '[\"&&name\" => binding]'")
            environment[s[2:]] = v
    else:
        for k, v in unwrapMap(envMap).items():
            environment[unwrapStr(k)] = v
    # Don't catch user exceptions; on traceback, we'll have a trail
    # auto-added that indicates that the exception came through
    # eval() or whatnot.
    result, newEnv = evaluateRaise([code], environment)
    if newEnv is not None:
        # XXX monteMap()
        d = monteMap()
        for k, vi in topLocals.items():
            d[StrObject(k)] = newEnv.local[vi]
        addendum = ConstMap(d)
        envMap = addendum._or(envMap)
    return result, envMap
コード例 #10
0
ファイル: root.py プロジェクト: monte-language/typhon
    def callAtom(self, atom, arguments, namedArgsMap=None, span=None):
        """
        This method is used to reuse atoms without having to rebuild them.

        This is the correct method to call if you have an atom.
        """

        # 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)

        if namedArgsMap is None or namedArgsMap.isEmpty():
            namedArgsMap = MIRANDA_MAP
        else:
            from typhon.objects.collections.maps import ConstMap
            namedArgsMap = ConstMap(namedArgsMap._or(MIRANDA_ARGS))

        try:
            return self.recvNamed(atom, arguments, namedArgsMap)
        except Refused as r:
            r.addTrail(self, atom, arguments, span)
            raise
        except UserException as ue:
            ue.addTrail(self, atom, arguments, span)
            raise
        except MemoryError:
            ue = userError(u"Memory corruption or exhausted heap")
            ue.addTrail(self, atom, arguments, span)
            raise ue
        except StackOverflow:
            check_stack_overflow()
            ue = userError(u"Stack overflow")
            ue.addTrail(self, atom, arguments, span)
            raise ue
コード例 #11
0
ファイル: runtime.py プロジェクト: washort/typhon
    def recv(self, atom, args):
        if atom is GETBUCKETS_0:
            d = monteMap()
            for name, count in self.buckets.items():
                size = self.sizes.get(name, -1)
                d[StrObject(name)] = ConstList(
                    [IntObject(size), IntObject(count)])
            return ConstMap(d)

        if atom is GETMEMORYUSAGE_0:
            return IntObject(self.memoryUsage)

        if atom is GETOBJECTCOUNT_0:
            return IntObject(self.objectCount)

        raise Refused(self, atom, args)
コード例 #12
0
    def recv(self, atom, args):
        if atom is GETARGUMENTS_0:
            return ConstList(
                [StrObject(arg.decode("utf-8")) for arg in self.config.argv])

        if atom is GETENVIRONMENT_0:
            # XXX monteMap()
            d = monteMap()
            for key, value in os.environ.items():
                k = StrObject(key.decode("utf-8"))
                v = StrObject(value.decode("utf-8"))
                d[k] = v
            return ConstMap(d)

        if atom is GETPID_0:
            return IntObject(os.getpid())

        if atom is INTERRUPT_0:
            os.kill(os.getpid(), signal.SIGINT)
            return NullObject

        raise Refused(self, atom, args)
コード例 #13
0
    def recv(self, atom, args):
        if atom is GETARGUMENTS_0:
            return ConstList([BytesObject(arg) for arg in self.argv])

        if atom is GETENVIRONMENT_0:
            # XXX monteMap()
            d = monteMap()
            for key, value in self.env.items():
                k = BytesObject(key)
                v = BytesObject(value)
                d[k] = v
            return ConstMap(d)

        if atom is GETPID_0:
            return IntObject(self.pid)

        if atom is INTERRUPT_0:
            os.kill(self.pid, signal.SIGINT)
            return NullObject

        if atom is WAIT_0:
            return self.makeWaiter()

        raise Refused(self, atom, args)
コード例 #14
0
    def takeTurn(self):
        from typhon.objects.refs import Promise, resolution

        with self._pendingLock:
            resolver, target, atom, args, namedArgs = self._pending.pop(0)

        # If the target is a promise, then we should send to it instead of
        # calling. Try to resolve it as much as possible first, though.
        target = resolution(target)

        self.log(
            u"Taking turn: %s<-%s(%s) (resolver: %s)" %
            (target.toQuote(), atom.verb, u", ".join(
                [arg.toQuote()
                 for arg in args]), u"yes" if resolver is not None else u"no"))
        if resolver is None:
            try:
                # callOnly/sendOnly.
                if isinstance(target, Promise):
                    target.sendOnly(atom, args, namedArgs)
                else:
                    # Oh, that's right; we don't do callOnly since it's silly.
                    target.callAtom(atom, args, namedArgs)
            except UserException as ue:
                self.log(u"Uncaught user exception while taking turn"
                         u" (and no resolver): %s" %
                         ue.formatError().decode("utf-8"),
                         tags=["serious"])
            except VatCheckpointed:
                self.log(u"Ran out of checkpoints while taking turn",
                         tags=["serious"])
            except Ejecting:
                self.log(u"Ejector tried to escape vat turn boundary",
                         tags=["serious"])

        else:
            from typhon.objects.collections.maps import ConstMap, monteMap
            from typhon.objects.exceptions import sealException
            from typhon.objects.refs import Smash
            # XXX monteMap()
            _d = monteMap()
            _d[StrObject(u"FAIL")] = Smash(resolver)
            MIRANDA_ARGS = ConstMap(_d)
            namedArgs = namedArgs._or(MIRANDA_ARGS)
            try:
                # call/send.
                if isinstance(target, Promise):
                    result = target.send(atom, args, namedArgs)
                else:
                    result = target.callAtom(atom, args, namedArgs)
                # Resolver may be invoked from the code in this turn, so
                # strict=False to skip this if already resolved.
                resolver.resolve(result, strict=False)
            except UserException as ue:
                resolver.smash(sealException(ue))
            except VatCheckpointed:
                self.log(
                    u"Ran out of checkpoints while taking turn; breaking resolver",
                    tags=["serious"])
                resolver.smash(
                    sealException(userError(u"Vat ran out of checkpoints")))
            except Ejecting:
                self.log(u"Ejector tried to escape vat turn boundary",
                         tags=["serious"])
                resolver.smash(
                    sealException(
                        userError(u"Ejector tried to escape from vat")))
コード例 #15
0
def runTyphon(argv):
    # Start metrics.
    recorder = globalRecorder()
    recorder.start()

    # Initialize libsodium.
    if rsodium.init() < 0:
        print "Couldn't initialize libsodium!"
        return 1

    config = Configuration(argv)

    if config.verbose:
        enableDebugPrint()

    config.enableLogging()

    if len(config.argv) < 2:
        print "No file provided?"
        return 1

    # Pass user configuration to the JIT.
    set_user_param(None, config.jit)

    # Intialize our loop.
    uv_loop = ruv.alloc_loop()

    # Usurp SIGPIPE, as libuv does not handle it.
    rsignal.pypysig_ignore(rsignal.SIGPIPE)

    # Initialize our first vat. It shall be immortal.
    vatManager = VatManager()
    vat = Vat(vatManager, uv_loop, checkpoints=-1)
    vatManager.vats.append(vat)

    # Update loop timing information. Until the loop really gets going, we
    # have to do this ourselves in order to get the timing correct for early
    # timers.
    ruv.update_time(uv_loop)
    try:
        with scopedVat(vat) as vat:
            prelude = loadPrelude(config, recorder, vat)
    except LoadFailed as lf:
        print lf
        return 1
    except CompilerFailed as cf:
        debug_print("Caught exception while importing prelude:",
                cf.formatError())
        return 1
    except UserException as ue:
        debug_print("Caught exception while importing prelude:",
                ue.formatError())
        return 1

    registerGlobals(prelude)

    scope = safeScope()
    scope.update(prelude)
    ss = scope.copy()
    reflectedSS = monteMap()
    for k, b in ss.iteritems():
        reflectedSS[StrObject(u"&&" + k)] = b
    ss[u"safeScope"] = finalBinding(ConstMap(reflectedSS), deepFrozenGuard)
    reflectedSS[StrObject(u"&&safeScope")] = ss[u"safeScope"]
    scope[u"safeScope"] = ss[u"safeScope"]
    scope.update(unsafeScope(config))
    # The initial vat is included as `currentVat` to the first level of
    # loading and such.
    scope[u"currentVat"] = finalBinding(vat, anyGuard)
    reflectedUnsafeScope = monteMap()
    unsafeScopeDict = {}
    for k, b in scope.iteritems():
        reflectedUnsafeScope[StrObject(u"&&" + k)] = b
        unsafeScopeDict[k] = b
    rus = finalBinding(ConstMap(reflectedUnsafeScope), anyGuard)
    reflectedUnsafeScope[StrObject(u"&&unsafeScope")] = rus
    unsafeScopeDict[u"unsafeScope"] = rus
    try:
        module = obtainModule([""], recorder, config.argv[1])
    except LoadFailed as lf:
        print lf
        return 1

    if config.loadOnly:
        # We are finished.
        return 0

    if not config.benchmark:
        benchmarkSettings.disable()

    with profiling("vmprof.log", config.profile):
        # Update loop timing information.
        ruv.update_time(uv_loop)
        debug_print("Taking initial turn in script...")
        result = NullObject
        try:
            with recorder.context("Time spent in vats"):
                with scopedVat(vat):
                    result = module.eval(unsafeScopeDict)[0]
            if result is None:
                return 1
        except UserException as ue:
            debug_print("Caught exception while taking initial turn:",
                    ue.formatError())
            return 1

        # Exit status code.
        exitStatus = 0
        # Update loop timing information.
        ruv.update_time(uv_loop)
        try:
            runUntilDone(vatManager, uv_loop, recorder)
            rv = resolution(result) if result is not None else NullObject
            if isinstance(rv, IntObject):
                exitStatus = rv.getInt()
        except SystemExit:
            pass
            # Huh, apparently this doesn't work. Wonder why/why not.
            # exitStatus = se.code
        finally:
            recorder.stop()
            recorder.printResults()

    # Clean up and exit.
    cleanUpEverything()
    return exitStatus
コード例 #16
0
def mkMirandaArgs():
    # XXX monteMap()
    _d = monteMap()
    _d[StrObject(u"FAIL")] = theThrower
    return ConstMap(_d)
コード例 #17
0
 def testUnwrapMapPromise(self):
     with scopedVat(testingVat()):
         p = makeNear(ConstMap({}))
         self.assertEqual(unwrapMap(p).items(), [])
コード例 #18
0
ファイル: vats.py プロジェクト: dckc/typhon
    def takeTurn(self):
        from typhon.objects.refs import Promise, resolution

        with self._pendingLock:
            resolver, target, atom, args, namedArgs = self._pending.pop(0)

        # If the target is a promise, then we should send to it instead of
        # calling. Try to resolve it as much as possible first, though.
        target = resolution(target)

        # self.log(u"Taking turn: %s<-%s(%s) (resolver: %s)" %
        #          (target.toQuote(), atom.verb,
        #           u", ".join([arg.toQuote() for arg in args]),
        #           u"yes" if resolver is not None else u"no"))
        if resolver is None:
            try:
                # callOnly/sendOnly.
                if isinstance(target, Promise):
                    target.sendOnly(atom, args, namedArgs)
                else:
                    # Oh, that's right; we don't do callOnly since it's silly.
                    target.callAtom(atom, args, namedArgs)
            except UserException as ue:
                self.log(u"Uncaught user exception while taking turn"
                         u" (and no resolver): %s" %
                         ue.formatError().decode("utf-8"),
                         tags=["serious"])
            except VatCheckpointed:
                self.log(u"Ran out of checkpoints while taking turn",
                         tags=["serious"])
            except Ejecting:
                self.log(u"Ejector tried to escape vat turn boundary",
                         tags=["serious"])

        else:
            from typhon.objects.collections.maps import ConstMap, monteMap
            from typhon.objects.exceptions import sealException
            from typhon.objects.refs import Smash

            # XXX monteMap()
            mirandaArgs = monteMap()
            mirandaArgs[StrObject(u"FAIL")] = Smash(resolver)
            namedArgs = ConstMap(namedArgs._or(mirandaArgs))
            try:
                # call/send.
                if isinstance(target, Promise):
                    result = target.send(atom, args, namedArgs)
                else:
                    result = target.callAtom(atom, args, namedArgs)
                # The resolver may have already been invoked, so we'll use
                # .resolveRace/1 instead of .resolve/1. ~ C.
                resolver.resolveRace(result)
            except UserException as ue:
                resolver.smash(sealException(ue))
            except VatCheckpointed:
                self.log(u"Ran out of checkpoints while taking turn; breaking resolver",
                         tags=["serious"])
                resolver.smash(sealException(userError(u"Vat ran out of checkpoints")))
            except Ejecting:
                self.log(u"Ejector tried to escape vat turn boundary",
                         tags=["serious"])
                resolver.smash(sealException(userError(u"Ejector tried to escape from vat")))
コード例 #19
0
ファイル: makers.py プロジェクト: dckc/typhon
def makeMap(pairs):
    """
    Given a `List[Pair]`, produce a `Map`.
    """

    return ConstMap.fromPairs(pairs)
コード例 #20
0
ファイル: test_collections.py プロジェクト: washort/typhon
 def testContains(self):
     d = monteMap()
     d[IntObject(42)] = IntObject(5)
     m = ConstMap(d)
     self.assertTrue(m.contains(IntObject(42)))
     self.assertFalse(m.contains(IntObject(7)))
コード例 #21
0
 def testToString(self):
     d = monteMap()
     self.assertEqual(ConstMap(d).toString(), u"[].asMap()")
コード例 #22
0
 def testContains(self):
     d = monteMap()
     d[IntObject(42)] = IntObject(5)
     m = ConstMap(d)
     self.assertTrue(m.contains(IntObject(42)))
     self.assertFalse(m.contains(IntObject(7)))
コード例 #23
0
ファイル: lists.py プロジェクト: markrwilliams/typhon
    def _recv(self, atom, args):
        if atom is _UNCALL_0:
            from typhon.objects.collections.maps import EMPTY_MAP
            return ConstList([
                self.snapshot(),
                StrObject(u"diverge"),
                ConstList([]), EMPTY_MAP
            ])

        if atom is ADD_1:
            other = args[0]
            return ConstList(self.strategy.fetch_all(self) + unwrapList(other))

        if atom is ASMAP_0:
            from typhon.objects.collections.maps import ConstMap
            return ConstMap(self.asMap())

        if atom is ASSET_0:
            from typhon.objects.collections.sets import ConstSet
            return ConstSet(self.asSet())

        if atom is DIVERGE_0:
            return FlexList(self.strategy.fetch_all(self))

        if atom is EXTEND_1:
            from typhon.objects.refs import resolution
            l = resolution(args[0])
            # The early exits are essential here; without them, we might pass
            # an empty list to strategy.append(), which causes a crash. ~ C.
            if isinstance(l, ConstList):
                if l.size() == 0:
                    return NullObject
                data = l.strategy.fetch_all(l)
            elif isinstance(l, FlexList):
                if l.size() == 0:
                    return NullObject
                data = l.strategy.fetch_all(l)
            else:
                data = listFromIterable(l)[:]
            self.strategy.append(self, data)
            return NullObject

        if atom is GET_1:
            # Lookup by index.
            index = unwrapInt(args[0])
            if index >= self.strategy.size(self) or index < 0:
                raise userError(u"Index %d is out of bounds" % index)
            return self.strategy.fetch(self, index)

        if atom is INDEXOF_1:
            return IntObject(self.indexOf(args[0]))

        if atom is INSERT_2:
            index = unwrapInt(args[0])
            value = args[1]
            if index < 0:
                raise userError(u"Index %d is out of bounds" % index)
            self.strategy.insert(self, index, [value])
            return NullObject

        if atom is LAST_0:
            size = self.strategy.size(self)
            if size:
                return self.strategy.fetch(self, size - 1)
            raise userError(u"Empty list has no last element")

        if atom is MULTIPLY_1:
            # multiply/1: Create a new list by repeating this list's contents.
            index = unwrapInt(args[0])
            return ConstList(self.strategy.fetch_all(self) * index)

        if atom is POP_0:
            try:
                return self.strategy.pop(self, self.strategy.size(self) - 1)
            except IndexError:
                raise userError(u"pop/0: Pop from empty list")

        if atom is PUSH_1:
            self.strategy.append(self, args)
            return NullObject

        if atom is PUT_2:
            # Replace by index.
            index = unwrapInt(args[0])
            return self.put(index, args[1])

        if atom is REVERSE_0:
            new = self.strategy.fetch_all(self)[:]
            new.reverse()
            return ConstList(new)

        if atom is REVERSEINPLACE_0:
            new = self.strategy.fetch_all(self)[:]
            new.reverse()
            self.strategy.store_all(self, new)
            return NullObject

        if atom is WITH_1:
            # with/1: Create a new list with an appended object.
            return ConstList(self.strategy.fetch_all(self) + args)

        if atom is WITH_2:
            # Make a new ConstList.
            return self.snapshot().put(unwrapInt(args[0]), args[1])

        raise Refused(self, atom, args)
コード例 #24
0
ファイル: lists.py プロジェクト: markrwilliams/typhon
    def _recv(self, atom, args):
        if atom is ADD_1:
            other = unwrapList(args[0])
            if len(other):
                return ConstList(self.strategy.fetch_all(self) + other)
            else:
                return self

        if atom is ASMAP_0:
            from typhon.objects.collections.maps import ConstMap
            return ConstMap(self.asMap())

        if atom is ASSET_0:
            from typhon.objects.collections.sets import ConstSet
            return ConstSet(self.asSet())

        if atom is DIVERGE_0:
            return FlexList(self.strategy.fetch_all(self)[:])

        if atom is GET_1:
            # Lookup by index.
            index = unwrapInt(args[0])
            if index < 0:
                raise userError(u"Index %d cannot be negative" % index)
            if index >= self.strategy.size(self):
                raise userError(u"Index %d is out of bounds" % index)
            return self.strategy.fetch(self, index)

        if atom is INDEXOF_1:
            return IntObject(self.indexOf(args[0]))

        if atom is LAST_0:
            size = self.strategy.size(self)
            if size:
                return self.strategy.fetch(self, size - 1)
            raise userError(u"Empty list has no last element")

        if atom is MULTIPLY_1:
            # multiply/1: Create a new list by repeating this list's contents.
            count = unwrapInt(args[0])
            if count < 0:
                raise userError(u"Can't multiply list %d times" % count)
            elif count == 0:
                return ConstList([])
            return ConstList(self.strategy.fetch_all(self) * count)

        if atom is OP__CMP_1:
            other = unwrapList(args[0])
            return IntObject(self.cmp(other))

        if atom is REVERSE_0:
            # This might seem slightly inefficient, and it might be, but I
            # want to make it very clear to RPython that we are not mutating
            # the list after we assign it to the new object.
            new = self.strategy.fetch_all(self)[:]
            new.reverse()
            return ConstList(new)

        if atom is SORT_0:
            return self.sort()

        if atom is STARTOF_1:
            return IntObject(self.startOf(unwrapList(args[0])))

        if atom is STARTOF_2:
            start = unwrapInt(args[1])
            if start < 0:
                raise userError(u"startOf/2: Negative start %d not permitted" %
                                start)
            return IntObject(self.startOf(unwrapList(args[0]), start))

        if atom is WITH_1:
            # with/1: Create a new list with an appended object.
            return ConstList(self.strategy.fetch_all(self) + args)

        if atom is WITH_2:
            # Replace by index.
            index = unwrapInt(args[0])
            return self.put(index, args[1])

        if atom is _UNCALL_0:
            from typhon.scopes.safe import theMakeList
            from typhon.objects.collections.maps import EMPTY_MAP
            return ConstList([theMakeList, StrObject(u"run"), self, EMPTY_MAP])

        raise Refused(self, atom, args)
コード例 #25
0
ファイル: safe.py プロジェクト: markrwilliams/typhon
def makeMap(pairs):
    """
    Given a `List[Pair]`, produce a `Map`.
    """

    return ConstMap.fromPairs(pairs)