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