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 recv(self, atom, args): if atom is RUN_1: return IntObject(int(unwrapStr(args[0]).encode('utf-8'))) if atom is RUN_2: inp = unwrapStr(args[0]) radix = unwrapInt(args[1]) try: v = int(inp.encode("utf-8"), radix) except ValueError: raise userError(u"Invalid literal for base %d: %s" % ( radix, inp)) return IntObject(v) if atom is FROMBYTES_1: return IntObject(int(unwrapBytes(args[0]))) if atom is FROMBYTES_2: bs = unwrapBytes(args[0]) radix = unwrapInt(args[1]) try: v = int(bs, radix) except ValueError: raise userError(u"Invalid literal for base %d: %s" % ( radix, bytesToString(bs))) return IntObject(v) raise Refused(self, atom, args)
def fromMonte(doc, verb, params, namedParams, guard, block): if doc is NullObject: d = u"" else: d = unwrapStr(doc) return Method(d, unwrapStr(verb), unwrapList(params), unwrapList(namedParams), guard if guard is not NullObject else None, block)
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 recv(self, atom, args): if atom is FROMSTRING_1: return BytesObject("".join([chr(ord(c)) for c in unwrapStr(args[0])])) if atom is FROMINTS_1: data = unwrapList(args[0]) return BytesObject("".join([chr(unwrapInt(i)) for i in data])) raise Refused(self, atom, args)
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)
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: fullpath = os.path.join(base, path) if os.path.exists(fullpath): return StrObject(fullpath.decode("utf-8")) return NullObject raise Refused(self, atom, args)
def bench(obj, name): name = unwrapStr(name).encode("utf-8") if not benchmarkSettings.enabled: debug_print("Not running benchmark", name, "since benchmarking is disabled") return ConstList([IntObject(0), DoubleObject(0.0)]) debug_print("Benchmarking", name) # Step 1: Calibrate timing loop. debug_print("Calibrating timing loop...") # Unroll do-while iteration. loops = 1 debug_print("Trying 1 loop...") taken = time.time() obj.call(u"run", []) taken = time.time() - taken while taken < 1.0 and loops < 100000000: debug_print("Took", taken, "seconds to run", loops, "loops") loops *= 10 debug_print("Trying", loops, "loops...") acc = 0 taken = time.time() while acc < loops: acc += 1 obj.call(u"run", []) taken = time.time() - taken debug_print("Okay! Will take", loops, "loops at", taken, "seconds") # Step 2: Take trials. debug_print("Taking trials...") trialCount = 3 - 1 # Unroll first iteration to get maximum. acc = 0 taken = time.time() while acc < loops: acc += 1 obj.call(u"run", []) taken = time.time() - taken result = taken while trialCount: trialCount -= 1 acc = 0 taken = time.time() while acc < loops: acc += 1 obj.call(u"run", []) taken = time.time() - taken if taken < result: result = taken # All done! return ConstList([IntObject(loops), DoubleObject(taken)])
def recv(self, atom, args): if atom is RUN_1: return DoubleObject(float(unwrapStr(args[0]).encode('utf-8'))) if atom is FROMBYTES_1: data = unwrapList(args[0]) x = unpack_float("".join([chr(unwrapInt(byte)) for byte in data]), True) return DoubleObject(x) raise Refused(self, atom, args)
def makeFileResource(path): """ Make a file Resource. """ path = unwrapStr(path) segments = [segment.encode("utf-8") for segment in path.split(u'/')] if not path.startswith(u'/'): # Relative path. segments = os.getcwd().split('/') + segments log.log(["fs"], u"makeFileResource.run/1: Relative path '%s'" % path) return FileResource(segments)
def recv(self, atom, args): if atom is FROMAST_3: code, topLocals = codeFromAst(args[0], self.recorder, unwrapStr(args[2])) return evalToPair(code, topLocals, args[1], True)[0] if atom is RUN_2: code, topLocals = moduleFromString(args[0], self.recorder) return evalToPair(code, topLocals, args[1])[0] if atom is EVALTOPAIR_2: code, topLocals = moduleFromString(args[0], self.recorder) result, envMap = evalToPair(code, topLocals, args[1]) return ConstList([result, envMap]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is ASK_1: return wrapBool(self.ask(args[0])) if atom is GETGUARD_1: return self.getGuard(unwrapStr(args[0])) if atom is GETOBJECTEXPR_0: return self.ast if atom is GETFQN_0: return StrObject(self.fqn) raise Refused(self, atom, args)
def mirandaMethods(self, atom, arguments, namedArgsMap): from typhon.objects.collections.maps import EMPTY_MAP if atom is _CONFORMTO_1: # Welcome to _conformTo/1. # to _conformTo(_): return self return self if atom is _GETALLEGEDINTERFACE_0: # Welcome to _getAllegedInterface/0. interface = self.optInterface() if interface is None: from typhon.objects.interfaces import ComputedInterface interface = ComputedInterface(self) return interface if atom is _PRINTON_1: # Welcome to _printOn/1. from typhon.objects.constants import NullObject self.printOn(arguments[0]) return NullObject if atom is _RESPONDSTO_2: from typhon.objects.constants import wrapBool from typhon.objects.data import unwrapInt, unwrapStr verb = unwrapStr(arguments[0]) arity = unwrapInt(arguments[1]) atom = getAtom(verb, arity) result = (atom in self.respondingAtoms() or atom in mirandaAtoms) return wrapBool(result) if atom is _SEALEDDISPATCH_1: # to _sealedDispatch(_): return null from typhon.objects.constants import NullObject return NullObject if atom is _UNCALL_0: from typhon.objects.constants import NullObject return NullObject if atom is _WHENMORERESOLVED_1: # Welcome to _whenMoreResolved. # This method's implementation, in Monte, should be: # to _whenMoreResolved(callback): callback<-(self) from typhon.vats import currentVat vat = currentVat.get() vat.sendOnly(arguments[0], RUN_1, [self], EMPTY_MAP) from typhon.objects.constants import NullObject return NullObject return None
def recv(self, atom, args): if atom is GETCONTENTS_0: return self.open(openGetContentsCB, flags=os.O_RDONLY, mode=0000) if atom is SETCONTENTS_1: data = unwrapBytes(args[0]) sibling = self.temporarySibling(".setContents") p, r = makePromise() vat = currentVat.get() uv_loop = vat.uv_loop fs = ruv.alloc_fs() path = sibling.asBytes() # Use CREAT | EXCL to cause a failure if the temporary file # already exists. flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL sc = SetContents(vat, data, r, sibling, self) ruv.stashFS(fs, (vat, sc)) ruv.fsOpen(uv_loop, fs, path, flags, 0777, openSetContentsCB) return p if atom is OPENFOUNT_0: return self.open(openFountCB, flags=os.O_RDONLY, mode=0000) if atom is OPENDRAIN_0: # Create the file if it doesn't yet exist, and truncate it if it # does. Trust the umask to be reasonable for now. flags = os.O_CREAT | os.O_WRONLY # XXX this behavior should be configurable via namedarg? flags |= os.O_TRUNC return self.open(openDrainCB, flags=flags, mode=0777) if atom is RENAME_1: fr = args[0] if not isinstance(fr, FileResource): raise userError(u"rename/1: Must be file resource") return self.rename(fr.asBytes()) if atom is SIBLING_1: name = unwrapStr(args[0]) if u'/' in name: raise userError(u"sibling/1: Illegal file name '%s'" % name) return self.sibling(name.encode("utf-8")) if atom is TEMPORARYSIBLING_0: return self.temporarySibling(".new") raise Refused(self, atom, args)
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 callWithMessage(self, target, message): """ Pass a message of `[verb :Str, args :List, namedArgs :Map]` to an object. """ if len(message) != 3: raise userError( u"callWithPair/2 requires a [verb, args, namedArgs] triple") verb = unwrapStr(message[0]) args = unwrapList(message[1]) namedArgs = resolution(message[2]) if not isinstance(namedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") return target.call(verb, args, namedArgs)
def recv(self, atom, args): from typhon.objects.collections.maps import EMPTY_MAP if atom is SEED_1: f = args[0] if not f.auditedBy(deepFrozenStamp): self.log(u"seed/1: Warning: Seeded receiver is not DeepFrozen") self.log(u"seed/1: Warning: This is gonna be an error soon!") from typhon.objects.refs import packLocalRef return packLocalRef(self.send(f, RUN_0, [], EMPTY_MAP), self, currentVat.get()) if atom is SPROUT_2: name = unwrapStr(args[0]) checkpoints = unwrapInt(args[1]) vat = Vat(self._manager, self.uv_loop, name, checkpoints=checkpoints) self._manager.vats.append(vat) return vat 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"] }) 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 _print(self, item): item = resolution(item) if isinstance(item, StrObject): self.ub.append(unwrapStr(item)) else: self.objPrint(item)
def callAtom(self, atom, arguments, namedArgsMap): """ This method is used to reuse atoms without having to rebuild them. """ from typhon.objects.collections.maps import EMPTY_MAP # Promote the atom, on the basis that atoms are generally reused. atom = promote(atom) # Log the atom to the JIT log. Don't do this if the atom's not # promoted; it'll be slow. jit_debug(atom.repr) try: return self.recvNamed(atom, arguments, namedArgsMap) except Refused as r: # This block of method implementations is Typhon's Miranda # protocol. ~ C. if atom is _CONFORMTO_1: # Welcome to _conformTo/1. # to _conformTo(_): return self return self if atom is _GETALLEGEDINTERFACE_0: # Welcome to _getAllegedInterface/0. interface = self.optInterface() if interface is None: from typhon.objects.interfaces import ComputedInterface interface = ComputedInterface(self) return interface if atom is _PRINTON_1: # Welcome to _printOn/1. from typhon.objects.constants import NullObject self.printOn(arguments[0]) return NullObject if atom is _RESPONDSTO_2: from typhon.objects.constants import wrapBool from typhon.objects.data import unwrapInt, unwrapStr verb = unwrapStr(arguments[0]) arity = unwrapInt(arguments[1]) atom = getAtom(verb, arity) result = (atom in self.respondingAtoms() or atom in mirandaAtoms) return wrapBool(result) if atom is _SEALEDDISPATCH_1: # to _sealedDispatch(_): return null from typhon.objects.constants import NullObject return NullObject if atom is _UNCALL_0: from typhon.objects.constants import NullObject return NullObject if atom is _WHENMORERESOLVED_1: # Welcome to _whenMoreResolved. # This method's implementation, in Monte, should be: # to _whenMoreResolved(callback): callback<-(self) from typhon.vats import currentVat vat = currentVat.get() vat.sendOnly(arguments[0], RUN_1, [self], EMPTY_MAP) from typhon.objects.constants import NullObject return NullObject addTrail(r, self, atom, arguments) raise except UserException as ue: addTrail(ue, self, atom, arguments) raise except MemoryError: ue = userError(u"Memory corruption or exhausted heap") addTrail(ue, self, atom, arguments) raise ue except StackOverflow: check_stack_overflow() ue = userError(u"Stack overflow") addTrail(ue, self, atom, arguments) raise ue
def recv(self, atom, args): if atom is CALLWITHPAIR_2 or atom is CALLWITHPAIR_3: target = args[0] pair = unwrapList(args[1]) if len(pair) not in (2, 3): raise userError(u"callWithPair/2 requires a pair!") if len(pair) == 3: namedArgs = pair[2] else: namedArgs = EMPTY_MAP sendVerb = unwrapStr(pair[0]) sendArgs = unwrapList(pair[1]) rv = target.call(sendVerb, sendArgs, namedArgs) if rv is None: print "callWithPair/2: Returned None:", \ target.__class__.__name__, sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is CALL_3 or atom is CALL_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) if len(args) == 3: namedArgs = EMPTY_MAP else: namedArgs = args[3] rv = target.call(sendVerb, sendArgs, namedArgs) if rv is None: print "call/3: Returned None:", target.__class__.__name__, \ sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is SENDONLY_3: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() vat.sendOnly(target, sendAtom, sendArgs, EMPTY_MAP) return NullObject if atom is SEND_3: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.send(target, sendAtom, sendArgs, EMPTY_MAP) if atom is CALLWITHMESSAGE_2: target = args[0] msg = unwrapList(args[1]) if len(msg) != 3: raise userError( u"callWithPair/2 requires a [verb, args, namedArgs] triple" ) sendVerb = unwrapStr(msg[0]) sendArgs = unwrapList(msg[1]) sendNamedArgs = resolution(msg[2]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") rv = target.call(sendVerb, sendArgs, sendNamedArgs) if rv is None: print "callWithPair/2: Returned None:", \ target.__class__.__name__, sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is CALL_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") rv = target.call(sendVerb, sendArgs, sendNamedArgs) if rv is None: print "call/3: Returned None:", target.__class__.__name__, \ sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is SENDONLY_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.sendOnly(target, sendAtom, sendArgs, sendNamedArgs) if atom is SEND_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.send(target, sendAtom, sendArgs, sendNamedArgs) if atom is TOQUOTE_1: return StrObject(args[0].toQuote()) if atom is TOSTRING_1: return StrObject(toString(args[0])) raise Refused(self, atom, args)
def unwrap(self, value): return unwrapStr(value)
def recv(self, atom, args): if atom is CALLWITHPAIR_2 or atom is CALLWITHPAIR_3: target = args[0] pair = unwrapList(args[1]) if len(pair) not in (2, 3): raise userError(u"callWithPair/2 requires a pair!") if len(pair) == 3: namedArgs = pair[2] else: namedArgs = EMPTY_MAP sendVerb = unwrapStr(pair[0]) sendArgs = unwrapList(pair[1]) rv = target.call(sendVerb, sendArgs, namedArgs) if rv is None: print "callWithPair/2: Returned None:", \ target.__class__.__name__, sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is CALL_3 or atom is CALL_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) if len(args) == 3: namedArgs = EMPTY_MAP else: namedArgs = args[3] rv = target.call(sendVerb, sendArgs, namedArgs) if rv is None: print "call/3: Returned None:", target.__class__.__name__, \ sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is SENDONLY_3: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() vat.sendOnly(target, sendAtom, sendArgs, EMPTY_MAP) return NullObject if atom is SEND_3: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.send(target, sendAtom, sendArgs, EMPTY_MAP) if atom is CALLWITHMESSAGE_2: target = args[0] msg = unwrapList(args[1]) if len(msg) != 3: raise userError( u"callWithPair/2 requires a [verb, args, namedArgs] triple") sendVerb = unwrapStr(msg[0]) sendArgs = unwrapList(msg[1]) sendNamedArgs = resolution(msg[2]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") rv = target.call(sendVerb, sendArgs, sendNamedArgs) if rv is None: print "callWithPair/2: Returned None:", \ target.__class__.__name__, sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is CALL_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") rv = target.call(sendVerb, sendArgs, sendNamedArgs) if rv is None: print "call/3: Returned None:", target.__class__.__name__, \ sendVerb.encode("utf-8") raise RuntimeError("Implementation error") return rv if atom is SENDONLY_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.sendOnly(target, sendAtom, sendArgs, sendNamedArgs) if atom is SEND_4: target = args[0] sendVerb = unwrapStr(args[1]) sendArgs = unwrapList(args[2]) sendNamedArgs = resolution(args[3]) if not isinstance(sendNamedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(sendVerb, len(sendArgs)) vat = currentVat.get() return vat.send(target, sendAtom, sendArgs, sendNamedArgs) if atom is TOQUOTE_1: return StrObject(args[0].toQuote()) if atom is TOSTRING_1: return StrObject(toString(args[0])) raise Refused(self, atom, args)