Commit dc4d003b authored by Kevin Modzelewski's avatar Kevin Modzelewski

More refcounting fixes

parent 158465fc
......@@ -1137,6 +1137,8 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
_base = Exception;
if (dict == NULL)
dict = new BoxedDict();
else
Py_INCREF(dict);
try {
char* dot_pos = strchr(name, '.');
......@@ -1149,11 +1151,13 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
BoxedClass* base = static_cast<BoxedClass*>(_base);
if (PyDict_GetItemString(dict, "__module__") == NULL) {
PyDict_SetItemString(dict, "__module__", boxString(llvm::StringRef(name, dot_pos - name)));
PyDict_SetItemString(dict, "__module__", autoDecref(boxString(llvm::StringRef(name, dot_pos - name))));
}
checkAndThrowCAPIException();
Box* cls = runtimeCall(type_cls, ArgPassSpec(3), boxedName, BoxedTuple::create({ base }), dict, NULL, NULL);
Box* cls = runtimeCall(type_cls, ArgPassSpec(3), boxedName, autoDecref(BoxedTuple::create({ base })), dict, NULL, NULL);
Py_DECREF(boxedName);
Py_DECREF(dict);
return cls;
} catch (ExcInfo e) {
// PyErr_NewException isn't supposed to fail, and callers sometimes take advantage of that
......
......@@ -878,10 +878,12 @@ extern "C" void PyErr_SetExcInfo(PyObject* type, PyObject* value, PyObject* trac
}
extern "C" void PyErr_SetString(PyObject* exception, const char* string) noexcept {
PyErr_SetObject(exception, boxString(string));
PyErr_SetObject(exception, autoDecref(boxString(string)));
}
extern "C" void PyErr_SetObject(PyObject* exception, PyObject* value) noexcept {
Py_XINCREF(exception);
Py_XINCREF(value);
PyErr_Restore(exception, value, NULL);
}
......
......@@ -329,9 +329,18 @@ extern "C" PyObject* PyDict_GetItem(PyObject* dict, PyObject* key) noexcept {
ASSERT(PyDict_Check(dict) || dict->cls == attrwrapper_cls, "%s", getTypeName(dict));
if (PyDict_Check(dict)) {
BoxedDict* d = static_cast<BoxedDict*>(dict);
return d->getOrNull(key);
/* preserve the existing exception */
PyObject* err_type, *err_value, *err_tb;
PyErr_Fetch(&err_type, &err_value, &err_tb);
Box* b = d->getOrNull(key);
/* ignore errors */
PyErr_Restore(err_type, err_value, err_tb);
return b;
}
assert(0 && "check refcounting");
auto&& tstate = _PyThreadState_Current;
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
......@@ -392,7 +401,7 @@ extern "C" int PyDict_Next(PyObject* op, Py_ssize_t* ppos, PyObject** pkey, PyOb
extern "C" PyObject* PyDict_GetItemString(PyObject* dict, const char* key) noexcept {
if (dict->cls == attrwrapper_cls)
return unwrapAttrWrapper(dict)->getattr(internStringMortal(key));
return unwrapAttrWrapper(dict)->getattr(autoDecref(internStringMortal(key)));
Box* key_s;
try {
......@@ -400,7 +409,7 @@ extern "C" PyObject* PyDict_GetItemString(PyObject* dict, const char* key) noexc
} catch (ExcInfo e) {
abort();
}
return PyDict_GetItem(dict, key_s);
return PyDict_GetItem(dict, autoDecref(key_s));
}
Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
......
......@@ -79,6 +79,7 @@ HiddenClass* HiddenClass::getOrMakeChild(BoxedString* attr) {
static StatCounter num_hclses("num_hidden_classes");
num_hclses.log();
// XXX: need to hold a ref to the string (or maybe we don't if we can hook the un-interning)
HiddenClass* rtn = new HiddenClass(this);
rtn->attr_offsets[attr] = this->attributeArraySize();
this->children[attr] = rtn;
......
This diff is collapsed.
......@@ -2142,7 +2142,7 @@ public:
internStringMortalInplace(key);
self->b->setattr(key, value, NULL);
return None;
Py_RETURN_NONE;
}
static int ass_sub(PyDictObject* mp, PyObject* v, PyObject* w) noexcept {
......@@ -2154,6 +2154,7 @@ public:
res = AttrWrapper::setitem((Box*)mp, v, w);
}
assert(res == None);
Py_DECREF(res);
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
......@@ -2259,7 +2260,7 @@ public:
self->b->delattr(key, NULL);
else
raiseExcHelper(KeyError, "'%s'", key->data());
return None;
Py_RETURN_NONE;
}
static Box* str(Box* _self) {
......
......@@ -77,7 +77,7 @@ void boundSliceWithLength(i64* start_out, i64* stop_out, i64 start, i64 stop, i6
Box* boxStringOrNone(const char* s) {
if (s == NULL) {
return None;
return incref(None);
} else {
return boxString(s);
}
......
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