unwinding.h 4.38 KB
Newer Older
Kevin Modzelewski's avatar
Kevin Modzelewski committed
1
// Copyright (c) 2014-2015 Dropbox, Inc.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef PYSTON_CODEGEN_UNWINDING_H
#define PYSTON_CODEGEN_UNWINDING_H

#include <unordered_map>

#include "codegen/codegen.h"

22 23 24 25
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#undef UNW_LOCAL_ONLY

26 27
namespace pyston {

Travis Hance's avatar
exec  
Travis Hance committed
28 29
class Box;
class BoxedDict;
30
class BoxedModule;
Travis Hance's avatar
exec  
Travis Hance committed
31 32 33
class BoxedTraceback;
struct FrameInfo;

34 35
void registerDynamicEhFrame(uint64_t code_addr, size_t code_size, uint64_t eh_frame_addr, size_t eh_frame_size);

36
void setupUnwinding();
37
BoxedModule* getCurrentModule();
38 39
Box* getGlobals();     // returns either the module or a globals dict
Box* getGlobalsDict(); // always returns a dict-like object
40
CompiledFunction* getCFForAddress(uint64_t addr);
41

42
Box* getTraceback();
43

44 45 46
class PythonUnwindSession;
PythonUnwindSession* beginPythonUnwindSession();
PythonUnwindSession* getActivePythonUnwindSession();
47
void throwingException(PythonUnwindSession* unwind_session);
48 49 50
void endPythonUnwindSession(PythonUnwindSession* unwind_session);
void* getPythonUnwindSessionExceptionStorage(PythonUnwindSession* unwind_session);
void unwindingThroughFrame(PythonUnwindSession* unwind_session, unw_cursor_t* cursor);
51 52

void exceptionCaughtInInterpreter(LineInfo line_info, ExcInfo* exc_info);
53

54
CLFunction* getTopPythonFunction();
55

56 57 58 59
// debugging/stat helper, returns python filename:linenumber, or "unknown:-1" if it fails
std::string getCurrentPythonLine();

// doesn't really belong in unwinding.h, since it's stats related, but it needs to unwind to get the current line...
60
void logByCurrentPythonLine(const std::string& stat_name);
61

Travis Hance's avatar
exec  
Travis Hance committed
62 63
// Adds stack locals and closure locals into the locals dict, and returns it.
Box* fastLocalsToBoxedLocals();
64

65 66 67 68 69 70 71
class PythonFrameIteratorImpl;
class PythonFrameIterator {
private:
    std::unique_ptr<PythonFrameIteratorImpl> impl;

public:
    CompiledFunction* getCF();
72
    CLFunction* getCL();
73 74
    FrameInfo* getFrameInfo();
    bool exists() { return impl.get() != NULL; }
75
    AST_stmt* getCurrentStatement();
76
    Box* fastLocalsToBoxedLocals();
77
    Box* getGlobalsDict();
78 79 80 81 82

    // Gets the "current version" of this frame: if the frame has executed since
    // the iterator was obtained, the methods may return old values. This returns
    // an updated copy that returns the updated values.
    // The "current version" will live at the same stack location, but any other
83 84
    // similarities need to be verified by the caller, ie it is up to the caller
    // to determine that we didn't leave and reenter the stack frame.
85 86 87
    // This function can only be called from the thread that created this object.
    PythonFrameIterator getCurrentVersion();

88 89 90
    // Assuming this is a valid frame iterator, return the next frame back (ie older).
    PythonFrameIterator back();

91 92
    PythonFrameIterator(PythonFrameIterator&& rhs);
    void operator=(PythonFrameIterator&& rhs);
93
    PythonFrameIterator(std::unique_ptr<PythonFrameIteratorImpl> impl);
94 95 96 97 98
    ~PythonFrameIterator();
};

PythonFrameIterator getPythonFrame(int depth);

99 100 101
// Fetches a writeable pointer to the frame-local excinfo object,
// calculating it if necessary (from previous frames).
ExcInfo* getFrameExcInfo();
102

Travis Hance's avatar
exec  
Travis Hance committed
103 104 105 106 107 108 109 110 111 112 113
struct FrameStackState {
    // This includes all # variables (but not the ! ones).
    // Therefore, it's not the same as the BoxedLocals.
    // This also means that it contains
    // CREATED_CLOSURE_NAME, PASSED_CLOSURE_NAME, and GENERATOR_NAME.
    BoxedDict* locals;

    // The frame_info is a pointer to the frame_info on the stack, so it is invalid
    // after the frame ends.
    FrameInfo* frame_info;

114
    FrameStackState() {}
Travis Hance's avatar
exec  
Travis Hance committed
115 116 117 118 119
    FrameStackState(BoxedDict* locals, FrameInfo* frame_info) : locals(locals), frame_info(frame_info) {}
};

// Returns all the stack locals, including hidden ones.
FrameStackState getFrameStackState();
120

121 122 123 124 125 126
struct DeoptState {
    FrameStackState frame_state;
    CompiledFunction* cf;
    AST_stmt* current_stmt;
};
DeoptState getDeoptState();
127 128 129
}

#endif