def testListEqualityRecursion(self): # Yes, this is very hacky. first = ConstList([IntObject(42)]) first.strategy.append(first, [first]) second = ConstList([IntObject(42)]) second.strategy.append(second, [second]) self.assertEqual(optSame(first, second), EQUAL)
def recv(self, atom, args): if atom.verb == u"run": return ConstList(args) if atom is FROMITERABLE_1: return ConstList(listFromIterable(args[0])[:]) raise Refused(self, atom, args)
def unsealException(specimen, ej): """ Unseal a specimen. """ if isinstance(specimen, SealedException): trail = ConstList([StrObject(s) for s in specimen.trail]) return ConstList([specimen.value, trail]) throw(ej, StrObject(u"Cannot unseal non-thrown object"))
def recv(self, atom, args): if atom is _UNCALL_0: from typhon.objects.collections.maps import EMPTY_MAP from typhon.scopes.safe import theVarSlotGuardMaker return ConstList([ theVarSlotGuardMaker, StrObject(u"get"), ConstList([self.valueGuard]), EMPTY_MAP ]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is _UNCALL_0: from typhon.scopes.safe import theFinalSlotMaker from typhon.objects.collections.maps import EMPTY_MAP return ConstList([ theFinalSlotMaker, StrObject(u"run"), ConstList([self._obj, self._guard, NullObject]), EMPTY_MAP ]) return Slot.recv(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 connect(self): vat = currentVat.get() stream = ruv.alloc_tcp(vat.uv_loop) fount, fountResolver = makePromise() drain, drainResolver = makePromise() # Ugh, the hax. resolvers = ConstList([fountResolver, drainResolver]) ruv.stashStream(ruv.rffi.cast(ruv.stream_tp, stream), (vat, resolvers)) # Make the actual connection. ruv.tcpConnect(stream, self.host, self.port, connectCB) # Return the promises. return ConstList([fount, drain])
def pop(self): from typhon.objects.collections.lists import ConstList if self.objectMap: key, value = self.objectMap.popitem() return ConstList([key, value]) else: raise userError(u"pop/0: Pop from empty map")
def runMatchers(self, atom, args, namedArgs): message = ConstList([StrObject(atom.verb), ConstList(args), namedArgs]) for matcher in self.codeScript.strategy.getMatchers(): with Ejector() as ej: try: return self.runMatcher(matcher, message, ej) except Ejecting as e: if e.ejector is ej: # Looks like unification failed. On to the next # matcher! continue else: # It's not ours, cap'n. raise raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GETHANDLES_0: l = [] # ruv.walk(self.loop, walkCB, eraseList(l)) return ConstList([LoopHandle(h) for h in l]) raise Refused(self, atom, args)
def sendAll(self, atom, args, namedArgs): if self.checkSlot(): ref = self.resolutionBox.get() return send(ref, atom, args, namedArgs) else: return send(self.handler, HANDLESEND_3, [StrObject(atom.verb), ConstList(args), namedArgs], EMPTY_MAP)
def getWindowSize(self): from typhon.objects.data import wrapInt from typhon.objects.collections.lists import ConstList with scoped_alloc(INTP.TO, 1) as widthp, \ scoped_alloc(INTP.TO, 1) as heightp: ruv.TTYGetWinSize(self._tty, widthp, heightp) width = intmask(widthp[0]) height = intmask(heightp[0]) return ConstList([wrapInt(width), wrapInt(height)])
def recv(self, atom, args): if atom is _UNCALL_0: from typhon.objects.collections.maps import EMPTY_MAP return ConstList([ sameGuardMaker, StrObject(u"get"), ConstList([self.value]), EMPTY_MAP ]) if atom is COERCE_2: from typhon.objects.equality import optSame, EQUAL specimen, ej = args[0], args[1] if optSame(specimen, self.value) is EQUAL: return specimen ej.call(u"run", [ConstList([specimen, StrObject(u"is not"), self.value])]) if atom is GETVALUE_0: return self.value raise Refused(self, atom, args)
def recv(self, atom, args): if atom is _UNCALL_0: from typhon.objects.collections.maps import EMPTY_MAP from typhon.scopes.safe import theFinalSlotGuardMaker return ConstList([ theFinalSlotGuardMaker, StrObject(u"get"), ConstList([self.valueGuard]), EMPTY_MAP ]) if atom is GETGUARD_0: return self.valueGuard if atom is COERCE_2: return self.coerce(args[0], args[1]) if atom is SUPERSETOF_1: s = args[0] if isinstance(s, FinalSlot): return self.valueGuard.call(u"supersetOf", [s._guard]) return wrapBool(False) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is NEXT_1: if self._index < len(self.s): from typhon.objects.collections.lists import ConstList rv = [IntObject(self._index), CharObject(self.s[self._index])] self._index += 1 return ConstList(rv) else: ej = args[0] ej.call(u"run", [StrObject(u"Iterator exhausted")]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GETALGORITHM_0: return StrObject(u"CSPRNG (libsodium)") if atom is GETENTROPY_0: # uint32_t in the FFI, so exactly 32 bits every time. return ConstList([ IntObject(32), IntObject(intmask(rsodium.randombytesRandom())) ]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GET_0: return self.get() if atom is GETGUARD_0: return self.guard if atom is _UNCALL_0: from typhon.objects.collections.maps import EMPTY_MAP from typhon.scopes.safe import theSlotBinder return ConstList([ ConstList([ theSlotBinder, StrObject(u"run"), ConstList([self.guard]) ]), StrObject(u"run"), ConstList([self.slot, NullObject]), EMPTY_MAP ]) raise Refused(self, atom, args)
def gaiCB(gai, status, ai): status = intmask(status) vat, resolver = ruv.unstashGAI(gai) with scopedVat(vat): assert isinstance(resolver, LocalResolver), "implementation error" if status < 0: msg = ruv.formatError(status).decode("utf-8") resolver.smash(StrObject(u"libuv error: %s" % msg)) else: gaiList = walkAI(ai) resolver.resolve(ConstList(gaiList[:])) ruv.freeAddrInfo(ai) ruv.free(gai)
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 COERCE_2: for g in self.subguards: with Ejector() as ej: try: return g.call(u"coerce", [args[0], ej]) except Ejecting as e: if e.ejector is ej: continue throw(args[1], StrObject(u"No subguards matched")) if atom is SUPERSETOF_1: for g in self.subguards: if not unwrapBool(g.call(u"supersetOf", [args[0]])): return wrapBool(False) return wrapBool(True) if atom is _UNCALL_0: from typhon.objects.collections.maps import EMPTY_MAP return ConstList([ anyGuard, StrObject(u"get"), ConstList(self.subguards), EMPTY_MAP ]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is COMBINE_1: return self.combine(args[0]) if atom is GETSTARTCOL_0: return self.getStartCol() if atom is GETSTARTLINE_0: return self.getStartLine() if atom is GETENDCOL_0: return self.getEndCol() if atom is GETENDLINE_0: return self.getEndLine() if atom is ISONETOONE_0: return self.isOneToOne() if atom is NOTONETOONE_0: return self.notOneToOne() if atom is _UNCALL_0: from typhon.objects.collections.lists import ConstList from typhon.objects.collections.maps import EMPTY_MAP return ConstList([ makeSourceSpan, StrObject(u"run"), ConstList([wrapBool(self._isOneToOne), IntObject(self.startLine), IntObject(self.startCol), IntObject(self.endLine), IntObject(self.endCol)]), EMPTY_MAP]) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GETBUCKETS_0: d = monteMap() for name, count in self.buckets.items(): size = self.sizes.get(name, -1) d[StrObject(name)] = ConstList( [IntObject(size), IntObject(count)]) return ConstMap(d) if atom is GETMEMORYUSAGE_0: return IntObject(self.memoryUsage) if atom is GETOBJECTCOUNT_0: return IntObject(self.objectCount) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is SEAL_1: message = unwrapBytes(args[0]) nonce = rsodium.freshNonce() cipher = rsodium.boxSeal(message, nonce, self.publicKey, self.secretKey) return ConstList([BytesObject(cipher), BytesObject(nonce)]) if atom is UNSEAL_2: cipher = unwrapBytes(args[0]) nonce = unwrapBytes(args[1]) try: message = rsodium.boxUnseal(cipher, nonce, self.publicKey, self.secretKey) except rsodium.SodiumError: raise userError(u"unseal/2: Couldn't open this box") return BytesObject(message) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is COERCE_2: return args[0] if atom is SUPERSETOF_1: return wrapBool(True) if atom is EXTRACTGUARDS_2: g = args[0] ej = args[1] if isinstance(g, AnyOfGuard): return ConstList(g.subguards) else: ej.call(u"run", [StrObject(u"Not an AnyOf guard")]) if atom is GETMETHODS_0: return ConstSet(monteSet()) if atom.verb == u"get": return AnyOfGuard(args) raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GETARGUMENTS_0: return ConstList( [StrObject(arg.decode("utf-8")) for arg in self.config.argv]) if atom is GETENVIRONMENT_0: # XXX monteMap() d = monteMap() for key, value in os.environ.items(): k = StrObject(key.decode("utf-8")) v = StrObject(value.decode("utf-8")) d[k] = v return ConstMap(d) if atom is GETPID_0: return IntObject(os.getpid()) if atom is INTERRUPT_0: os.kill(os.getpid(), signal.SIGINT) return NullObject raise Refused(self, atom, args)
def recv(self, atom, args): if atom is GETARGUMENTS_0: return ConstList([BytesObject(arg) for arg in self.argv]) if atom is GETENVIRONMENT_0: # XXX monteMap() d = monteMap() for key, value in self.env.items(): k = BytesObject(key) v = BytesObject(value) d[k] = v return ConstMap(d) if atom is GETPID_0: return IntObject(self.pid) if atom is INTERRUPT_0: os.kill(self.pid, signal.SIGINT) return NullObject if atom is WAIT_0: return self.makeWaiter() raise Refused(self, atom, args)
def recv(self, atom, args): if atom is FROMPUBLICBYTES_1: publicKey = unwrapBytes(args[0]) expectedSize = intmask(rsodium.cryptoBoxPublickeybytes()) if len(publicKey) != expectedSize: message = u"Expected key length of %d bytes, not %d" % ( expectedSize, len(publicKey)) raise userError(message) return PublicKey(publicKey) if atom is FROMSECRETBYTES_1: secretKey = unwrapBytes(args[0]) expectedSize = intmask(rsodium.cryptoBoxSecretkeybytes()) if len(secretKey) != expectedSize: message = u"Expected key length of %d bytes, not %d" % ( expectedSize, len(secretKey)) raise userError(message) return SecretKey(secretKey) if atom is RUN_0: public, secret = rsodium.freshKeypair() return ConstList([PublicKey(public), SecretKey(secret)]) raise Refused(self, atom, args)
def testSlice(self): l = ConstList(map(CharObject, "abcdefg")) result = l.call(u"slice", [IntObject(3), IntObject(6)]) chars = [char._c for char in unwrapList(result)] self.assertEqual(chars, list("def"))
def testHashInequalItems(self): a = ConstList([IntObject(42), CharObject(u'é')]) b = ConstList([IntObject(42), CharObject(u'e')]) self.assertNotEqual(a.hash(), b.hash())
def testJoin(self): s = StrObject(u"|") result = s.call( u"join", [ConstList([StrObject(u"5"), StrObject(u"42")])]) self.assertEqual(result._s, u"5|42")
def testCmpShortRight(self): a = ConstList([IntObject(2), IntObject(4)]) b = ConstList([IntObject(2)]) result = a.call(u"op__cmp", [b]) self.assertEqual(result.getInt(), 1)
def testHashEqual(self): a = ConstList([IntObject(42), CharObject(u'é')]) b = ConstList([IntObject(42), CharObject(u'é')]) self.assertEqual(a.hash(), b.hash())
def recv(self, atom, args): if atom is ADD_1: other = args[0] if isinstance(other, BytesObject): return BytesObject(self._bs + other._bs) if isinstance(other, IntObject): return BytesObject(self._bs + str(chr(other._i))) if atom is ASLIST_0: from typhon.objects.collections.lists import ConstList return ConstList(self.asList()) if atom is ASSET_0: from typhon.objects.collections.sets import ConstSet return ConstSet(self.asSet()) if atom is CONTAINS_1: needle = args[0] if isinstance(needle, IntObject): return wrapBool(chr(needle._i) in self._bs) if isinstance(needle, BytesObject): return wrapBool(needle._bs in self._bs) if atom is GET_1: index = unwrapInt(args[0]) if not 0 <= index < len(self._bs): raise userError(u"string.get/1: Index out of bounds: %d" % index) return IntObject(ord(self._bs[index])) if atom is INDEXOF_1: needle = unwrapBytes(args[0]) return IntObject(self._bs.find(needle)) if atom is INDEXOF_2: needle = unwrapBytes(args[0]) offset = unwrapInt(args[1]) if offset < 0: raise userError(u"indexOf/2: Negative offset %d not supported" % offset) return IntObject(self._bs.find(needle, offset)) if atom is JOIN_1: from typhon.objects.collections.lists import unwrapList return BytesObject(self.join(unwrapList(args[0]))) if atom is LASTINDEXOF_1: needle = unwrapBytes(args[0]) return IntObject(self._bs.rfind(needle)) if atom is MULTIPLY_1: amount = args[0] if isinstance(amount, IntObject): return BytesObject(self._bs * amount._i) if atom is OP__CMP_1: return polyCmp(self._bs, unwrapBytes(args[0])) if atom is REPLACE_2: return BytesObject(replace(self._bs, unwrapBytes(args[0]), unwrapBytes(args[1]))) if atom is SIZE_0: return IntObject(len(self._bs)) if atom is SLICE_1: start = unwrapInt(args[0]) if start < 0: raise userError(u"Slice start cannot be negative") return BytesObject(self._bs[start:]) if atom is SLICE_2: start = unwrapInt(args[0]) stop = unwrapInt(args[1]) if start < 0: raise userError(u"Slice start cannot be negative") if stop < 0: raise userError(u"Slice stop cannot be negative") return BytesObject(self._bs[start:stop]) if atom is SPLIT_1: from typhon.objects.collections.lists import ConstList return ConstList(self.split(unwrapBytes(args[0]))) if atom is SPLIT_2: from typhon.objects.collections.lists import ConstList return ConstList(self.split(unwrapBytes(args[0]), unwrapInt(args[1]))) if atom is TOLOWERCASE_0: return BytesObject(self.toLowerCase()) if atom is TOUPPERCASE_0: return BytesObject(self.toUpperCase()) if atom is TRIM_0: return BytesObject(self.trim()) if atom is WITH_1: return BytesObject(self._bs + chr(unwrapInt(args[0]))) if atom is _MAKEITERATOR_0: return bytesIterator(self._bs) raise Refused(self, atom, args)