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