Commit c7af9a18 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix a number of bugs to get pickle working

- Some missing refcounting annotations
- We would allocate before guarding, so if the guards failed we would
  leak those objects.
  - The code now treats this conservatively (like it should), which
    might result in more rewriter aborts.  I manually tried to fix
    the case that was hitting this for now.
- Small bug in the llvm-tier type specialization
parent 7018c659
......@@ -2354,8 +2354,10 @@ extern "C" PyObject* PyNumber_Float(PyObject* o) noexcept {
if (o == NULL)
return null_error();
if (o->cls == float_cls)
if (o->cls == float_cls) {
Py_INCREF(o);
return o;
}
PyNumberMethods* m;
m = o->cls->tp_as_number;
......
......@@ -1822,7 +1822,7 @@ public:
if (!canStaticallyResolveGetattrs())
return NULL;
Box* rtattr = cls->getattr(attr);
Box* rtattr = typeLookup(cls, attr);
if (rtattr == NULL) {
if (no_attribute) {
*no_attribute = true;
......
......@@ -41,7 +41,7 @@ static Box* toComplex(Box* self) noexcept {
} else if (PyInt_Check(self)) {
r = new BoxedComplex(static_cast<BoxedInt*>(self)->n, 0.0);
} else if (PyFloat_Check(self)) {
r = new BoxedComplex((static_cast<BoxedFloat*>(PyNumber_Float(self)))->d, 0.0);
r = new BoxedComplex((static_cast<BoxedFloat*>(autoDecref(PyNumber_Float(self))))->d, 0.0);
} else if (PyLong_Check(self)) {
double real = PyLong_AsDouble(self);
if (real == -1 && PyErr_Occurred())
......@@ -427,7 +427,7 @@ Box* complexGetnewargs(BoxedComplex* self) {
if (!PyComplex_Check(self))
raiseExcHelper(TypeError, "descriptor '__getnewargs__' requires a 'complex' object but received a '%s'",
getTypeName(self));
return BoxedTuple::create({ boxFloat(self->real), boxFloat(self->imag) });
return BoxedTuple::create({ autoDecref(boxFloat(self->real)), autoDecref(boxFloat(self->imag)) });
}
Box* complexNonzero(BoxedComplex* self) {
......
......@@ -320,6 +320,13 @@ Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, A
}
bool oargs_owned[1];
bool arg1_class_guarded = false;
if (rewrite_args && argspec.num_args >= 1) {
// Try to do the guard before rearrangeArguments if possible:
rewrite_args->arg1->addAttrGuard(offsetof(Box, cls), (intptr_t)arg1->cls);
arg1_class_guarded = true;
}
bool rewrite_success = false;
rearrangeArguments(paramspec, NULL, self->method->ml_name, defaults, rewrite_args, rewrite_success, argspec, arg1,
arg2, arg3, args, oargs, keyword_names, oargs_owned);
......@@ -340,7 +347,7 @@ Box* BoxedMethodDescriptor::tppCall(Box* _self, CallRewriteArgs* rewrite_args, A
getFullNameOfClass(self->type).c_str(), getFullTypeName(arg1).c_str());
}
if (rewrite_args) {
if (rewrite_args && !arg1_class_guarded) {
rewrite_args->arg1->addAttrGuard(offsetof(Box, cls), (intptr_t)arg1->cls);
}
......
......@@ -4324,7 +4324,7 @@ void rearrangeArgumentsInternal(ParamReceiveSpec paramspec, const ParamNames* pa
(void*)BoxedTuple::create5, //
(void*)BoxedTuple::create6, //
};
varargs_val = rewrite_args->rewriter->call(false, create_ptrs[varargs_size], unused_positional_rvars)
varargs_val = rewrite_args->rewriter->call(true, create_ptrs[varargs_size], unused_positional_rvars)
->setType(RefType::OWNED);
is_owned = true;
}
......
......@@ -3164,6 +3164,7 @@ static PyObject* reduce_2(PyObject* obj) noexcept {
if (state->cls == attrwrapper_cls) {
PyObject* real_dict = PyDict_New();
PyDict_Update(real_dict, state);
Py_DECREF(state);
state = real_dict;
}
}
......
# expected: reffail
import copy
class C(object):
pass
......
# expected: reffail
class MyList(list):
pass
......
# expected: reffail
import marshal
o = [-1, 1.23456789, complex(1.2, 3.4)]
o += [True, False, None]
......
# expected: reffail
import pickle
l = [[], (123,)]
......
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