Commit 1956b795 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Have functions keep a reference to their modules

I think technically only the globals are needed but I think this is
probably safer.

There's a FunctionMetadata* inbetween that doesn't get memory managed,
so the function just looks through that for now.
parent c2f81a09
......@@ -233,7 +233,7 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
void ASTInterpreter::setGlobals(Box* globals) {
assert(!this->frame_info.globals);
this->frame_info.globals = globals;
this->frame_info.globals = incref(globals);
}
ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs, int num_vregs)
......
......@@ -285,7 +285,8 @@ void IRGenState::setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* pas
// set frame_info.passed_closure
builder.CreateStore(passed_closure, getPassedClosureGep(builder, al));
// set frame_info.globals
builder.CreateStore(passed_globals, getGlobalsGep(builder, al));
auto globals_store = builder.CreateStore(passed_globals, getGlobalsGep(builder, al));
getRefcounts()->refConsumed(passed_globals, globals_store);
// set frame_info.vregs
builder.CreateStore(vregs, getVRegsGep(builder, al));
builder.CreateStore(getConstantInt(num_user_visible_vregs, g.i32), getNumVRegsGep(builder, al));
......
......@@ -251,6 +251,8 @@ extern "C" void deinitFrame(FrameInfo* frame_info) {
Py_CLEAR(frame_info->exc.value);
Py_CLEAR(frame_info->exc.traceback);
}
Py_CLEAR(frame_info->globals);
}
int frameinfo_traverse(FrameInfo* frame_info, visitproc visit, void* arg) noexcept {
......
......@@ -338,6 +338,9 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(FunctionMetadata* md, std::initi
}
if (md->source) {
auto parent_module = md->source->parent_module;
Py_INCREF(parent_module);
Box* globals_for_name = globals;
if (!globals_for_name) {
assert(md->source->scoping->areGlobalsFromModule());
......@@ -412,6 +415,10 @@ static void functionDtor(Box* b) {
Py_XDECREF(self->name);
Py_XDECREF(self->closure);
Py_XDECREF(self->globals);
if (self->md->source) {
auto parent_module = self->md->source->parent_module;
Py_DECREF(parent_module);
}
Py_XDECREF(self->defaults);
self->cls->tp_free(self);
......@@ -426,6 +433,10 @@ static int func_traverse(BoxedFunction* f, visitproc visit, void* arg) noexcept
Py_VISIT(f->name);
Py_VISIT(f->closure);
if (f->md->source) {
Py_VISIT(f->md->source->parent_module);
}
// Py_VISIT(f->func_dict);
Py_TRAVERSE(f->attrs);
return 0;
......@@ -440,6 +451,10 @@ static int builtin_func_traverse(BoxedBuiltinFunctionOrMethod* f, visitproc visi
Py_VISIT(f->name);
Py_VISIT(f->closure);
if (f->md->source) {
Py_VISIT(f->md->source->parent_module);
}
return 0;
}
......
# expected: reffail
import sys_modules_replacement_target
print hasattr(sys_modules_replacement_target, "path")
# expected: reffail
# Not sure how important or necessary this behavior is, but
# CPython's behavior around sys.modules seems to be that it saves
# an internal reference to the object, so if you set sys.modules
......
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