Commit 51b685f5 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Basic refcounting in the interpreter

parent e3dcb351
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
namespace pyston { namespace pyston {
static int calculateNumVRegs(FunctionMetadata* md);
namespace { namespace {
class ASTInterpreter; class ASTInterpreter;
...@@ -76,8 +78,8 @@ public: ...@@ -76,8 +78,8 @@ public:
private: private:
Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body); Value createFunction(AST* node, AST_arguments* args, const std::vector<AST_stmt*>& body);
Value doBinOp(AST_expr* node, Value left, Value right, int op, BinExpType exp_type); Value doBinOp(AST_expr* node, Value left, Value right, int op, BinExpType exp_type);
void doStore(AST_expr* node, Value value); void doStore(AST_expr* node, STOLEN(Value) value);
void doStore(AST_Name* name, Value value); void doStore(AST_Name* name, STOLEN(Value) value);
Box* doOSR(AST_Jump* node); Box* doOSR(AST_Jump* node);
Value getNone(); Value getNone();
...@@ -157,6 +159,18 @@ private: ...@@ -157,6 +159,18 @@ private:
bool should_jit; bool should_jit;
public: public:
~ASTInterpreter() {
Py_XDECREF(frame_info.boxedLocals);
int nvregs = calculateNumVRegs(md);
for (int i = 0; i < nvregs; i++) {
Py_XDECREF(vregs[i]);
}
Py_DECREF(this->globals);
}
llvm::DenseMap<InternedString, int>& getSymVRegMap() { llvm::DenseMap<InternedString, int>& getSymVRegMap() {
assert(source_info->cfg); assert(source_info->cfg);
return source_info->cfg->sym_vreg_map; return source_info->cfg->sym_vreg_map;
...@@ -224,6 +238,7 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) { ...@@ -224,6 +238,7 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
void ASTInterpreter::setGlobals(Box* globals) { void ASTInterpreter::setGlobals(Box* globals) {
this->globals = globals; this->globals = globals;
Py_INCREF(globals);
} }
ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs) ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs)
...@@ -285,6 +300,8 @@ void ASTInterpreter::startJITing(CFGBlock* block, int exit_offset) { ...@@ -285,6 +300,8 @@ void ASTInterpreter::startJITing(CFGBlock* block, int exit_offset) {
assert(ENABLE_BASELINEJIT); assert(ENABLE_BASELINEJIT);
assert(!jit); assert(!jit);
assert(0 && "refcounting not set up");
auto& code_blocks = md->code_blocks; auto& code_blocks = md->code_blocks;
JitCodeBlock* code_block = NULL; JitCodeBlock* code_block = NULL;
if (!code_blocks.empty()) if (!code_blocks.empty())
...@@ -340,7 +357,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) { ...@@ -340,7 +357,7 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
} }
Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at) { Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_block, AST_stmt* start_at) {
Value v; Value v(nullptr, nullptr);
bool from_start = start_block == NULL && start_at == NULL; bool from_start = start_block == NULL && start_at == NULL;
...@@ -366,6 +383,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -366,6 +383,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
} }
interpreter.current_inst = s; interpreter.current_inst = s;
Py_XDECREF(v.o);
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
} }
} else { } else {
...@@ -398,6 +416,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -398,6 +416,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
interpreter.current_inst = s; interpreter.current_inst = s;
if (interpreter.jit) if (interpreter.jit)
interpreter.jit->emitSetCurrentInst(s); interpreter.jit->emitSetCurrentInst(s);
Py_XDECREF(v.o);
v = interpreter.visit_stmt(s); v = interpreter.visit_stmt(s);
} }
} }
...@@ -434,17 +453,19 @@ Value ASTInterpreter::doBinOp(AST_expr* node, Value left, Value right, int op, B ...@@ -434,17 +453,19 @@ Value ASTInterpreter::doBinOp(AST_expr* node, Value left, Value right, int op, B
return Value(); return Value();
} }
void ASTInterpreter::doStore(AST_Name* node, Value value) { void ASTInterpreter::doStore(AST_Name* node, STOLEN(Value) value) {
if (node->lookup_type == ScopeInfo::VarScopeType::UNKNOWN) if (node->lookup_type == ScopeInfo::VarScopeType::UNKNOWN)
node->lookup_type = scope_info->getScopeTypeOfName(node->id); node->lookup_type = scope_info->getScopeTypeOfName(node->id);
InternedString name = node->id; InternedString name = node->id;
ScopeInfo::VarScopeType vst = node->lookup_type; ScopeInfo::VarScopeType vst = node->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) { if (vst == ScopeInfo::VarScopeType::GLOBAL) {
assert(0 && "check refcounting");
if (jit) if (jit)
jit->emitSetGlobal(globals, name.getBox(), value); jit->emitSetGlobal(globals, name.getBox(), value);
setGlobal(globals, name.getBox(), value.o); setGlobal(globals, name.getBox(), value.o);
} else if (vst == ScopeInfo::VarScopeType::NAME) { } else if (vst == ScopeInfo::VarScopeType::NAME) {
assert(0 && "check refcounting");
if (jit) if (jit)
jit->emitSetItemName(name.getBox(), value); jit->emitSetItemName(name.getBox(), value);
assert(frame_info.boxedLocals != NULL); assert(frame_info.boxedLocals != NULL);
...@@ -453,6 +474,7 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) { ...@@ -453,6 +474,7 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) {
} else { } else {
bool closure = vst == ScopeInfo::VarScopeType::CLOSURE; bool closure = vst == ScopeInfo::VarScopeType::CLOSURE;
if (jit) { if (jit) {
assert(0 && "check refcounting");
if (!closure) { if (!closure) {
bool is_live = source_info->getLiveness()->isLiveAtEnd(name, current_block); bool is_live = source_info->getLiveness()->isLiveAtEnd(name, current_block);
if (is_live) if (is_live)
...@@ -465,9 +487,12 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) { ...@@ -465,9 +487,12 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) {
assert(getSymVRegMap().count(name)); assert(getSymVRegMap().count(name));
assert(getSymVRegMap()[name] == node->vreg); assert(getSymVRegMap()[name] == node->vreg);
Box* prev = vregs[node->vreg];
vregs[node->vreg] = value.o; vregs[node->vreg] = value.o;
Py_XDECREF(prev);
if (closure) { if (closure) {
assert(0 && "check refcounting");
created_closure->elts[scope_info->getClosureOffset(name)] = value.o; created_closure->elts[scope_info->getClosureOffset(name)] = value.o;
} }
} }
...@@ -524,7 +549,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) { ...@@ -524,7 +549,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
} }
Value ASTInterpreter::getNone() { Value ASTInterpreter::getNone() {
return Value(None, jit ? jit->imm(None) : NULL); return Value(incref(None), jit ? jit->imm(None) : NULL);
} }
Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) { Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) {
...@@ -538,7 +563,10 @@ Value ASTInterpreter::visit_unaryop(AST_UnaryOp* node) { ...@@ -538,7 +563,10 @@ 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);
return 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);
return r;
} }
Value ASTInterpreter::visit_slice(AST_slice* node) { Value ASTInterpreter::visit_slice(AST_slice* node) {
...@@ -599,6 +627,8 @@ Value ASTInterpreter::visit_branch(AST_Branch* node) { ...@@ -599,6 +627,8 @@ Value ASTInterpreter::visit_branch(AST_Branch* node) {
next_block = node->iftrue; next_block = node->iftrue;
else else
next_block = node->iffalse; next_block = node->iffalse;
// TODO could potentially avoid doing this if we skip the incref in NONZERO
Py_DECREF(v.o);
if (jit) { if (jit) {
jit->emitJump(next_block); jit->emitJump(next_block);
...@@ -812,7 +842,10 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) { ...@@ -812,7 +842,10 @@ Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* 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);
return doBinOp(node, left, right, node->op_type, BinExpType::AugBinOp); Value r = doBinOp(node, left, right, node->op_type, BinExpType::AugBinOp);
Py_DECREF(left.o);
Py_DECREF(right.o);
return r;
} }
Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
...@@ -879,6 +912,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) { ...@@ -879,6 +912,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
assert(node->args.size() == 1); assert(node->args.size() == 1);
Value obj = visit_expr(node->args[0]); Value obj = visit_expr(node->args[0]);
v = Value(boxBool(nonzero(obj.o)), jit ? jit->emitNonzero(obj) : NULL); v = Value(boxBool(nonzero(obj.o)), jit ? jit->emitNonzero(obj) : NULL);
Py_DECREF(obj.o);
} else if (node->opcode == AST_LangPrimitive::SET_EXC_INFO) { } else if (node->opcode == AST_LangPrimitive::SET_EXC_INFO) {
assert(node->args.size() == 3); assert(node->args.size() == 3);
...@@ -1235,8 +1269,7 @@ Value ASTInterpreter::visit_assign(AST_Assign* node) { ...@@ -1235,8 +1269,7 @@ Value ASTInterpreter::visit_assign(AST_Assign* node) {
assert(node->targets.size() == 1 && "cfg should have lowered it to a single target"); assert(node->targets.size() == 1 && "cfg should have lowered it to a single target");
Value v = visit_expr(node->value); Value v = visit_expr(node->value);
for (AST_expr* e : node->targets) doStore(node->targets[0], v);
doStore(e, v);
return Value(); return Value();
} }
...@@ -1249,9 +1282,9 @@ Value ASTInterpreter::visit_print(AST_Print* node) { ...@@ -1249,9 +1282,9 @@ Value ASTInterpreter::visit_print(AST_Print* node) {
jit->emitPrint(dest, var, node->nl); jit->emitPrint(dest, var, node->nl);
if (node->dest) if (node->dest)
printHelper(dest.o, var.o, node->nl); printHelper(autoDecref(dest.o), autoXDecref(var.o), node->nl);
else else
printHelper(getSysStdout(), var.o, node->nl); printHelper(getSysStdout(), autoXDecref(var.o), node->nl);
return Value(); return Value();
} }
...@@ -1273,7 +1306,10 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) { ...@@ -1273,7 +1306,10 @@ Value ASTInterpreter::visit_compare(AST_Compare* node) {
RELEASE_ASSERT(node->comparators.size() == 1, "not implemented"); RELEASE_ASSERT(node->comparators.size() == 1, "not implemented");
Value left = visit_expr(node->left); Value left = visit_expr(node->left);
Value right = visit_expr(node->comparators[0]); Value right = visit_expr(node->comparators[0]);
return doBinOp(node, left, right, node->ops[0], BinExpType::Compare); Value r = doBinOp(node, left, right, node->ops[0], BinExpType::Compare);
Py_DECREF(left.o);
Py_DECREF(right.o);
return r;
} }
Value ASTInterpreter::visit_expr(AST_expr* node) { Value ASTInterpreter::visit_expr(AST_expr* node) {
...@@ -1424,6 +1460,7 @@ Value ASTInterpreter::visit_num(AST_Num* node) { ...@@ -1424,6 +1460,7 @@ Value ASTInterpreter::visit_num(AST_Num* node) {
o = parent_module->getPureImaginaryConstant(node->n_float); o = parent_module->getPureImaginaryConstant(node->n_float);
} else } else
RELEASE_ASSERT(0, "not implemented"); RELEASE_ASSERT(0, "not implemented");
Py_INCREF(o);
return Value(o, jit ? jit->imm(o) : NULL); return Value(o, jit ? jit->imm(o) : NULL);
} }
...@@ -1499,10 +1536,12 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1499,10 +1536,12 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
if (jit) if (jit)
v.var = jit->emitGetGlobal(globals, node->id.getBox()); v.var = jit->emitGetGlobal(globals, node->id.getBox());
assert(0 && "check refcounting");
v.o = getGlobal(globals, node->id.getBox()); v.o = getGlobal(globals, node->id.getBox());
return v; return v;
} }
case ScopeInfo::VarScopeType::DEREF: { case ScopeInfo::VarScopeType::DEREF: {
assert(0 && "check refcounting");
return Value(ASTInterpreterJitInterface::derefHelper(this, node->id), return Value(ASTInterpreterJitInterface::derefHelper(this, node->id),
jit ? jit->emitDeref(node->id) : NULL); jit ? jit->emitDeref(node->id) : NULL);
} }
...@@ -1510,6 +1549,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1510,6 +1549,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
case ScopeInfo::VarScopeType::CLOSURE: { case ScopeInfo::VarScopeType::CLOSURE: {
Value v; Value v;
if (jit) { if (jit) {
assert(0 && "check refcounting");
bool is_live = false; bool is_live = false;
if (node->lookup_type == ScopeInfo::VarScopeType::FAST) if (node->lookup_type == ScopeInfo::VarScopeType::FAST)
is_live = source_info->getLiveness()->isLiveAtEnd(node->id, current_block); is_live = source_info->getLiveness()->isLiveAtEnd(node->id, current_block);
...@@ -1525,6 +1565,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1525,6 +1565,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
assert(getSymVRegMap()[node->id] == node->vreg); assert(getSymVRegMap()[node->id] == node->vreg);
Box* val = vregs[node->vreg]; Box* val = vregs[node->vreg];
if (val) { if (val) {
Py_INCREF(val);
v.o = val; v.o = val;
return v; return v;
} }
...@@ -1533,6 +1574,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) { ...@@ -1533,6 +1574,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
RELEASE_ASSERT(0, "should be unreachable"); RELEASE_ASSERT(0, "should be unreachable");
} }
case ScopeInfo::VarScopeType::NAME: { case ScopeInfo::VarScopeType::NAME: {
assert(0 && "check refcounting");
Value v; Value v;
if (jit) if (jit)
v.var = jit->emitGetBoxedLocal(node->id.getBox()); v.var = jit->emitGetBoxedLocal(node->id.getBox());
...@@ -1566,6 +1608,7 @@ Value ASTInterpreter::visit_list(AST_List* node) { ...@@ -1566,6 +1608,7 @@ Value ASTInterpreter::visit_list(AST_List* node) {
} }
Value ASTInterpreter::visit_tuple(AST_Tuple* node) { Value ASTInterpreter::visit_tuple(AST_Tuple* node) {
return getNone();
llvm::SmallVector<RewriterVar*, 8> items; llvm::SmallVector<RewriterVar*, 8> items;
BoxedTuple* rtn = BoxedTuple::create(node->elts.size()); BoxedTuple* rtn = BoxedTuple::create(node->elts.size());
...@@ -1804,7 +1847,7 @@ Box* astInterpretFunction(FunctionMetadata* md, Box* closure, Box* generator, Bo ...@@ -1804,7 +1847,7 @@ Box* astInterpretFunction(FunctionMetadata* md, Box* closure, Box* generator, Bo
interpreter.initArguments((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2, arg3, args); interpreter.initArguments((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2, arg3, args);
Box* v = ASTInterpreter::execute(interpreter); Box* v = ASTInterpreter::execute(interpreter);
return v ? v : None; return v ? v : incref(None);
} }
Box* astInterpretFunctionEval(FunctionMetadata* md, Box* globals, Box* boxedLocals) { Box* astInterpretFunctionEval(FunctionMetadata* md, Box* globals, Box* boxedLocals) {
......
...@@ -323,10 +323,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) { ...@@ -323,10 +323,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
FutureFlags future_flags = getFutureFlags(m->body, fn); FutureFlags future_flags = getFutureFlags(m->body, fn);
ScopingAnalysis* scoping = new ScopingAnalysis(m, true); ScopingAnalysis* scoping = new ScopingAnalysis(m, true);
std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, future_flags, m, m->body, boxString(fn))); auto fn_str = getStaticString(fn); // XXX this is not a static string
std::unique_ptr<SourceInfo> si(new SourceInfo(bm, scoping, future_flags, m, m->body, fn_str));
static BoxedString* doc_str = getStaticString("__doc__"); static BoxedString* doc_str = getStaticString("__doc__");
bm->setattr(doc_str, si->getDocString(), NULL); bm->setattr(doc_str, autoDecref(si->getDocString()), NULL);
static BoxedString* builtins_str = getStaticString("__builtins__"); static BoxedString* builtins_str = getStaticString("__builtins__");
if (!bm->hasattr(builtins_str)) if (!bm->hasattr(builtins_str))
...@@ -338,6 +339,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) { ...@@ -338,6 +339,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_interpreted_module_toplevel"); UNAVOIDABLE_STAT_TIMER(t0, "us_timer_interpreted_module_toplevel");
Box* r = astInterpretFunction(md, NULL, NULL, NULL, NULL, NULL, NULL, NULL); Box* r = astInterpretFunction(md, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
assert(r == None); assert(r == None);
Py_DECREF(r);
} }
Box* evalOrExec(FunctionMetadata* md, Box* globals, Box* boxedLocals) { Box* evalOrExec(FunctionMetadata* md, Box* globals, Box* boxedLocals) {
......
...@@ -20,7 +20,8 @@ namespace pyston { ...@@ -20,7 +20,8 @@ namespace pyston {
InternedString InternedStringPool::get(llvm::StringRef arg) { InternedString InternedStringPool::get(llvm::StringRef arg) {
// HACK: should properly track this liveness: // HACK: should properly track this liveness:
BoxedString* s = internStringImmortal(arg); // XXX it's not a static string
BoxedString* s = getStaticString(arg);
#ifndef NDEBUG #ifndef NDEBUG
return InternedString(s, this); return InternedString(s, this);
......
...@@ -164,13 +164,14 @@ extern "C" bool softspace(Box* b, bool newval) { ...@@ -164,13 +164,14 @@ extern "C" bool softspace(Box* b, bool newval) {
r = 0; r = 0;
} else { } else {
r = nonzero(gotten); r = nonzero(gotten);
Py_DECREF(gotten);
} }
} catch (ExcInfo e) { } catch (ExcInfo e) {
r = 0; r = 0;
} }
try { try {
setattr(b, softspace_str, boxInt(newval)); setattr(b, softspace_str, autoDecref(boxInt(newval)));
} catch (ExcInfo e) { } catch (ExcInfo e) {
r = 0; r = 0;
} }
...@@ -193,11 +194,12 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) { ...@@ -193,11 +194,12 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) {
callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), space_str, 0, 0, 0, callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), space_str, 0, 0, 0,
0); 0);
Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var); Box* str_or_unicode_var = (var->cls == unicode_cls) ? incref(var) : str(var);
Box* write_rtn = callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), Box* write_rtn = callattrInternal<CXX, NOT_REWRITABLE>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1),
str_or_unicode_var, 0, 0, 0, 0); autoDecref(str_or_unicode_var), 0, 0, 0, 0);
if (!write_rtn) if (!write_rtn)
raiseAttributeError(dest, write_str->s()); raiseAttributeError(dest, write_str->s());
Py_DECREF(write_rtn);
} }
if (nl) { if (nl) {
...@@ -205,6 +207,8 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) { ...@@ -205,6 +207,8 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) {
newline_str, 0, 0, 0, 0); newline_str, 0, 0, 0, 0);
if (!write_rtn) if (!write_rtn)
raiseAttributeError(dest, write_str->s()); raiseAttributeError(dest, write_str->s());
Py_DECREF(write_rtn);
if (!var) if (!var)
softspace(dest, false); softspace(dest, false);
} }
......
...@@ -3427,21 +3427,24 @@ int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept { ...@@ -3427,21 +3427,24 @@ int BoxedModule::traverse(Box* _m, visitproc visit, void* arg) noexcept {
return 0; return 0;
} }
template <typename CM>
void clearContiguousMap(CM& cm) {
for (auto&& p : cm) {
Py_DECREF(cm.getMapped(p.second));
}
cm.~ContiguousMap();
}
int BoxedModule::clear(Box* b) noexcept { int BoxedModule::clear(Box* b) noexcept {
BoxedModule* self = static_cast<BoxedModule*>(b); BoxedModule* self = static_cast<BoxedModule*>(b);
self->clearAttrs(); self->clearAttrs();
assert(!self->str_constants.size()); clearContiguousMap(self->str_constants);
assert(!self->unicode_constants.size()); clearContiguousMap(self->unicode_constants);
clearContiguousMap(self->int_constants);
for (auto p : self->int_constants) { clearContiguousMap(self->float_constants);
Py_DECREF(self->int_constants.getMapped(p.second)); clearContiguousMap(self->imaginary_constants);
} clearContiguousMap(self->long_constants);
self->int_constants.~ContiguousMap();
assert(!self->float_constants.size());
assert(!self->imaginary_constants.size());
assert(!self->long_constants.size());
assert(!self->keep_alive.size()); assert(!self->keep_alive.size());
return 0; return 0;
......
...@@ -70,7 +70,7 @@ void setupSysEnd(); ...@@ -70,7 +70,7 @@ void setupSysEnd();
BORROWED(BoxedDict*) getSysModulesDict(); BORROWED(BoxedDict*) getSysModulesDict();
BORROWED(BoxedList*) getSysPath(); BORROWED(BoxedList*) getSysPath();
extern "C" Box* getSysStdout(); extern "C" BORROWED(Box*) getSysStdout();
extern "C" BoxedTuple* EmptyTuple; extern "C" BoxedTuple* EmptyTuple;
extern "C" BoxedString* EmptyString; extern "C" BoxedString* EmptyString;
...@@ -389,6 +389,9 @@ public: ...@@ -389,6 +389,9 @@ public:
template <typename B, bool Nullable = false> DecrefHandle<B, Nullable> autoDecref(B* b) { template <typename B, bool Nullable = false> DecrefHandle<B, Nullable> autoDecref(B* b) {
return DecrefHandle<B, Nullable>(b); return DecrefHandle<B, Nullable>(b);
} }
template <typename B> DecrefHandle<B, true> autoXDecref(B* b) {
return DecrefHandle<B, true>(b);
}
template <typename B> B* incref(B* b) { template <typename B> B* incref(B* b) {
Py_INCREF(b); Py_INCREF(b);
...@@ -946,12 +949,12 @@ public: ...@@ -946,12 +949,12 @@ public:
BoxedModule() {} // noop constructor to disable zero-initialization of cls BoxedModule() {} // noop constructor to disable zero-initialization of cls
std::string name(); std::string name();
BoxedString* getStringConstant(llvm::StringRef ast_str, bool intern = false); BORROWED(BoxedString*) getStringConstant(llvm::StringRef ast_str, bool intern = false);
Box* getUnicodeConstant(llvm::StringRef ast_str); BORROWED(Box*) getUnicodeConstant(llvm::StringRef ast_str);
BoxedInt* getIntConstant(int64_t n); BORROWED(BoxedInt*) getIntConstant(int64_t n);
BoxedFloat* getFloatConstant(double d); BORROWED(BoxedFloat*) getFloatConstant(double d);
Box* getPureImaginaryConstant(double d); BORROWED(Box*) getPureImaginaryConstant(double d);
Box* getLongConstant(llvm::StringRef s); BORROWED(Box*) getLongConstant(llvm::StringRef s);
static void dealloc(Box* b) noexcept; static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept; static int traverse(Box* self, visitproc visit, void *arg) 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