Commit a9fe6120 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add sys.exc_info which accesses the frame-local ExcInfo

Currently nothing sets that though.
parent 1e672eb3
...@@ -127,6 +127,7 @@ private: ...@@ -127,6 +127,7 @@ private:
BoxedClosure* passed_closure, *created_closure; BoxedClosure* passed_closure, *created_closure;
BoxedGenerator* generator; BoxedGenerator* generator;
unsigned edgecount; unsigned edgecount;
FrameInfo frame_info;
public: public:
AST_stmt* getCurrentStatement() { AST_stmt* getCurrentStatement() {
...@@ -135,6 +136,7 @@ public: ...@@ -135,6 +136,7 @@ public:
} }
CompiledFunction* getCF() { return compiled_func; } CompiledFunction* getCF() { return compiled_func; }
FrameInfo* getFrameInfo() { return &frame_info; }
const SymMap& getSymbolTable() { return sym_table; } const SymMap& getSymbolTable() { return sym_table; }
void gcVisit(GCVisitor* visitor); void gcVisit(GCVisitor* visitor);
}; };
...@@ -189,6 +191,12 @@ CompiledFunction* getCFForInterpretedFrame(void* frame_ptr) { ...@@ -189,6 +191,12 @@ CompiledFunction* getCFForInterpretedFrame(void* frame_ptr) {
return interpreter->getCF(); return interpreter->getCF();
} }
FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = s_interpreterMap[frame_ptr];
assert(interpreter);
return interpreter->getFrameInfo();
}
BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible) { BoxedDict* localsForInterpretedFrame(void* frame_ptr, bool only_user_visible) {
ASTInterpreter* interpreter = s_interpreterMap[frame_ptr]; ASTInterpreter* interpreter = s_interpreterMap[frame_ptr];
assert(interpreter); assert(interpreter);
...@@ -225,7 +233,7 @@ void gatherInterpreterRoots(GCVisitor* visitor) { ...@@ -225,7 +233,7 @@ void gatherInterpreterRoots(GCVisitor* visitor) {
ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function) ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
: compiled_func(compiled_function), source_info(compiled_function->clfunc->source), scope_info(0), next_block(0), : compiled_func(compiled_function), source_info(compiled_function->clfunc->source), scope_info(0), next_block(0),
current_block(0), current_inst(0), last_exception(NULL, NULL, NULL), passed_closure(0), created_closure(0), current_block(0), current_inst(0), last_exception(NULL, NULL, NULL), passed_closure(0), created_closure(0),
generator(0), edgecount(0) { generator(0), edgecount(0), frame_info(ExcInfo(NULL, NULL, NULL)) {
CLFunction* f = compiled_function->clfunc; CLFunction* f = compiled_function->clfunc;
if (!source_info->cfg) if (!source_info->cfg)
......
...@@ -35,6 +35,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_stmt* start_at, BoxedDict* local ...@@ -35,6 +35,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_stmt* start_at, BoxedDict* local
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr); AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
CompiledFunction* getCFForInterpretedFrame(void* frame_ptr); CompiledFunction* getCFForInterpretedFrame(void* frame_ptr);
FrameInfo* getFrameInfoForInterpretedFrame(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);
......
...@@ -85,8 +85,10 @@ llvm::Value* IRGenState::getFrameInfoVar() { ...@@ -85,8 +85,10 @@ llvm::Value* IRGenState::getFrameInfoVar() {
llvm::AllocaInst* al = builder.CreateAlloca(g.frame_info_type, NULL, "frame_info"); llvm::AllocaInst* al = builder.CreateAlloca(g.frame_info_type, NULL, "frame_info");
assert(al->isStaticAlloca()); assert(al->isStaticAlloca());
static_assert(offsetof(FrameInfo, exc_type) == 0, ""); static_assert(offsetof(FrameInfo, exc) == 0, "");
llvm::Value* exctype_gep = builder.CreateConstInBoundsGEP2_32(al, 0, 0); static_assert(offsetof(ExcInfo, type) == 0, "");
llvm::Value* exctype_gep
= builder.CreateConstInBoundsGEP2_32(builder.CreateConstInBoundsGEP2_32(al, 0, 0), 0, 0);
builder.CreateStore(embedConstantPtr(NULL, g.llvm_value_type_ptr), exctype_gep); builder.CreateStore(embedConstantPtr(NULL, g.llvm_value_type_ptr), exctype_gep);
frame_info = al; frame_info = al;
......
...@@ -281,6 +281,14 @@ public: ...@@ -281,6 +281,14 @@ public:
abort(); abort();
} }
FrameInfo* getFrameInfo() {
if (id.type == PythonFrameId::COMPILED) {
} else if (id.type == PythonFrameId::INTERPRETED) {
return getFrameInfoForInterpretedFrame((void*)id.bp);
}
abort();
}
const PythonFrameId& getId() const { return id; } const PythonFrameId& getId() const { return id; }
static std::unique_ptr<PythonFrameIterator> end() { return std::unique_ptr<PythonFrameIterator>(nullptr); } static std::unique_ptr<PythonFrameIterator> end() { return std::unique_ptr<PythonFrameIterator>(nullptr); }
...@@ -450,15 +458,35 @@ const LineInfo* getMostRecentLineInfo() { ...@@ -450,15 +458,35 @@ const LineInfo* getMostRecentLineInfo() {
return lineInfoForFrame(*frame); return lineInfoForFrame(*frame);
} }
FrameInfo* getTopFrameInfo() { ExcInfo getFrameExcInfo() {
std::unique_ptr<PythonFrameIterator> frame = getTopPythonFrame(); std::vector<ExcInfo*> to_update;
if (frame.get_id().type == PythonFrameId::COMPILED) { ExcInfo* cur_exc = NULL;
abort(); for (PythonFrameIterator& frame_iter : unwindPythonFrames()) {
} else if (frame.get_id().type == PythonFrameId::INTERPRETED) { FrameInfo* frame_info = frame_iter.getFrameInfo();
abort();
} else { cur_exc = &frame_info->exc;
abort(); if (!cur_exc->type) {
to_update.push_back(cur_exc);
continue;
}
break;
}
assert(cur_exc); // Only way this could still be NULL is if there weren't any python frames
if (!cur_exc->type) {
// No exceptions found:
*cur_exc = ExcInfo(None, None, None);
}
assert(cur_exc->value);
assert(cur_exc->traceback);
for (auto* ex : to_update) {
*ex = *cur_exc;
} }
return *cur_exc;
} }
CompiledFunction* getTopCompiledFunction() { CompiledFunction* getTopCompiledFunction() {
......
...@@ -30,9 +30,8 @@ CompiledFunction* getCFForAddress(uint64_t addr); ...@@ -30,9 +30,8 @@ CompiledFunction* getCFForAddress(uint64_t addr);
class BoxedDict; class BoxedDict;
BoxedDict* getLocals(bool only_user_visible); BoxedDict* getLocals(bool only_user_visible);
struct FrameInfo; // Fetches the frame-local excinfo object, calculating it if necessary (from previous frames):
FrameInfo* getTopFrameInfo(); ExcInfo getFrameExcInfo();
} }
#endif #endif
...@@ -483,6 +483,8 @@ struct FrameInfo { ...@@ -483,6 +483,8 @@ struct FrameInfo {
// In Pyston, exc is the frame-local value of sys.exc_info. // In Pyston, exc is the frame-local value of sys.exc_info.
// - This makes frame entering+leaving faster at the expense of slower exceptions. // - This makes frame entering+leaving faster at the expense of slower exceptions.
ExcInfo exc; ExcInfo exc;
FrameInfo(ExcInfo exc) : exc(exc) {}
}; };
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
#include "codegen/unwinding.h"
#include "core/types.h" #include "core/types.h"
#include "gc/collector.h" #include "gc/collector.h"
#include "runtime/inline/boxing.h" #include "runtime/inline/boxing.h"
...@@ -32,9 +33,11 @@ BoxedModule* sys_module; ...@@ -32,9 +33,11 @@ BoxedModule* sys_module;
BoxedDict* sys_modules_dict; BoxedDict* sys_modules_dict;
Box* sysExcInfo() { Box* sysExcInfo() {
return new BoxedTuple({ cur_thread_state.curexc_type ? cur_thread_state.curexc_type : None, ExcInfo exc = getFrameExcInfo();
cur_thread_state.curexc_value ? cur_thread_state.curexc_value : None, assert(exc.type);
cur_thread_state.curexc_traceback ? cur_thread_state.curexc_traceback : None }); assert(exc.value);
assert(exc.traceback);
return new BoxedTuple({ exc.type, exc.value, exc.traceback });
} }
static Box* sysExit(Box* arg) { static Box* sysExit(Box* arg) {
......
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