Commit c5d2083e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #881 from undingen/wrapper2

when calling a BoxedWrapperDescriptor don't create a BoxedWrapperObject
parents 0a8385c9 65e3ce5b
...@@ -1878,8 +1878,10 @@ public: ...@@ -1878,8 +1878,10 @@ public:
} }
ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override { ConcreteCompilerVariable* nonzero(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var) override {
static BoxedString* attr = internStringImmortal("__nonzero__"); if (cls == None->cls)
return makeBool(false);
static BoxedString* attr = internStringImmortal("__nonzero__");
bool no_attribute = false; bool no_attribute = false;
ConcreteCompilerVariable* called_constant ConcreteCompilerVariable* called_constant
= tryCallattrConstant(emitter, info, var, attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL, &no_attribute); = tryCallattrConstant(emitter, info, var, attr, true, ArgPassSpec(0, 0, 0, 0), {}, NULL, &no_attribute);
......
...@@ -471,6 +471,106 @@ Box* BoxedWrapperDescriptor::__call__(BoxedWrapperDescriptor* descr, PyObject* s ...@@ -471,6 +471,106 @@ Box* BoxedWrapperDescriptor::__call__(BoxedWrapperDescriptor* descr, PyObject* s
return BoxedWrapperObject::__call__(wrapper, args, kw); return BoxedWrapperObject::__call__(wrapper, args, kw);
} }
template <ExceptionStyle S>
Box* BoxedWrapperDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
if (S == CAPI) {
try {
return tppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
STAT_TIMER(t0, "us_timer_boxedwrapperdecsriptor_call", (_self->cls->is_user_defined ? 10 : 20));
assert(_self->cls == wrapperdescr_cls);
BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(_self);
int flags = self->wrapper->flags;
wrapperfunc wrapper = self->wrapper->wrapper;
assert(self->wrapper->offset > 0);
ParamReceiveSpec paramspec(1, 0, true, false);
if (flags == PyWrapperFlag_KEYWORDS) {
paramspec = ParamReceiveSpec(1, 0, true, true);
} else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
paramspec = ParamReceiveSpec(1, 0, true, false);
} else if (flags == PyWrapperFlag_1ARG) {
paramspec = ParamReceiveSpec(1, 0, false, false);
} else if (flags == PyWrapperFlag_2ARG) {
paramspec = ParamReceiveSpec(2, 0, false, false);
} else {
RELEASE_ASSERT(0, "%d", flags);
}
Box** oargs = NULL;
bool rewrite_success = false;
rearrangeArguments(paramspec, NULL, self->wrapper->name.data(), NULL, rewrite_args, rewrite_success, argspec, arg1,
arg2, arg3, args, oargs, keyword_names);
if (paramspec.takes_varargs)
assert(arg2 && arg2->cls == tuple_cls);
if (!rewrite_success)
rewrite_args = NULL;
Box* rtn;
if (flags == PyWrapperFlag_KEYWORDS) {
wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
rtn = (*wk)(arg1, arg2, self->wrapped, arg3);
if (rewrite_args) {
auto rewriter = rewrite_args->rewriter;
rewrite_args->out_rtn
= rewriter->call(true, (void*)wk, rewrite_args->arg1, rewrite_args->arg2,
rewriter->loadConst((intptr_t)self->wrapped, Location::forArg(2)), rewrite_args->arg3);
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
rtn = (*wrapper)(arg1, arg2, self->wrapped);
if (rewrite_args) {
auto rewriter = rewrite_args->rewriter;
rewrite_args->out_rtn = rewriter->call(true, (void*)wrapper, rewrite_args->arg1, rewrite_args->arg2,
rewriter->loadConst((intptr_t)self->wrapped, Location::forArg(2)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_1ARG) {
wrapperfunc_1arg wrapper_1arg = (wrapperfunc_1arg)wrapper;
rtn = (*wrapper_1arg)(arg1, self->wrapped);
if (rewrite_args) {
auto rewriter = rewrite_args->rewriter;
rewrite_args->out_rtn = rewriter->call(true, (void*)wrapper, rewrite_args->arg1,
rewriter->loadConst((intptr_t)self->wrapped, Location::forArg(1)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_2ARG) {
rtn = (*wrapper)(arg1, arg2, self->wrapped);
if (rewrite_args) {
auto rewriter = rewrite_args->rewriter;
rewrite_args->out_rtn = rewriter->call(true, (void*)wrapper, rewrite_args->arg1, rewrite_args->arg2,
rewriter->loadConst((intptr_t)self->wrapped, Location::forArg(2)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else {
RELEASE_ASSERT(0, "%d", flags);
}
checkAndThrowCAPIException();
assert(rtn && "should have set + thrown an exception!");
return rtn;
}
void BoxedWrapperDescriptor::gcHandler(GCVisitor* v, Box* _o) { void BoxedWrapperDescriptor::gcHandler(GCVisitor* v, Box* _o) {
assert(_o->cls == wrapperdescr_cls); assert(_o->cls == wrapperdescr_cls);
BoxedWrapperDescriptor* o = static_cast<BoxedWrapperDescriptor*>(_o); BoxedWrapperDescriptor* o = static_cast<BoxedWrapperDescriptor*>(_o);
...@@ -543,110 +643,26 @@ template <ExceptionStyle S> ...@@ -543,110 +643,26 @@ template <ExceptionStyle S>
Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) { const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
if (S == CAPI) {
try {
return tppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (_self->cls->is_user_defined ? 10 : 20)); STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (_self->cls->is_user_defined ? 10 : 20));
assert(_self->cls == wrapperobject_cls); assert(_self->cls == wrapperobject_cls);
BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self); BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self);
int flags = self->descr->wrapper->flags;
wrapperfunc wrapper = self->descr->wrapper->wrapper;
assert(self->descr->wrapper->offset > 0); assert(self->descr->wrapper->offset > 0);
RewriterVar* r_obj = NULL;
Box** new_args = NULL;
if (argspec.totalPassed() >= 3)
new_args = (Box**)alloca(sizeof(Box*) * (argspec.totalPassed() + 1 - 3));
if (rewrite_args && !rewrite_args->func_guarded) { if (rewrite_args) {
rewrite_args->obj->addAttrGuard(offsetof(BoxedWrapperObject, descr), (intptr_t)self->descr); if (!rewrite_args->func_guarded)
} rewrite_args->obj->addAttrGuard(offsetof(BoxedWrapperObject, descr), (intptr_t)self->descr);
r_obj = rewrite_args->obj->getAttr(offsetof(BoxedWrapperObject, obj), Location::forArg(0));
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 if (flags == PyWrapperFlag_1ARG) {
paramspec = ParamReceiveSpec(0, 0, false, false);
} else if (flags == PyWrapperFlag_2ARG) {
paramspec = ParamReceiveSpec(1, 0, false, false);
} else {
RELEASE_ASSERT(0, "%d", flags);
}
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, oargs, keyword_names);
if (paramspec.takes_varargs)
assert(arg1 && arg1->cls == tuple_cls);
if (!rewrite_success)
rewrite_args = NULL;
Box* rtn;
if (flags == PyWrapperFlag_KEYWORDS) {
wrapperfunc_kwds wk = (wrapperfunc_kwds)wrapper;
rtn = (*wk)(self->obj, arg1, self->descr->wrapped, arg2);
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);
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_PYSTON || flags == 0) {
rtn = (*wrapper)(self->obj, arg1, 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)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_1ARG) {
wrapperfunc_1arg wrapper_1arg = (wrapperfunc_1arg)wrapper;
rtn = (*wrapper_1arg)(self->obj, 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, rewriter->loadConst((intptr_t)self->descr->wrapped, Location::forArg(1)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else if (flags == PyWrapperFlag_2ARG) {
rtn = (*wrapper)(self->obj, arg1, 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)));
rewrite_args->rewriter->checkAndThrowCAPIException(rewrite_args->out_rtn);
rewrite_args->out_success = true;
}
} else {
RELEASE_ASSERT(0, "%d", flags);
} }
ArgPassSpec new_argspec
checkAndThrowCAPIException(); = bindObjIntoArgs(self->obj, r_obj, rewrite_args, argspec, arg1, arg2, arg3, args, new_args);
assert(rtn && "should have set + thrown an exception!"); return BoxedWrapperDescriptor::tppCall<S>(self->descr, rewrite_args, new_argspec, arg1, arg2, arg3, new_args,
return rtn; keyword_names);
} }
void BoxedWrapperObject::gcHandler(GCVisitor* v, Box* _o) { void BoxedWrapperObject::gcHandler(GCVisitor* v, Box* _o) {
...@@ -711,6 +727,8 @@ void setupDescr() { ...@@ -711,6 +727,8 @@ void setupDescr() {
wrapperdescr_cls->giveAttr("__doc__", wrapperdescr_cls->giveAttr("__doc__",
new (pyston_getset_cls) BoxedGetsetDescriptor(wrapperdescrGetDoc, NULL, NULL)); new (pyston_getset_cls) BoxedGetsetDescriptor(wrapperdescrGetDoc, NULL, NULL));
wrapperdescr_cls->tp_descr_get = BoxedWrapperDescriptor::descr_get; wrapperdescr_cls->tp_descr_get = BoxedWrapperDescriptor::descr_get;
wrapperdescr_cls->tpp_call.capi_val = BoxedWrapperDescriptor::tppCall<CAPI>;
wrapperdescr_cls->tpp_call.cxx_val = BoxedWrapperDescriptor::tppCall<CXX>;
add_operators(wrapperdescr_cls); add_operators(wrapperdescr_cls);
wrapperdescr_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)wrapperDescrRepr, UNKNOWN, 1))); wrapperdescr_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)wrapperDescrRepr, UNKNOWN, 1)));
wrapperdescr_cls->freeze(); wrapperdescr_cls->freeze();
......
...@@ -1123,23 +1123,33 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1123,23 +1123,33 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
return sm->sm_callable; return sm->sm_callable;
} else if (descr->cls == wrapperdescr_cls) { } else if (descr->cls == wrapperdescr_cls) {
BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(descr); if (for_call) {
Box* inst = obj; if (rewrite_args) {
Box* owner = obj->cls; rewrite_args->out_success = true;
rewrite_args->out_rtn = r_descr;
Box* r = BoxedWrapperDescriptor::descr_get(self, inst, owner); rewrite_args->out_return_convention = GetattrRewriteArgs::VALID_RETURN;
*r_bind_obj_out = rewrite_args->obj;
}
*bind_obj_out = obj;
return descr;
} else {
BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(descr);
Box* inst = obj;
Box* owner = obj->cls;
Box* r = BoxedWrapperDescriptor::descr_get(self, inst, owner);
if (rewrite_args) { if (rewrite_args) {
// TODO: inline this? // TODO: inline this?
RewriterVar* r_rtn = rewrite_args->rewriter->call( RewriterVar* r_rtn = rewrite_args->rewriter->call(
/* has_side_effects= */ false, (void*)&BoxedWrapperDescriptor::descr_get, r_descr, rewrite_args->obj, /* has_side_effects= */ false, (void*)&BoxedWrapperDescriptor::descr_get, r_descr,
r_descr->getAttr(offsetof(Box, cls), Location::forArg(2))); rewrite_args->obj, r_descr->getAttr(offsetof(Box, cls), Location::forArg(2)));
rewrite_args->out_success = true; rewrite_args->out_success = true;
rewrite_args->out_rtn = r_rtn; rewrite_args->out_rtn = r_rtn;
rewrite_args->out_return_convention = GetattrRewriteArgs::VALID_RETURN; rewrite_args->out_return_convention = GetattrRewriteArgs::VALID_RETURN;
}
return r;
} }
return r;
} }
return NULL; return NULL;
...@@ -2446,20 +2456,20 @@ extern "C" bool nonzero(Box* obj) { ...@@ -2446,20 +2456,20 @@ extern "C" bool nonzero(Box* obj) {
static BoxedString* len_str = internStringImmortal("__len__"); static BoxedString* len_str = internStringImmortal("__len__");
// try __nonzero__ // try __nonzero__
GetattrRewriteArgs grewrite_args(rewriter.get(), r_obj, rewriter ? rewriter->getReturnDestination() : Location()); CallRewriteArgs crewrite_args(rewriter.get(), r_obj, rewriter ? rewriter->getReturnDestination() : Location());
Box* func = getclsattrInternal(obj, nonzero_str, rewriter ? &grewrite_args : NULL); Box* rtn = callattrInternal0<CXX>(obj, nonzero_str, CLASS_ONLY, rewriter ? &crewrite_args : NULL, ArgPassSpec(0));
if (!grewrite_args.out_success) if (!crewrite_args.out_success)
rewriter.reset(); rewriter.reset();
if (!func) { if (!rtn) {
// try __len__ // try __len__
grewrite_args crewrite_args
= GetattrRewriteArgs(rewriter.get(), r_obj, rewriter ? rewriter->getReturnDestination() : Location()); = CallRewriteArgs(rewriter.get(), r_obj, rewriter ? rewriter->getReturnDestination() : Location());
func = getclsattrInternal(obj, len_str, rewriter ? &grewrite_args : NULL); rtn = callattrInternal0<CXX>(obj, len_str, CLASS_ONLY, rewriter ? &crewrite_args : NULL, ArgPassSpec(0));
if (!grewrite_args.out_success) if (!crewrite_args.out_success)
rewriter.reset(); rewriter.reset();
if (func == NULL) { if (rtn == NULL) {
ASSERT(obj->cls->is_user_defined || obj->cls == classobj_cls || obj->cls == type_cls ASSERT(obj->cls->is_user_defined || obj->cls == classobj_cls || obj->cls == type_cls
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls || isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls
|| obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == capifunc_cls || obj->cls == instancemethod_cls || obj->cls == module_cls || obj->cls == capifunc_cls
...@@ -2475,11 +2485,8 @@ extern "C" bool nonzero(Box* obj) { ...@@ -2475,11 +2485,8 @@ extern "C" bool nonzero(Box* obj) {
return true; return true;
} }
} }
CallRewriteArgs cargs(rewriter.get(), grewrite_args.out_rtn, if (crewrite_args.out_success) {
rewriter ? rewriter->getReturnDestination() : Location()); RewriterVar* b = rewriter->call(false, (void*)nonzeroHelper, crewrite_args.out_rtn);
Box* rtn = runtimeCallInternal0<CXX>(func, rewriter ? &cargs : NULL, ArgPassSpec(0));
if (cargs.out_success) {
RewriterVar* b = rewriter->call(false, (void*)nonzeroHelper, cargs.out_rtn);
rewriter->commitReturning(b); rewriter->commitReturning(b);
} }
return nonzeroHelper(rtn); return nonzeroHelper(rtn);
......
...@@ -1008,6 +1008,9 @@ public: ...@@ -1008,6 +1008,9 @@ public:
static Box* descr_get(Box* self, Box* inst, Box* owner) noexcept; static Box* descr_get(Box* self, Box* inst, Box* owner) noexcept;
static Box* __call__(BoxedWrapperDescriptor* descr, PyObject* self, BoxedTuple* args, Box** _args); static Box* __call__(BoxedWrapperDescriptor* descr, PyObject* self, BoxedTuple* args, Box** _args);
template <ExceptionStyle S>
static Box* tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI);
static void gcHandler(GCVisitor* v, Box* _o); static void gcHandler(GCVisitor* v, Box* _o);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment