Commit 66200ef5 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix refcounting for a bunch of locals/globals functions

Most of these need to return borrowed references in order to match the C API.
parent 2f702c0a
...@@ -453,7 +453,7 @@ extern "C" BORROWED(PyObject*) PyModule_GetDict(PyObject* _m) noexcept { ...@@ -453,7 +453,7 @@ extern "C" BORROWED(PyObject*) PyModule_GetDict(PyObject* _m) noexcept {
BoxedModule* m = static_cast<BoxedModule*>(_m); BoxedModule* m = static_cast<BoxedModule*>(_m);
assert(PyModule_Check(m)); assert(PyModule_Check(m));
return autoDecref(m->getAttrWrapper()); return m->getAttrWrapper();
} }
extern "C" int PyModule_AddObject(PyObject* _m, const char* name, STOLEN(PyObject*) value) noexcept { extern "C" int PyModule_AddObject(PyObject* _m, const char* name, STOLEN(PyObject*) value) noexcept {
......
...@@ -3466,7 +3466,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept { ...@@ -3466,7 +3466,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls->giveAttrBorrowed("__base__", base); cls->giveAttrBorrowed("__base__", base);
assert(cls->tp_dict == NULL); assert(cls->tp_dict == NULL);
cls->tp_dict = cls->getAttrWrapper(); cls->tp_dict = incref(cls->getAttrWrapper());
assert(cls->tp_name); assert(cls->tp_name);
......
...@@ -469,6 +469,7 @@ extern "C" int PyEval_MergeCompilerFlags(PyCompilerFlags* cf) noexcept { ...@@ -469,6 +469,7 @@ extern "C" int PyEval_MergeCompilerFlags(PyCompilerFlags* cf) noexcept {
} }
static void pickGlobalsAndLocals(Box*& globals, Box*& locals) { static void pickGlobalsAndLocals(Box*& globals, Box*& locals) {
assert(0 && "check refcounting");
if (globals == None) if (globals == None)
globals = NULL; globals = NULL;
......
...@@ -353,19 +353,12 @@ public: ...@@ -353,19 +353,12 @@ public:
return getFrameInfo()->stmt; return getFrameInfo()->stmt;
} }
Box* getGlobals() { BORROWED(Box*) getGlobalsDict() {
assert(0 && "check refcounting (of callers)"); Box* globals = getFrameInfo()->globals;
Box* r = getFrameInfo()->globals;
return incref(r);
}
Box* getGlobalsDict() {
Box* globals = getGlobals();
if (!globals) if (!globals)
return NULL; return NULL;
if (PyModule_Check(globals)) { if (PyModule_Check(globals)) {
AUTO_DECREF(globals);
return globals->getAttrWrapper(); return globals->getAttrWrapper();
} }
return globals; return globals;
...@@ -729,14 +722,14 @@ FunctionMetadata* getTopPythonFunction() { ...@@ -729,14 +722,14 @@ FunctionMetadata* getTopPythonFunction() {
return frame_info->md; return frame_info->md;
} }
Box* getGlobals() { BORROWED(Box*) getGlobals() {
FrameInfo* frame_info = getTopFrameInfo(); FrameInfo* frame_info = getTopFrameInfo();
if (!frame_info) if (!frame_info)
return NULL; return NULL;
return frame_info->globals; return frame_info->globals;
} }
Box* getGlobalsDict() { BORROWED(Box*) getGlobalsDict() {
Box* globals = getGlobals(); Box* globals = getGlobals();
if (globals && PyModule_Check(globals)) if (globals && PyModule_Check(globals))
globals = globals->getAttrWrapper(); globals = globals->getAttrWrapper();
...@@ -874,7 +867,7 @@ DeoptState getDeoptState() { ...@@ -874,7 +867,7 @@ DeoptState getDeoptState() {
return rtn; return rtn;
} }
Box* fastLocalsToBoxedLocals() { BORROWED(Box*) fastLocalsToBoxedLocals() {
return getPythonFrameInfo(0)->updateBoxedLocals(); return getPythonFrameInfo(0)->updateBoxedLocals();
} }
...@@ -891,7 +884,7 @@ static BoxedDict* localsForFrame(Box** vregs, CFG* cfg) { ...@@ -891,7 +884,7 @@ static BoxedDict* localsForFrame(Box** vregs, CFG* cfg) {
return rtn; return rtn;
} }
Box* FrameInfo::updateBoxedLocals() { BORROWED(Box*) FrameInfo::updateBoxedLocals() {
STAT_TIMER(t0, "us_timer_updateBoxedLocals", 0); STAT_TIMER(t0, "us_timer_updateBoxedLocals", 0);
FrameInfo* frame_info = this; FrameInfo* frame_info = this;
...@@ -922,15 +915,17 @@ Box* FrameInfo::updateBoxedLocals() { ...@@ -922,15 +915,17 @@ Box* FrameInfo::updateBoxedLocals() {
Box* val = closure->elts[derefInfo.offset]; Box* val = closure->elts[derefInfo.offset];
Box* boxedName = name.getBox(); Box* boxedName = name.getBox();
if (val != NULL) { if (val != NULL) {
assert(0 &&" add refcounting");
d->d[boxedName] = val; d->d[boxedName] = val;
} else { } else {
assert(0 &&" add refcounting");
d->d.erase(boxedName); d->d.erase(boxedName);
} }
} }
if (!frame_info->boxedLocals) { if (!frame_info->boxedLocals) {
frame_info->boxedLocals = incref(d); frame_info->boxedLocals = d;
return d; return frame_info->boxedLocals;
} }
AUTO_DECREF(d); AUTO_DECREF(d);
...@@ -949,7 +944,7 @@ Box* FrameInfo::updateBoxedLocals() { ...@@ -949,7 +944,7 @@ Box* FrameInfo::updateBoxedLocals() {
} }
} }
return incref(frame_info->boxedLocals); return frame_info->boxedLocals;
} }
AST_stmt* PythonFrameIterator::getCurrentStatement() { AST_stmt* PythonFrameIterator::getCurrentStatement() {
...@@ -964,7 +959,7 @@ FunctionMetadata* PythonFrameIterator::getMD() { ...@@ -964,7 +959,7 @@ FunctionMetadata* PythonFrameIterator::getMD() {
return impl->getMD(); return impl->getMD();
} }
Box* PythonFrameIterator::getGlobalsDict() { BORROWED(Box*) PythonFrameIterator::getGlobalsDict() {
return impl->getGlobalsDict(); return impl->getGlobalsDict();
} }
......
...@@ -36,8 +36,8 @@ bool isUnwinding(); // use this instead of std::uncaught_exception ...@@ -36,8 +36,8 @@ bool isUnwinding(); // use this instead of std::uncaught_exception
void setupUnwinding(); void setupUnwinding();
BoxedModule* getCurrentModule(); BoxedModule* getCurrentModule();
Box* getGlobals(); // returns either the module or a globals dict BORROWED(Box*) getGlobals(); // returns either the module or a globals dict
Box* getGlobalsDict(); // always returns a dict-like object BORROWED(Box*) getGlobalsDict(); // always returns a dict-like object
CompiledFunction* getCFForAddress(uint64_t addr); CompiledFunction* getCFForAddress(uint64_t addr);
class PythonUnwindSession; class PythonUnwindSession;
...@@ -66,7 +66,7 @@ std::string getCurrentPythonLine(); ...@@ -66,7 +66,7 @@ std::string getCurrentPythonLine();
void logByCurrentPythonLine(const std::string& stat_name); void logByCurrentPythonLine(const std::string& stat_name);
// Adds stack locals and closure locals into the locals dict, and returns it. // Adds stack locals and closure locals into the locals dict, and returns it.
Box* fastLocalsToBoxedLocals(); BORROWED(Box*) fastLocalsToBoxedLocals();
class PythonFrameIteratorImpl; class PythonFrameIteratorImpl;
class PythonFrameIterator { class PythonFrameIterator {
...@@ -79,7 +79,7 @@ public: ...@@ -79,7 +79,7 @@ public:
FrameInfo* getFrameInfo(); FrameInfo* getFrameInfo();
bool exists() { return impl.get() != NULL; } bool exists() { return impl.get() != NULL; }
AST_stmt* getCurrentStatement(); AST_stmt* getCurrentStatement();
Box* getGlobalsDict(); BORROWED(Box*) getGlobalsDict();
PythonFrameIterator(PythonFrameIterator&& rhs); PythonFrameIterator(PythonFrameIterator&& rhs);
void operator=(PythonFrameIterator&& rhs); void operator=(PythonFrameIterator&& rhs);
......
...@@ -722,8 +722,7 @@ public: ...@@ -722,8 +722,7 @@ public:
void delattr(BoxedString* attr, DelattrRewriteArgs* rewrite_args); void delattr(BoxedString* attr, DelattrRewriteArgs* rewrite_args);
// Only valid for hc-backed instances: // Only valid for hc-backed instances:
// Maybe this should return a borrowed reference? BORROWED(Box*) getAttrWrapper();
Box* getAttrWrapper();
Box* reprIC(); Box* reprIC();
BoxedString* reprICAsString(); BoxedString* reprICAsString();
...@@ -982,7 +981,7 @@ struct FrameInfo { ...@@ -982,7 +981,7 @@ struct FrameInfo {
FrameInfo* back; FrameInfo* back;
FunctionMetadata* md; FunctionMetadata* md;
Box* updateBoxedLocals(); BORROWED(Box*) updateBoxedLocals();
FrameInfo(ExcInfo exc) FrameInfo(ExcInfo exc)
: exc(exc), : exc(exc),
......
...@@ -83,7 +83,7 @@ extern "C" Box* dir(Box* obj) { ...@@ -83,7 +83,7 @@ extern "C" Box* dir(Box* obj) {
extern "C" Box* vars(Box* obj) { extern "C" Box* vars(Box* obj) {
if (!obj) if (!obj)
return fastLocalsToBoxedLocals(); return incref(PyEval_GetLocals());
static BoxedString* dict_str = getStaticString("__dict__"); static BoxedString* dict_str = getStaticString("__dict__");
Box* rtn = getattrInternal<ExceptionStyle::CAPI>(obj, dict_str); Box* rtn = getattrInternal<ExceptionStyle::CAPI>(obj, dict_str);
...@@ -1251,7 +1251,7 @@ public: ...@@ -1251,7 +1251,7 @@ public:
static Box* __reduce__(Box* self) { static Box* __reduce__(Box* self) {
RELEASE_ASSERT(isSubclass(self->cls, BaseException), ""); RELEASE_ASSERT(isSubclass(self->cls, BaseException), "");
BoxedException* exc = static_cast<BoxedException*>(self); BoxedException* exc = static_cast<BoxedException*>(self);
return BoxedTuple::create({ self->cls, EmptyTuple, autoDecref(self->getAttrWrapper()) }); return BoxedTuple::create({ self->cls, EmptyTuple, self->getAttrWrapper() });
} }
}; };
...@@ -1388,19 +1388,17 @@ public: ...@@ -1388,19 +1388,17 @@ public:
} }
}; };
Box* globals() { static Box* globals() {
// TODO is it ok that we don't return a real dict here? return incref(getGlobalsDict());
return getGlobalsDict();
} }
Box* locals() { static Box* locals() {
return fastLocalsToBoxedLocals(); return incref(fastLocalsToBoxedLocals());
} }
extern "C" BORROWED(PyObject*) PyEval_GetLocals(void) noexcept { extern "C" BORROWED(PyObject*) PyEval_GetLocals(void) noexcept {
try { try {
assert(0 && "check refcounting"); return fastLocalsToBoxedLocals();
return locals();
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
return NULL; return NULL;
...@@ -1409,7 +1407,7 @@ extern "C" BORROWED(PyObject*) PyEval_GetLocals(void) noexcept { ...@@ -1409,7 +1407,7 @@ extern "C" BORROWED(PyObject*) PyEval_GetLocals(void) noexcept {
extern "C" BORROWED(PyObject*) PyEval_GetGlobals(void) noexcept { extern "C" BORROWED(PyObject*) PyEval_GetGlobals(void) noexcept {
try { try {
return autoXDecref(globals()); return getGlobalsDict();
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
return NULL; return NULL;
...@@ -1681,7 +1679,7 @@ Box* input(Box* prompt) { ...@@ -1681,7 +1679,7 @@ Box* input(Box* prompt) {
str++; str++;
Box* gbls = globals(); Box* gbls = globals();
Box* lcls = locals(); Box* lcls = PyEval_GetLocals();
// CPython has these safety checks that the builtin functions exist // CPython has these safety checks that the builtin functions exist
// in the current global scope. // in the current global scope.
......
...@@ -223,7 +223,7 @@ static Box* classobjGetattribute(Box* _cls, Box* _attr) { ...@@ -223,7 +223,7 @@ static Box* classobjGetattribute(Box* _cls, Box* _attr) {
// These are special cases in CPython as well: // These are special cases in CPython as well:
if (attr->data()[0] == '_' && attr->data()[1] == '_') { if (attr->data()[0] == '_' && attr->data()[1] == '_') {
if (attr->s() == "__dict__") if (attr->s() == "__dict__")
return cls->getAttrWrapper(); return incref(cls->getAttrWrapper());
if (attr->s() == "__bases__") if (attr->s() == "__bases__")
return incref(cls->bases); return incref(cls->bases);
...@@ -461,7 +461,7 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_ ...@@ -461,7 +461,7 @@ static Box* _instanceGetattribute(Box* _inst, BoxedString* attr_str, bool raise_
// These are special cases in CPython as well: // These are special cases in CPython as well:
if (attr_str->data()[0] == '_' && attr_str->data()[1] == '_') { if (attr_str->data()[0] == '_' && attr_str->data()[1] == '_') {
if (attr_str->s() == "__dict__") if (attr_str->s() == "__dict__")
return inst->getAttrWrapper(); return incref(inst->getAttrWrapper());
if (attr_str->s() == "__class__") if (attr_str->s() == "__class__")
return incref(inst->inst_cls); return incref(inst->inst_cls);
......
...@@ -94,7 +94,7 @@ public: ...@@ -94,7 +94,7 @@ public:
if (f->hasExited()) if (f->hasExited())
return incref(f->_locals); return incref(f->_locals);
return f->frame_info->updateBoxedLocals(); return incref(f->frame_info->updateBoxedLocals());
} }
static Box* globals(Box* obj, void*) { static Box* globals(Box* obj, void*) {
...@@ -103,7 +103,7 @@ public: ...@@ -103,7 +103,7 @@ public:
if (!f->_globals) { if (!f->_globals) {
Box* globals = f->frame_info->globals; Box* globals = f->frame_info->globals;
if (globals && PyModule_Check(globals)) if (globals && PyModule_Check(globals))
f->_globals = globals->getAttrWrapper(); f->_globals = incref(globals->getAttrWrapper());
else { else {
f->_globals = incref(globals); f->_globals = incref(globals);
} }
......
...@@ -768,7 +768,7 @@ BoxedClass* BoxedClass::create(BoxedClass* metaclass, BoxedClass* base, int attr ...@@ -768,7 +768,7 @@ BoxedClass* BoxedClass::create(BoxedClass* metaclass, BoxedClass* base, int attr
void BoxedClass::finishInitialization() { void BoxedClass::finishInitialization() {
assert(!this->tp_dict); assert(!this->tp_dict);
this->tp_dict = this->getAttrWrapper(); this->tp_dict = incref(this->getAttrWrapper());
commonClassSetup(this); commonClassSetup(this);
tp_flags |= Py_TPFLAGS_READY; tp_flags |= Py_TPFLAGS_READY;
......
...@@ -1333,13 +1333,13 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) { ...@@ -1333,13 +1333,13 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
static Box* typeDict(Box* obj, void* context) { static Box* typeDict(Box* obj, void* context) {
if (obj->cls->instancesHaveHCAttrs()) if (obj->cls->instancesHaveHCAttrs())
return PyDictProxy_New(autoDecref(obj->getAttrWrapper())); return PyDictProxy_New(obj->getAttrWrapper());
abort(); abort();
} }
static Box* typeSubDict(Box* obj, void* context) { static Box* typeSubDict(Box* obj, void* context) {
if (obj->cls->instancesHaveHCAttrs()) if (obj->cls->instancesHaveHCAttrs())
return obj->getAttrWrapper(); return incref(obj->getAttrWrapper());
if (obj->cls->instancesHaveDictAttrs()) if (obj->cls->instancesHaveDictAttrs())
return obj->getDict(); return obj->getDict();
abort(); abort();
...@@ -2739,7 +2739,7 @@ void Box::giveAttrDescriptor(const char* attr, Box* (*get)(Box*, void*), void (* ...@@ -2739,7 +2739,7 @@ void Box::giveAttrDescriptor(const char* attr, Box* (*get)(Box*, void*), void (*
giveAttr(bstr, new (pyston_getset_cls) BoxedGetsetDescriptor(bstr, get, set, NULL)); giveAttr(bstr, new (pyston_getset_cls) BoxedGetsetDescriptor(bstr, get, set, NULL));
} }
Box* Box::getAttrWrapper() { BORROWED(Box*) Box::getAttrWrapper() {
assert(cls->instancesHaveHCAttrs()); assert(cls->instancesHaveHCAttrs());
HCAttrs* attrs = getHCAttrsPtr(); HCAttrs* attrs = getHCAttrsPtr();
HiddenClass* hcls = attrs->hcls; HiddenClass* hcls = attrs->hcls;
...@@ -2748,7 +2748,7 @@ Box* Box::getAttrWrapper() { ...@@ -2748,7 +2748,7 @@ Box* Box::getAttrWrapper() {
hcls = root_hcls; hcls = root_hcls;
if (hcls->type == HiddenClass::DICT_BACKED) { if (hcls->type == HiddenClass::DICT_BACKED) {
return incref(attrs->attr_list->attrs[0]); return attrs->attr_list->attrs[0];
} }
int offset = hcls->getAttrwrapperOffset(); int offset = hcls->getAttrwrapperOffset();
...@@ -2758,15 +2758,17 @@ Box* Box::getAttrWrapper() { ...@@ -2758,15 +2758,17 @@ Box* Box::getAttrWrapper() {
auto new_hcls = hcls->getAttrwrapperChild(); auto new_hcls = hcls->getAttrwrapperChild();
appendNewHCAttr(aw, NULL); appendNewHCAttr(aw, NULL);
attrs->hcls = new_hcls; attrs->hcls = new_hcls;
Py_DECREF(aw);
return aw; return aw;
} else { } else {
assert(hcls->type == HiddenClass::SINGLETON); assert(hcls->type == HiddenClass::SINGLETON);
appendNewHCAttr(aw, NULL); appendNewHCAttr(aw, NULL);
hcls->appendAttrwrapper(); hcls->appendAttrwrapper();
Py_DECREF(aw);
return aw; return aw;
} }
} }
return incref(attrs->attr_list->attrs[offset]); return attrs->attr_list->attrs[offset];
} }
extern "C" PyObject* PyObject_GetAttrWrapper(PyObject* obj) noexcept { extern "C" PyObject* PyObject_GetAttrWrapper(PyObject* obj) noexcept {
......
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