Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
97f3f482
Commit
97f3f482
authored
Feb 26, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit '0d4b2' into refcounting
parents
db8b9589
0d4b2bd7
Changes
20
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
442 additions
and
314 deletions
+442
-314
from_cpython/CMakeLists.txt
from_cpython/CMakeLists.txt
+1
-0
from_cpython/Include/code.h
from_cpython/Include/code.h
+2
-0
from_cpython/Include/frameobject.h
from_cpython/Include/frameobject.h
+7
-1
from_cpython/Include/traceback.h
from_cpython/Include/traceback.h
+4
-8
from_cpython/Python/traceback.c
from_cpython/Python/traceback.c
+310
-0
src/CMakeLists.txt
src/CMakeLists.txt
+0
-1
src/capi/errors.cpp
src/capi/errors.cpp
+59
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+3
-4
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+1
-2
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+20
-55
src/codegen/unwinding.h
src/codegen/unwinding.h
+3
-6
src/runtime/capi.cpp
src/runtime/capi.cpp
+0
-8
src/runtime/code.cpp
src/runtime/code.cpp
+9
-0
src/runtime/cxx_unwind.cpp
src/runtime/cxx_unwind.cpp
+0
-1
src/runtime/exceptions.cpp
src/runtime/exceptions.cpp
+16
-20
src/runtime/frame.cpp
src/runtime/frame.cpp
+5
-0
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+1
-1
src/runtime/traceback.cpp
src/runtime/traceback.cpp
+0
-141
src/runtime/traceback.h
src/runtime/traceback.h
+0
-64
src/runtime/types.cpp
src/runtime/types.cpp
+1
-2
No files found.
from_cpython/CMakeLists.txt
View file @
97f3f482
...
...
@@ -96,6 +96,7 @@ file(GLOB_RECURSE STDOBJECT_SRCS Objects
obmalloc.c
stringobject.c
structseq.c
traceback.c
unicodectype.c
unicodeobject.c
weakrefobject.c
...
...
from_cpython/Include/code.h
View file @
97f3f482
...
...
@@ -93,6 +93,8 @@ PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int) PYSTON_NOEXCEPT;
// Pyston addition:
PyAPI_FUNC
(
int
)
PyCode_GetArgCount
(
PyCodeObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyCode_GetFilename
(
PyCodeObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyCode_GetName
(
PyCodeObject
*
)
PYSTON_NOEXCEPT
;
/* for internal use only */
#define _PyCode_GETCODEPTR(co, pp) \
...
...
from_cpython/Include/frameobject.h
View file @
97f3f482
...
...
@@ -83,12 +83,18 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
#endif
typedef
struct
_PyFrameObject
PyFrameObject
;
typedef
struct
_frame
PyFrameObject
;
PyAPI_DATA
(
PyTypeObject
*
)
frame_cls
;
#define PyFrame_Type (*frame_cls)
#define PyFrame_Check(op) (((PyObject*)op)->ob_type == &PyFrame_Type)
/* Return the line of code the frame is currently executing. */
PyAPI_FUNC
(
int
)
PyFrame_GetLineNumber
(
PyFrameObject
*
)
PYSTON_NOEXCEPT
;
// Pyston changes: add a function to get globals
PyAPI_FUNC
(
PyObject
*
)
PyFrame_GetGlobals
(
PyFrameObject
*
)
PYSTON_NOEXCEPT
;
// Pyston changes: add a function to get the code object
PyAPI_FUNC
(
PyObject
*
)
PyFrame_GetCode
(
PyFrameObject
*
)
PYSTON_NOEXCEPT
;
// Pyston changes: add a function to get frame object by level
PyAPI_FUNC
(
PyFrameObject
*
)
PyFrame_ForStackLevel
(
int
stack_level
)
PYSTON_NOEXCEPT
;
...
...
from_cpython/Include/traceback.h
View file @
97f3f482
...
...
@@ -10,8 +10,6 @@ struct _frame;
/* Traceback interface */
// Pyston change: not necessarily our object format
#if 0
typedef
struct
_traceback
{
PyObject_HEAD
struct
_traceback
*
tb_next
;
...
...
@@ -19,18 +17,16 @@ typedef struct _traceback {
int
tb_lasti
;
int
tb_lineno
;
}
PyTracebackObject
;
#endif
typedef
struct
_PyTracebackObject
PyTracebackObject
;
PyAPI_FUNC
(
int
)
PyTraceBack_Here
(
struct
_frame
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyTraceBack_Print
(
PyObject
*
,
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
_Py_DisplaySourceLine
(
PyObject
*
,
const
char
*
,
int
,
int
)
PYSTON_NOEXCEPT
;
// Pyston change: this function does not modify curexc_traceback but instead sets the supplied tb
PyAPI_FUNC
(
int
)
PyTraceBack_Here_Tb
(
struct
_frame
*
,
PyTracebackObject
**
)
PYSTON_NOEXCEPT
;
/* Reveal traceback type so we can typecheck traceback objects */
// Pyston change: not a static type any more
PyAPI_DATA
(
PyTypeObject
*
)
traceback_cls
;
#define PyTraceBack_Type (*traceback_cls)
// PyAPI_DATA(PyTypeObject) PyTraceBack_Type;
PyAPI_DATA
(
PyTypeObject
)
PyTraceBack_Type
;
#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type)
#ifdef __cplusplus
...
...
from_cpython/Python/traceback.c
0 → 100644
View file @
97f3f482
// This file is originally from CPython 2.7, with modifications for Pyston
/* Traceback implementation */
#include "Python.h"
#include "code.h"
#include "frameobject.h"
#include "structmember.h"
#include "osdefs.h"
#include "traceback.h"
#define OFF(x) offsetof(PyTracebackObject, x)
static
PyMemberDef
tb_memberlist
[]
=
{
{
"tb_next"
,
T_OBJECT
,
OFF
(
tb_next
),
READONLY
},
{
"tb_frame"
,
T_OBJECT
,
OFF
(
tb_frame
),
READONLY
},
{
"tb_lasti"
,
T_INT
,
OFF
(
tb_lasti
),
READONLY
},
{
"tb_lineno"
,
T_INT
,
OFF
(
tb_lineno
),
READONLY
},
{
NULL
}
/* Sentinel */
};
static
void
tb_dealloc
(
PyTracebackObject
*
tb
)
{
PyObject_GC_UnTrack
(
tb
);
Py_TRASHCAN_SAFE_BEGIN
(
tb
)
Py_XDECREF
(
tb
->
tb_next
);
Py_XDECREF
(
tb
->
tb_frame
);
PyObject_GC_Del
(
tb
);
Py_TRASHCAN_SAFE_END
(
tb
)
}
static
int
tb_traverse
(
PyTracebackObject
*
tb
,
visitproc
visit
,
void
*
arg
)
{
Py_VISIT
(
tb
->
tb_next
);
Py_VISIT
(
tb
->
tb_frame
);
return
0
;
}
static
void
tb_clear
(
PyTracebackObject
*
tb
)
{
Py_CLEAR
(
tb
->
tb_next
);
Py_CLEAR
(
tb
->
tb_frame
);
}
PyTypeObject
PyTraceBack_Type
=
{
// Pyston change:
// PyVarObject_HEAD_INIT(&PyType_Type, 0)
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"traceback"
,
sizeof
(
PyTracebackObject
),
0
,
// Pyston change:
//(destructor)tb_dealloc, /*tp_dealloc*/
(
destructor
)
0
,
0
,
/*tp_print*/
0
,
/*tp_getattr*/
0
,
/*tp_setattr*/
0
,
/*tp_compare*/
0
,
/*tp_repr*/
0
,
/*tp_as_number*/
0
,
/*tp_as_sequence*/
0
,
/*tp_as_mapping*/
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
0
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
|
Py_TPFLAGS_HAVE_GC
,
/* tp_flags */
0
,
/* tp_doc */
(
traverseproc
)
tb_traverse
,
/* tp_traverse */
(
inquiry
)
tb_clear
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_iter */
0
,
/* tp_iternext */
0
,
/* tp_methods */
tb_memberlist
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
};
static
PyTracebackObject
*
newtracebackobject
(
PyTracebackObject
*
next
,
PyFrameObject
*
frame
)
{
PyTracebackObject
*
tb
;
if
((
next
!=
NULL
&&
!
PyTraceBack_Check
(
next
))
||
frame
==
NULL
||
!
PyFrame_Check
(
frame
))
{
PyErr_BadInternalCall
();
return
NULL
;
}
tb
=
PyObject_GC_New
(
PyTracebackObject
,
&
PyTraceBack_Type
);
if
(
tb
!=
NULL
)
{
Py_XINCREF
(
next
);
tb
->
tb_next
=
next
;
Py_XINCREF
(
frame
);
tb
->
tb_frame
=
(
struct
_frame
*
)
frame
;
// Pyston change: we don't have tb_lasti
// tb->tb_lasti = frame->f_lasti;
tb
->
tb_lasti
=
-
1
;
tb
->
tb_lineno
=
PyFrame_GetLineNumber
(
frame
);
PyObject_GC_Track
(
tb
);
}
return
tb
;
}
int
PyTraceBack_Here
(
PyFrameObject
*
frame
)
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
PyTracebackObject
*
oldtb
=
(
PyTracebackObject
*
)
tstate
->
curexc_traceback
;
PyTracebackObject
*
tb
=
newtracebackobject
(
oldtb
,
frame
);
if
(
tb
==
NULL
)
return
-
1
;
tstate
->
curexc_traceback
=
(
PyObject
*
)
tb
;
Py_XDECREF
(
oldtb
);
return
0
;
}
// Pyston change: this function does not modify curexc_traceback but instead sets the supplied tb
int
PyTraceBack_Here_Tb
(
PyFrameObject
*
frame
,
PyTracebackObject
**
tb
)
{
if
((
PyObject
*
)
*
tb
==
Py_None
)
*
tb
=
NULL
;
*
tb
=
newtracebackobject
(
*
tb
,
frame
);
if
(
*
tb
==
NULL
)
return
-
1
;
return
0
;
}
int
_Py_DisplaySourceLine
(
PyObject
*
f
,
const
char
*
filename
,
int
lineno
,
int
indent
)
{
int
err
=
0
;
FILE
*
xfp
=
NULL
;
char
linebuf
[
2000
];
int
i
;
char
namebuf
[
MAXPATHLEN
+
1
];
if
(
filename
==
NULL
)
return
-
1
;
/* This is needed by Emacs' compile command */
#define FMT " File \"%.500s\", line %d, in %.500s\n"
xfp
=
fopen
(
filename
,
"r"
PY_STDIOTEXTMODE
);
if
(
xfp
==
NULL
)
{
/* Search tail of filename in sys.path before giving up */
PyObject
*
path
;
const
char
*
tail
=
strrchr
(
filename
,
SEP
);
if
(
tail
==
NULL
)
tail
=
filename
;
else
tail
++
;
path
=
PySys_GetObject
(
"path"
);
if
(
path
!=
NULL
&&
PyList_Check
(
path
))
{
Py_ssize_t
_npath
=
PyList_Size
(
path
);
int
npath
=
Py_SAFE_DOWNCAST
(
_npath
,
Py_ssize_t
,
int
);
size_t
taillen
=
strlen
(
tail
);
for
(
i
=
0
;
i
<
npath
;
i
++
)
{
PyObject
*
v
=
PyList_GetItem
(
path
,
i
);
if
(
v
==
NULL
)
{
PyErr_Clear
();
break
;
}
if
(
PyString_Check
(
v
))
{
size_t
len
;
len
=
PyString_GET_SIZE
(
v
);
if
(
len
+
1
+
taillen
>=
MAXPATHLEN
)
continue
;
/* Too long */
strcpy
(
namebuf
,
PyString_AsString
(
v
));
if
(
strlen
(
namebuf
)
!=
len
)
continue
;
/* v contains '\0' */
if
(
len
>
0
&&
namebuf
[
len
-
1
]
!=
SEP
)
namebuf
[
len
++
]
=
SEP
;
strcpy
(
namebuf
+
len
,
tail
);
xfp
=
fopen
(
namebuf
,
"r"
PY_STDIOTEXTMODE
);
if
(
xfp
!=
NULL
)
{
break
;
}
}
}
}
}
if
(
xfp
==
NULL
)
return
err
;
if
(
err
!=
0
)
{
fclose
(
xfp
);
return
err
;
}
for
(
i
=
0
;
i
<
lineno
;
i
++
)
{
char
*
pLastChar
=
&
linebuf
[
sizeof
(
linebuf
)
-
2
];
do
{
*
pLastChar
=
'\0'
;
if
(
Py_UniversalNewlineFgets
(
linebuf
,
sizeof
linebuf
,
xfp
,
NULL
)
==
NULL
)
break
;
/* fgets read *something*; if it didn't get as
far as pLastChar, it must have found a newline
or hit the end of the file; if pLastChar is \n,
it obviously found a newline; else we haven't
yet seen a newline, so must continue */
}
while
(
*
pLastChar
!=
'\0'
&&
*
pLastChar
!=
'\n'
);
}
if
(
i
==
lineno
)
{
char
buf
[
11
];
char
*
p
=
linebuf
;
while
(
*
p
==
' '
||
*
p
==
'\t'
||
*
p
==
'\014'
)
p
++
;
/* Write some spaces before the line */
strcpy
(
buf
,
" "
);
assert
(
strlen
(
buf
)
==
10
);
while
(
indent
>
0
)
{
if
(
indent
<
10
)
buf
[
indent
]
=
'\0'
;
err
=
PyFile_WriteString
(
buf
,
f
);
if
(
err
!=
0
)
break
;
indent
-=
10
;
}
if
(
err
==
0
)
err
=
PyFile_WriteString
(
p
,
f
);
if
(
err
==
0
&&
strchr
(
p
,
'\n'
)
==
NULL
)
err
=
PyFile_WriteString
(
"
\n
"
,
f
);
}
fclose
(
xfp
);
return
err
;
}
static
int
tb_displayline
(
PyObject
*
f
,
const
char
*
filename
,
int
lineno
,
const
char
*
name
)
{
int
err
=
0
;
char
linebuf
[
2000
];
if
(
filename
==
NULL
||
name
==
NULL
)
return
-
1
;
/* This is needed by Emacs' compile command */
#define FMT " File \"%.500s\", line %d, in %.500s\n"
PyOS_snprintf
(
linebuf
,
sizeof
(
linebuf
),
FMT
,
filename
,
lineno
,
name
);
err
=
PyFile_WriteString
(
linebuf
,
f
);
if
(
err
!=
0
)
return
err
;
return
_Py_DisplaySourceLine
(
f
,
filename
,
lineno
,
4
);
}
static
int
tb_printinternal
(
PyTracebackObject
*
tb
,
PyObject
*
f
,
long
limit
)
{
int
err
=
0
;
long
depth
=
0
;
PyTracebackObject
*
tb1
=
tb
;
while
(
tb1
!=
NULL
)
{
depth
++
;
tb1
=
tb1
->
tb_next
;
}
while
(
tb
!=
NULL
&&
err
==
0
)
{
if
(
depth
<=
limit
)
{
/*
// Pyston change: we can't directly access the fields
err = tb_displayline(f,
PyString_AsString(
tb->tb_frame->f_code->co_filename),
tb->tb_lineno,
PyString_AsString(tb->tb_frame->f_code->co_name));
*/
PyCodeObject
*
code
=
(
PyCodeObject
*
)
PyFrame_GetCode
(
tb
->
tb_frame
);
err
=
tb_displayline
(
f
,
PyString_AsString
(
PyCode_GetFilename
(
code
)),
tb
->
tb_lineno
,
PyString_AsString
(
PyCode_GetName
(
code
)));
}
depth
--
;
tb
=
tb
->
tb_next
;
if
(
err
==
0
)
err
=
PyErr_CheckSignals
();
}
return
err
;
}
int
PyTraceBack_Print
(
PyObject
*
v
,
PyObject
*
f
)
{
int
err
;
PyObject
*
limitv
;
long
limit
=
1000
;
if
(
v
==
NULL
)
return
0
;
if
(
!
PyTraceBack_Check
(
v
))
{
PyErr_BadInternalCall
();
return
-
1
;
}
limitv
=
PySys_GetObject
(
"tracebacklimit"
);
if
(
limitv
&&
PyInt_Check
(
limitv
))
{
limit
=
PyInt_AsLong
(
limitv
);
if
(
limit
<=
0
)
return
0
;
}
err
=
PyFile_WriteString
(
"Traceback (most recent call last):
\n
"
,
f
);
if
(
!
err
)
err
=
tb_printinternal
((
PyTracebackObject
*
)
v
,
f
,
limit
);
return
err
;
}
src/CMakeLists.txt
View file @
97f3f482
...
...
@@ -103,7 +103,6 @@ add_library(PYSTON_OBJECTS OBJECT ${OPTIONAL_SRCS}
runtime/set.cpp
runtime/str.cpp
runtime/super.cpp
runtime/traceback.cpp
runtime/tuple.cpp
runtime/types.cpp
runtime/util.cpp
...
...
src/capi/errors.cpp
View file @
97f3f482
...
...
@@ -538,4 +538,63 @@ extern "C" PyObject* PyErr_ProgramText(const char* filename, int lineno) noexcep
}
return
NULL
;
}
/* Set file and line information for the current exception.
If the exception is not a SyntaxError, also sets additional attributes
to make printing of exceptions believe it is a syntax error. */
extern
"C"
void
PyErr_SyntaxLocation
(
const
char
*
filename
,
int
lineno
)
noexcept
{
PyObject
*
exc
,
*
v
,
*
tb
,
*
tmp
;
/* add attributes for the line number and filename for the error */
PyErr_Fetch
(
&
exc
,
&
v
,
&
tb
);
PyErr_NormalizeException
(
&
exc
,
&
v
,
&
tb
);
/* XXX check that it is, indeed, a syntax error. It might not
* be, though. */
tmp
=
PyInt_FromLong
(
lineno
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"lineno"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
if
(
filename
!=
NULL
)
{
tmp
=
PyString_FromString
(
filename
);
if
(
tmp
==
NULL
)
PyErr_Clear
();
else
{
if
(
PyObject_SetAttrString
(
v
,
"filename"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
tmp
=
PyErr_ProgramText
(
filename
,
lineno
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"text"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
}
if
(
PyObject_SetAttrString
(
v
,
"offset"
,
Py_None
))
{
PyErr_Clear
();
}
if
(
exc
!=
PyExc_SyntaxError
)
{
if
(
!
PyObject_HasAttrString
(
v
,
"msg"
))
{
tmp
=
PyObject_Str
(
v
);
if
(
tmp
)
{
if
(
PyObject_SetAttrString
(
v
,
"msg"
,
tmp
))
PyErr_Clear
();
Py_DECREF
(
tmp
);
}
else
{
PyErr_Clear
();
}
}
if
(
!
PyObject_HasAttrString
(
v
,
"print_file_and_line"
))
{
if
(
PyObject_SetAttrString
(
v
,
"print_file_and_line"
,
Py_None
))
PyErr_Clear
();
}
}
PyErr_Restore
(
exc
,
v
,
tb
);
}
}
src/codegen/ast_interpreter.cpp
View file @
97f3f482
...
...
@@ -346,9 +346,8 @@ Box* ASTInterpreter::execJITedBlock(CFGBlock* b) {
assert
(
getPythonFrameInfo
(
0
)
==
getFrameInfo
());
auto
source
=
getMD
()
->
source
.
get
();
stmt
->
cxx_exception_count
++
;
caughtCxxException
(
LineInfo
(
stmt
->
lineno
,
stmt
->
col_offset
,
source
->
getFn
(),
source
->
getName
()),
&
e
);
caughtCxxException
(
&
e
);
next_block
=
((
AST_Invoke
*
)
stmt
)
->
exc_dest
;
last_exception
=
e
;
...
...
@@ -827,13 +826,13 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
finishJITing
(
next_block
);
}
}
catch
(
ExcInfo
e
)
{
assert
(
node
==
getCurrentStatement
());
abortJITing
();
assert
(
getPythonFrameInfo
(
0
)
==
getFrameInfo
());
auto
source
=
getMD
()
->
source
.
get
();
node
->
cxx_exception_count
++
;
caughtCxxException
(
LineInfo
(
node
->
lineno
,
node
->
col_offset
,
source
->
getFn
(),
source
->
getName
()),
&
e
);
caughtCxxException
(
&
e
);
next_block
=
node
->
exc_dest
;
last_exception
=
e
;
...
...
src/codegen/irgen/irgenerator.cpp
View file @
97f3f482
...
...
@@ -2929,8 +2929,7 @@ public:
phi_node
=
emitter
.
getBuilder
()
->
CreatePHI
(
g
.
llvm_aststmt_type_ptr
,
0
);
emitter
.
emitSetCurrentStmt
(
current_stmt
);
emitter
.
getBuilder
()
->
CreateCall
(
g
.
funcs
.
caughtCapiException
,
{
phi_node
,
embedRelocatablePtr
(
irstate
->
getSourceInfo
(),
g
.
i8_ptr
)
});
emitter
.
getBuilder
()
->
CreateCall
(
g
.
funcs
.
caughtCapiException
);
if
(
!
final_dest
)
{
// Propagate the exception out of the function:
...
...
src/codegen/unwinding.cpp
View file @
97f3f482
...
...
@@ -41,7 +41,6 @@
#include "runtime/ctxswitching.h"
#include "runtime/objmodel.h"
#include "runtime/generator.h"
#include "runtime/traceback.h"
#include "runtime/types.h"
...
...
@@ -560,8 +559,7 @@ public:
if
(
exceptionAtLineCheck
())
{
// TODO: shouldn't fetch this multiple times?
frame_iter
.
getCurrentStatement
()
->
cxx_exception_count
++
;
auto
line_info
=
lineInfoForFrameInfo
(
prev_frame_info
);
exceptionAtLine
(
line_info
,
&
exc_info
.
traceback
);
exceptionAtLine
(
&
exc_info
.
traceback
);
}
}
}
...
...
@@ -682,39 +680,6 @@ template <typename Func> void unwindPythonStack(Func func) {
//
// 4. Unless we've hit the end of the stack, go to 2 and keep unwinding.
//
static
StatCounter
us_gettraceback
(
"us_gettraceback"
);
Box
*
getTraceback
()
{
STAT_TIMER
(
t0
,
"us_timer_gettraceback"
,
20
);
if
(
!
ENABLE_FRAME_INTROSPECTION
)
{
static
bool
printed_warning
=
false
;
if
(
!
printed_warning
)
{
printed_warning
=
true
;
fprintf
(
stderr
,
"Warning: can't get traceback since ENABLE_FRAME_INTROSPECTION=0
\n
"
);
}
return
None
;
}
if
(
!
ENABLE_TRACEBACKS
)
{
static
bool
printed_warning
=
false
;
if
(
!
printed_warning
)
{
printed_warning
=
true
;
fprintf
(
stderr
,
"Warning: can't get traceback since ENABLE_TRACEBACKS=0
\n
"
);
}
return
None
;
}
Timer
_t
(
"getTraceback"
,
1000
);
Box
*
tb
=
None
;
for
(
FrameInfo
*
frame_info
=
getTopFrameInfo
();
frame_info
;
frame_info
=
frame_info
->
back
)
{
BoxedTraceback
::
here
(
lineInfoForFrameInfo
(
frame_info
),
&
tb
,
getFrame
(
frame_info
));
}
long
us
=
_t
.
end
();
us_gettraceback
.
log
(
us
);
return
static_cast
<
BoxedTraceback
*>
(
tb
);
}
ExcInfo
*
getFrameExcInfo
()
{
std
::
vector
<
ExcInfo
*>
to_update
;
...
...
@@ -1042,7 +1007,10 @@ void _printStacktrace() {
}
recursive
=
true
;
printTraceback
(
getTraceback
());
Box
*
file
=
PySys_GetObject
(
"stderr"
);
PyTracebackObject
*
tb
=
NULL
;
PyTraceBack_Here_Tb
((
struct
_frame
*
)
getFrame
(
0
),
&
tb
);
PyTraceBack_Print
((
Box
*
)
tb
,
file
);
recursive
=
false
;
}
...
...
@@ -1057,26 +1025,23 @@ extern "C" void abort() {
Stats
::
dump
();
fprintf
(
stderr
,
"Someone called abort!
\n
"
);
// If traceback_cls is NULL, then we somehow died early on, and won't be able to display a traceback.
if
(
traceback_cls
)
{
// If we call abort(), things may be seriously wrong. Set an alarm() to
// try to handle cases that we would just hang.
// (Ex if we abort() from a static constructor, and _printStackTrace uses
// that object, _printStackTrace will hang waiting for the first construction
// to finish.)
alarm
(
1
);
try
{
_printStacktrace
();
}
catch
(
ExcInfo
)
{
fprintf
(
stderr
,
"error printing stack trace during abort()"
);
}
// Cancel the alarm.
// This is helpful for when running in a debugger, since otherwise the debugger will catch the
// abort and let you investigate, but the alarm will still come back to kill the program.
alarm
(
0
);
// If we call abort(), things may be seriously wrong. Set an alarm() to
// try to handle cases that we would just hang.
// (Ex if we abort() from a static constructor, and _printStackTrace uses
// that object, _printStackTrace will hang waiting for the first construction
// to finish.)
alarm
(
1
);
try
{
_printStacktrace
();
}
catch
(
ExcInfo
)
{
fprintf
(
stderr
,
"error printing stack trace during abort()"
);
}
// Cancel the alarm.
// This is helpful for when running in a debugger, since otherwise the debugger will catch the
// abort and let you investigate, but the alarm will still come back to kill the program.
alarm
(
0
);
}
if
(
PAUSE_AT_ABORT
)
{
...
...
src/codegen/unwinding.h
View file @
97f3f482
...
...
@@ -28,7 +28,6 @@ namespace pyston {
class
Box
;
class
BoxedDict
;
class
BoxedModule
;
class
BoxedTraceback
;
struct
FrameInfo
;
void
registerDynamicEhFrame
(
uint64_t
code_addr
,
size_t
code_size
,
uint64_t
eh_frame_addr
,
size_t
eh_frame_size
);
...
...
@@ -41,8 +40,6 @@ Box* getGlobals(); // returns either the module or a globals dict
Box
*
getGlobalsDict
();
// always returns a dict-like object
CompiledFunction
*
getCFForAddress
(
uint64_t
addr
);
Box
*
getTraceback
();
class
PythonUnwindSession
;
PythonUnwindSession
*
beginPythonUnwindSession
();
PythonUnwindSession
*
getActivePythonUnwindSession
();
...
...
@@ -54,9 +51,9 @@ void unwindingThroughFrame(PythonUnwindSession* unwind_session, unw_cursor_t* cu
void
logException
(
ExcInfo
*
exc_info
);
void
startReraise
();
bool
exceptionAtLineCheck
();
void
exceptionAtLine
(
LineInfo
line_info
,
Box
**
traceback
);
void
caughtCxxException
(
LineInfo
line_info
,
ExcInfo
*
exc_info
);
extern
"C"
void
caughtCapiException
(
AST_stmt
*
current_stmt
,
void
*
source_info
);
void
exceptionAtLine
(
Box
**
traceback
);
void
caughtCxxException
(
ExcInfo
*
exc_info
);
extern
"C"
void
caughtCapiException
();
extern
"C"
void
reraiseCapiExcAsCxx
()
__attribute__
((
noreturn
));
...
...
src/runtime/capi.cpp
View file @
97f3f482
...
...
@@ -43,7 +43,6 @@
#include "runtime/import.h"
#include "runtime/objmodel.h"
#include "runtime/rewrite_args.h"
#include "runtime/traceback.h"
#include "runtime/types.h"
namespace
pyston
{
...
...
@@ -936,13 +935,6 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept {
return
PyInstance_Check
(
o
)
?
(
Box
*
)
static_cast
<
BoxedInstance
*>
(
o
)
->
inst_cls
:
o
->
cls
;
}
extern
"C"
int
PyTraceBack_Print
(
PyObject
*
v
,
PyObject
*
f
)
noexcept
{
RELEASE_ASSERT
(
f
->
cls
==
&
PyFile_Type
&&
((
PyFileObject
*
)
f
)
->
f_fp
==
stderr
,
"sorry will only print tracebacks to stderr right now"
);
printTraceback
(
v
);
return
0
;
}
#define Py_DEFAULT_RECURSION_LIMIT 1000
static
int
recursion_limit
=
Py_DEFAULT_RECURSION_LIMIT
;
extern
"C"
{
...
...
src/runtime/code.cpp
View file @
97f3f482
...
...
@@ -110,6 +110,15 @@ extern "C" int PyCode_GetArgCount(PyCodeObject* op) noexcept {
return
unboxInt
(
BoxedCode
::
argcount
((
Box
*
)
op
,
NULL
));
}
extern
"C"
PyObject
*
PyCode_GetFilename
(
PyCodeObject
*
op
)
noexcept
{
RELEASE_ASSERT
(
PyCode_Check
((
Box
*
)
op
),
""
);
return
BoxedCode
::
filename
((
Box
*
)
op
,
NULL
);
}
extern
"C"
PyObject
*
PyCode_GetName
(
PyCodeObject
*
op
)
noexcept
{
RELEASE_ASSERT
(
PyCode_Check
((
Box
*
)
op
),
""
);
return
BoxedCode
::
name
((
Box
*
)
op
,
NULL
);
}
void
setupCode
()
{
code_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedCode
),
false
,
"code"
,
true
,
NULL
,
NULL
,
false
);
...
...
src/runtime/cxx_unwind.cpp
View file @
97f3f482
...
...
@@ -27,7 +27,6 @@
#include "core/types.h" // for ExcInfo
#include "core/util.h" // Timer
#include "runtime/generator.h" // generatorEntry
#include "runtime/traceback.h" // BoxedTraceback::addLine
#define UNW_LOCAL_ONLY
#include <libunwind.h>
...
...
src/runtime/exceptions.cpp
View file @
97f3f482
...
...
@@ -20,7 +20,6 @@
#include "core/ast.h"
#include "core/options.h"
#include "runtime/objmodel.h"
#include "runtime/traceback.h"
#include "runtime/types.h"
#include "runtime/util.h"
...
...
@@ -35,8 +34,6 @@ void raiseExc(STOLEN(Box*) exc_obj) {
// of the syntax error in the traceback, even though it is not part of the execution:
void
raiseSyntaxError
(
const
char
*
msg
,
int
lineno
,
int
col_offset
,
llvm
::
StringRef
file
,
llvm
::
StringRef
func
,
bool
compiler_error
)
{
Box
*
exc
;
Box
*
tb
=
None
;
if
(
compiler_error
)
{
// This is how CPython's compiler_error() works:
assert
(
file
.
data
()[
file
.
size
()]
==
'\0'
);
...
...
@@ -47,15 +44,14 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, llvm::StringR
}
auto
args
=
BoxedTuple
::
create
({
boxString
(
file
),
boxInt
(
lineno
),
None
,
loc
});
exc
=
runtimeCall
(
SyntaxError
,
ArgPassSpec
(
2
),
boxString
(
msg
),
args
,
NULL
,
NULL
,
NULL
);
Box
*
exc
=
runtimeCall
(
SyntaxError
,
ArgPassSpec
(
2
),
boxString
(
msg
),
args
,
NULL
,
NULL
,
NULL
);
assert
(
!
PyErr_Occurred
());
throw
ExcInfo
(
exc
->
cls
,
exc
,
None
);
}
else
{
// This is more like how the parser handles it:
exc
=
runtimeCall
(
SyntaxError
,
ArgPassSpec
(
1
),
boxString
(
msg
),
NULL
,
NULL
,
NULL
,
NULL
);
t
b
=
new
BoxedTraceback
(
LineInfo
(
lineno
,
col_offset
,
boxString
(
file
),
boxString
(
func
)),
None
,
getFrame
(
0
)
);
PyErr_SetString
(
SyntaxError
,
msg
);
PyErr_SyntaxLocation
(
file
.
str
().
c_str
(),
lineno
);
t
hrowCAPIException
(
);
}
assert
(
!
PyErr_Occurred
());
throw
ExcInfo
(
exc
->
cls
,
exc
,
tb
);
}
void
raiseSyntaxErrorHelper
(
llvm
::
StringRef
file
,
llvm
::
StringRef
func
,
AST
*
node_at
,
const
char
*
msg
,
...)
{
...
...
@@ -257,12 +253,9 @@ void logException(ExcInfo* exc_info) {
#endif
}
extern
"C"
void
caughtCapiException
(
AST_stmt
*
stmt
,
void
*
_source_info
)
{
SourceInfo
*
source
=
static_cast
<
SourceInfo
*>
(
_source_info
);
extern
"C"
void
caughtCapiException
()
{
PyThreadState
*
tstate
=
PyThreadState_GET
();
exceptionAtLine
(
LineInfo
(
stmt
->
lineno
,
stmt
->
col_offset
,
source
->
getFn
(),
source
->
getName
()),
&
tstate
->
curexc_traceback
);
exceptionAtLine
(
&
tstate
->
curexc_traceback
);
}
extern
"C"
void
reraiseCapiExcAsCxx
()
{
...
...
@@ -275,16 +268,17 @@ extern "C" void reraiseCapiExcAsCxx() {
throw
e
;
}
// XXX rename this
extern
"C"
void
rawThrow
(
Box
*
type
,
Box
*
value
,
Box
*
tb
)
{
startReraise
();
throw
ExcInfo
(
type
,
value
,
tb
);
}
void
caughtCxxException
(
LineInfo
line_info
,
ExcInfo
*
exc_info
)
{
void
caughtCxxException
(
ExcInfo
*
exc_info
)
{
static
StatCounter
frames_unwound
(
"num_frames_unwound_python"
);
frames_unwound
.
log
();
exceptionAtLine
(
line_info
,
&
exc_info
->
traceback
);
exceptionAtLine
(
&
exc_info
->
traceback
);
}
...
...
@@ -302,9 +296,11 @@ bool exceptionAtLineCheck() {
return
true
;
}
void
exceptionAtLine
(
LineInfo
line_info
,
Box
**
traceback
)
{
if
(
exceptionAtLineCheck
())
BoxedTraceback
::
here
(
line_info
,
traceback
,
autoDecref
(
getFrame
((
FrameInfo
*
)
cur_thread_state
.
frame_info
)));
void
exceptionAtLine
(
Box
**
traceback
)
{
if
(
exceptionAtLineCheck
())
{
PyTraceBack_Here_Tb
((
struct
_frame
*
)
autoDecref
(
getFrame
((
FrameInfo
*
)
cur_thread_state
.
frame_info
)),
(
PyTracebackObject
**
)
traceback
);
}
}
void
startReraise
()
{
...
...
src/runtime/frame.cpp
View file @
97f3f482
...
...
@@ -21,7 +21,9 @@
namespace
pyston
{
extern
"C"
{
BoxedClass
*
frame_cls
;
}
// Issues:
// - breaks gdb backtraces
...
...
@@ -225,6 +227,9 @@ extern "C" int PyFrame_GetLineNumber(PyFrameObject* _f) noexcept {
extern
"C"
PyObject
*
PyFrame_GetGlobals
(
PyFrameObject
*
f
)
noexcept
{
return
BoxedFrame
::
globals
((
Box
*
)
f
,
NULL
);
}
extern
"C"
PyObject
*
PyFrame_GetCode
(
PyFrameObject
*
f
)
noexcept
{
return
BoxedFrame
::
code
((
Box
*
)
f
,
NULL
);
}
extern
"C"
PyFrameObject
*
PyFrame_ForStackLevel
(
int
stack_level
)
noexcept
{
return
(
PyFrameObject
*
)
getFrame
(
stack_level
);
...
...
src/runtime/objmodel.cpp
View file @
97f3f482
...
...
@@ -3034,7 +3034,7 @@ extern "C" bool nonzero(Box* obj) {
}
ASSERT
(
obj
->
cls
->
is_user_defined
||
obj
->
cls
->
instances_are_nonzero
||
obj
->
cls
==
classobj_cls
||
obj
->
cls
==
type_cls
||
isSubclass
(
obj
->
cls
,
Exception
)
||
obj
->
cls
==
&
PyFile_Type
||
obj
->
cls
==
traceback_cls
||
obj
->
cls
==
instancemethod_cls
||
obj
->
cls
==
module_cls
||
obj
->
cls
==
&
PyTraceBack_Type
||
obj
->
cls
==
instancemethod_cls
||
obj
->
cls
==
module_cls
||
obj
->
cls
==
capifunc_cls
||
obj
->
cls
==
builtin_function_or_method_cls
||
obj
->
cls
==
method_cls
||
obj
->
cls
==
frame_cls
||
obj
->
cls
==
generator_cls
||
obj
->
cls
==
capi_getset_cls
||
obj
->
cls
==
pyston_getset_cls
||
obj
->
cls
==
wrapperdescr_cls
...
...
src/runtime/traceback.cpp
deleted
100644 → 0
View file @
db8b9589
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// 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.
#include "runtime/traceback.h"
#include <algorithm>
#include <cstring>
#include <sstream>
#include "capi/types.h"
#include "core/ast.h"
#include "core/common.h"
#include "core/stats.h"
#include "core/types.h"
#include "runtime/inline/list.h"
#include "runtime/list.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
#include "runtime/util.h"
namespace
pyston
{
extern
"C"
{
BoxedClass
*
traceback_cls
;
}
void
printTraceback
(
Box
*
b
)
{
if
(
b
==
None
)
return
;
assert
(
b
->
cls
==
traceback_cls
);
BoxedTraceback
*
tb
=
static_cast
<
BoxedTraceback
*>
(
b
);
fprintf
(
stderr
,
"Traceback (most recent call last):
\n
"
);
for
(;
tb
&&
tb
!=
None
;
tb
=
static_cast
<
BoxedTraceback
*>
(
tb
->
tb_next
))
{
auto
&
line
=
tb
->
line
;
fprintf
(
stderr
,
" File
\"
%s
\"
, line %d, in %s
\n
"
,
line
.
file
->
c_str
(),
line
.
line
,
line
.
func
->
c_str
());
if
(
line
.
line
<
0
)
continue
;
FILE
*
f
=
fopen
(
line
.
file
->
c_str
(),
"r"
);
if
(
f
)
{
assert
(
line
.
line
<
10000000
&&
"Refusing to try to seek that many lines forward"
);
for
(
int
i
=
1
;
i
<
line
.
line
;
i
++
)
{
char
*
buf
=
NULL
;
size_t
size
;
size_t
r
=
getline
(
&
buf
,
&
size
,
f
);
if
(
r
!=
-
1
)
free
(
buf
);
}
char
*
buf
=
NULL
;
size_t
size
;
size_t
r
=
getline
(
&
buf
,
&
size
,
f
);
if
(
r
!=
-
1
)
{
while
(
buf
[
r
-
1
]
==
'\n'
or
buf
[
r
-
1
]
==
'\r'
)
r
--
;
char
*
ptr
=
buf
;
while
(
*
ptr
==
' '
||
*
ptr
==
'\t'
)
{
ptr
++
;
r
--
;
}
fprintf
(
stderr
,
" %.*s
\n
"
,
(
int
)
r
,
ptr
);
free
(
buf
);
}
fclose
(
f
);
}
}
}
void
BoxedTraceback
::
dealloc
(
Box
*
b
)
noexcept
{
BoxedTraceback
*
self
=
static_cast
<
BoxedTraceback
*>
(
b
);
Py_DECREF
(
self
->
tb_next
);
Py_DECREF
(
self
->
line
.
file
);
Py_DECREF
(
self
->
line
.
func
);
Py_DECREF
(
self
->
tb_frame
);
PyObject_GC_Del
(
b
);
}
int
BoxedTraceback
::
traverse
(
Box
*
self
,
visitproc
visit
,
void
*
arg
)
noexcept
{
BoxedTraceback
*
tb
=
static_cast
<
BoxedTraceback
*>
(
self
);
Py_VISIT
(
tb
->
tb_next
);
Py_VISIT
(
tb
->
tb_frame
);
Py_VISIT
(
tb
->
line
.
file
);
Py_VISIT
(
tb
->
line
.
func
);
return
0
;
}
int
BoxedTraceback
::
clear
(
Box
*
self
)
noexcept
{
abort
();
}
void
BoxedTraceback
::
here
(
LineInfo
lineInfo
,
Box
**
tb
,
Box
*
frame
)
{
Box
*
old_tb
=
*
tb
;
*
tb
=
new
BoxedTraceback
(
std
::
move
(
lineInfo
),
*
tb
,
frame
);
Py_DECREF
(
old_tb
);
}
extern
"C"
int
_Py_DisplaySourceLine
(
PyObject
*
f
,
const
char
*
filename
,
int
lineno
,
int
indent
)
noexcept
{
RELEASE_ASSERT
(
0
,
"Not implemented."
);
}
void
setupTraceback
()
{
traceback_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedTraceback
),
false
,
"traceback"
,
true
,
(
destructor
)
BoxedTraceback
::
dealloc
,
NULL
,
true
,
(
traverseproc
)
BoxedTraceback
::
traverse
,
(
inquiry
)
BoxedTraceback
::
clear
);
/*
* Currently not supported.
traceback_cls->giveAttr("tb_lasti", new (pyston_getset_cls) BoxedGetsetDescriptor(traceback_tb_lasti, NULL, NULL));
*/
traceback_cls
->
giveAttr
(
"tb_frame"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedTraceback
,
tb_frame
)));
traceback_cls
->
giveAttr
(
"tb_next"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedTraceback
,
tb_next
)));
traceback_cls
->
giveAttr
(
"tb_lineno"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
INT
,
offsetof
(
BoxedTraceback
,
line
)
+
offsetof
(
LineInfo
,
line
)));
traceback_cls
->
freeze
();
}
}
src/runtime/traceback.h
deleted
100644 → 0
View file @
db8b9589
// Copyright (c) 2014-2015 Dropbox, Inc.
//
// 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_RUNTIME_TRACEBACK_H
#define PYSTON_RUNTIME_TRACEBACK_H
#include "core/types.h"
#include "runtime/types.h"
namespace
pyston
{
namespace
gc
{
class
GCVisitor
;
}
extern
"C"
BoxedClass
*
traceback_cls
;
class
BoxedTraceback
:
public
Box
{
public:
LineInfo
line
;
Box
*
tb_next
;
Box
*
tb_frame
;
BoxedTraceback
(
LineInfo
line
,
Box
*
tb_next
,
Box
*
tb_frame
)
:
line
(
std
::
move
(
line
)),
tb_next
(
tb_next
),
tb_frame
(
tb_frame
)
{
Py_INCREF
(
tb_next
);
Py_INCREF
(
line
.
file
);
Py_INCREF
(
line
.
func
);
if
(
!
tb_frame
)
this
->
tb_frame
=
None
;
else
assert
(
tb_frame
->
cls
==
frame_cls
);
Py_INCREF
(
this
->
tb_frame
);
}
DEFAULT_CLASS
(
traceback_cls
);
static
Box
*
lineno
(
Box
*
obj
,
void
*
);
static
void
gcHandler
(
gc
::
GCVisitor
*
v
,
Box
*
b
);
// somewhat equivalent to PyTraceBack_Here
static
void
here
(
LineInfo
lineInfo
,
Box
**
tb
,
Box
*
frame
);
static
void
dealloc
(
Box
*
b
)
noexcept
;
static
int
traverse
(
Box
*
self
,
visitproc
visit
,
void
*
arg
)
noexcept
;
static
int
clear
(
Box
*
self
)
noexcept
;
};
void
printTraceback
(
Box
*
b
);
void
setupTraceback
();
}
#endif
src/runtime/types.cpp
View file @
97f3f482
...
...
@@ -47,7 +47,6 @@
#include "runtime/rewrite_args.h"
#include "runtime/set.h"
#include "runtime/super.h"
#include "runtime/traceback.h"
#include "runtime/util.h"
extern
"C"
void
initerrno
();
...
...
@@ -4099,7 +4098,6 @@ void setupRuntime() {
_PyWarnings_Init
();
_string_init
();
setupDescr
();
setupTraceback
();
setupCode
();
setupFrame
();
...
...
@@ -4267,6 +4265,7 @@ void setupRuntime() {
PyType_Ready
(
&
PyCObject_Type
);
PyType_Ready
(
&
PyDictProxy_Type
);
PyType_Ready
(
&
PyTraceBack_Type
);
initerrno
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment