Commit 8e88774f authored by Chris Toshok's avatar Chris Toshok

a few cleanups

1. remove the BoxedTraceback** argument from maybeTracebackHere.  the unwinding.cpp
   code can get it just as easily.
2. combine UNWIND_STATE_OSR and UNWIND_STATE_RERAISE into UNWIND_STATE_SKIPNEXT,
   since they share the same behavior.
3. put the SKIPNEXT behavior in the callers of unwindProcessFrame.  Now unwindProcessFrame
   does nothing but create a PythonFrameIteratorImpl (if it can), and if it can
   calls its callback with it.
4. initialize the unwind state to NORMAL in raiseExc.
parent af1aea2f
......@@ -473,14 +473,7 @@ bool unwindProcessFrame(unw_word_t ip, unw_word_t bp, unw_cursor_t* cursor, Fram
}
}
if (threading::ThreadStateInternal::getUnwindState() == UNWIND_STATE_NORMAL) {
bool stop = func(&info);
if (stop)
return true;
}
threading::ThreadStateInternal::setUnwindState((bool)cf->entry_descriptor ? UNWIND_STATE_OSR : UNWIND_STATE_NORMAL);
return false;
return func(&info);
}
// While I'm not a huge fan of the callback-passing style, libunwind cursors are only valid for
......@@ -505,8 +498,19 @@ template <typename Func> void unwindPythonStack(Func func) {
unw_word_t ip = get_cursor_ip(&cursor);
unw_word_t bp = get_cursor_bp(&cursor);
if (unwindProcessFrame(ip, bp, &cursor, func))
bool stop_unwinding = unwindProcessFrame(ip, bp, &cursor, [&](PythonFrameIteratorImpl* frame_iter) {
bool rtn = false;
if (threading::ThreadStateInternal::getUnwindState() == UNWIND_STATE_NORMAL)
rtn = func(frame_iter);
threading::ThreadStateInternal::setUnwindState(
(bool)frame_iter->cf->entry_descriptor ? UNWIND_STATE_SKIPNEXT : UNWIND_STATE_NORMAL);
return rtn;
});
if (stop_unwinding) {
break;
}
if (inGeneratorEntry(ip)) {
// for generators continue unwinding in the context in which the generator got called
......@@ -548,14 +552,21 @@ static const LineInfo lineInfoForFrame(PythonFrameIteratorImpl* frame_it) {
return LineInfo(current_stmt->lineno, current_stmt->col_offset, source->fn, source->getName());
}
void maybeTracebackHere(void* unw_cursor, BoxedTraceback** tb) {
void maybeTracebackHere(void* unw_cursor) {
unw_cursor_t* cursor = (unw_cursor_t*)unw_cursor;
unw_word_t ip = get_cursor_ip(cursor);
unw_word_t bp = get_cursor_bp(cursor);
BoxedTraceback** tb_loc
= reinterpret_cast<BoxedTraceback**>(&threading::ThreadStateInternal::getExceptionFerry()->traceback);
unwindProcessFrame(ip, bp, cursor, [&](PythonFrameIteratorImpl* frame_iter) {
BoxedTraceback::Here(lineInfoForFrame(frame_iter), tb);
if (threading::ThreadStateInternal::getUnwindState() == UNWIND_STATE_NORMAL)
BoxedTraceback::Here(lineInfoForFrame(frame_iter), tb_loc);
threading::ThreadStateInternal::setUnwindState((bool)frame_iter->cf->entry_descriptor ? UNWIND_STATE_SKIPNEXT
: UNWIND_STATE_NORMAL);
return false;
});
}
......@@ -718,7 +729,7 @@ PythonFrameIterator::PythonFrameIterator(std::unique_ptr<PythonFrameIteratorImpl
std::swap(this->impl, impl);
}
// TODO factor getStackLoclasIncludingUserHidden and fastLocalsToBoxedLocals
// TODO factor getStackLocalsIncludingUserHidden and fastLocalsToBoxedLocals
// because they are pretty ugly but have a pretty repetitive pattern.
FrameStackState getFrameStackState() {
......
......@@ -36,7 +36,7 @@ CompiledFunction* getCFForAddress(uint64_t addr);
BoxedTraceback* getTraceback();
void maybeTracebackHere(void* unw_cursor, BoxedTraceback** tb);
void maybeTracebackHere(void* unw_cursor);
struct ExecutionPoint {
CompiledFunction* cf;
......
......@@ -33,11 +33,11 @@ class GCVisitor;
}
// somewhat similar to CPython's WHY_* enum
// UNWIND_STATE_NORMAL : == WHY_EXCEPTION. we call it "NORMAL" since we often unwind due to things other than
// UNWIND_STATE_NORMAL : == WHY_EXCEPTION. we call it "NORMAL" since we often unwind due to things other than
// exceptions (getGlobals, getLocals, etc)
// UNWIND_STATE_RERAISE: same as NORMAL, except we are supposed to skip the first frame.
// UNWIND_STATE_OSR : The previous frame was an osr replacement for the next one, so we should skip it
enum UnwindState { UNWIND_STATE_NORMAL = 0, UNWIND_STATE_RERAISE, UNWIND_STATE_OSR };
// UNWIND_STATE_SKIPNEXT: skip this frame (do not include it in tracebacks). this happens when re-raising an exception
// and also when dealing with osr replacements (we skip the frame we OSR).
enum UnwindState { UNWIND_STATE_NORMAL = 0, UNWIND_STATE_SKIPNEXT };
namespace threading {
......
......@@ -493,9 +493,6 @@ static inline void unwind_loop(ExcInfo* exc_data) {
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
BoxedTraceback** tb_loc
= reinterpret_cast<BoxedTraceback**>(&threading::ThreadStateInternal::getExceptionFerry()->traceback);
while (unw_step(&cursor) > 0) {
unw_proc_info_t pip;
{
......@@ -509,7 +506,7 @@ static inline void unwind_loop(ExcInfo* exc_data) {
print_frame(&cursor, &pip);
}
maybeTracebackHere(&cursor, tb_loc);
maybeTracebackHere(&cursor);
// Skip frames without handlers
if (pip.handler == 0) {
......
......@@ -76,6 +76,7 @@ void raiseRaw(const ExcInfo& e) {
}
void raiseExc(Box* exc_obj) {
threading::ThreadStateInternal::setUnwindState(UNWIND_STATE_NORMAL);
raiseRaw(ExcInfo(exc_obj->cls, exc_obj, new BoxedTraceback()));
}
......@@ -205,7 +206,7 @@ extern "C" void raise0() {
raiseExcHelper(TypeError, "exceptions must be old-style classes or derived from BaseException, not NoneType");
threading::ThreadStateInternal::setUnwindState(UNWIND_STATE_RERAISE);
threading::ThreadStateInternal::setUnwindState(UNWIND_STATE_SKIPNEXT);
raiseRaw(*exc_info);
}
......@@ -285,7 +286,7 @@ extern "C" void raise3(Box* arg0, Box* arg1, Box* arg2) {
bool reraise = arg2 != NULL && arg2 != None;
auto exc_info = excInfoForRaise(arg0, arg1, arg2);
threading::ThreadStateInternal::setUnwindState(reraise ? UNWIND_STATE_RERAISE : UNWIND_STATE_NORMAL);
threading::ThreadStateInternal::setUnwindState(reraise ? UNWIND_STATE_SKIPNEXT : UNWIND_STATE_NORMAL);
raiseRaw(exc_info);
}
......
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