Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds) { STAT_TIMER(t0, "us_timer_boxedwrapperobject__call__", (self->cls->is_user_defined ? 1 : 2)); assert(self->cls == wrapperobject_cls); assert(args->cls == tuple_cls); assert(kwds->cls == dict_cls); int flags = self->descr->wrapper->flags; wrapperfunc wrapper = self->descr->wrapper->wrapper; assert(self->descr->wrapper->offset > 0); Box* rtn; if (flags == PyWrapperFlag_KEYWORDS) { wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; rtn = (*wk)(self->obj, args, self->descr->wrapped, kwds); } else if (flags == PyWrapperFlag_PYSTON || flags == 0) { rtn = (*wrapper)(self->obj, args, self->descr->wrapped); } else { RELEASE_ASSERT(0, "%d", flags); } checkAndThrowCAPIException(); assert(rtn && "should have set + thrown an exception!"); return rtn; }
BoxedLong* _longNew(Box* val, Box* _base) { BoxedLong* rtn = new BoxedLong(); if (_base) { if (!isSubclass(_base->cls, int_cls)) raiseExcHelper(TypeError, "an integer is required"); int base = static_cast<BoxedInt*>(_base)->n; if (!isSubclass(val->cls, str_cls)) raiseExcHelper(TypeError, "long() can't convert non-string with explicit base"); BoxedString* s = static_cast<BoxedString*>(val); rtn = (BoxedLong*)PyLong_FromString(s->data(), NULL, base); checkAndThrowCAPIException(); } else { if (isSubclass(val->cls, long_cls)) { BoxedLong* l = static_cast<BoxedLong*>(val); if (val->cls == long_cls) return l; BoxedLong* rtn = new BoxedLong(); mpz_init_set(rtn->n, l->n); return rtn; } else if (isSubclass(val->cls, int_cls)) { mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n); } else if (val->cls == str_cls) { llvm::StringRef s = static_cast<BoxedString*>(val)->s(); assert(s.data()[s.size()] == '\0'); int r = mpz_init_set_str(rtn->n, s.data(), 10); RELEASE_ASSERT(r == 0, ""); } else if (val->cls == float_cls) { mpz_init_set_si(rtn->n, static_cast<BoxedFloat*>(val)->d); } else { static BoxedString* long_str = static_cast<BoxedString*>(PyString_InternFromString("__long__")); Box* r = callattr(val, long_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }), ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); if (!r) { fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n", getTypeName(val)); raiseExcHelper(TypeError, ""); } if (isSubclass(r->cls, int_cls)) { mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(r)->n); } else if (!isSubclass(r->cls, long_cls)) { raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name); } else { return static_cast<BoxedLong*>(r); } } }
Box* BoxedMethodDescriptor::__call__(BoxedMethodDescriptor* self, Box* obj, BoxedTuple* varargs, Box** _args) { STAT_TIMER(t0, "us_timer_boxedmethoddescriptor__call__", 10); BoxedDict* kwargs = static_cast<BoxedDict*>(_args[0]); assert(self->cls == method_cls); assert(varargs->cls == tuple_cls); assert(kwargs->cls == dict_cls); int ml_flags = self->method->ml_flags; int call_flags; if (ml_flags & METH_CLASS) { if (!isSubclass(obj->cls, type_cls)) raiseExcHelper(TypeError, "descriptor '%s' requires a type but received a '%s'", self->method->ml_name, getFullTypeName(obj).c_str()); call_flags = ml_flags & (~METH_CLASS); } else { if (!isSubclass(obj->cls, self->type)) raiseExcHelper(TypeError, "descriptor '%s' requires a '%s' object but received a '%s'", self->method->ml_name, getFullNameOfClass(self->type).c_str(), getFullTypeName(obj).c_str()); call_flags = ml_flags; } threading::GLPromoteRegion _gil_lock; Box* rtn; if (call_flags == METH_NOARGS) { RELEASE_ASSERT(varargs->size() == 0, ""); RELEASE_ASSERT(kwargs->d.size() == 0, ""); rtn = (Box*)self->method->ml_meth(obj, NULL); } else if (call_flags == METH_VARARGS) { RELEASE_ASSERT(kwargs->d.size() == 0, ""); rtn = (Box*)self->method->ml_meth(obj, varargs); } else if (call_flags == (METH_VARARGS | METH_KEYWORDS)) { rtn = (Box*)((PyCFunctionWithKeywords)self->method->ml_meth)(obj, varargs, kwargs); } else if (call_flags == METH_O) { RELEASE_ASSERT(kwargs->d.size() == 0, ""); RELEASE_ASSERT(varargs->size() == 1, ""); rtn = (Box*)self->method->ml_meth(obj, varargs->elts[0]); } else { RELEASE_ASSERT(0, "0x%x", call_flags); } checkAndThrowCAPIException(); assert(rtn && "should have set + thrown an exception!"); return rtn; }
Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) { assert(_self->cls == wrapperobject_cls); BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self); int flags = self->descr->wrapper->flags; wrapperfunc wrapper = self->descr->wrapper->wrapper; assert(self->descr->wrapper->offset > 0); if (rewrite_args && !rewrite_args->func_guarded) { rewrite_args->obj->addAttrGuard(offsetof(BoxedWrapperObject, descr), (intptr_t)self->descr); } ParamReceiveSpec paramspec(0, 0, true, false); if (flags == PyWrapperFlag_KEYWORDS) { paramspec = ParamReceiveSpec(0, 0, true, true); } else if (flags == PyWrapperFlag_PYSTON || flags == 0) { paramspec = ParamReceiveSpec(0, 0, true, false); } else { RELEASE_ASSERT(0, "%d", flags); } Box* oarg1 = NULL; Box* oarg2 = NULL; Box* oarg3 = NULL; Box** oargs = NULL; bool rewrite_success = false; rearrangeArguments(paramspec, NULL, self->descr->wrapper->name.data(), NULL, rewrite_args, rewrite_success, argspec, arg1, arg2, arg3, args, keyword_names, oarg1, oarg2, oarg3, args); assert(oarg1 && oarg1->cls == tuple_cls); if (!paramspec.takes_kwargs) assert(oarg2 == NULL); assert(oarg3 == NULL); assert(oargs == NULL); if (!rewrite_success) rewrite_args = NULL; Box* rtn; if (flags == PyWrapperFlag_KEYWORDS) { wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper; rtn = (*wk)(self->obj, oarg1, self->descr->wrapped, oarg2); if (rewrite_args) { auto rewriter = rewrite_args->rewriter; auto r_obj = rewrite_args->obj->getAttr(offsetof(BoxedWrapperObject, obj), Location::forArg(0)); rewrite_args->out_rtn = rewriter->call( true, (void*)wk, r_obj, rewrite_args->arg1, rewriter->loadConst((intptr_t)self->descr->wrapped, Location::forArg(2)), rewrite_args->arg2); rewriter->call(false, (void*)checkAndThrowCAPIException); rewrite_args->out_success = true; } } else if (flags == PyWrapperFlag_PYSTON || flags == 0) { rtn = (*wrapper)(self->obj, oarg1, self->descr->wrapped); if (rewrite_args) { auto rewriter = rewrite_args->rewriter; auto r_obj = rewrite_args->obj->getAttr(offsetof(BoxedWrapperObject, obj), Location::forArg(0)); rewrite_args->out_rtn = rewriter->call(true, (void*)wrapper, r_obj, rewrite_args->arg1, rewriter->loadConst((intptr_t)self->descr->wrapped, Location::forArg(2))); rewriter->call(false, (void*)checkAndThrowCAPIException); rewrite_args->out_success = true; } } else { RELEASE_ASSERT(0, "%d", flags); } checkAndThrowCAPIException(); assert(rtn && "should have set + thrown an exception!"); return rtn; }