Commit 1f55b52d authored by Travis Hance's avatar Travis Hance

have getLocals get variables passed into the closure as well

parent 87ef0bbc
......@@ -137,7 +137,10 @@ public:
CompiledFunction* getCF() { return compiled_func; }
FrameInfo* getFrameInfo() { return &frame_info; }
BoxedClosure* getPassedClosure() { return passed_closure; }
const SymMap& getSymbolTable() { return sym_table; }
const ScopeInfo* getScopeInfo() { return scope_info; }
void addSymbol(InternedString name, Box* value, bool allow_duplicates);
void gcVisit(GCVisitor* visitor);
};
......@@ -1217,9 +1220,16 @@ BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible) {
rtn->d[new BoxedString(l.first.str())] = l.second;
}
return rtn;
}
BoxedClosure* passedClosureForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = s_interpreterMap[frame_ptr];
assert(interpreter);
return interpreter->getPassedClosure();
}
void gatherInterpreterRoots(GCVisitor* visitor) {
for (const auto& p : s_interpreterMap) {
p.second->gcVisit(visitor);
......
......@@ -24,6 +24,7 @@ class GCVisitor;
class AST_expr;
class AST_stmt;
class Box;
class BoxedClosure;
class BoxedDict;
struct CompiledFunction;
struct LineInfo;
......@@ -40,6 +41,7 @@ AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
CompiledFunction* getCFForInterpretedFrame(void* frame_ptr);
struct FrameInfo;
FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr);
BoxedClosure* passedClosureForInterpretedFrame(void* frame_ptr);
void gatherInterpreterRoots(gc::GCVisitor* visitor);
BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible);
......
......@@ -1673,7 +1673,7 @@ public:
Box* deserializeFromFrame(const FrameVals& vals) override {
assert(vals.size() == 1);
abort();
return reinterpret_cast<Box*>(vals[0]);
}
} _CLOSURE;
ConcreteCompilerType* CLOSURE = &_CLOSURE;
......
......@@ -23,10 +23,12 @@
#include "llvm/IR/DebugInfo.h"
#include "llvm/Object/ObjectFile.h"
#include "analysis/scoping_analysis.h"
#include "codegen/ast_interpreter.h"
#include "codegen/codegen.h"
#include "codegen/compvars.h"
#include "codegen/irgen/hooks.h"
#include "codegen/irgen/irgenerator.h"
#include "codegen/stackmaps.h"
#include "core/util.h"
#include "runtime/ctxswitching.h"
......@@ -536,12 +538,15 @@ BoxedModule* getCurrentModule() {
return compiledFunction->clfunc->source->parent_module;
}
BoxedDict* getLocals(bool only_user_visible) {
BoxedDict* getLocals(bool only_user_visible, bool includeClosure) {
for (PythonFrameIterator& frame_info : unwindPythonFrames()) {
BoxedDict* d;
BoxedClosure* closure;
CompiledFunction* cf;
if (frame_info.getId().type == PythonFrameId::COMPILED) {
BoxedDict* d = new BoxedDict();
d = new BoxedDict();
CompiledFunction* cf = frame_info.getCF();
cf = frame_info.getCF();
uint64_t ip = frame_info.getId().ip;
assert(ip > cf->code_start);
......@@ -601,11 +606,52 @@ BoxedDict* getLocals(bool only_user_visible) {
}
}
return d;
closure = NULL;
if (includeClosure && cf->location_map->names.count(PASSED_CLOSURE_NAME) > 0) {
for (const LocationMap::LocationTable::LocationEntry& e :
cf->location_map->names[PASSED_CLOSURE_NAME].locations) {
if (e.offset < offset && offset <= e.offset + e.length) {
const auto& locs = e.locations;
llvm::SmallVector<uint64_t, 1> vals;
for (auto& loc : locs) {
vals.push_back(frame_info.readLocation(loc));
}
Box* v = e.type->deserializeFromFrame(vals);
assert(gc::isValidGCObject(v));
closure = static_cast<BoxedClosure*>(v);
}
}
}
} else if (frame_info.getId().type == PythonFrameId::INTERPRETED) {
return localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible);
d = localsForInterpretedFrame((void*)frame_info.getId().bp, only_user_visible);
if (includeClosure) {
closure = passedClosureForInterpretedFrame((void*)frame_info.getId().bp);
cf = getCFForInterpretedFrame((void*)frame_info.getId().bp);
}
} else {
abort();
}
abort();
if (includeClosure) {
// Add the locals from the closure
for (; closure != NULL; closure = closure->parent) {
assert(closure->cls == closure_cls);
for (auto& attr_offset : closure->attrs.hcls->attr_offsets) {
const std::string& name = attr_offset.first;
int offset = attr_offset.second;
Box* val = closure->attrs.attr_list->attrs[offset];
ScopeInfo* scope_info = cf->clfunc->source->getScopeInfo();
if (val != NULL && scope_info->refersToClosure(scope_info->internString(name))) {
d->d[boxString(name)] = val;
}
}
}
}
return d;
}
RELEASE_ASSERT(0, "Internal error: unable to find any python frames");
}
......
......@@ -28,7 +28,7 @@ class BoxedTraceback;
BoxedTraceback* getTraceback();
class BoxedDict;
BoxedDict* getLocals(bool only_user_visible);
BoxedDict* getLocals(bool only_user_visible, bool includeClosure);
// Fetches a writeable pointer to the frame-local excinfo object,
// calculating it if necessary (from previous frames).
......
......@@ -580,7 +580,7 @@ Box* eval(Box* code) {
// TODO implement full functionality (args and stuff)
RELEASE_ASSERT(code->cls == str_cls, "eval not implemented for non-strings");
BoxedDict* locals = getLocals(true /* only_user_visible */);
BoxedDict* locals = getLocals(true /* only_user_visible */, true /* includeClosure */);
BoxedModule* module = getCurrentModule();
return runEval(static_cast<BoxedString*>(code)->s.c_str(), locals, module);
......@@ -753,7 +753,7 @@ Box* globals() {
}
Box* locals() {
return getLocals(true /* filter */);
return getLocals(true /* filter */, true /* includeClosure */);
}
Box* divmod(Box* lhs, Box* rhs) {
......
......@@ -154,7 +154,7 @@ extern "C" Box* deopt(AST_expr* expr, Box* value) {
static StatCounter num_deopt("num_deopt");
num_deopt.log();
auto locals = getLocals(false /* filter */);
auto locals = getLocals(false /* filter */, false /* includeClosure */);
auto execution_point = getExecutionPoint();
// Should we only do this selectively?
......
......@@ -123,6 +123,8 @@ def do_changing_local():
eval("[print_changing_local() for changing_local in range(5)]")
do_changing_local()
"""
x = 2
def wrap():
x = 1
......@@ -144,4 +146,3 @@ def wrap():
inner2()
wrap()
"""
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