Commit 624173aa authored by Kevin Modzelewski's avatar Kevin Modzelewski

Working towards exception-correct refcounting

parent 60706fc8
...@@ -417,7 +417,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -417,7 +417,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
if (interpreter.jit) if (interpreter.jit)
interpreter.jit->emitSetCurrentInst(s); interpreter.jit->emitSetCurrentInst(s);
if (v.o) { if (v.o) {
Py_XDECREF(v.o); Py_DECREF(v.o);
if (v.var) if (v.var)
v.var->decvref(); v.var->decvref();
} }
...@@ -575,9 +575,9 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) { ...@@ -575,9 +575,9 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) {
Value ASTInterpreter::visit_binop(AST_BinOp* node) { Value ASTInterpreter::visit_binop(AST_BinOp* node) {
Value left = visit_expr(node->left); Value left = visit_expr(node->left);
Value right = visit_expr(node->right); Value right = visit_expr(node->right);
AUTO_DECREF(left.o);
AUTO_DECREF(right.o);
Value r = doBinOp(node, left, right, node->op_type, BinExpType::BinOp); Value r = doBinOp(node, left, right, node->op_type, BinExpType::BinOp);
Py_DECREF(left.o);
Py_DECREF(right.o);
if (jit) { if (jit) {
left.var->decvref(); left.var->decvref();
right.var->decvref(); right.var->decvref();
...@@ -930,7 +930,9 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -930,7 +930,9 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
Box* value = last_exception.value ? last_exception.value : None; Box* value = last_exception.value ? last_exception.value : None;
Box* traceback = last_exception.traceback ? last_exception.traceback : None; Box* traceback = last_exception.traceback ? last_exception.traceback : None;
v = Value(BoxedTuple::create({ type, value, traceback }), jit ? jit->emitLandingpad() : NULL); v = Value(BoxedTuple::create({ type, value, traceback }), jit ? jit->emitLandingpad() : NULL);
last_exception = ExcInfo(NULL, NULL, NULL); Py_CLEAR(last_exception.type);
Py_CLEAR(last_exception.value);
Py_CLEAR(last_exception.traceback);
} else if (node->opcode == AST_LangPrimitive::CHECK_EXC_MATCH) { } else if (node->opcode == AST_LangPrimitive::CHECK_EXC_MATCH) {
assert(node->args.size() == 2); assert(node->args.size() == 2);
Value obj = visit_expr(node->args[0]); Value obj = visit_expr(node->args[0]);
......
...@@ -107,7 +107,7 @@ InternedStringPool& SourceInfo::getInternedStrings() { ...@@ -107,7 +107,7 @@ InternedStringPool& SourceInfo::getInternedStrings() {
return scoping->getInternedStrings(); return scoping->getInternedStrings();
} }
BoxedString* SourceInfo::getName() { BORROWED(BoxedString*) SourceInfo::getName() {
assert(ast); assert(ast);
static BoxedString* lambda_name = getStaticString("<lambda>"); static BoxedString* lambda_name = getStaticString("<lambda>");
...@@ -115,15 +115,15 @@ BoxedString* SourceInfo::getName() { ...@@ -115,15 +115,15 @@ BoxedString* SourceInfo::getName() {
switch (ast->type) { switch (ast->type) {
case AST_TYPE::ClassDef: case AST_TYPE::ClassDef:
return incref(ast_cast<AST_ClassDef>(ast)->name.getBox()); return ast_cast<AST_ClassDef>(ast)->name.getBox();
case AST_TYPE::FunctionDef: case AST_TYPE::FunctionDef:
return incref(ast_cast<AST_FunctionDef>(ast)->name.getBox()); return ast_cast<AST_FunctionDef>(ast)->name.getBox();
case AST_TYPE::Lambda: case AST_TYPE::Lambda:
return incref(lambda_name); return lambda_name;
case AST_TYPE::Module: case AST_TYPE::Module:
case AST_TYPE::Expression: case AST_TYPE::Expression:
case AST_TYPE::Suite: case AST_TYPE::Suite:
return incref(module_name); return module_name;
default: default:
RELEASE_ASSERT(0, "%d", ast->type); RELEASE_ASSERT(0, "%d", ast->type);
} }
......
...@@ -104,7 +104,7 @@ std::string getInplaceOpSymbol(int op_type) { ...@@ -104,7 +104,7 @@ std::string getInplaceOpSymbol(int op_type) {
return std::string(getOpSymbol(op_type)) + '='; return std::string(getOpSymbol(op_type)) + '=';
} }
BoxedString* getOpName(int op_type) { BORROWED(BoxedString*) getOpName(int op_type) {
assert(op_type != AST_TYPE::Is); assert(op_type != AST_TYPE::Is);
assert(op_type != AST_TYPE::IsNot); assert(op_type != AST_TYPE::IsNot);
......
...@@ -394,7 +394,7 @@ public: ...@@ -394,7 +394,7 @@ public:
const std::vector<AST_stmt*> body; const std::vector<AST_stmt*> body;
BoxedString* getName(); BoxedString* getName();
BoxedString* getFn() { return fn; } BORROWED(BoxedString*) getFn() { return fn; }
InternedString mangleName(InternedString id); InternedString mangleName(InternedString id);
......
...@@ -3176,6 +3176,8 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3176,6 +3176,8 @@ 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) {
...@@ -3208,11 +3210,12 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3208,11 +3210,12 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
assert(S == CAPI); assert(S == CAPI);
return NULL; return NULL;
} }
AUTO_DECREF(val);
Box** args = (Box**)extra_args[0]; Box** args = (Box**)extra_args[0];
const std::vector<BoxedString*>* keyword_names = (const std::vector<BoxedString*>*)extra_args[1]; const std::vector<BoxedString*>* keyword_names = (const std::vector<BoxedString*>*)extra_args[1];
Box* rtn Box* rtn
= runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names); = runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
Py_DECREF(val);
return rtn; return rtn;
} }
}; };
...@@ -3243,10 +3246,11 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3243,10 +3246,11 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) }; void* _args[2] = { args, const_cast<std::vector<BoxedString*>*>(keyword_names) };
Box* rtn = Helper::call(val, argspec, arg1, arg2, arg3, _args); Box* rtn = Helper::call(val, argspec, arg1, arg2, arg3, _args);
Py_XDECREF(bind_obj);
return rtn; return rtn;
} }
AUTO_DECREF(val);
Box* r; Box* r;
if (rewrite_args) { if (rewrite_args) {
CallRewriteArgs crewrite_args(rewrite_args); CallRewriteArgs crewrite_args(rewrite_args);
...@@ -3257,8 +3261,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe ...@@ -3257,8 +3261,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
} else { } else {
r = runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names); r = runtimeCallInternal<S, NOT_REWRITABLE>(val, NULL, argspec, arg1, arg2, arg3, args, keyword_names);
} }
Py_XDECREF(bind_obj);
Py_DECREF(val);
if (rewrite_args) { if (rewrite_args) {
if (r_bind_obj) if (r_bind_obj)
r_bind_obj->decvref(); r_bind_obj->decvref();
...@@ -4073,6 +4075,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -4073,6 +4075,11 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
throw e; throw e;
} }
AUTO_XDECREF(arg1);
AUTO_XDECREF(arg2);
AUTO_XDECREF(arg3);
AUTO_XDECREF_ARRAY(args, num_output_args - 3);
if (rewrite_args && !rewrite_success) { if (rewrite_args && !rewrite_success) {
assert(0 && "check refcounting"); assert(0 && "check refcounting");
// These are the cases that we weren't able to rewrite. // These are the cases that we weren't able to rewrite.
...@@ -4162,12 +4169,6 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -4162,12 +4169,6 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
res = callCLFunc<S, rewritable>(md, rewrite_args, num_output_args, closure, NULL, func->globals, arg1, arg2, res = callCLFunc<S, rewritable>(md, rewrite_args, num_output_args, closure, NULL, func->globals, arg1, arg2,
arg3, oargs); arg3, oargs);
} }
Py_XDECREF(arg1);
Py_XDECREF(arg2);
Py_XDECREF(arg3);
for (int i = 0; i < num_output_args - 3; i++) {
Py_XDECREF(oargs[i]);
}
if (rewrite_args) { if (rewrite_args) {
RELEASE_ASSERT(num_output_args <= 3, "figure out vrefs for arg array"); RELEASE_ASSERT(num_output_args <= 3, "figure out vrefs for arg array");
for (int i = 0; i < num_output_args; i++) { for (int i = 0; i < num_output_args; i++) {
......
...@@ -101,11 +101,20 @@ Box* BoxedTraceback::getLines(Box* b) { ...@@ -101,11 +101,20 @@ Box* BoxedTraceback::getLines(Box* b) {
} }
void BoxedTraceback::here(LineInfo lineInfo, Box** tb) { void BoxedTraceback::here(LineInfo lineInfo, Box** tb) {
Box* old_tb = *tb;
*tb = new BoxedTraceback(std::move(lineInfo), *tb); *tb = new BoxedTraceback(std::move(lineInfo), *tb);
Py_DECREF(old_tb);
} }
void BoxedTraceback::dealloc(Box* b) noexcept { void BoxedTraceback::dealloc(Box* b) noexcept {
abort(); BoxedTraceback* self = static_cast<BoxedTraceback*>(b);
Py_DECREF(self->tb_next);
Py_XDECREF(self->py_lines);
Py_DECREF(self->line.file);
Py_DECREF(self->line.func);
PyObject_GC_Del(b);
} }
int BoxedTraceback::traverse(Box* self, visitproc visit, void *arg) noexcept { int BoxedTraceback::traverse(Box* self, visitproc visit, void *arg) noexcept {
......
...@@ -393,6 +393,23 @@ template <typename B, bool Nullable = false> DecrefHandle<B, Nullable> autoDecre ...@@ -393,6 +393,23 @@ template <typename B, bool Nullable = false> DecrefHandle<B, Nullable> autoDecre
template <typename B> DecrefHandle<B, true> autoXDecref(B* b) { template <typename B> DecrefHandle<B, true> autoXDecref(B* b) {
return DecrefHandle<B, true>(b); return DecrefHandle<B, true>(b);
} }
#define AUTO_DECREF(x) DecrefHandle<Box, false> CAT(_autodecref_, __LINE__)((x))
#define AUTO_XDECREF(x) DecrefHandle<Box, true> CAT(_autodecref_, __LINE__)((x))
class AutoXDecrefArray {
private:
Box** array;
int size;
public:
AutoXDecrefArray(Box** array, int size) : array(array), size(size) {}
~AutoXDecrefArray() {
for (int i = 0; i < size; i++) {
Py_XDECREF(array[i]);
}
}
};
#define AUTO_XDECREF_ARRAY(x, size) AutoXDecrefArray CAT(_autodecref_, __LINE__)((x), (size))
template <typename B> B* incref(B* b) { template <typename B> B* incref(B* b) {
Py_INCREF(b); Py_INCREF(b);
......
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