def recv(self, atom, args): if atom is PRINT_1: item = resolution(args[0]) self._print(item) return NullObject if atom is PRINTLN_1: item = resolution(args[0]) self.println(item) return NullObject if atom is LNPRINT_1: item = resolution(args[0]) self.lnPrint(item) return NullObject if atom is QUOTE_1: item = resolution(args[0]) if isinstance(item, CharObject) or isinstance(item, StrObject): self.ub.append(item.toQuote()) else: self.objPrint(item) return NullObject if atom is INDENT_1: return self.indent(args[0]) raise Refused(self, atom, args)
def auditedBy(auditor, specimen): """ Whether an auditor has audited a specimen. """ from typhon.objects.refs import resolution from typhon.objects.constants import wrapBool return wrapBool(resolution(specimen).auditedBy(auditor))
def takeTurn(self): from typhon.objects.exceptions import sealException from typhon.objects.refs import Promise, resolution with self._pendingLock: resolver, target, atom, args, namedArgs = self._pending.pop(0) # Set up our Miranda FAIL. if namedArgs.extractStringKey(u"FAIL", None) is None: if resolver is not None: FAIL = resolver.makeSmasher() else: from typhon.objects.ejectors import theThrower FAIL = theThrower namedArgs = namedArgs.withStringKey(u"FAIL", FAIL) # 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")) try: if isinstance(target, Promise): if resolver is None: target.sendOnly(atom, args, namedArgs) else: result = target.send(atom, args, namedArgs) # The resolver may have already been invoked, so we'll use # .resolveRace/1 instead of .resolve/1. ~ C. resolver.resolveRace(result) else: result = target.callAtom(atom, args, namedArgs) if resolver is not None: # Same logic as above. resolver.resolveRace(result) except UserException as ue: if resolver is not None: resolver.smash(sealException(ue)) else: 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"]) if resolver is not None: resolver.smash( sealException(userError(u"Vat ran out of checkpoints"))) except Ejecting: self.log(u"Ejector tried to escape vat turn boundary", tags=["serious"]) if resolver is not None: resolver.smash( sealException( userError(u"Ejector tried to escape from vat")))
def checkSlot(self): if self.committed: return True self.resolutionBox = resolution(self.resolutionBox) if isResolved(self.resolutionBox): self.commit() return True return False
def promoteToBigInt(o): from typhon.objects.refs import resolution i = resolution(o) if isinstance(i, BigInt): return i.bi if isinstance(i, IntObject): return rbigint.fromint(i.getInt()) raise WrongType(u"Not promotable to big integer!")
def unwrapMap(o): from typhon.objects.refs import resolution m = resolution(o) if isinstance(m, ConstMap): return m.objectMap if isinstance(m, FlexMap): return m.objectMap raise WrongType(u"Not a map!")
def unwrapList(o, ej=None): from typhon.objects.refs import resolution l = resolution(o) if isinstance(l, ConstList): return l.objs if isinstance(l, FlexList): return l.strategy.fetch_all(l) throwStr(ej, u"Not a list!")
def unwrapBool(o): from typhon.objects.refs import resolution b = resolution(o) if b is TrueObject: return True if b is FalseObject: return False raise WrongType(u"Not a boolean!")
def unwrapBool(o): from typhon.objects.refs import resolution b = resolution(o) if b is TrueObject: return True if b is FalseObject: return False raise userError(u"Not a boolean!")
def unwrapSet(o): from typhon.objects.refs import resolution m = resolution(o) if isinstance(m, ConstSet): return m.objectSet if isinstance(m, FlexSet): return m.objectSet raise WrongType(u"Not a set!")
def unwrapList(o, ej=None): from typhon.objects.refs import resolution l = resolution(o) if isinstance(l, ConstList): return l.strategy.fetch_all(l) if isinstance(l, FlexList): return l.strategy.fetch_all(l) throw(ej, StrObject(u"Not a list!"))
def takeTurn(self): from typhon.objects.exceptions import sealException from typhon.objects.refs import Promise, resolution with self._pendingLock: resolver, target, atom, args, namedArgs = self._pending.pop(0) # Set up our Miranda FAIL. if namedArgs.extractStringKey(u"FAIL", None) is None: if resolver is not None: FAIL = resolver.makeSmasher() else: from typhon.objects.ejectors import theThrower FAIL = theThrower namedArgs = namedArgs.withStringKey(u"FAIL", FAIL) # 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")) try: if isinstance(target, Promise): if resolver is None: target.sendOnly(atom, args, namedArgs) else: result = target.send(atom, args, namedArgs) # The resolver may have already been invoked, so we'll use # .resolveRace/1 instead of .resolve/1. ~ C. resolver.resolveRace(result) else: result = target.callAtom(atom, args, namedArgs) if resolver is not None: # Same logic as above. resolver.resolveRace(result) except UserException as ue: if resolver is not None: resolver.smash(sealException(ue)) else: 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"]) if resolver is not None: resolver.smash(sealException(userError(u"Vat ran out of checkpoints"))) except Ejecting: self.log(u"Ejector tried to escape vat turn boundary", tags=["serious"]) if resolver is not None: resolver.smash(sealException(userError(u"Ejector tried to escape from vat")))
def __init__(self, ref): self.ref = resolution(ref) self.fringe = [] # Compute a "sameYet" hash, which represents a snapshot of how this # key's traversal had resolved at the time of key creation. snapHash = samenessHash(self.ref, HASH_DEPTH, self.fringe) for f in self.fringe: snapHash ^= f.fringeHash() self.snapHash = snapHash
def promoteToDouble(o): from typhon.objects.refs import resolution n = resolution(o) if isinstance(n, IntObject): return float(n.getInt()) if isinstance(n, DoubleObject): return n.getDouble() if isinstance(n, BigInt): return n.bi.tofloat() raise WrongType(u"Failed to promote to double")
def unwrapInt(o): from typhon.objects.refs import resolution i = resolution(o) if isinstance(i, IntObject): return i.getInt() if isinstance(i, BigInt): try: return i.bi.toint() except OverflowError: raise WrongType(u"Integer was too large") raise WrongType(u"Not an integer!")
def unwrapInt(o): from typhon.objects.refs import resolution i = resolution(o) if isinstance(i, IntObject): return i.getInt() if isinstance(i, BigInt): try: return i.bi.toint() except OverflowError: pass raise WrongType(u"Not an integer!")
def isInt(obj): from typhon.objects.refs import resolution obj = resolution(obj) if isinstance(obj, IntObject): return True if isinstance(obj, BigInt): try: obj.bi.toint() return True except OverflowError: return False return False
def coerce(self, specimen, ej): specimen = resolution(specimen) val = self.subCoerce(specimen) if val is None: newspec = specimen.call(u"_conformTo", [self]) val = self.subCoerce(newspec) if val is None: throw(ej, StrObject(u"%s does not conform to %s" % (specimen.toQuote(), self.toQuote()))) else: return val else: return val
def objPrint(self, item): item = resolution(item) if isinstance(item, Promise): self.ub.append(u"<promise>") return elif item in self.context: self.ub.append(u"<**CYCLE**>") return self.context[item] = None try: item.call(u"_printOn", [self]) except UserException, e: self.ub.append(u"<** %s throws %s when printed**>" % (item.toString(), e.error()))
def objPrint(self, item): item = resolution(item) if isinstance(item, Promise): self.ub.append(u"<promise>") elif item in self.context: self.ub.append(u"<**CYCLE**>") else: self.context[item] = None try: item.call(u"_printOn", [self]) except UserException, e: self.ub.append(u"<** %s throws %s when printed**>" % (item.toString(), e.error())) del self.context[item]
def sendOnly(self, target, verb, args, namedArgs): """ Send a message to an object. The message will be delivered on some subsequent turn. """ namedArgs = resolution(namedArgs) if not isinstance(namedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(verb, len(args)) vat = currentVat.get() vat.sendOnly(target, sendAtom, args, namedArgs)
def samenessFringe(original, path, fringe, sofar=None): """ Walk an object graph, building up the fringe. Returns whether the graph is settled. """ # Resolve the object. o = resolution(original) # Handle primitive cases first. if o in (NullObject, TrueObject, FalseObject): return True if (isinstance(o, CharObject) or isinstance(o, DoubleObject) or isinstance(o, IntObject) or isinstance(o, BigInt) or isinstance(o, StrObject) or isinstance(o, BytesObject) or isinstance(o, TraversalKey)): return True if isinstance(o, ConstMap) and o.empty(): return True if sofar is None: sofar = {} elif o in sofar: return True if isinstance(o, ConstList): sofar[o] = None return listFringe(o, fringe, path, sofar) if selfless in o.auditorStamps(): if transparentStamp in o.auditorStamps(): sofar[o] = None return samenessFringe(o.call(u"_uncall", []), path, fringe, sofar) if semitransparentStamp in o.auditorStamps(): sofar[o] = None p = o.call(u"_uncall", []) if not isinstance(p, SealedPortrayal): userError( u'Semitransparent portrayal was not a SealedPortrayal!') return samenessFringe(p, path, fringe, sofar) if isResolved(o): return True # Welp, it's unsettled. if fringe is not None: fringe.append(FringeNode(o, path)) return False
def samenessFringe(original, path, fringe, sofar=None): """ Walk an object graph, building up the fringe. Returns whether the graph is settled. """ # Resolve the object. o = resolution(original) # Handle primitive cases first. if o in (NullObject, TrueObject, FalseObject): return True if (isinstance(o, CharObject) or isinstance(o, DoubleObject) or isinstance(o, IntObject) or isinstance(o, BigInt) or isinstance(o, StrObject) or isinstance(o, BytesObject) or isinstance(o, TraversalKey)): return True if isinstance(o, ConstMap) and o.empty(): return True if sofar is None: sofar = {} elif o in sofar: return True if isinstance(o, ConstList): sofar[o] = None return listFringe(o, fringe, path, sofar) if selfless in o.auditorStamps(): if transparentStamp in o.auditorStamps(): sofar[o] = None return samenessFringe(o.call(u"_uncall", []), path, fringe, sofar) if semitransparentStamp in o.auditorStamps(): sofar[o] = None p = o.call(u"_uncall", []) if not isinstance(p, SealedPortrayal): userError(u'Semitransparent portrayal was not a SealedPortrayal!') return samenessFringe(p, path, fringe, sofar) if isResolved(o): return True # Welp, it's unsettled. if fringe is not None: fringe.append(FringeNode(o, path)) return False
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 nearGuard(specimen, ej): """ A guard over references to near values. This guard admits any near value, as well as any resolved reference to any near value. This guard is unretractable. """ specimen = resolution(specimen) if isinstance(specimen, Promise): msg = u"Specimen is in non-near state %s" % specimen.state().repr throw(ej, StrObject(msg)) return specimen
def coerce(self, specimen, ej): specimen = resolution(specimen) val = self.subCoerce(specimen) if val is None: newspec = specimen.call(u"_conformTo", [self]) val = self.subCoerce(newspec) if val is None: throw( ej, StrObject(u"%s does not conform to %s" % (specimen.toQuote(), self.toQuote()))) else: return val else: return val
def samenessFringe(original, path, fringe, sofar=None): """ Walk an object graph, building up the fringe. Returns whether the graph is settled. """ # Resolve the object. o = resolution(original) # Handle primitive cases first. if o is NullObject: return True if ( isinstance(o, BoolObject) or isinstance(o, CharObject) or isinstance(o, DoubleObject) or isinstance(o, IntObject) or isinstance(o, BigInt) or isinstance(o, StrObject) or isinstance(o, TraversalKey) ): return True if isinstance(o, ConstMap) and len(o.objectMap) == 0: return True if sofar is None: sofar = {} elif o in sofar: return True if isinstance(o, ConstList): sofar[o] = None return listFringe(o, fringe, path, sofar) if selfless in o.auditorStamps(): if transparentStamp in o.auditorStamps(): return samenessFringe(o.call(u"_uncall", []), path, fringe, sofar) # XXX Semitransparent support goes here if isResolved(o): return True # Welp, it's unsettled. if fringe is not None: fringe.append(FringeNode(o, path)) return False
def unwrapBytes(o): from typhon.objects.refs import resolution s = resolution(o) if isinstance(s, BytesObject): return s.getBytes() # XXX temporary only: Permit lists of ints. # from typhon.objects.collections.lists import ConstList, unwrapList # if isinstance(s, ConstList): # buf = "" # l = unwrapList(s) # for obj in l: # if isinstance(obj, IntObject): # buf += chr(obj._i) # else: # raise WrongType(u"Not a byte!") # return buf raise WrongType(u"Not a bytestring!")
def send(self, target, verb, args, namedArgs): """ Send a message to an object, returning a promise for the message delivery. The promise will be fulfilled after successful delivery, or smashed upon error. The message will be delivered on some subsequent turn. """ namedArgs = resolution(namedArgs) if not isinstance(namedArgs, ConstMap): raise WrongType(u"namedArgs must be a ConstMap") # Signed, sealed, delivered, I'm yours. sendAtom = getAtom(verb, len(args)) vat = currentVat.get() return vat.send(target, sendAtom, args, namedArgs)
def samenessFringe(original, path, fringe, sofar=None): """ Walk an object graph, building up the fringe. Returns whether the graph is settled. """ # Resolve the object. o = resolution(original) # Handle primitive cases first. if o is NullObject: return True if (isinstance(o, BoolObject) or isinstance(o, CharObject) or isinstance(o, DoubleObject) or isinstance(o, IntObject) or isinstance(o, BigInt) or isinstance(o, StrObject) or isinstance(o, TraversalKey)): return True if isinstance(o, ConstMap) and len(o.objectMap) == 0: return True if sofar is None: sofar = {} elif o in sofar: return True if isinstance(o, ConstList): sofar[o] = None return listFringe(o, fringe, path, sofar) if selfless in o.auditorStamps(): if transparentStamp in o.auditorStamps(): sofar[o] = None return samenessFringe(o.call(u"_uncall", []), path, fringe, sofar) # XXX Semitransparent support goes here if isResolved(o): return True # Welp, it's unsettled. if fringe is not None: fringe.append(FringeNode(o, path)) return False
def coerce(self, specimen, ej): specimen = resolution(specimen) val = subCoerce(specimen) if val is None: try: newspec = specimen.call(u"_conformTo", [self]) except UserException: msg = u"%s threw exception while conforming to %s" % ( specimen.toQuote(), self.toQuote()) throwStr(ej, msg) else: val = subCoerce(newspec) if val is None: throwStr(ej, u"%s does not conform to %s" % ( specimen.toQuote(), self.toQuote())) else: return val else: return val
def objPrint(self, item): item = resolution(item) if isinstance(item, Promise) and isBroken(item): if item._problem in self.context: self.ub.append(u"<Ref broken by: **CYCLE**>") else: self.ub.append(item.toString()) elif isinstance(item, Promise) and not item.isResolved(): self.ub.append(u"<promise>") elif isinstance(item, Promise): # probably a far ref of some kind self.ub.append(item.toString()) elif item in self.context: self.ub.append(u"<**CYCLE**>") else: self.context[item] = None try: item.call(u"_printOn", [self]) except UserException, e: self.ub.append(u"<** %s throws %s when printed**>" % ( item.toString(), e.error())) del self.context[item]
def quote(self, item): item = resolution(item) if isinstance(item, CharObject) or isinstance(item, StrObject): self.ub.append(item.toQuote()) else: self.objPrint(item)
def unwrapChar(o): from typhon.objects.refs import resolution c = resolution(o) if isinstance(c, CharObject): return c.getChar() raise WrongType(u"Not a char!")
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
def _print(self, item): item = resolution(item) if isinstance(item, StrObject): self.ub.append(unwrapStr(item)) else: self.objPrint(item)
def unwrapStr(o): from typhon.objects.refs import resolution s = resolution(o) if isinstance(s, StrObject): return s.getString() raise WrongType(u"Not a string!")
def unwrapDouble(o): from typhon.objects.refs import resolution d = resolution(o) if isinstance(d, DoubleObject): return d.getDouble() raise WrongType(u"Not a double!")
def isDouble(obj): from typhon.objects.refs import resolution return isinstance(resolution(obj), DoubleObject)
def unwrapBigInt(o): from typhon.objects.refs import resolution bi = resolution(o) if isinstance(bi, BigInt): return bi.bi raise WrongType(u"Not a big integer!")
def isChar(obj): from typhon.objects.refs import resolution return isinstance(resolution(obj), CharObject)
def isBytes(obj): from typhon.objects.refs import resolution return isinstance(resolution(obj), BytesObject)
def unwrapBytes(o): from typhon.objects.refs import resolution s = resolution(o) if isinstance(s, BytesObject): return s.getBytes() raise WrongType(u"Not a bytestring!")