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
67c85513
Commit
67c85513
authored
Jan 20, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'exc_info'
parents
c75e90df
ee9a3a41
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
212 additions
and
36 deletions
+212
-36
Makefile
Makefile
+4
-0
src/analysis/type_analysis.cpp
src/analysis/type_analysis.cpp
+1
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+21
-1
src/codegen/ast_interpreter.h
src/codegen/ast_interpreter.h
+2
-0
src/codegen/codegen.h
src/codegen/codegen.h
+1
-0
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+52
-0
src/codegen/irgen/irgenerator.h
src/codegen/irgen/irgenerator.h
+4
-1
src/codegen/patchpoints.cpp
src/codegen/patchpoints.cpp
+16
-0
src/codegen/runtime_hooks.cpp
src/codegen/runtime_hooks.cpp
+3
-0
src/codegen/stackmaps.h
src/codegen/stackmaps.h
+6
-0
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+47
-7
src/codegen/unwinding.h
src/codegen/unwinding.h
+2
-5
src/core/ast.cpp
src/core/ast.cpp
+3
-0
src/core/ast.h
src/core/ast.h
+1
-0
src/core/cfg.cpp
src/core/cfg.cpp
+17
-1
src/core/types.h
src/core/types.h
+10
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+0
-8
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+6
-3
src/runtime/generator.cpp
src/runtime/generator.cpp
+1
-1
src/runtime/inline/link_forcer.cpp
src/runtime/inline/link_forcer.cpp
+3
-5
src/runtime/stacktrace.cpp
src/runtime/stacktrace.cpp
+8
-3
test/tests/augassign.py
test/tests/augassign.py
+4
-1
No files found.
Makefile
View file @
67c85513
...
...
@@ -969,6 +969,10 @@ test_cpp_ll:
$(CLANGPP_EXE)
$(TEST_DIR)
/test.cpp
-o
test.ll
-c
-O3
-emit-llvm
-S
-std
=
c++11
-g
less test.ll
rm
test.ll
bench_exceptions
:
$(CLANGPP_EXE)
$(TEST_DIR)
/bench_exceptions.cpp
-o
bench_exceptions
-O3
-std
=
c++11
zsh
-c
'ulimit -v
$(MAX_MEM_KB)
; ulimit -d
$(MAX_MEM_KB)
; time ./bench_exceptions'
rm
bench_exceptions
TEST_EXT_MODULE_NAMES
:=
basic_test descr_test slots_test
...
...
src/analysis/type_analysis.cpp
View file @
67c85513
...
...
@@ -371,6 +371,7 @@ private:
case
AST_LangPrimitive
:
:
IMPORT_NAME
:
return
UNKNOWN
;
case
AST_LangPrimitive
:
:
NONE
:
case
AST_LangPrimitive
:
:
SET_EXC_INFO
:
return
NONE
;
case
AST_LangPrimitive
:
:
NONZERO
:
return
BOOL
;
...
...
src/codegen/ast_interpreter.cpp
View file @
67c85513
...
...
@@ -127,6 +127,7 @@ private:
BoxedClosure
*
passed_closure
,
*
created_closure
;
BoxedGenerator
*
generator
;
unsigned
edgecount
;
FrameInfo
frame_info
;
public:
AST_stmt
*
getCurrentStatement
()
{
...
...
@@ -135,6 +136,7 @@ public:
}
CompiledFunction
*
getCF
()
{
return
compiled_func
;
}
FrameInfo
*
getFrameInfo
()
{
return
&
frame_info
;
}
const
SymMap
&
getSymbolTable
()
{
return
sym_table
;
}
void
gcVisit
(
GCVisitor
*
visitor
);
};
...
...
@@ -189,6 +191,12 @@ CompiledFunction* getCFForInterpretedFrame(void* frame_ptr) {
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
)
{
ASTInterpreter
*
interpreter
=
s_interpreterMap
[
frame_ptr
];
assert
(
interpreter
);
...
...
@@ -225,7 +233,7 @@ void gatherInterpreterRoots(GCVisitor* visitor) {
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
:
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
),
generator
(
0
),
edgecount
(
0
)
{
generator
(
0
),
edgecount
(
0
)
,
frame_info
(
ExcInfo
(
NULL
,
NULL
,
NULL
))
{
CLFunction
*
f
=
compiled_function
->
clfunc
;
if
(
!
source_info
->
cfg
)
...
...
@@ -590,6 +598,18 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
assert
(
node
->
args
.
size
()
==
1
);
Value
obj
=
visit_expr
(
node
->
args
[
0
]);
v
=
boxBool
(
nonzero
(
obj
.
o
));
}
else
if
(
node
->
opcode
==
AST_LangPrimitive
::
SET_EXC_INFO
)
{
assert
(
node
->
args
.
size
()
==
3
);
Value
type
=
visit_expr
(
node
->
args
[
0
]);
assert
(
type
.
o
);
Value
value
=
visit_expr
(
node
->
args
[
1
]);
assert
(
value
.
o
);
Value
traceback
=
visit_expr
(
node
->
args
[
2
]);
assert
(
traceback
.
o
);
getFrameInfo
()
->
exc
=
ExcInfo
(
type
.
o
,
value
.
o
,
traceback
.
o
);
v
=
None
;
}
else
RELEASE_ASSERT
(
0
,
"not implemented"
);
return
v
;
...
...
src/codegen/ast_interpreter.h
View file @
67c85513
...
...
@@ -35,6 +35,8 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_stmt* start_at, BoxedDict* local
AST_stmt
*
getCurrentStatementForInterpretedFrame
(
void
*
frame_ptr
);
CompiledFunction
*
getCFForInterpretedFrame
(
void
*
frame_ptr
);
struct
FrameInfo
;
FrameInfo
*
getFrameInfoForInterpretedFrame
(
void
*
frame_ptr
);
void
gatherInterpreterRoots
(
gc
::
GCVisitor
*
visitor
);
BoxedDict
*
localsForInterpretedFrame
(
void
*
frame_ptr
,
bool
only_user_visible
);
...
...
src/codegen/codegen.h
View file @
67c85513
...
...
@@ -70,6 +70,7 @@ struct GlobalState {
llvm
::
Type
*
llvm_class_type
,
*
llvm_class_type_ptr
;
llvm
::
Type
*
llvm_opaque_type
;
llvm
::
Type
*
llvm_str_type_ptr
;
llvm
::
Type
*
frame_info_type
;
llvm
::
Type
*
llvm_clfunction_type_ptr
,
*
llvm_closure_type_ptr
,
*
llvm_generator_type_ptr
;
llvm
::
Type
*
llvm_module_type_ptr
,
*
llvm_bool_type_ptr
;
llvm
::
Type
*
llvm_excinfo_type
;
...
...
src/codegen/irgen/irgenerator.cpp
View file @
67c85513
...
...
@@ -38,6 +38,7 @@
namespace
pyston
{
extern
"C"
void
dumpLLVM
(
llvm
::
Value
*
v
)
{
v
->
getType
()
->
dump
();
v
->
dump
();
}
...
...
@@ -71,6 +72,30 @@ llvm::Value* IRGenState::getScratchSpace(int min_bytes) {
return
scratch_space
;
}
llvm
::
Value
*
IRGenState
::
getFrameInfoVar
()
{
if
(
!
frame_info
)
{
llvm
::
BasicBlock
&
entry_block
=
getLLVMFunction
()
->
getEntryBlock
();
llvm
::
IRBuilder
<
true
>
builder
(
&
entry_block
);
if
(
entry_block
.
begin
()
!=
entry_block
.
end
())
builder
.
SetInsertPoint
(
&
entry_block
,
entry_block
.
getFirstInsertionPt
());
llvm
::
AllocaInst
*
al
=
builder
.
CreateAlloca
(
g
.
frame_info_type
,
NULL
,
"frame_info"
);
assert
(
al
->
isStaticAlloca
());
static_assert
(
offsetof
(
FrameInfo
,
exc
)
==
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
);
frame_info
=
al
;
}
return
frame_info
;
}
ScopeInfo
*
IRGenState
::
getScopeInfo
()
{
return
getSourceInfo
()
->
getScopeInfo
();
}
...
...
@@ -575,6 +600,31 @@ private:
return
boolFromI1
(
emitter
,
v
);
}
case
AST_LangPrimitive
:
:
SET_EXC_INFO
:
{
assert
(
node
->
args
.
size
()
==
3
);
CompilerVariable
*
type
=
evalExpr
(
node
->
args
[
0
],
unw_info
);
CompilerVariable
*
value
=
evalExpr
(
node
->
args
[
1
],
unw_info
);
CompilerVariable
*
traceback
=
evalExpr
(
node
->
args
[
2
],
unw_info
);
auto
*
builder
=
emitter
.
getBuilder
();
llvm
::
Value
*
frame_info
=
irstate
->
getFrameInfoVar
();
llvm
::
Value
*
exc_info
=
builder
->
CreateConstInBoundsGEP2_32
(
frame_info
,
0
,
0
);
assert
(
exc_info
->
getType
()
==
g
.
llvm_excinfo_type
->
getPointerTo
());
ConcreteCompilerVariable
*
converted_type
=
type
->
makeConverted
(
emitter
,
UNKNOWN
);
builder
->
CreateStore
(
converted_type
->
getValue
(),
builder
->
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
0
));
converted_type
->
decvref
(
emitter
);
ConcreteCompilerVariable
*
converted_value
=
value
->
makeConverted
(
emitter
,
UNKNOWN
);
builder
->
CreateStore
(
converted_value
->
getValue
(),
builder
->
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
1
));
converted_value
->
decvref
(
emitter
);
ConcreteCompilerVariable
*
converted_traceback
=
traceback
->
makeConverted
(
emitter
,
UNKNOWN
);
builder
->
CreateStore
(
converted_traceback
->
getValue
(),
builder
->
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
2
));
converted_traceback
->
decvref
(
emitter
);
return
getNone
();
}
default:
RELEASE_ASSERT
(
0
,
"%d"
,
node
->
opcode
);
}
...
...
@@ -2240,6 +2290,8 @@ public:
std
::
vector
<
llvm
::
Value
*>&
stackmap_args
)
override
{
int
initial_args
=
stackmap_args
.
size
();
stackmap_args
.
push_back
(
irstate
->
getFrameInfoVar
());
assert
(
INT
->
llvmType
()
==
g
.
i64
);
stackmap_args
.
push_back
(
getConstantInt
((
uint64_t
)
current_stmt
,
g
.
i64
));
pp
->
addFrameVar
(
"!current_stmt"
,
INT
);
...
...
src/codegen/irgen/irgenerator.h
View file @
67c85513
...
...
@@ -58,11 +58,13 @@ private:
llvm
::
MDNode
*
func_dbg_info
;
llvm
::
AllocaInst
*
scratch_space
;
llvm
::
Value
*
frame_info
;
int
scratch_size
;
public:
IRGenState
(
CompiledFunction
*
cf
,
SourceInfo
*
source_info
,
GCBuilder
*
gc
,
llvm
::
MDNode
*
func_dbg_info
)
:
cf
(
cf
),
source_info
(
source_info
),
gc
(
gc
),
func_dbg_info
(
func_dbg_info
),
scratch_space
(
NULL
),
scratch_size
(
0
)
{
:
cf
(
cf
),
source_info
(
source_info
),
gc
(
gc
),
func_dbg_info
(
func_dbg_info
),
scratch_space
(
NULL
),
frame_info
(
NULL
),
scratch_size
(
0
)
{
assert
(
cf
->
func
);
assert
(
!
cf
->
clfunc
);
// in this case don't need to pass in sourceinfo
}
...
...
@@ -76,6 +78,7 @@ public:
GCBuilder
*
getGC
()
{
return
gc
;
}
llvm
::
Value
*
getScratchSpace
(
int
min_bytes
);
llvm
::
Value
*
getFrameInfoVar
();
ConcreteCompilerType
*
getReturnType
()
{
assert
(
cf
->
spec
);
...
...
src/codegen/patchpoints.cpp
View file @
67c85513
...
...
@@ -63,6 +63,12 @@ int PatchpointInfo::patchpointSize() {
return
CALL_ONLY_SIZE
;
}
bool
StackMap
::
Record
::
Location
::
operator
==
(
const
StackMap
::
Record
::
Location
&
rhs
)
{
// TODO: this check is overly-strict. Some fields are not used depending
// on the value of type, and I don't think "flags" is used at all currently.
return
(
type
==
rhs
.
type
)
&&
(
flags
==
rhs
.
flags
)
&&
(
regnum
==
rhs
.
regnum
)
&&
(
offset
==
rhs
.
offset
);
}
void
PatchpointInfo
::
parseLocationMap
(
StackMap
::
Record
*
r
,
LocationMap
*
map
)
{
assert
(
r
->
locations
.
size
()
==
totalStackmapArgs
());
...
...
@@ -70,6 +76,16 @@ void PatchpointInfo::parseLocationMap(StackMap::Record* r, LocationMap* map) {
// printf("parsing pp %ld:\n", reinterpret_cast<int64_t>(this));
StackMap
::
Record
::
Location
frame_info_location
=
r
->
locations
[
cur_arg
];
cur_arg
++
;
// We could allow the frame_info to exist in a different location for each callsite,
// but in reality it will always live at a fixed stack offset.
if
(
map
->
frameInfoFound
())
{
assert
(
frame_info_location
==
map
->
frame_info_location
);
}
else
{
map
->
frame_info_location
=
frame_info_location
;
}
for
(
FrameVarInfo
&
frame_var
:
frame_vars
)
{
int
num_args
=
frame_var
.
type
->
numFrameArgs
();
...
...
src/codegen/runtime_hooks.cpp
View file @
67c85513
...
...
@@ -146,6 +146,9 @@ void initGlobalFuncs(GlobalState& g) {
g
.
llvm_excinfo_type
=
g
.
stdlib_module
->
getTypeByName
(
"struct.pyston::ExcInfo"
);
assert
(
g
.
llvm_excinfo_type
);
g
.
frame_info_type
=
g
.
stdlib_module
->
getTypeByName
(
"struct.pyston::FrameInfo"
);
assert
(
g
.
frame_info_type
);
#define GET(N) g.funcs.N = getFunc((void*)N, STRINGIFY(N))
g
.
funcs
.
printf
=
addFunc
((
void
*
)
printf
,
g
.
i8_ptr
,
true
);
...
...
src/codegen/stackmaps.h
View file @
67c85513
...
...
@@ -48,6 +48,8 @@ struct StackMap {
uint8_t
flags
;
uint16_t
regnum
;
int32_t
offset
;
bool
operator
==
(
const
Location
&
rhs
);
};
struct
__attribute__
((
__packed__
))
LiveOut
{
...
...
@@ -73,6 +75,10 @@ struct StackMap {
class
LocationMap
{
public:
std
::
vector
<
uint64_t
>
constants
;
StackMap
::
Record
::
Location
frame_info_location
;
bool
frameInfoFound
()
{
return
frame_info_location
.
type
!=
0
;
}
struct
LocationTable
{
struct
LocationEntry
{
uint64_t
_debug_pp_id
;
...
...
src/codegen/unwinding.cpp
View file @
67c85513
...
...
@@ -236,6 +236,9 @@ public:
if
(
loc
.
type
==
StackMap
::
Record
::
Location
::
LocationType
::
Register
)
{
// TODO: need to make sure we deal with patchpoints appropriately
return
getReg
(
loc
.
regnum
);
}
else
if
(
loc
.
type
==
StackMap
::
Record
::
Location
::
LocationType
::
Direct
)
{
uint64_t
reg_val
=
getReg
(
loc
.
regnum
);
return
reg_val
+
loc
.
offset
;
}
else
if
(
loc
.
type
==
StackMap
::
Record
::
Location
::
LocationType
::
Indirect
)
{
uint64_t
reg_val
=
getReg
(
loc
.
regnum
);
uint64_t
addr
=
reg_val
+
loc
.
offset
;
...
...
@@ -281,6 +284,19 @@ public:
abort
();
}
FrameInfo
*
getFrameInfo
()
{
if
(
id
.
type
==
PythonFrameId
::
COMPILED
)
{
CompiledFunction
*
cf
=
getCF
();
assert
(
cf
->
location_map
->
frameInfoFound
());
const
auto
&
frame_info_loc
=
cf
->
location_map
->
frame_info_location
;
return
reinterpret_cast
<
FrameInfo
*>
(
readLocation
(
frame_info_loc
));
}
else
if
(
id
.
type
==
PythonFrameId
::
INTERPRETED
)
{
return
getFrameInfoForInterpretedFrame
((
void
*
)
id
.
bp
);
}
abort
();
}
const
PythonFrameId
&
getId
()
const
{
return
id
;
}
static
std
::
unique_ptr
<
PythonFrameIterator
>
end
()
{
return
std
::
unique_ptr
<
PythonFrameIterator
>
(
nullptr
);
}
...
...
@@ -450,6 +466,37 @@ const LineInfo* getMostRecentLineInfo() {
return
lineInfoForFrame
(
*
frame
);
}
ExcInfo
getFrameExcInfo
()
{
std
::
vector
<
ExcInfo
*>
to_update
;
ExcInfo
*
cur_exc
=
NULL
;
for
(
PythonFrameIterator
&
frame_iter
:
unwindPythonFrames
())
{
FrameInfo
*
frame_info
=
frame_iter
.
getFrameInfo
();
cur_exc
=
&
frame_info
->
exc
;
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
()
{
return
getTopPythonFrame
()
->
getCF
();
}
...
...
@@ -460,13 +507,6 @@ BoxedModule* getCurrentModule() {
return
compiledFunction
->
clfunc
->
source
->
parent_module
;
}
ExecutionPoint
getExecutionPoint
()
{
auto
frame
=
getTopPythonFrame
();
auto
cf
=
frame
->
getCF
();
auto
current_stmt
=
frame
->
getCurrentStatement
();
return
ExecutionPoint
({.
cf
=
cf
,
.
current_stmt
=
current_stmt
});
}
BoxedDict
*
getLocals
(
bool
only_user_visible
)
{
for
(
PythonFrameIterator
&
frame_info
:
unwindPythonFrames
())
{
if
(
frame_info
.
getId
().
type
==
PythonFrameId
::
COMPILED
)
{
...
...
src/codegen/unwinding.h
View file @
67c85513
...
...
@@ -30,11 +30,8 @@ CompiledFunction* getCFForAddress(uint64_t addr);
class
BoxedDict
;
BoxedDict
*
getLocals
(
bool
only_user_visible
);
struct
ExecutionPoint
{
CompiledFunction
*
cf
;
AST_stmt
*
current_stmt
;
};
ExecutionPoint
getExecutionPoint
();
// Fetches the frame-local excinfo object, calculating it if necessary (from previous frames):
ExcInfo
getFrameExcInfo
();
}
#endif
src/core/ast.cpp
View file @
67c85513
...
...
@@ -1455,6 +1455,9 @@ bool PrintVisitor::visit_langprimitive(AST_LangPrimitive* node) {
case
AST_LangPrimitive
:
:
NONZERO
:
printf
(
"NONZERO"
);
break
;
case
AST_LangPrimitive
:
:
SET_EXC_INFO
:
printf
(
"SET_EXC_INFO"
);
break
;
default:
RELEASE_ASSERT
(
0
,
"%d"
,
node
->
opcode
);
}
...
...
src/core/ast.h
View file @
67c85513
...
...
@@ -977,6 +977,7 @@ public:
IMPORT_STAR
,
NONE
,
NONZERO
,
SET_EXC_INFO
,
}
opcode
;
std
::
vector
<
AST_expr
*>
args
;
...
...
src/core/cfg.cpp
View file @
67c85513
...
...
@@ -527,6 +527,13 @@ private:
made
->
col_offset
=
orig
->
col_offset
;
made
->
lineno
=
orig
->
lineno
;
return
made
;
}
else
if
(
val
->
type
==
AST_TYPE
::
Index
)
{
AST_Index
*
orig
=
ast_cast
<
AST_Index
>
(
val
);
AST_Index
*
made
=
new
AST_Index
();
made
->
value
=
_dup
(
orig
->
value
);
made
->
col_offset
=
orig
->
col_offset
;
made
->
lineno
=
orig
->
lineno
;
return
made
;
}
else
{
RELEASE_ASSERT
(
0
,
"%d"
,
val
->
type
);
}
...
...
@@ -968,6 +975,8 @@ private:
rtn
=
remapIfExp
(
ast_cast
<
AST_IfExp
>
(
node
));
break
;
case
AST_TYPE
:
:
Index
:
if
(
ast_cast
<
AST_Index
>
(
node
)
->
value
->
type
==
AST_TYPE
::
Num
)
return
node
;
rtn
=
remapIndex
(
ast_cast
<
AST_Index
>
(
node
));
break
;
case
AST_TYPE
:
:
Lambda
:
...
...
@@ -1851,7 +1860,7 @@ public:
cfg
->
placeBlock
(
exc_handler_block
);
curblock
=
exc_handler_block
;
// TODO
: this should be an EXCEPTION_MATCHES(exc_type_name
)
// TODO
This is supposed to be exc_type_name (value doesn't matter for checking matches
)
AST_expr
*
exc_obj
=
makeName
(
exc_value_name
,
AST_TYPE
::
Load
,
node
->
lineno
);
bool
caught_all
=
false
;
...
...
@@ -1862,6 +1871,7 @@ public:
if
(
exc_handler
->
type
)
{
AST_expr
*
handled_type
=
remapExpr
(
exc_handler
->
type
);
// TODO: this should be an EXCEPTION_MATCHES(exc_type_name)
AST_LangPrimitive
*
is_caught_here
=
new
AST_LangPrimitive
(
AST_LangPrimitive
::
ISINSTANCE
);
is_caught_here
->
args
.
push_back
(
_dup
(
exc_obj
));
is_caught_here
->
args
.
push_back
(
handled_type
);
...
...
@@ -1883,6 +1893,12 @@ public:
caught_all
=
true
;
}
AST_LangPrimitive
*
set_exc_info
=
new
AST_LangPrimitive
(
AST_LangPrimitive
::
SET_EXC_INFO
);
set_exc_info
->
args
.
push_back
(
makeName
(
exc_type_name
,
AST_TYPE
::
Load
,
node
->
lineno
));
set_exc_info
->
args
.
push_back
(
makeName
(
exc_value_name
,
AST_TYPE
::
Load
,
node
->
lineno
));
set_exc_info
->
args
.
push_back
(
makeName
(
exc_traceback_name
,
AST_TYPE
::
Load
,
node
->
lineno
));
push_back
(
makeExpr
(
set_exc_info
));
if
(
exc_handler
->
name
)
{
pushAssign
(
exc_handler
->
name
,
_dup
(
exc_obj
));
}
...
...
src/core/types.h
View file @
67c85513
...
...
@@ -476,6 +476,16 @@ struct ExcInfo {
ExcInfo
(
Box
*
type
,
Box
*
value
,
Box
*
traceback
)
:
type
(
type
),
value
(
value
),
traceback
(
traceback
)
{}
bool
matches
(
BoxedClass
*
cls
)
const
;
};
struct
FrameInfo
{
// *Not the same semantics as CPython's frame->f_exc*
// In CPython, f_exc is the saved exc_info from the previous frame.
// In Pyston, exc is the frame-local value of sys.exc_info.
// - This makes frame entering+leaving faster at the expense of slower exceptions.
ExcInfo
exc
;
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
)
{}
};
}
#endif
src/runtime/builtin_modules/builtins.cpp
View file @
67c85513
...
...
@@ -688,13 +688,6 @@ Box* locals() {
return
getLocals
(
true
/* filter */
);
}
Box
*
deopt
()
{
auto
locals
=
getLocals
(
false
/* filter */
);
auto
execution_point
=
getExecutionPoint
();
return
astInterpretFrom
(
execution_point
.
cf
,
execution_point
.
current_stmt
,
locals
);
}
Box
*
divmod
(
Box
*
lhs
,
Box
*
rhs
)
{
return
binopInternal
(
lhs
,
rhs
,
AST_TYPE
::
DivMod
,
false
,
NULL
);
}
...
...
@@ -1054,7 +1047,6 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"globals"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
globals
,
UNKNOWN
,
0
,
0
,
false
,
false
)));
builtins_module
->
giveAttr
(
"locals"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
locals
,
UNKNOWN
,
0
,
0
,
false
,
false
)));
builtins_module
->
giveAttr
(
"deopt"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
deopt
,
UNKNOWN
,
0
,
0
,
false
,
false
)));
builtins_module
->
giveAttr
(
"iter"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
getiter
,
UNKNOWN
,
1
,
0
,
false
,
false
)));
...
...
src/runtime/builtin_modules/sys.cpp
View file @
67c85513
...
...
@@ -19,6 +19,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "codegen/unwinding.h"
#include "core/types.h"
#include "gc/collector.h"
#include "runtime/inline/boxing.h"
...
...
@@ -32,9 +33,11 @@ BoxedModule* sys_module;
BoxedDict
*
sys_modules_dict
;
Box
*
sysExcInfo
()
{
return
new
BoxedTuple
({
cur_thread_state
.
curexc_type
?
cur_thread_state
.
curexc_type
:
None
,
cur_thread_state
.
curexc_value
?
cur_thread_state
.
curexc_value
:
None
,
cur_thread_state
.
curexc_traceback
?
cur_thread_state
.
curexc_traceback
:
None
});
ExcInfo
exc
=
getFrameExcInfo
();
assert
(
exc
.
type
);
assert
(
exc
.
value
);
assert
(
exc
.
traceback
);
return
new
BoxedTuple
({
exc
.
type
,
exc
.
value
,
exc
.
traceback
});
}
static
Box
*
sysExit
(
Box
*
arg
)
{
...
...
src/runtime/generator.cpp
View file @
67c85513
...
...
@@ -100,7 +100,7 @@ Box* generatorThrow(Box* s, BoxedClass* e) {
assert
(
isSubclass
(
e
,
Exception
));
BoxedGenerator
*
self
=
static_cast
<
BoxedGenerator
*>
(
s
);
Box
*
ex
=
exceptionNew1
(
e
);
self
->
exception
=
ExcInfo
(
ex
->
cls
,
ex
,
N
ULL
);
self
->
exception
=
ExcInfo
(
ex
->
cls
,
ex
,
N
one
);
return
generatorSend
(
self
,
None
);
}
...
...
src/runtime/inline/link_forcer.cpp
View file @
67c85513
...
...
@@ -35,13 +35,11 @@ static void forceLink(void* x) {
printf
(
"%p
\n
"
,
x
);
}
extern
"C"
void
__py_personality_v0
()
{
RELEASE_ASSERT
(
0
,
"not used"
);
}
namespace
_force
{
// Force the "FrameInfo" type to make it into the stdlib:
FrameInfo
*
_frame_info_forcer
;
#define FORCE(name) forceLink((void*)name)
void
force
()
{
FORCE
(
softspace
);
...
...
src/runtime/stacktrace.cpp
View file @
67c85513
...
...
@@ -100,6 +100,11 @@ static std::vector<const LineInfo*> last_tb;
void
raiseRaw
(
const
ExcInfo
&
e
)
__attribute__
((
__noreturn__
));
void
raiseRaw
(
const
ExcInfo
&
e
)
{
// Should set these to None before getting here:
assert
(
e
.
type
);
assert
(
e
.
value
);
assert
(
e
.
traceback
);
// Using libgcc:
throw
e
;
...
...
@@ -112,7 +117,7 @@ void raiseExc(Box* exc_obj) {
last_tb
=
std
::
move
(
entries
);
last_exc
=
exc_obj
;
raiseRaw
(
ExcInfo
(
exc_obj
->
cls
,
exc_obj
,
N
ULL
));
raiseRaw
(
ExcInfo
(
exc_obj
->
cls
,
exc_obj
,
N
one
));
}
// Have a special helper function for syntax errors, since we want to include the location
...
...
@@ -125,7 +130,7 @@ void raiseSyntaxError(const char* msg, int lineno, int col_offset, const std::st
// TODO: leaks this!
last_tb
.
push_back
(
new
LineInfo
(
lineno
,
col_offset
,
file
,
func
));
raiseRaw
(
ExcInfo
(
SyntaxError
,
last_exc
,
N
ULL
));
raiseRaw
(
ExcInfo
(
SyntaxError
,
last_exc
,
N
one
));
}
static
void
_printTraceback
(
const
std
::
vector
<
const
LineInfo
*>&
tb
)
{
...
...
@@ -216,7 +221,7 @@ extern "C" void exit(int code) {
}
void
raise0
()
{
raiseRaw
(
ExcInfo
(
last_exc
->
cls
,
last_exc
,
N
ULL
));
raiseRaw
(
ExcInfo
(
last_exc
->
cls
,
last_exc
,
N
one
));
}
bool
ExcInfo
::
matches
(
BoxedClass
*
cls
)
const
{
...
...
test/tests/augassign.py
View file @
67c85513
...
...
@@ -44,4 +44,7 @@ def f2():
f2
()
print
f
(
4
,
2
)
print
f
(
4.1
,
2.3
)
try
:
print
f
(
4.1
,
2.3
)
except
TypeError
,
e
:
print
e
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