Commit e78dc8d7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Tried to audit all of runtime/ and capi/

parent 154a71e8
......@@ -12,8 +12,8 @@ PyAPI_FUNC(long) PyImport_GetMagicNumber(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(const char *name, PyObject *co) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
const char *name, PyObject *co, char *pathname) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyImport_GetModuleDict(void) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyImport_AddModule(const char *name) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(const char *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(const char *name,
......
......@@ -29,7 +29,7 @@ typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *,
typedef PyObject *(*PyNoArgsFunction)(PyObject *);
PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) PyCFunction_GetSelf(PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *) PYSTON_NOEXCEPT;
// Pyston change: changed to function calls
......
......@@ -515,7 +515,7 @@ PyAPI_FUNC(int) PyType_Ready(PyTypeObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
PyObject *, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *) PYSTON_NOEXCEPT;
PyAPI_FUNC(BORROWED(PyObject *)) _PyType_Lookup(PyTypeObject *, PyObject *) PYSTON_NOEXCEPT;
// Pyston change: modified this to take a const char*
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, const char *, PyObject **) PYSTON_NOEXCEPT;
PyAPI_FUNC(unsigned int) PyType_ClearCache(void) PYSTON_NOEXCEPT;
......
......@@ -82,7 +82,7 @@ calliter_iternext(calliterobject *it)
// Pyston change: for __hasnext__ based iteration, return the cached next value
if (it->it_nextvalue != NULL) {
PyObject* rv = it->it_nextvalue;
Py_CLEAR(it->it_nextvalue);
it->it_nextvalue = NULL;
return rv;
}
......
......@@ -61,10 +61,10 @@ BoxedString* mangleNameBoxedString(BoxedString* id, BoxedString* private_name) {
assert(private_name);
int len = id->size();
if (len < 2 || id->s()[0] != '_' || id->s()[1] != '_')
return id;
return incref(id);
if ((id->s()[len - 2] == '_' && id->s()[len - 1] == '_') || id->s().find('.') != llvm::StringRef::npos)
return id;
return incref(id);
const char* p = private_name->data();
while (*p == '_') {
......@@ -72,7 +72,7 @@ BoxedString* mangleNameBoxedString(BoxedString* id, BoxedString* private_name) {
len--;
}
if (*p == '\0')
return id;
return incref(id);
return static_cast<BoxedString*>(boxStringTwine("_" + (p + id->s())));
}
......
......@@ -1717,6 +1717,7 @@ void Rewriter::_allocateAndCopy(RewriterVar* result, RewriterVar* array_ptr, int
}
RewriterVar* Rewriter::allocateAndCopyPlus1(RewriterVar* first_elem, RewriterVar* rest_ptr, int n_rest) {
assert(0 && "check refcounting");
STAT_TIMER(t0, "us_timer_rewriter", 10);
if (n_rest > 0)
......
......@@ -57,7 +57,7 @@ extern "C" int PyObject_Cmp(PyObject* o1, PyObject* o2, int* result) noexcept {
extern "C" PyObject* PyObject_Type(PyObject* o) noexcept {
if (o == NULL)
return null_error();
return o->cls;
return incref(o->cls);
}
extern "C" Py_ssize_t _PyObject_LengthHint(PyObject* o, Py_ssize_t defaultvalue) noexcept {
......@@ -747,6 +747,7 @@ extern "C" Py_ssize_t PyObject_Size(PyObject* o) noexcept {
BoxedInt* r = lenInternal<ExceptionStyle::CAPI, NOT_REWRITABLE>(o, NULL);
if (!r)
return -1;
AUTO_DECREF(r);
return r->n;
}
......
......@@ -455,7 +455,7 @@ extern "C" BORROWED(PyObject*) PyModule_GetDict(PyObject* _m) noexcept {
return autoDecref(m->getAttrWrapper());
}
extern "C" int PyModule_AddObject(PyObject* _m, const char* name, PyObject* value) noexcept {
extern "C" int PyModule_AddObject(PyObject* _m, const char* name, STOLEN(PyObject*) value) noexcept {
BoxedModule* m = static_cast<BoxedModule*>(_m);
assert(m->cls == module_cls);
......
......@@ -873,6 +873,7 @@ static PyObject* call_attribute(PyObject* self, PyObject* attr, PyObject* name)
template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs* rewrite_args, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
assert(0 && "check refcounting");
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......@@ -1108,6 +1109,7 @@ template Box* slotTpGetattrHookInternal<CXX, NOT_REWRITABLE>(Box* self, BoxedStr
Box* new_attr = typeLookup(self, _new_str);
assert(new_attr);
new_attr = processDescriptor(new_attr, None, self);
AUTO_DECREF(new_attr);
return runtimeCall(new_attr, ArgPassSpec(1, 0, true, true), self, args, kwds, NULL, NULL);
} catch (ExcInfo e) {
......@@ -3338,6 +3340,7 @@ template <ExceptionStyle S>
static Box* tppProxyToTpCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args,
const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
assert(0 && "check refcounting");
ParamReceiveSpec paramspec(0, 0, true, true);
if (!argspec.has_kwargs && argspec.num_keywords == 0) {
paramspec.takes_kwargs = false;
......
......@@ -56,7 +56,7 @@ public:
const char* s = static_cast<BoxedCApiFunction*>(b)->method_def->ml_name;
if (s)
return boxString(s);
return None;
return incref(None);
}
static Box* doc(Box* b, void*) {
......@@ -64,7 +64,7 @@ public:
const char* s = static_cast<BoxedCApiFunction*>(b)->method_def->ml_doc;
if (s)
return boxString(s);
return None;
return incref(None);
}
static void dealloc(Box* _o) noexcept {
......
......@@ -64,7 +64,7 @@ FunctionMetadata::FunctionMetadata(int num_args, bool takes_varargs, bool takes_
internal_callable(NULL, NULL) {
}
BoxedCode* FunctionMetadata::getCode() {
BORROWED(BoxedCode*) FunctionMetadata::getCode() {
if (!code_obj) {
code_obj = new BoxedCode(this);
// FunctionMetadatas don't currently participate in GC. They actually never get freed currently.
......
......@@ -605,7 +605,7 @@ inline BoxedString* internStringMortal(llvm::StringRef s) {
// TODO this is an immortal intern for now
// Ref usage: this transfers a ref from the passed-in string to the new one.
// Typical usage:
// Py_INCREF(s);
// Py_INCREF(s); // or otherwise make sure it was owned
// internStringMortalInplace(s);
// AUTO_DECREF(s);
inline void internStringMortalInplace(BoxedString*& s) noexcept {
......@@ -896,7 +896,7 @@ class BoxedClass;
// TODO these shouldn't be here
void setupRuntime();
Box* createAndRunModule(BoxedString* name, const std::string& fn);
BoxedModule* createModule(BoxedString* name, const char* fn = NULL, const char* doc = NULL) noexcept;
BORROWED(BoxedModule*) createModule(BoxedString* name, const char* fn = NULL, const char* doc = NULL) noexcept;
Box* moduleInit(BoxedModule* self, Box* name, Box* doc = NULL);
// TODO where to put this
......
......@@ -224,7 +224,9 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr) noexcept {
}
BoxedString* s = static_cast<BoxedString*>(attr);
Py_INCREF(s);
internStringMortalInplace(s);
AUTO_DECREF(s);
Box* r = getattrInternal<ExceptionStyle::CAPI>(o, s);
......@@ -239,7 +241,9 @@ extern "C" PyObject* PyObject_GetAttr(PyObject* o, PyObject* attr) noexcept {
extern "C" PyObject* PyObject_GenericGetAttr(PyObject* o, PyObject* name) noexcept {
try {
BoxedString* s = static_cast<BoxedString*>(name);
Py_INCREF(s);
internStringMortalInplace(s);
AUTO_DECREF(s);
Box* r = getattrInternalGeneric<false, NOT_REWRITABLE>(o, s, NULL, false, false, NULL, NULL);
if (!r)
PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name,
......@@ -680,7 +684,7 @@ extern "C" int Py_FlushLine(void) noexcept {
return PyFile_WriteString("\n", f);
}
void setCAPIException(const ExcInfo& e) {
void setCAPIException(STOLEN(const ExcInfo&) e) {
PyErr_Restore(e.type, e.value, e.traceback);
}
......@@ -745,6 +749,7 @@ extern "C" void Py_Exit(int sts) noexcept {
}
extern "C" void PyErr_GetExcInfo(PyObject** ptype, PyObject** pvalue, PyObject** ptraceback) noexcept {
assert(0 && "check refcounting");
ExcInfo* exc = getFrameExcInfo();
*ptype = exc->type;
*pvalue = exc->value;
......@@ -752,6 +757,7 @@ extern "C" void PyErr_GetExcInfo(PyObject** ptype, PyObject** pvalue, PyObject**
}
extern "C" void PyErr_SetExcInfo(PyObject* type, PyObject* value, PyObject* traceback) noexcept {
assert(0 && "check refcounting");
ExcInfo* exc = getFrameExcInfo();
exc->type = type ? type : None;
exc->value = value ? value : None;
......@@ -1579,7 +1585,7 @@ extern "C" PyCFunction PyCFunction_GetFunction(PyObject* op) noexcept {
return static_cast<BoxedCApiFunction*>(op)->getFunction();
}
extern "C" PyObject* PyCFunction_GetSelf(PyObject* op) noexcept {
extern "C" PyObject* PyCFunction_GetSelf(BORROWED(PyObject*) op) noexcept {
if (!PyCFunction_Check(op)) {
PyErr_BadInternalCall();
return NULL;
......@@ -1712,6 +1718,7 @@ template <ExceptionStyle S>
Box* BoxedCApiFunction::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) {
assert(0 && "check refcounting");
if (S == CAPI) {
try {
return tppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
......
......@@ -510,6 +510,7 @@ template Box* instanceGetattroInternal<CAPI>(Box*, Box*, GetattrRewriteArgs*) no
template Box* instanceGetattroInternal<CXX>(Box*, Box*, GetattrRewriteArgs*);
void instanceSetattroInternal(Box* _inst, Box* _attr, STOLEN(Box*) value, SetattrRewriteArgs* rewrite_args) {
assert(0 && "check refcounting");
STAT_TIMER(t0, "us_timer_instance_setattro", 0);
RELEASE_ASSERT(_inst->cls == instance_cls, "");
......
......@@ -190,7 +190,8 @@ static Box* propertyDeleter(Box* self, Box* obj) {
static Box* staticmethodInit(Box* _self, Box* f) {
RELEASE_ASSERT(isSubclass(_self->cls, staticmethod_cls), "");
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
self->sm_callable = f;
Py_CLEAR(self->sm_callable);
self->sm_callable = incref(f);
return incref(None);
}
......@@ -246,6 +247,7 @@ template <ExceptionStyle S>
Box* BoxedMethodDescriptor::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) {
assert(0 && "check refcounting");
if (S == CAPI) {
try {
return tppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
......@@ -577,6 +579,7 @@ Box* BoxedWrapperDescriptor::__call__(BoxedWrapperDescriptor* descr, PyObject* s
getFullNameOfClass(descr->type).c_str(), getFullTypeName(self).c_str());
auto wrapper = new BoxedWrapperObject(descr, self);
AUTO_DECREF(wrapper);
return BoxedWrapperObject::__call__(wrapper, args, kw);
}
......@@ -584,6 +587,7 @@ 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) {
assert(0 && "Check refcounting");
if (S == CAPI) {
try {
return tppCall<CXX>(_self, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
......@@ -735,6 +739,7 @@ static Box* wrapperObjectRepr(Box* _o) {
}
Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds) {
assert(0 && "check refcounting");
STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (self->cls->is_user_defined ? 10 : 20));
assert(self->cls == wrapperobject_cls);
......@@ -775,6 +780,7 @@ template <ExceptionStyle S>
Box* BoxedWrapperObject::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) {
assert(0 && "check refcounting");
STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (_self->cls->is_user_defined ? 10 : 20));
assert(_self->cls == wrapperobject_cls);
......
......@@ -266,7 +266,7 @@ template <enum ExceptionStyle S> Box* dictGetitem(BoxedDict* self, Box* k) noexc
}
if (S == CAPI) {
PyErr_SetObject(KeyError, BoxedTuple::create1(k));
PyErr_SetObject(KeyError, autoDecref(BoxedTuple::create1(k)));
return NULL;
} else
raiseExcHelper(KeyError, k);
......@@ -456,7 +456,27 @@ static int dict_ass_sub(PyDictObject* mp, PyObject* v, PyObject* w) noexcept {
}
extern "C" int PyDict_DelItem(PyObject* op, PyObject* key) noexcept {
ASSERT(PyDict_Check(op) || op->cls == attrwrapper_cls, "%s", getTypeName(op));
if (PyDict_Check(op)) {
assert(0 && "untested");
try {
auto it = self->d.find(k);
} catch (ExcInfo e) {
setCAPIException(e);
return -1;
}
if (it == self->d.end())
PyErr_SetObject(KeyError, autoDecref(BoxedTuple::create1(key)));
return -1;
}
Box* v = it->second;
self->d.erase(it);
Py_DECREF(v);
return 0;
}
ASSERT(op->cls == attrwrapper_cls, "%s", getTypeName(op));
try {
delitem(op, key);
return 0;
......
......@@ -42,11 +42,12 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringR
Py_INCREF(Py_None);
loc = Py_None;
}
AUTO_DECREF(loc);
auto args = BoxedTuple::create({ autoDecref(boxString(file)), autoDecref(boxInt(lineno)), None, loc });
Box* exc = runtimeCall(SyntaxError, ArgPassSpec(2), autoDecref(boxString(msg)), args, NULL, NULL, NULL);
assert(!PyErr_Occurred());
throw ExcInfo(exc->cls, exc, None);
throw ExcInfo(incref(exc->cls), exc, incref(None));
} else {
PyErr_SetString(SyntaxError, msg);
PyErr_SyntaxLocation(file.str().c_str(), lineno);
......@@ -161,6 +162,7 @@ ExcInfo excInfoForRaise(STOLEN(Box*) type, STOLEN(Box*) value, STOLEN(Box*) tb)
}
extern "C" void raise0(ExcInfo* frame_exc_info) {
assert(0 && "check refcounting");
updateFrameExcInfoIfNeeded(frame_exc_info);
assert(frame_exc_info->type);
......@@ -174,6 +176,7 @@ extern "C" void raise0(ExcInfo* frame_exc_info) {
}
extern "C" void raise0_capi(ExcInfo* frame_exc_info) noexcept {
assert(0 && "check refcounting");
updateFrameExcInfoIfNeeded(frame_exc_info);
assert(frame_exc_info->type);
......@@ -192,6 +195,7 @@ extern "C" void raise0_capi(ExcInfo* frame_exc_info) noexcept {
}
extern "C" void raise3(STOLEN(Box*) arg0, STOLEN(Box*) arg1, STOLEN(Box*) arg2) {
assert(0 && "Check refcounting");
bool reraise = arg2 != NULL && arg2 != None;
auto exc_info = excInfoForRaise(arg0, arg1, arg2);
......@@ -203,6 +207,7 @@ extern "C" void raise3(STOLEN(Box*) arg0, STOLEN(Box*) arg1, STOLEN(Box*) arg2)
}
extern "C" void raise3_capi(STOLEN(Box*) arg0, STOLEN(Box*) arg1, STOLEN(Box*) arg2) noexcept {
assert(0 && "Check refcounting");
bool reraise = arg2 != NULL && arg2 != None;
ExcInfo exc_info(NULL, NULL, NULL);
......@@ -297,11 +302,6 @@ void caughtCxxException(ExcInfo* exc_info) {
struct ExcState {
bool is_reraise;
constexpr ExcState() : is_reraise(false) {}
} static __thread exc_state;
bool exceptionAtLineCheck() {
if (exc_state.is_reraise) {
exc_state.is_reraise = false;
......
......@@ -201,6 +201,7 @@ Box* getFrame(int depth) {
void frameInvalidateBack(BoxedFrame* frame) {
RELEASE_ASSERT(!frame->hasExited(), "should not happen");
assert(!frame->_back && "have to decref it");
frame->_back = NULL;
}
......@@ -226,14 +227,19 @@ extern "C" void deinitFrame(FrameInfo* frame_info) {
}
extern "C" void setFrameExcInfo(FrameInfo* frame_info, STOLEN(Box*) type, STOLEN(Box*) value, STOLEN(Box*) tb) {
if (frame_info->exc.type) {
Py_DECREF(frame_info->exc.type);
Py_DECREF(frame_info->exc.value);
Py_DECREF(frame_info->exc.traceback);
}
Box* old_type = frame_info->exc.type;
Box* old_value = frame_info->exc.type;
Box* old_traceback = frame_info->exc.type;
frame_info->exc.type = type;
frame_info->exc.value = value;
frame_info->exc.traceback = tb;
if (old_type) {
Py_DECREF(old_type);
Py_DECREF(old_value);
Py_DECREF(old_traceback);
}
}
extern "C" int PyFrame_GetLineNumber(PyFrameObject* _f) noexcept {
......
......@@ -121,7 +121,7 @@ void generatorEntry(BoxedGenerator* g) {
}
Box* generatorIter(Box* s) {
return s;
return incref(s);
}
// called from both generatorHasNext and generatorSend/generatorNext (but only if generatorHasNext hasn't been called)
......@@ -203,6 +203,7 @@ template <ExceptionStyle S> static bool generatorSendInternal(BoxedGenerator* se
// Reset the current exception.
// We could directly create the StopIteration exception but we delay creating it because often the caller is not
// interested in the exception (=generatorHasnext). If we really need it we will create it inside generatorSend.
assert(!self->exception.type && "need to decref existing exception");
self->exception = ExcInfo(NULL, NULL, NULL);
return false;
}
......@@ -269,7 +270,7 @@ Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** a
if (!exc_tb)
exc_tb = None;
ExcInfo exc_info = excInfoForRaise(exc_cls, exc_val, exc_tb);
ExcInfo exc_info = excInfoForRaise(incref(exc_cls), incref(exc_val), incref(exc_tb));
if (self->entryExited)
throw exc_info;
......@@ -283,14 +284,14 @@ Box* generatorClose(Box* s) {
// check if the generator already exited
if (self->entryExited)
return None;
return incref(None);
try {
generatorThrow(self, GeneratorExit, nullptr, nullptr);
autoDecref(generatorThrow(self, GeneratorExit, nullptr, nullptr));
raiseExcHelper(RuntimeError, "generator ignored GeneratorExit");
} catch (ExcInfo e) {
if (e.matches(StopIteration) || e.matches(GeneratorExit))
return None;
return incref(None);
throw e;
}
assert(0); // unreachable
......@@ -475,7 +476,7 @@ Box* generatorName(Box* _self, void* context) {
assert(isSubclass(_self->cls, generator_cls));
BoxedGenerator* self = static_cast<BoxedGenerator*>(_self);
return self->function->md->source->getName();
return incref(self->function->md->source->getName());
}
extern "C" int PyGen_NeedsFinalizing(PyGenObject* gen) noexcept {
......
......@@ -34,10 +34,10 @@ namespace pyston {
static void removeModule(BoxedString* name) {
BoxedDict* d = getSysModulesDict();
d->d.erase(name);
PyDict_DelItem(d, name);
}
extern "C" PyObject* PyImport_GetModuleDict(void) noexcept {
extern "C" BORROWED(PyObject*) PyImport_GetModuleDict(void) noexcept {
try {
return getSysModulesDict();
} catch (ExcInfo e) {
......@@ -48,6 +48,7 @@ extern "C" PyObject* PyImport_GetModuleDict(void) noexcept {
extern "C" PyObject* _PyImport_LoadDynamicModule(char* name, char* pathname, FILE* fp) noexcept {
BoxedString* name_boxed = boxString(name);
AUTO_DECREF(name_boxed);
try {
const char* lastdot = strrchr(name, '.');
const char* shortname;
......@@ -90,6 +91,7 @@ extern "C" PyObject* load_source_module(char* name, char* pathname, FILE* fp) no
extern "C" PyObject* PyImport_ExecCodeModuleEx(const char* name, PyObject* co, char* pathname) noexcept {
BoxedString* s = boxString(name);
AUTO_DECREF(s);
try {
RELEASE_ASSERT(co->cls == str_cls, "");
BoxedString* code = (BoxedString*)co;
......@@ -99,10 +101,10 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(const char* name, PyObject* co, c
return NULL;
static BoxedString* file_str = getStaticString("__file__");
module->setattr(file_str, boxString(pathname), NULL);
module->setattr(file_str, autoDecref(boxString(pathname)), NULL);
AST_Module* ast = parse_string(code->data(), /* future_flags = */ 0);
compileAndRunModule(ast, module);
return module;
return incref(module);
} catch (ExcInfo e) {
removeModule(s);
setCAPIException(e);
......@@ -155,11 +157,11 @@ BoxedModule* importCExtension(BoxedString* full_name, const std::string& last_na
BoxedModule* m = static_cast<BoxedModule*>(_m);
static BoxedString* file_str = getStaticString("__file__");
m->setattr(file_str, boxString(path), NULL);
m->setattr(file_str, autoDecref(boxString(path)), NULL);
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # dynamically loaded from %s\n", full_name->c_str(), path.c_str());
return m;
return incref(m);
}
}
......@@ -37,7 +37,7 @@ BoxedClass* iterwrapper_cls;
Box* seqiterIter(Box* s) {
RELEASE_ASSERT(s->cls == seqiter_cls || s->cls == seqreviter_cls, "");
return s;
return incref(s);
}
static Box* seqiterHasnext_capi(Box* s) noexcept {
......@@ -52,13 +52,14 @@ static Box* seqiterHasnext_capi(Box* s) noexcept {
if (!next) {
if (PyErr_ExceptionMatches(IndexError) || PyErr_ExceptionMatches(StopIteration)) {
PyErr_Clear();
self->b = NULL;
Py_CLEAR(self->b);
Py_RETURN_FALSE;
}
return NULL;
}
self->idx++;
RELEASE_ASSERT(!self->next, "");
self->next = next;
Py_RETURN_TRUE;
}
......@@ -85,12 +86,13 @@ Box* seqreviterHasnext_capi(Box* s) noexcept {
if (!next) {
if (PyErr_ExceptionMatches(IndexError) || PyErr_ExceptionMatches(StopIteration)) {
PyErr_Clear();
self->b = NULL;
Py_CLEAR(self->b);
Py_RETURN_FALSE;
}
return NULL;
}
self->idx--;
RELEASE_ASSERT(!self->next, "");
self->next = next;
Py_RETURN_TRUE;
}
......@@ -114,6 +116,7 @@ Box* seqiter_next(Box* s) noexcept {
hasnext = seqreviterHasnext_capi(s);
else
RELEASE_ASSERT(0, "");
AUTO_DECREF(hasnext);
if (hasnext != True)
return NULL;
}
......@@ -136,6 +139,7 @@ llvm_compat_bool iterwrapperHasnextUnboxed(Box* s) {
BoxedIterWrapper* self = static_cast<BoxedIterWrapper*>(s);
Box* next = PyIter_Next(self->iter);
RELEASE_ASSERT(!self->next, "");
self->next = next;
if (!next) {
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_StopIteration))
......
This diff is collapsed.
......@@ -219,9 +219,6 @@ inline std::tuple<Box*, Box*, Box*, Box**> getTupleFromArgsArray(Box** args, int
// Corresponds to a name lookup with GLOBAL scope. Checks the passed globals object, then the builtins,
// and if not found raises an exception.
extern "C" Box* getGlobal(Box* globals, BoxedString* name);
// Checks for the name just in the passed globals object, and returns NULL if it is not found.
// This includes if the globals object defined a custom __getattr__ method that threw an AttributeError.
Box* getFromGlobals(Box* globals, BoxedString* name);
extern "C" void setGlobal(Box* globals, BoxedString* name, STOLEN(Box*) value);
extern "C" void delGlobal(Box* globals, BoxedString* name);
......
......@@ -1304,7 +1304,7 @@ extern "C" Box* str_str(Box* _self) noexcept {
BoxedString* self = (BoxedString*)_self;
if (self->cls == str_cls)
return self;
return incref(self);
return boxString(self->s());
}
......@@ -2281,8 +2281,8 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'decode' requires a 'str' object but received a '%s'", getTypeName(self));
BORROWED(BoxedString*) encoding_str = (BoxedString*)encoding;
BORROWED(BoxedString*) error_str = (BoxedString*)error;
BoxedString* encoding_str = (BoxedString*)encoding;
BoxedString* error_str = (BoxedString*)error;
if (encoding_str && encoding_str->cls == unicode_cls)
encoding_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(encoding_str, NULL);
......@@ -2567,6 +2567,8 @@ extern "C" void PyString_Concat(register PyObject** pv, register PyObject* w) no
if (*pv == NULL)
return;
AUTO_DECREF(*pv);
if (w == NULL || !PyString_Check(*pv)) {
*pv = NULL;
return;
......
......@@ -196,7 +196,7 @@ static PyObject* superGet(PyObject* _self, PyObject* obj, PyObject* type) noexce
if (obj == NULL || obj == None || self->obj != NULL) {
/* Not binding to an object, or already bound */
return self;
return incref(self);
}
if (self->cls != super_cls) {
/* If self is an instance of a (strict) subclass of super,
......
......@@ -269,6 +269,7 @@ BoxedString* Box::reprICAsString() {
checkAndThrowCAPIException();
}
if (r->cls != str_cls) {
Py_DECREF(r);
raiseExcHelper(TypeError, "__repr__ did not return a string!");
}
return static_cast<BoxedString*>(r);
......@@ -298,7 +299,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md)
assert(0 && "check the refcounting here");
static BoxedString* name_str = getStaticString("__name__");
this->modname = globals_for_name->getattr(name_str);
this->modname = incref(globals_for_name->getattr(name_str));
this->doc = md->source->getDocString();
} else {
this->modname = PyString_InternFromString("__builtin__");
......@@ -462,6 +463,7 @@ BORROWED(BoxedString*) BoxedModule::getStringConstant(llvm::StringRef ast_str, b
// that we would keep the previously-created string alive.
// So, make sure to put it onto the keep_alive list.
if (r && !PyString_CHECK_INTERNED(r)) {
assert(0 && "check refcounting");
keep_alive.push_back(r);
r = NULL;
}
......@@ -567,6 +569,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
template <ExceptionStyle S>
static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
assert(0 && "check refcounting");
int npassed_args = argspec.totalPassed();
// Common CAPI path call this function with *args, **kw.
......@@ -613,6 +616,7 @@ static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec ar
static Box* typeCallInternal(BoxedFunctionBase* f, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1,
Box* arg2, Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
assert(0 && "check refcounting");
if (rewrite_args)
assert(rewrite_args->func_guarded);
......@@ -643,6 +647,7 @@ static PyObject* cpythonTypeCall(BoxedClass* type, PyObject* args, PyObject* kwd
}
static Box* unicodeNewHelper(BoxedClass* type, Box* string, Box* encoding_obj, Box** _args) {
assert(0 && "check refcounting");
Box* errors_obj = _args[0];
assert(isSubclass(type, unicode_cls));
......@@ -712,6 +717,7 @@ static Box* objectNewNoArgs(BoxedClass* cls) noexcept {
template <ExceptionStyle S>
static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* arg3,
Box** args, const std::vector<BoxedString*>* keyword_names) noexcept(S == CAPI) {
assert(0 && "check refcounting");
int npassed_args = argspec.totalPassed();
int npositional = argspec.num_args;
......@@ -1296,6 +1302,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
}
Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
assert(0 && "check refcounting");
assert(vararg->cls == tuple_cls);
bool pass_kwargs = (kwargs && kwargs->d.size());
......@@ -1334,6 +1341,7 @@ static Box* typeSubDict(Box* obj, void* context) {
}
void Box::setDictBacked(STOLEN(Box*) val) {
assert(0 && "check refcounting");
assert(this->cls->instancesHaveHCAttrs());
RELEASE_ASSERT(val->cls == dict_cls || val->cls == attrwrapper_cls, "");
......@@ -1348,6 +1356,7 @@ void Box::setDictBacked(STOLEN(Box*) val) {
}
static void typeSubSetDict(Box* obj, Box* val, void* context) {
assert(0 && "check refcounting");
if (obj->cls->instancesHaveDictAttrs()) {
RELEASE_ASSERT(val->cls == dict_cls, "");
obj->setDict(static_cast<BoxedDict*>(val));
......@@ -1373,6 +1382,7 @@ static void typeSubSetDict(Box* obj, Box* val, void* context) {
}
extern "C" void PyType_SetDict(PyTypeObject* type, PyObject* dict) noexcept {
assert(0 && "check refcounting");
typeSubSetDict(type, dict, NULL);
type->tp_dict = dict;
}
......@@ -1540,6 +1550,7 @@ static void funcSetName(Box* b, Box* v, void*) {
raiseExcHelper(TypeError, "__name__ must be set to a string object");
}
RELEASE_ASSERT(!func->name, "");
func->name = incref(static_cast<BoxedString*>(v));
}
......@@ -1592,11 +1603,11 @@ static Box* functionDefaults(Box* self, void*) {
assert(self->cls == function_cls);
BoxedFunction* func = static_cast<BoxedFunction*>(self);
if (!func->defaults)
return None;
return incref(None);
for (auto e : *func->defaults) {
RELEASE_ASSERT(e, "this function's defaults should not be available");
}
return func->defaults;
return incref(func->defaults);
}
static Box* functionGlobals(Box* self, void*) {
......@@ -1604,7 +1615,7 @@ static Box* functionGlobals(Box* self, void*) {
BoxedFunction* func = static_cast<BoxedFunction*>(self);
if (func->globals) {
assert(!func->md->source || !func->md->source->scoping->areGlobalsFromModule());
return func->globals;
return incref(func->globals);
}
assert(func->md->source);
assert(func->md->source->scoping->areGlobalsFromModule());
......@@ -1632,7 +1643,9 @@ static void functionSetDefaults(Box* b, Box* v, void*) {
BoxedTuple* t = static_cast<BoxedTuple*>(v);
func->defaults = t;
auto old_defaults = func->defaults;
func->defaults = incref(t);
Py_DECREF(old_defaults);
func->dependent_ics.invalidateAll();
}
......@@ -1822,7 +1835,7 @@ Box* sliceIndices(BoxedSlice* self, Box* len) {
if (PySlice_GetIndicesEx((PySliceObject*)self, ilen, &start, &stop, &step, &slicelength) < 0) {
throwCAPIException();
}
return BoxedTuple::create({ boxInt(start), boxInt(stop), boxInt(step) });
return BoxedTuple::create({ autoDecref(boxInt(start)), autoDecref(boxInt(stop)), autoDecref(boxInt(step)) });
}
static int slice_compare(PySliceObject* v, PySliceObject* w) noexcept {
......@@ -2127,9 +2140,12 @@ public:
// or PyModule_GetDict to return real dicts.
class AttrWrapper : public Box {
private:
// TODO: need to merge this with marius's change. this will need to become
// an owned reference.
BORROWED(Box*) b; // The parent object ('b') will keep the attrwrapper alive (forever)
void convertToDictBacked() {
assert(0 && "check refcounting");
HCAttrs* attrs = this->b->getHCAttrsPtr();
if (attrs->hcls->type == HiddenClass::DICT_BACKED)
return;
......@@ -2248,7 +2264,7 @@ public:
Box* r = self->b->getattr(key);
if (!r)
return def;
return incref(def);
return incref(r);
}
......@@ -2369,6 +2385,7 @@ public:
Box* rtn = contains<CAPI>(_self, _key);
if (!rtn)
return -1;
AUTO_DECREF(rtn);
return rtn == True;
}
......@@ -2410,8 +2427,7 @@ public:
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, "");
for (const auto& p : attrs->hcls->getStrAttrOffsets()) {
BoxedTuple* t = BoxedTuple::create({ p.first, attrs->attr_list->attrs[p.second] });
listAppend(rtn, t);
Py_DECREF(t);
listAppendStolen(rtn, t);
}
return rtn;
}
......@@ -2453,6 +2469,7 @@ public:
HCAttrs* attrs = self->b->getHCAttrsPtr();
RELEASE_ASSERT(attrs->hcls->type == HiddenClass::NORMAL || attrs->hcls->type == HiddenClass::SINGLETON, "");
attrs->clear();
AOEU
// Add the existing attrwrapper object (ie self) back as the attrwrapper:
self->b->appendNewHCAttr(self, NULL);
......@@ -3445,14 +3462,18 @@ void HCAttrs::clear() noexcept {
assert(hcls->type == HiddenClass::NORMAL || hcls->type == HiddenClass::SINGLETON);
// TODO: should swap in the new HCAttrs before doing any decrefs.
for (int i = 0; i < hcls->attributeArraySize(); i++) {
Py_DECREF(this->attr_list->attrs[i]);
}
auto old_attr_list = this->attr_list;
auto old_attr_list_size = hcls->attributeArraySize();
if (this->attr_list)
PyMem_FREE(this->attr_list);
new ((void*)this) HCAttrs(root_hcls);
if (old_attr_list) {
for (int i = 0; i < old_attr_list_size; i++) {
Py_DECREF(old_attr_list->attrs[i]);
}
PyMem_FREE(old_attr_list);
}
}
static void tupledealloc(PyTupleObject* op) noexcept {
......@@ -3508,15 +3529,18 @@ void BoxedModule::dealloc(Box* b) noexcept {
int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept {
BoxedModule* m = static_cast<BoxedModule*>(_m);
Py_VISIT_HCATTRS(m->attrs);
assert(!self->keep_alive.size());
return 0;
}
template <typename CM>
void clearContiguousMap(CM& cm) {
for (auto&& p : cm) {
Py_DECREF(cm.getMapped(p.second));
CM tmp;
std::swap(cm, tmp);
for (auto&& p : tmp) {
Py_DECREF(tmp.getMapped(p.second));
}
cm.clear();
}
int BoxedModule::clear(Box* b) noexcept {
......@@ -4401,7 +4425,7 @@ void setupRuntime() {
#endif
}
BoxedModule* createModule(BoxedString* name, const char* fn, const char* doc) noexcept {
BORROWED(BoxedModule*) createModule(BoxedString* name, const char* fn, const char* doc) noexcept {
assert((!fn || strlen(fn)) && "probably wanted to set the fn to <stdin>?");
BoxedDict* d = getSysModulesDict();
......
......@@ -253,9 +253,6 @@ public:
return true;
}
// Checks if this class or one of its parents has a non-default tp_dealloc
bool hasNonDefaultTpDealloc();
void freeze();
typedef size_t SlotOffset;
......
......@@ -143,7 +143,7 @@ extern "C" void dumpEx(void* p, int levels) {
printf("Freed memory\n");
return;
}
if (lowbyte == 0xcb) {
if (lowbyte == 0xfb) {
printf("Forbidden (redzone) memory\n");
return;
}
......@@ -227,6 +227,7 @@ extern "C" void dumpEx(void* p, int levels) {
if (PyLong_Check(b)) {
PyObject* str = longRepr(static_cast<BoxedLong*>(b));
AUTO_DECREF(str);
printf("Long value: %s\n", static_cast<BoxedString*>(str)->c_str());
}
......
class C(object):
def __delattr__(self, attr):
print "__delattr__"
del C.__delattr__
c = C()
del c.a
try:
del c.a
except Exception as e:
print e
class C(object):
def __getattr__(self, attr):
print "__getattr__"
del C.__getattr__
return attr
c = C()
print c.a
try:
print c.a
except Exception as e:
print e
class C(object):
def __setattr__(self, attr, val):
print "__setattr__", attr, val
del C.__setattr__
c = C()
c.a = 1
try:
c.a = 2
except Exception as e:
print e
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