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
38388e1b
Commit
38388e1b
authored
Jun 03, 2015
by
Marius Wachtler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Free generator even if the don't exit
parent
3a5b3e50
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
166 additions
and
65 deletions
+166
-65
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+89
-59
src/codegen/ast_interpreter.h
src/codegen/ast_interpreter.h
+1
-1
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+11
-4
src/core/types.h
src/core/types.h
+2
-0
src/gc/collector.cpp
src/gc/collector.cpp
+0
-1
src/runtime/types.cpp
src/runtime/types.cpp
+10
-0
test/tests/generator_collection_finally.py
test/tests/generator_collection_finally.py
+17
-0
test/tests/generator_collection_running.py
test/tests/generator_collection_running.py
+36
-0
No files found.
src/codegen/ast_interpreter.cpp
View file @
38388e1b
...
@@ -53,6 +53,31 @@ namespace pyston {
...
@@ -53,6 +53,31 @@ namespace pyston {
namespace
{
namespace
{
static
BoxedClass
*
astinterpreter_cls
;
class
ASTInterpreter
;
// Map from stack frame pointers for frames corresponding to ASTInterpreter::execute() to the ASTInterpreter handling
// them. Used to look up information about that frame. This is used for getting tracebacks, for CPython introspection
// (sys._getframe & co), and for GC scanning.
static
std
::
unordered_map
<
void
*
,
ASTInterpreter
*>
s_interpreterMap
;
static_assert
(
THREADING_USE_GIL
,
"have to make the interpreter map thread safe!"
);
class
RegisterHelper
{
private:
void
*
frame_addr
;
ASTInterpreter
*
interpreter
;
public:
RegisterHelper
(
ASTInterpreter
*
interpreter
,
void
*
frame_addr
);
~
RegisterHelper
();
static
void
deregister
(
void
*
frame_addr
)
{
assert
(
s_interpreterMap
.
count
(
frame_addr
));
s_interpreterMap
.
erase
(
frame_addr
);
}
};
union
Value
{
union
Value
{
bool
b
;
bool
b
;
int64_t
n
;
int64_t
n
;
...
@@ -68,7 +93,7 @@ union Value {
...
@@ -68,7 +93,7 @@ union Value {
}
}
};
};
class
ASTInterpreter
{
class
ASTInterpreter
:
public
Box
{
public:
public:
typedef
ContiguousMap
<
InternedString
,
Box
*>
SymMap
;
typedef
ContiguousMap
<
InternedString
,
Box
*>
SymMap
;
...
@@ -149,8 +174,11 @@ private:
...
@@ -149,8 +174,11 @@ private:
// This is either a module or a dict
// This is either a module or a dict
Box
*
globals
;
Box
*
globals
;
void
*
frame_addr
;
// used to clear entry inside the s_interpreterMap on destruction
public:
public:
DEFAULT_CLASS_SIMPLE
(
astinterpreter_cls
);
AST_stmt
*
getCurrentStatement
()
{
AST_stmt
*
getCurrentStatement
()
{
assert
(
current_inst
);
assert
(
current_inst
);
return
current_inst
;
return
current_inst
;
...
@@ -175,7 +203,16 @@ public:
...
@@ -175,7 +203,16 @@ public:
void
setFrameInfo
(
const
FrameInfo
*
frame_info
);
void
setFrameInfo
(
const
FrameInfo
*
frame_info
);
void
setGlobals
(
Box
*
globals
);
void
setGlobals
(
Box
*
globals
);
void
gcVisit
(
GCVisitor
*
visitor
);
static
void
gcHandler
(
GCVisitor
*
visitor
,
Box
*
box
);
static
void
simpleDestructor
(
Box
*
box
)
{
ASTInterpreter
*
inter
=
(
ASTInterpreter
*
)
box
;
assert
(
inter
->
cls
==
astinterpreter_cls
);
if
(
inter
->
frame_addr
)
RegisterHelper
::
deregister
(
inter
->
frame_addr
);
inter
->~
ASTInterpreter
();
}
friend
class
RegisterHelper
;
};
};
void
ASTInterpreter
::
addSymbol
(
InternedString
name
,
Box
*
value
,
bool
allow_duplicates
)
{
void
ASTInterpreter
::
addSymbol
(
InternedString
name
,
Box
*
value
,
bool
allow_duplicates
)
{
...
@@ -215,17 +252,17 @@ void ASTInterpreter::setGlobals(Box* globals) {
...
@@ -215,17 +252,17 @@ void ASTInterpreter::setGlobals(Box* globals) {
this
->
globals
=
globals
;
this
->
globals
=
globals
;
}
}
void
ASTInterpreter
::
gc
Visit
(
GCVisitor
*
visitor
)
{
void
ASTInterpreter
::
gc
Handler
(
GCVisitor
*
visitor
,
Box
*
box
)
{
visitor
->
visitRange
((
void
*
const
*
)
&
sym_table
.
vector
()[
0
],
(
void
*
const
*
)
&
sym_table
.
vector
()[
sym_table
.
size
()]
);
boxGCHandler
(
visitor
,
box
);
if
(
passed_closure
)
visitor
->
visit
(
passed_closure
)
;
ASTInterpreter
*
interp
=
(
ASTInterpreter
*
)
box
;
if
(
created_closure
)
auto
&&
vec
=
interp
->
sym_table
.
vector
();
visitor
->
visit
(
created_closure
);
visitor
->
visitRange
((
void
*
const
*
)
&
vec
[
0
],
(
void
*
const
*
)
&
vec
[
interp
->
sym_table
.
size
()]
);
if
(
generator
)
visitor
->
visit
(
interp
->
passed_closure
);
visitor
->
visit
(
generator
);
visitor
->
visit
(
interp
->
created_closure
);
if
(
frame_info
.
boxedLocals
)
visitor
->
visit
(
interp
->
generator
);
visitor
->
visit
(
frame_info
.
boxedLoc
als
);
visitor
->
visit
(
interp
->
glob
als
);
visitor
->
visit
(
globals
);
interp
->
frame_info
.
gcVisit
(
visitor
);
}
}
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
...
@@ -240,7 +277,8 @@ ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
...
@@ -240,7 +277,8 @@ ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
created_closure
(
0
),
created_closure
(
0
),
generator
(
0
),
generator
(
0
),
edgecount
(
0
),
edgecount
(
0
),
frame_info
(
ExcInfo
(
NULL
,
NULL
,
NULL
))
{
frame_info
(
ExcInfo
(
NULL
,
NULL
,
NULL
)),
frame_addr
(
0
)
{
CLFunction
*
f
=
compiled_function
->
clfunc
;
CLFunction
*
f
=
compiled_function
->
clfunc
;
if
(
!
source_info
->
cfg
)
if
(
!
source_info
->
cfg
)
...
@@ -279,25 +317,16 @@ void ASTInterpreter::initArguments(int nargs, BoxedClosure* _closure, BoxedGener
...
@@ -279,25 +317,16 @@ void ASTInterpreter::initArguments(int nargs, BoxedClosure* _closure, BoxedGener
}
}
}
}
// Map from stack frame pointers for frames corresponding to ASTInterpreter::execute() to the ASTInterpreter handling
RegisterHelper
::
RegisterHelper
(
ASTInterpreter
*
interpreter
,
void
*
frame_addr
)
// them. Used to look up information about that frame. This is used for getting tracebacks, for CPython introspection
:
frame_addr
(
frame_addr
),
interpreter
(
interpreter
)
{
// (sys._getframe & co), and for GC scanning.
interpreter
->
frame_addr
=
frame_addr
;
static
std
::
unordered_map
<
void
*
,
ASTInterpreter
*>
s_interpreterMap
;
static_assert
(
THREADING_USE_GIL
,
"have to make the interpreter map thread safe!"
);
class
RegisterHelper
{
private:
void
*
frame_addr
;
public:
RegisterHelper
(
ASTInterpreter
*
interpreter
,
void
*
frame_addr
)
:
frame_addr
(
frame_addr
)
{
s_interpreterMap
[
frame_addr
]
=
interpreter
;
s_interpreterMap
[
frame_addr
]
=
interpreter
;
}
}
~
RegisterHelper
()
{
assert
(
s_interpreterMap
.
count
(
frame_addr
));
RegisterHelper
::~
RegisterHelper
()
{
s_interpreterMap
.
erase
(
frame_addr
)
;
interpreter
->
frame_addr
=
nullptr
;
}
deregister
(
frame_addr
);
}
;
}
Value
ASTInterpreter
::
execute
(
ASTInterpreter
&
interpreter
,
CFGBlock
*
start_block
,
AST_stmt
*
start_at
)
{
Value
ASTInterpreter
::
execute
(
ASTInterpreter
&
interpreter
,
CFGBlock
*
start_block
,
AST_stmt
*
start_at
)
{
STAT_TIMER
(
t0
,
"us_timer_astinterpreter_execute"
);
STAT_TIMER
(
t0
,
"us_timer_astinterpreter_execute"
);
...
@@ -382,7 +411,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
...
@@ -382,7 +411,7 @@ void ASTInterpreter::doStore(AST_expr* node, Value value) {
doStore
(
name
->
id
,
value
);
doStore
(
name
->
id
,
value
);
}
else
if
(
node
->
type
==
AST_TYPE
::
Attribute
)
{
}
else
if
(
node
->
type
==
AST_TYPE
::
Attribute
)
{
AST_Attribute
*
attr
=
(
AST_Attribute
*
)
node
;
AST_Attribute
*
attr
=
(
AST_Attribute
*
)
node
;
setattr
(
visit_expr
(
attr
->
value
).
o
,
attr
->
attr
.
c_str
(),
value
.
o
);
pyston
::
setattr
(
visit_expr
(
attr
->
value
).
o
,
attr
->
attr
.
c_str
(),
value
.
o
);
}
else
if
(
node
->
type
==
AST_TYPE
::
Tuple
)
{
}
else
if
(
node
->
type
==
AST_TYPE
::
Tuple
)
{
AST_Tuple
*
tuple
=
(
AST_Tuple
*
)
node
;
AST_Tuple
*
tuple
=
(
AST_Tuple
*
)
node
;
Box
**
array
=
unpackIntoArray
(
value
.
o
,
tuple
->
elts
.
size
());
Box
**
array
=
unpackIntoArray
(
value
.
o
,
tuple
->
elts
.
size
());
...
@@ -897,7 +926,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
...
@@ -897,7 +926,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
}
}
case
AST_TYPE
:
:
Attribute
:
{
case
AST_TYPE
:
:
Attribute
:
{
AST_Attribute
*
attr
=
(
AST_Attribute
*
)
target_
;
AST_Attribute
*
attr
=
(
AST_Attribute
*
)
target_
;
delattr
(
visit_expr
(
attr
->
value
).
o
,
attr
->
attr
.
c_str
());
pyston
::
delattr
(
visit_expr
(
attr
->
value
).
o
,
attr
->
attr
.
c_str
());
break
;
break
;
}
}
case
AST_TYPE
:
:
Name
:
{
case
AST_TYPE
:
:
Name
:
{
...
@@ -1237,7 +1266,7 @@ Value ASTInterpreter::visit_tuple(AST_Tuple* node) {
...
@@ -1237,7 +1266,7 @@ Value ASTInterpreter::visit_tuple(AST_Tuple* node) {
}
}
Value
ASTInterpreter
::
visit_attribute
(
AST_Attribute
*
node
)
{
Value
ASTInterpreter
::
visit_attribute
(
AST_Attribute
*
node
)
{
return
getattr
(
visit_expr
(
node
->
value
).
o
,
node
->
attr
.
c_str
());
return
pyston
::
getattr
(
visit_expr
(
node
->
value
).
o
,
node
->
attr
.
c_str
());
}
}
}
}
...
@@ -1261,23 +1290,23 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
...
@@ -1261,23 +1290,23 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
}
}
++
cf
->
times_called
;
++
cf
->
times_called
;
ASTInterpreter
i
nterpreter
(
cf
);
ASTInterpreter
*
interpreter
=
new
ASTI
nterpreter
(
cf
);
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
if
(
unlikely
(
scope_info
->
usesNameLookup
()))
{
if
(
unlikely
(
scope_info
->
usesNameLookup
()))
{
interpreter
.
setBoxedLocals
(
new
BoxedDict
());
interpreter
->
setBoxedLocals
(
new
BoxedDict
());
}
}
assert
((
!
globals
)
==
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
assert
((
!
globals
)
==
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
if
(
globals
)
{
if
(
globals
)
{
interpreter
.
setGlobals
(
globals
);
interpreter
->
setGlobals
(
globals
);
}
else
{
}
else
{
interpreter
.
setGlobals
(
source_info
->
parent_module
);
interpreter
->
setGlobals
(
source_info
->
parent_module
);
}
}
interpreter
.
initArguments
(
nargs
,
(
BoxedClosure
*
)
closure
,
(
BoxedGenerator
*
)
generator
,
arg1
,
arg2
,
arg3
,
args
);
interpreter
->
initArguments
(
nargs
,
(
BoxedClosure
*
)
closure
,
(
BoxedGenerator
*
)
generator
,
arg1
,
arg2
,
arg3
,
args
);
Value
v
=
ASTInterpreter
::
execute
(
interpreter
);
Value
v
=
ASTInterpreter
::
execute
(
*
interpreter
);
return
v
.
o
?
v
.
o
:
None
;
return
v
.
o
?
v
.
o
:
None
;
}
}
...
@@ -1285,18 +1314,18 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
...
@@ -1285,18 +1314,18 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
globals
,
Box
*
boxedLocals
)
{
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
globals
,
Box
*
boxedLocals
)
{
++
cf
->
times_called
;
++
cf
->
times_called
;
ASTInterpreter
i
nterpreter
(
cf
);
ASTInterpreter
*
interpreter
=
new
ASTI
nterpreter
(
cf
);
interpreter
.
initArguments
(
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
interpreter
->
initArguments
(
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
interpreter
.
setBoxedLocals
(
boxedLocals
);
interpreter
->
setBoxedLocals
(
boxedLocals
);
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
assert
(
!
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
assert
(
!
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
assert
(
globals
);
assert
(
globals
);
interpreter
.
setGlobals
(
globals
);
interpreter
->
setGlobals
(
globals
);
Value
v
=
ASTInterpreter
::
execute
(
interpreter
);
Value
v
=
ASTInterpreter
::
execute
(
*
interpreter
);
return
v
.
o
?
v
.
o
:
None
;
return
v
.
o
?
v
.
o
:
None
;
}
}
...
@@ -1309,29 +1338,29 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
...
@@ -1309,29 +1338,29 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
assert
(
after_expr
);
assert
(
after_expr
);
assert
(
expr_val
);
assert
(
expr_val
);
ASTInterpreter
i
nterpreter
(
cf
);
ASTInterpreter
*
interpreter
=
new
ASTI
nterpreter
(
cf
);
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
.
get
();
assert
(
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
assert
(
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
interpreter
.
setGlobals
(
source_info
->
parent_module
);
interpreter
->
setGlobals
(
source_info
->
parent_module
);
for
(
const
auto
&
p
:
frame_state
.
locals
->
d
)
{
for
(
const
auto
&
p
:
frame_state
.
locals
->
d
)
{
assert
(
p
.
first
->
cls
==
str_cls
);
assert
(
p
.
first
->
cls
==
str_cls
);
auto
name
=
static_cast
<
BoxedString
*>
(
p
.
first
)
->
s
();
auto
name
=
static_cast
<
BoxedString
*>
(
p
.
first
)
->
s
();
if
(
name
==
PASSED_GENERATOR_NAME
)
{
if
(
name
==
PASSED_GENERATOR_NAME
)
{
interpreter
.
setGenerator
(
p
.
second
);
interpreter
->
setGenerator
(
p
.
second
);
}
else
if
(
name
==
PASSED_CLOSURE_NAME
)
{
}
else
if
(
name
==
PASSED_CLOSURE_NAME
)
{
interpreter
.
setPassedClosure
(
p
.
second
);
interpreter
->
setPassedClosure
(
p
.
second
);
}
else
if
(
name
==
CREATED_CLOSURE_NAME
)
{
}
else
if
(
name
==
CREATED_CLOSURE_NAME
)
{
interpreter
.
setCreatedClosure
(
p
.
second
);
interpreter
->
setCreatedClosure
(
p
.
second
);
}
else
{
}
else
{
InternedString
interned
=
cf
->
clfunc
->
source
->
getInternedStrings
().
get
(
name
);
InternedString
interned
=
cf
->
clfunc
->
source
->
getInternedStrings
().
get
(
name
);
interpreter
.
addSymbol
(
interned
,
p
.
second
,
false
);
interpreter
->
addSymbol
(
interned
,
p
.
second
,
false
);
}
}
}
}
interpreter
.
setFrameInfo
(
frame_state
.
frame_info
);
interpreter
->
setFrameInfo
(
frame_state
.
frame_info
);
CFGBlock
*
start_block
=
NULL
;
CFGBlock
*
start_block
=
NULL
;
AST_stmt
*
starting_statement
=
NULL
;
AST_stmt
*
starting_statement
=
NULL
;
...
@@ -1343,7 +1372,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
...
@@ -1343,7 +1372,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
assert
(
asgn
->
targets
[
0
]
->
type
==
AST_TYPE
::
Name
);
assert
(
asgn
->
targets
[
0
]
->
type
==
AST_TYPE
::
Name
);
auto
name
=
ast_cast
<
AST_Name
>
(
asgn
->
targets
[
0
]);
auto
name
=
ast_cast
<
AST_Name
>
(
asgn
->
targets
[
0
]);
assert
(
name
->
id
.
str
()[
0
]
==
'#'
);
assert
(
name
->
id
.
str
()[
0
]
==
'#'
);
interpreter
.
addSymbol
(
name
->
id
,
expr_val
,
true
);
interpreter
->
addSymbol
(
name
->
id
,
expr_val
,
true
);
break
;
break
;
}
else
if
(
enclosing_stmt
->
type
==
AST_TYPE
::
Expr
)
{
}
else
if
(
enclosing_stmt
->
type
==
AST_TYPE
::
Expr
)
{
auto
expr
=
ast_cast
<
AST_Expr
>
(
enclosing_stmt
);
auto
expr
=
ast_cast
<
AST_Expr
>
(
enclosing_stmt
);
...
@@ -1381,7 +1410,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
...
@@ -1381,7 +1410,7 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
assert
(
starting_statement
);
assert
(
starting_statement
);
}
}
Value
v
=
ASTInterpreter
::
execute
(
interpreter
,
start_block
,
starting_statement
);
Value
v
=
ASTInterpreter
::
execute
(
*
interpreter
,
start_block
,
starting_statement
);
return
v
.
o
?
v
.
o
:
None
;
return
v
.
o
?
v
.
o
:
None
;
}
}
...
@@ -1430,9 +1459,10 @@ BoxedClosure* passedClosureForInterpretedFrame(void* frame_ptr) {
...
@@ -1430,9 +1459,10 @@ BoxedClosure* passedClosureForInterpretedFrame(void* frame_ptr) {
return
interpreter
->
getPassedClosure
();
return
interpreter
->
getPassedClosure
();
}
}
void
gatherInterpreterRoots
(
GCVisitor
*
visitor
)
{
void
setupInterpreter
()
{
for
(
const
auto
&
p
:
s_interpreterMap
)
{
astinterpreter_cls
=
BoxedHeapClass
::
create
(
type_cls
,
object_cls
,
ASTInterpreter
::
gcHandler
,
0
,
0
,
p
.
second
->
gcVisit
(
visitor
);
sizeof
(
ASTInterpreter
),
false
,
"astinterpreter"
);
}
astinterpreter_cls
->
simple_destructor
=
ASTInterpreter
::
simpleDestructor
;
astinterpreter_cls
->
freeze
();
}
}
}
}
src/codegen/ast_interpreter.h
View file @
38388e1b
...
@@ -33,6 +33,7 @@ struct LineInfo;
...
@@ -33,6 +33,7 @@ struct LineInfo;
extern
const
void
*
interpreter_instr_addr
;
extern
const
void
*
interpreter_instr_addr
;
void
setupInterpreter
();
Box
*
astInterpretFunction
(
CompiledFunction
*
f
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
*
globals
,
Box
*
arg1
,
Box
*
astInterpretFunction
(
CompiledFunction
*
f
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
*
globals
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
);
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
globals
,
Box
*
boxedLocals
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
globals
,
Box
*
boxedLocals
);
...
@@ -46,7 +47,6 @@ struct FrameInfo;
...
@@ -46,7 +47,6 @@ struct FrameInfo;
FrameInfo
*
getFrameInfoForInterpretedFrame
(
void
*
frame_ptr
);
FrameInfo
*
getFrameInfoForInterpretedFrame
(
void
*
frame_ptr
);
BoxedClosure
*
passedClosureForInterpretedFrame
(
void
*
frame_ptr
);
BoxedClosure
*
passedClosureForInterpretedFrame
(
void
*
frame_ptr
);
void
gatherInterpreterRoots
(
gc
::
GCVisitor
*
visitor
);
BoxedDict
*
localsForInterpretedFrame
(
void
*
frame_ptr
,
bool
only_user_visible
);
BoxedDict
*
localsForInterpretedFrame
(
void
*
frame_ptr
,
bool
only_user_visible
);
}
}
...
...
src/codegen/irgen/irgenerator.cpp
View file @
38388e1b
...
@@ -117,8 +117,7 @@ static llvm::Value* getBoxedLocalsGep(llvm::IRBuilder<true>& builder, llvm::Valu
...
@@ -117,8 +117,7 @@ static llvm::Value* getBoxedLocalsGep(llvm::IRBuilder<true>& builder, llvm::Valu
static
llvm
::
Value
*
getExcinfoGep
(
llvm
::
IRBuilder
<
true
>&
builder
,
llvm
::
Value
*
v
)
{
static
llvm
::
Value
*
getExcinfoGep
(
llvm
::
IRBuilder
<
true
>&
builder
,
llvm
::
Value
*
v
)
{
static_assert
(
offsetof
(
FrameInfo
,
exc
)
==
0
,
""
);
static_assert
(
offsetof
(
FrameInfo
,
exc
)
==
0
,
""
);
static_assert
(
offsetof
(
ExcInfo
,
type
)
==
0
,
""
);
return
builder
.
CreateConstInBoundsGEP2_32
(
v
,
0
,
0
);
return
builder
.
CreateConstInBoundsGEP2_32
(
builder
.
CreateConstInBoundsGEP2_32
(
v
,
0
,
0
),
0
,
0
);
}
}
static
llvm
::
Value
*
getFrameObjGep
(
llvm
::
IRBuilder
<
true
>&
builder
,
llvm
::
Value
*
v
)
{
static
llvm
::
Value
*
getFrameObjGep
(
llvm
::
IRBuilder
<
true
>&
builder
,
llvm
::
Value
*
v
)
{
...
@@ -180,8 +179,16 @@ llvm::Value* IRGenState::getFrameInfoVar() {
...
@@ -180,8 +179,16 @@ llvm::Value* IRGenState::getFrameInfoVar() {
// The "normal" case
// The "normal" case
// frame_info.exc.type = NULL
// frame_info.exc.type = NULL
builder
.
CreateStore
(
getNullPtr
(
g
.
llvm_value_type_ptr
),
getExcinfoGep
(
builder
,
al
));
// frame_info.exc.value = NULL
// frame_info.exc.traceback = NULL
llvm
::
Constant
*
null_value
=
getNullPtr
(
g
.
llvm_value_type_ptr
);
llvm
::
Value
*
exc_info
=
getExcinfoGep
(
builder
,
al
);
builder
.
CreateStore
(
null_value
,
builder
.
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
offsetof
(
ExcInfo
,
type
)
/
sizeof
(
Box
*
)));
builder
.
CreateStore
(
null_value
,
builder
.
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
offsetof
(
ExcInfo
,
value
)
/
sizeof
(
Box
*
)));
builder
.
CreateStore
(
null_value
,
builder
.
CreateConstInBoundsGEP2_32
(
exc_info
,
0
,
offsetof
(
ExcInfo
,
traceback
)
/
sizeof
(
Box
*
)));
// frame_info.boxedLocals = NULL
// frame_info.boxedLocals = NULL
llvm
::
Value
*
boxed_locals_gep
=
getBoxedLocalsGep
(
builder
,
al
);
llvm
::
Value
*
boxed_locals_gep
=
getBoxedLocalsGep
(
builder
,
al
);
builder
.
CreateStore
(
getNullPtr
(
g
.
llvm_value_type_ptr
),
boxed_locals_gep
);
builder
.
CreateStore
(
getNullPtr
(
g
.
llvm_value_type_ptr
),
boxed_locals_gep
);
...
...
src/core/types.h
View file @
38388e1b
...
@@ -706,6 +706,8 @@ struct FrameInfo {
...
@@ -706,6 +706,8 @@ struct FrameInfo {
BoxedFrame
*
frame_obj
;
BoxedFrame
*
frame_obj
;
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
),
frame_obj
(
0
)
{}
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
),
frame_obj
(
0
)
{}
void
gcVisit
(
GCVisitor
*
visitor
);
};
};
struct
CallattrFlags
{
struct
CallattrFlags
{
...
...
src/gc/collector.cpp
View file @
38388e1b
...
@@ -277,7 +277,6 @@ void markPhase() {
...
@@ -277,7 +277,6 @@ void markPhase() {
GCVisitor
visitor
(
&
stack
);
GCVisitor
visitor
(
&
stack
);
threading
::
visitAllStacks
(
&
visitor
);
threading
::
visitAllStacks
(
&
visitor
);
gatherInterpreterRoots
(
&
visitor
);
for
(
auto
h
:
*
getRootHandles
())
{
for
(
auto
h
:
*
getRootHandles
())
{
visitor
.
visit
(
h
->
value
);
visitor
.
visit
(
h
->
value
);
...
...
src/runtime/types.cpp
View file @
38388e1b
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#include "capi/typeobject.h"
#include "capi/typeobject.h"
#include "capi/types.h"
#include "capi/types.h"
#include "codegen/ast_interpreter.h"
#include "codegen/unwinding.h"
#include "codegen/unwinding.h"
#include "core/options.h"
#include "core/options.h"
#include "core/stats.h"
#include "core/stats.h"
...
@@ -91,6 +92,14 @@ bool IN_SHUTDOWN = false;
...
@@ -91,6 +92,14 @@ bool IN_SHUTDOWN = false;
#define SLICE_STOP_OFFSET ((char*)&(((BoxedSlice*)0x01)->stop) - (char*)0x1)
#define SLICE_STOP_OFFSET ((char*)&(((BoxedSlice*)0x01)->stop) - (char*)0x1)
#define SLICE_STEP_OFFSET ((char*)&(((BoxedSlice*)0x01)->step) - (char*)0x1)
#define SLICE_STEP_OFFSET ((char*)&(((BoxedSlice*)0x01)->step) - (char*)0x1)
void
FrameInfo
::
gcVisit
(
GCVisitor
*
visitor
)
{
visitor
->
visit
(
boxedLocals
);
visitor
->
visit
(
exc
.
traceback
);
visitor
->
visit
(
exc
.
type
);
visitor
->
visit
(
exc
.
value
);
visitor
->
visit
(
frame_obj
);
}
// Analogue of PyType_GenericAlloc (default tp_alloc), but should only be used for Pyston classes!
// Analogue of PyType_GenericAlloc (default tp_alloc), but should only be used for Pyston classes!
extern
"C"
PyObject
*
PystonType_GenericAlloc
(
BoxedClass
*
cls
,
Py_ssize_t
nitems
)
noexcept
{
extern
"C"
PyObject
*
PystonType_GenericAlloc
(
BoxedClass
*
cls
,
Py_ssize_t
nitems
)
noexcept
{
assert
(
cls
);
assert
(
cls
);
...
@@ -2637,6 +2646,7 @@ void setupRuntime() {
...
@@ -2637,6 +2646,7 @@ void setupRuntime() {
closure_cls
->
freeze
();
closure_cls
->
freeze
();
setupInterpreter
();
setupCAPI
();
setupCAPI
();
// Can't set up object methods until we set up CAPI support:
// Can't set up object methods until we set up CAPI support:
...
...
test/tests/generator_collection_finally.py
0 → 100644
View file @
38388e1b
# expected: fail
# We currently don't call finalizers when destroying a generator.
def
G
():
try
:
yield
0
yield
1
print
"end"
except
Exception
as
e
:
print
e
finally
:
print
"finally"
def
foo
():
g
=
G
()
print
g
.
next
()
print
g
.
next
()
foo
()
test/tests/generator_collection_running.py
0 → 100644
View file @
38388e1b
# This test checks if generators which get started but haven't yet stopped (=not raisen a StopIteration exc, etc)
# get freed when there aren't any references to the generators left.
import
gc
import
weakref
class
C
(
object
):
val
=
42
def
G
():
l
=
range
(
100
)
yield
weakref
.
ref
(
C
())
while
True
:
yield
1
def
get_weakrefs
(
num
=
5
):
wr
=
[]
for
i
in
range
(
num
):
g
=
G
()
w
=
g
.
next
()
wr
.
append
(
w
)
return
wr
def
recurse
(
f
,
n
):
if
n
:
return
recurse
(
f
,
n
-
1
)
return
f
()
wr
=
recurse
(
get_weakrefs
,
100
)
gc
.
collect
()
for
w
in
wr
:
try
:
print
w
.
__hash__
()
print
w
().
val
except
TypeError
as
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