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)
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
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"))
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
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 {}
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 {}
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"))
def testUnwrapMapPromise(self): with scopedVat(testingVat()): p = makeNear(ConstMap({})) self.assertEqual(unwrapMap(p).items(), [])
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"))
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