Commit e44c12e4 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make bind_obj_out borrowed

Looked at all places it comes from and this looks safe
(it's alive at least as long as the other arguments).

We are now crashing on cpython_oldstyle_getattr_crash (a CPython crasher)
but that's not really the fault of this change.
parent 2c916cb1
...@@ -872,7 +872,7 @@ static PyObject* call_attribute(PyObject* self, PyObject* attr, PyObject* name) ...@@ -872,7 +872,7 @@ static PyObject* call_attribute(PyObject* self, PyObject* attr, PyObject* name)
template <ExceptionStyle S, Rewritable rewritable> template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs* rewrite_args, bool for_call, Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs* rewrite_args, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) { BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
rewrite_args = NULL; rewrite_args = NULL;
......
...@@ -58,7 +58,7 @@ int compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const ch ...@@ -58,7 +58,7 @@ int compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const ch
class GetattrRewriteArgs; class GetattrRewriteArgs;
template <ExceptionStyle S, Rewritable rewritable> template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool for_call, Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI); BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI);
} }
#endif #endif
...@@ -1807,7 +1807,7 @@ bool isNondataDescriptorInstanceSpecialCase(Box* descr) { ...@@ -1807,7 +1807,7 @@ bool isNondataDescriptorInstanceSpecialCase(Box* descr) {
template <Rewritable rewritable> template <Rewritable rewritable>
Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* obj, Box* descr, RewriterVar* r_descr, Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* obj, Box* descr, RewriterVar* r_descr,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) { bool for_call, BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
rewrite_args = NULL; rewrite_args = NULL;
...@@ -1888,7 +1888,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1888,7 +1888,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
} }
return boxInstanceMethod(im_self, im_func, im_class); return boxInstanceMethod(im_self, im_func, im_class);
} else { } else {
*bind_obj_out = incref(im_self); *bind_obj_out = im_self;
if (rewrite_args) { if (rewrite_args) {
rewrite_args->setReturn(r_im_func, ReturnConvention::HAS_RETURN); rewrite_args->setReturn(r_im_func, ReturnConvention::HAS_RETURN);
*r_bind_obj_out = r_im_self; *r_bind_obj_out = r_im_self;
...@@ -1915,7 +1915,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1915,7 +1915,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
rewrite_args->setReturn(r_descr, ReturnConvention::HAS_RETURN); rewrite_args->setReturn(r_descr, ReturnConvention::HAS_RETURN);
*r_bind_obj_out = rewrite_args->obj; *r_bind_obj_out = rewrite_args->obj;
} }
*bind_obj_out = incref(obj); *bind_obj_out = obj;
return incref(descr); return incref(descr);
} else { } else {
BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(descr); BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(descr);
...@@ -1944,7 +1944,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box ...@@ -1944,7 +1944,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
// r_descr must represent a valid object. // r_descr must represent a valid object.
template <Rewritable rewritable> template <Rewritable rewritable>
Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls, Box* descr, RewriterVar* r_descr, Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls, Box* descr, RewriterVar* r_descr,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) { bool for_call, BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
rewrite_args = NULL; rewrite_args = NULL;
...@@ -1999,7 +1999,7 @@ Box* boxChar(char c) { ...@@ -1999,7 +1999,7 @@ Box* boxChar(char c) {
// r_descr needs to represent a valid object // r_descr needs to represent a valid object
template <Rewritable rewritable> template <Rewritable rewritable>
Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedString* attr_name, Box* obj, Box* descr, Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedString* attr_name, Box* obj, Box* descr,
RewriterVar* r_descr, bool for_call, Box** bind_obj_out, RewriterVar* r_descr, bool for_call, BORROWED(Box**) bind_obj_out,
RewriterVar** r_bind_obj_out) { RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
...@@ -2214,7 +2214,7 @@ static void ensureValidCapiReturn(Box* r) { ...@@ -2214,7 +2214,7 @@ static void ensureValidCapiReturn(Box* r) {
template <ExceptionStyle S, Rewritable rewritable> template <ExceptionStyle S, Rewritable rewritable>
Box* getattrInternalEx(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call, Box* getattrInternalEx(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) { BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
rewrite_args = NULL; rewrite_args = NULL;
...@@ -2431,7 +2431,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) { ...@@ -2431,7 +2431,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) {
template <bool IsType, Rewritable rewritable> template <bool IsType, Rewritable rewritable>
Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call, Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) { BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) { if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args); assert(!rewrite_args);
rewrite_args = NULL; rewrite_args = NULL;
...@@ -3745,8 +3745,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3745,8 +3745,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
return val; return val;
} }
AUTO_XDECREF(bind_obj);
if (bind_obj != NULL) { if (bind_obj != NULL) {
Box** new_args = NULL; Box** new_args = NULL;
if (npassed_args >= 3) { if (npassed_args >= 3) {
......
...@@ -168,7 +168,7 @@ template <ExceptionStyle S> inline Box* getattrInternal(Box* obj, BoxedString* a ...@@ -168,7 +168,7 @@ template <ExceptionStyle S> inline Box* getattrInternal(Box* obj, BoxedString* a
// __getattribute__. // __getattribute__.
template <bool IsType, Rewritable rewritable> template <bool IsType, Rewritable rewritable>
Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call, Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out); BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out);
extern "C" PyObject* type_getattro(PyObject* o, PyObject* name) noexcept; extern "C" PyObject* type_getattro(PyObject* o, PyObject* name) noexcept;
......
# skip-if: '-n' in EXTRA_JIT_ARGS or '-O' in EXTRA_JIT_ARGS
# Tests to see if we add any extra refs to function arguments. # Tests to see if we add any extra refs to function arguments.
import sys import sys
...@@ -7,4 +8,13 @@ def f(o): ...@@ -7,4 +8,13 @@ def f(o):
print sys.getrefcount(o) print sys.getrefcount(o)
# This gives 3 for CPython and our interpreter, but 2 for the llvm tier: # This gives 3 for CPython and our interpreter, but 2 for the llvm tier:
# f(object()) f(object())
import sys
class C(object):
def foo(self, *args):
print sys.getrefcount(self)
c = C()
a = (c.foo)
print sys.getrefcount(c)
c.foo()
# skip-if: True
# - sadly, we have now inherited CPython's buggy behavior here
# This segfaults under python-dbg # This segfaults under python-dbg
# (In a release build it "works" since the use-after-free happens without penalty.) # (In a release build it "works" since the use-after-free happens without penalty.)
......
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