Example #1
0
    def recv(self, atom, args):
        if atom is RUN_1:
            pname = unwrapStr(args[0])
            for extension in [".ty", ".mast"]:
                path = pname.encode("utf-8") + extension
                for base in self.paths:
                    try:
                        with open(os.path.join(base, path), "rb") as handle:
                            source = handle.read()
                            with self.recorder.context("Deserialization"):
                                return loadMASTBytes(source)
                    except IOError:
                        continue
            raise userError(u"Could not locate " + pname)

        if atom is RUN_2:
            scope = unwrapMap(args[1])
            d = {}
            for k, v in scope.items():
                s = unwrapStr(k)
                if not s.startswith("&&"):
                    raise userError(u"evalMonteFile scope map must be of the "
                                    "form '[\"&&name\" => binding]'")
                d[s[2:]] = scope[k]

            code = obtainModule(self.paths,
                                unwrapStr(args[0]).encode("utf-8"),
                                self.recorder)
            return evaluateRaise([code], d)[0]
        raise Refused(self, atom, args)
Example #2
0
def loadPrelude(config, recorder, vat):
    scope = safeScope()
    # For the prelude (and only the prelude), permit the boot scope.
    scope.update(bootScope(config.libraryPaths, recorder))
    registerGlobals({u"Bool": scope[u"Bool"],
                     u"Bytes": scope[u"Bytes"],
                     u"Char": scope[u"Char"],
                     u"Double": scope[u"Double"],
                     u"Int": scope[u"Int"],
                     u"Str": scope[u"Str"],
                     u"Void": scope[u"Void"]})

    module = obtainModule(config.libraryPaths, recorder, "prelude")
    with recorder.context("Time spent in prelude"):
        result = module.eval(scope)[0]

    assert result is not None, "Prelude returned None"
    assert isinstance(result, ConstMap), "Prelude returned non-Map"

    prelude = {}
    for key, value in unwrapMap(result).items():
        s = unwrapStr(key)
        assert s.startswith(u"&&"), "Prelude key doesn't start with &&"
        prelude[s[2:]] = value
    log(["info", "prelude"], u"Loaded the prelude")
    return prelude
Example #3
0
def makeProcess(executable, args, environment):
    """
    Create a subordinate process on the current node from the given
    executable, arguments, and environment.
    """

    # Third incarnation: libuv-powered and requiring bytes.
    executable = unwrapBytes(executable)
    # This could be an LC, but doing it this way fixes the RPython annotation
    # for the list to be non-None.
    argv = []
    for arg in unwrapList(args):
        s = unwrapBytes(arg)
        assert s is not None, "proven impossible by hand"
        argv.append(s)
    env = {}
    for (k, v) in unwrapMap(environment).items():
        env[unwrapBytes(k)] = unwrapBytes(v)
    packedEnv = [k + '=' + v for (k, v) in env.items()]

    vat = currentVat.get()
    try:
        process = ruv.allocProcess()
        sub = SubProcess(vat, process, argv, env)
        ruv.spawn(vat.uv_loop, process,
                  file=executable, args=argv, env=packedEnv)
        sub.retrievePID()
        return sub
    except ruv.UVError as uve:
        raise userError(u"makeProcess: Couldn't spawn process: %s" %
                        uve.repr().decode("utf-8"))
Example #4
0
def makeProcess(executable, args, environment):
    """
    Create a subordinate process on the current node from the given
    executable, arguments, and environment.
    """

    # Third incarnation: libuv-powered and requiring bytes.
    executable = unwrapBytes(executable)
    # This could be an LC, but doing it this way fixes the RPython annotation
    # for the list to be non-None.
    argv = []
    for arg in unwrapList(args):
        s = unwrapBytes(arg)
        assert s is not None, "proven impossible by hand"
        argv.append(s)
    env = {}
    for (k, v) in unwrapMap(environment).items():
        env[unwrapBytes(k)] = unwrapBytes(v)
    packedEnv = [k + '=' + v for (k, v) in env.items()]

    vat = currentVat.get()
    try:
        process = ruv.allocProcess()
        sub = SubProcess(vat, process, argv, env)
        ruv.spawn(vat.uv_loop,
                  process,
                  file=executable,
                  args=argv,
                  env=packedEnv)
        sub.retrievePID()
        return sub
    except ruv.UVError as uve:
        raise userError(u"makeProcess: Couldn't spawn process: %s" %
                        uve.repr().decode("utf-8"))
Example #5
0
def loadPrelude(config, recorder, vat):
    scope = safeScope()
    # For the prelude (and only the prelude), permit the boot scope.
    scope.update(bootScope(config.libraryPaths, recorder))
    registerGlobals({u"Bool": scope[u"Bool"],
                     u"Bytes": scope[u"Bytes"],
                     u"Char": scope[u"Char"],
                     u"Double": scope[u"Double"],
                     u"Int": scope[u"Int"],
                     u"Str": scope[u"Str"],
                     u"Void": scope[u"Void"]})

    module = obtainModule(config.libraryPaths, recorder, "prelude")
    with recorder.context("Time spent in prelude"):
        result = module.eval(scope)[0]

    assert result is not None, "Prelude returned None"
    assert isinstance(result, ConstMap), "Prelude returned non-Map"

    prelude = {}
    for key, value in unwrapMap(result).items():
        s = unwrapStr(key)
        assert s.startswith(u"&&"), "Prelude key doesn't start with &&"
        prelude[s[2:]] = value
    log(["info", "prelude"], u"Loaded the prelude")
    return prelude
Example #6
0
    def recv(self, atom, args):
        if atom is RUN_1:
            pname = unwrapStr(args[0])
            for extension in [".ty", ".mast"]:
                path = pname.encode("utf-8") + extension
                for base in self.paths:
                    try:
                        with open(os.path.join(base, path), "rb") as handle:
                            source = handle.read()
                            with self.recorder.context("Deserialization"):
                                return loadMASTBytes(source)
                    except IOError:
                        continue
            raise userError(u"Could not locate " + pname)

        if atom is RUN_2:
            scope = unwrapMap(args[1])
            d = {}
            for k, v in scope.items():
                s = unwrapStr(k)
                if not s.startswith("&&"):
                    raise userError(u"evalMonteFile scope map must be of the "
                                    "form '[\"&&name\" => binding]'")
                d[s[2:]] = scope[k]

            code = obtainModule(self.paths, unwrapStr(args[0]).encode("utf-8"),
                                self.recorder)
            return evaluateRaise([code], d)[0]
        raise Refused(self, atom, args)
Example #7
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
Example #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
Example #9
0
def loadPrelude(config, recorder, vat):
    scope = safeScope()
    # For the prelude (and only the prelude), permit the boot scope.
    scope.update(bootScope(config.libraryPaths, recorder))
    registerGlobals({
        u"Bool": scope[u"Bool"],
        u"Bytes": scope[u"Bytes"],
        u"Char": scope[u"Char"],
        u"Double": scope[u"Double"],
        u"Int": scope[u"Int"],
        u"Str": scope[u"Str"],
        u"Void": scope[u"Void"]
    })

    code = obtainModule(config.libraryPaths, "prelude", recorder)
    with recorder.context("Time spent in prelude"):
        result = evaluateTerms([code], scope)

    if result is None:
        print "Prelude returned None!?"
        return {}

    # debug_print("Prelude result:", result.toQuote())

    if isinstance(result, ConstMap):
        prelude = {}
        for key, value in unwrapMap(result).items():
            if isinstance(key, StrObject):
                s = unwrapStr(key)
                if not s.startswith(u"&&"):
                    print "Prelude map key", s, "doesn't start with '&&'"
                else:
                    prelude[s[2:]] = value
            else:
                print "Prelude map key", key, "isn't a string"
        return prelude

    print "Prelude didn't return map!?"
    return {}
Example #10
0
def loadPrelude(config, recorder, vat):
    scope = safeScope()
    # For the prelude (and only the prelude), permit the boot scope.
    scope.update(bootScope(config.libraryPaths, recorder))
    registerGlobals({u"Bool": scope[u"Bool"],
                     u"Bytes": scope[u"Bytes"],
                     u"Char": scope[u"Char"],
                     u"Double": scope[u"Double"],
                     u"Int": scope[u"Int"],
                     u"Str": scope[u"Str"],
                     u"Void": scope[u"Void"]})

    code = obtainModule(config.libraryPaths, "prelude", recorder)
    with recorder.context("Time spent in prelude"):
        result = evaluateTerms([code], scope)

    if result is None:
        print "Prelude returned None!?"
        return {}


    # debug_print("Prelude result:", result.toQuote())

    if isinstance(result, ConstMap):
        prelude = {}
        for key, value in unwrapMap(result).items():
            if isinstance(key, StrObject):
                s = unwrapStr(key)
                if not s.startswith(u"&&"):
                    print "Prelude map key", s, "doesn't start with '&&'"
                else:
                    prelude[s[2:]] = value
            else:
                print "Prelude map key", key, "isn't a string"
        return prelude

    print "Prelude didn't return map!?"
    return {}
Example #11
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"))
Example #12
0
 def testUnwrapMapPromise(self):
     with scopedVat(testingVat()):
         p = makeNear(ConstMap({}))
         self.assertEqual(unwrapMap(p).items(), [])
Example #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"))
Example #14
0
    def recvNamed(self, atom, args, namedArgs):
        if atom is RUN_3:
            # Fourth incarnation: Now with stdio hookups.
            executable = unwrapBytes(args[0])
            # This could be an LC, but doing it this way fixes the RPython annotation
            # for the list to be non-None.
            argv = []
            for arg in unwrapList(args[1]):
                s = unwrapBytes(arg)
                assert s is not None, "proven impossible by hand"
                argv.append(s)
            env = {}
            for (k, v) in unwrapMap(args[2]).items():
                env[unwrapBytes(k)] = unwrapBytes(v)
            packedEnv = [k + '=' + v for (k, v) in env.items()]

            vat = currentVat.get()

            # Set up the list of streams. Note that, due to (not incorrect)
            # libuv behavior, we must wait for the subprocess to be spawned
            # before we can interact with the pipes that we are creating; to
            # do this, we'll have a list of the (f, d) pairs that we need to
            # start, and we'll ensure that that doesn't happen until after the
            # process has spawned.
            streams = []
            fount = namedArgs.extractStringKey(u"stdinFount", None)
            if fount is None:
                streams.append(nullptr(ruv.stream_t))
            else:
                stream = ruv.rffi.cast(ruv.stream_tp,
                                       ruv.alloc_pipe(vat.uv_loop))
                streams.append(stream)
                drain = StreamDrain(stream, vat)
                vat.sendOnly(fount, FLOWTO_1, [drain], EMPTY_MAP)
            for name in [u"stdoutDrain", u"stderrDrain"]:
                drain = namedArgs.extractStringKey(name, None)
                if drain is None:
                    streams.append(nullptr(ruv.stream_t))
                else:
                    stream = ruv.rffi.cast(ruv.stream_tp,
                                           ruv.alloc_pipe(vat.uv_loop))
                    streams.append(stream)
                    fount = StreamFount(stream, vat)
                    vat.sendOnly(fount, FLOWTO_1, [drain], EMPTY_MAP)

            try:
                process = ruv.allocProcess()
                sub = SubProcess(vat, process, argv, env)
                ruv.spawn(vat.uv_loop, process,
                          file=executable, args=argv, env=packedEnv,
                          streams=streams)
                sub.retrievePID()
                return sub
            except ruv.UVError as uve:
                raise userError(u"makeProcess: Couldn't spawn process: %s" %
                                uve.repr().decode("utf-8"))
        val = self.mirandaMethods(atom, args, namedArgs)
        if val is None:
            raise Refused(self, atom, args)
        else:
            return val
Example #15
0
 def testUnwrapMapPromise(self):
     with scopedVat(testingVat()):
         p = makeNear(ConstMap({}))
         self.assertEqual(unwrapMap(p).items(), [])