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
9e42fe36
Commit
9e42fe36
authored
Mar 28, 2015
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added to BoxedList so it will work for functions inside the exec
parent
9c78c3d4
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
62 additions
and
28 deletions
+62
-28
src/analysis/scoping_analysis.cpp
src/analysis/scoping_analysis.cpp
+12
-10
src/analysis/scoping_analysis.h
src/analysis/scoping_analysis.h
+2
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+9
-5
src/codegen/ast_interpreter.h
src/codegen/ast_interpreter.h
+1
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+1
-1
src/runtime/generator.cpp
src/runtime/generator.cpp
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+4
-4
src/runtime/objmodel.h
src/runtime/objmodel.h
+1
-1
src/runtime/types.cpp
src/runtime/types.cpp
+10
-3
src/runtime/types.h
src/runtime/types.h
+8
-2
test/tests/exec_in_test.py
test/tests/exec_in_test.py
+13
-0
No files found.
src/analysis/scoping_analysis.cpp
View file @
9e42fe36
...
@@ -275,9 +275,11 @@ private:
...
@@ -275,9 +275,11 @@ private:
std
::
vector
<
std
::
pair
<
InternedString
,
DerefInfo
>>
allDerefVarsAndInfo
;
std
::
vector
<
std
::
pair
<
InternedString
,
DerefInfo
>>
allDerefVarsAndInfo
;
bool
allDerefVarsAndInfoCached
;
bool
allDerefVarsAndInfoCached
;
bool
globals_from_module
;
public:
public:
ScopeInfoBase
(
ScopeInfo
*
parent
,
ScopingAnalysis
::
ScopeNameUsage
*
usage
,
AST
*
ast
,
bool
usesNameLookup
)
ScopeInfoBase
(
ScopeInfo
*
parent
,
ScopingAnalysis
::
ScopeNameUsage
*
usage
,
AST
*
ast
,
bool
usesNameLookup
,
bool
globals_from_module
)
:
parent
(
parent
),
usage
(
usage
),
ast
(
ast
),
usesNameLookup_
(
usesNameLookup
),
allDerefVarsAndInfoCached
(
false
)
{
:
parent
(
parent
),
usage
(
usage
),
ast
(
ast
),
usesNameLookup_
(
usesNameLookup
),
allDerefVarsAndInfoCached
(
false
)
,
globals_from_module
(
globals_from_module
)
{
assert
(
usage
);
assert
(
usage
);
assert
(
ast
);
assert
(
ast
);
...
@@ -325,7 +327,7 @@ public:
...
@@ -325,7 +327,7 @@ public:
bool
usesNameLookup
()
override
{
return
usesNameLookup_
;
}
bool
usesNameLookup
()
override
{
return
usesNameLookup_
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areGlobalsFromModule
()
override
{
return
tru
e
;
}
bool
areGlobalsFromModule
()
override
{
return
globals_from_modul
e
;
}
DerefInfo
getDerefInfo
(
InternedString
name
)
override
{
DerefInfo
getDerefInfo
(
InternedString
name
)
override
{
assert
(
getScopeTypeOfName
(
name
)
==
VarScopeType
::
DEREF
);
assert
(
getScopeTypeOfName
(
name
)
==
VarScopeType
::
DEREF
);
...
@@ -816,7 +818,7 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
...
@@ -816,7 +818,7 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
switch
(
node
->
type
)
{
switch
(
node
->
type
)
{
case
AST_TYPE
:
:
ClassDef
:
{
case
AST_TYPE
:
:
ClassDef
:
{
ScopeInfoBase
*
scopeInfo
ScopeInfoBase
*
scopeInfo
=
new
ScopeInfoBase
(
parent_info
,
usage
,
usage
->
node
,
true
/* usesNameLookup */
);
=
new
ScopeInfoBase
(
parent_info
,
usage
,
usage
->
node
,
true
/* usesNameLookup */
,
globals_from_module
);
this
->
scopes
[
node
]
=
scopeInfo
;
this
->
scopes
[
node
]
=
scopeInfo
;
break
;
break
;
}
}
...
@@ -826,9 +828,9 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
...
@@ -826,9 +828,9 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
case
AST_TYPE
:
:
DictComp
:
case
AST_TYPE
:
:
DictComp
:
case
AST_TYPE
:
:
SetComp
:
{
case
AST_TYPE
:
:
SetComp
:
{
ScopeInfoBase
*
scopeInfo
=
new
ScopeInfoBase
(
parent_info
,
usage
,
usage
->
node
,
ScopeInfoBase
*
scopeInfo
=
new
ScopeInfoBase
(
parent_info
,
usage
,
usage
->
node
,
usage
->
hasNameForcingSyntax
()
/* usesNameLookup */
);
usage
->
hasNameForcingSyntax
()
/* usesNameLookup */
,
this
->
scopes
[
node
]
=
scopeInfo
;
globals_from_module
)
;
break
;
this
->
scopes
[
node
]
=
scopeInfo
;
break
;
}
}
default:
default:
RELEASE_ASSERT
(
0
,
"%d"
,
usage
->
node
->
type
);
RELEASE_ASSERT
(
0
,
"%d"
,
usage
->
node
->
type
);
...
@@ -882,16 +884,16 @@ ScopeInfo* ScopingAnalysis::getScopeInfoForNode(AST* node) {
...
@@ -882,16 +884,16 @@ ScopeInfo* ScopingAnalysis::getScopeInfoForNode(AST* node) {
return
analyzeSubtree
(
node
);
return
analyzeSubtree
(
node
);
}
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Module
*
m
)
:
parent_module
(
m
),
interned_strings
(
*
m
->
interned_strings
.
get
())
{
ScopingAnalysis
::
ScopingAnalysis
(
AST_Module
*
m
)
:
parent_module
(
m
),
interned_strings
(
*
m
->
interned_strings
.
get
())
,
globals_from_module
(
true
)
{
scopes
[
m
]
=
new
ModuleScopeInfo
();
scopes
[
m
]
=
new
ModuleScopeInfo
();
}
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Expression
*
e
,
bool
globals_from_module
)
:
interned_strings
(
*
e
->
interned_strings
.
get
())
{
ScopingAnalysis
::
ScopingAnalysis
(
AST_Expression
*
e
,
bool
globals_from_module
)
:
interned_strings
(
*
e
->
interned_strings
.
get
())
,
globals_from_module
(
globals_from_module
)
{
// It's an expression, so it can't have a `global` statement
// It's an expression, so it can't have a `global` statement
scopes
[
e
]
=
new
EvalExprScopeInfo
(
globals_from_module
);
scopes
[
e
]
=
new
EvalExprScopeInfo
(
globals_from_module
);
}
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
{
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
,
globals_from_module
(
globals_from_module
)
{
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
,
globals_from_module
);
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
,
globals_from_module
);
}
}
}
}
src/analysis/scoping_analysis.h
View file @
9e42fe36
...
@@ -159,6 +159,8 @@ private:
...
@@ -159,6 +159,8 @@ private:
ScopeInfo
*
analyzeSubtree
(
AST
*
node
);
ScopeInfo
*
analyzeSubtree
(
AST
*
node
);
void
processNameUsages
(
NameUsageMap
*
usages
);
void
processNameUsages
(
NameUsageMap
*
usages
);
bool
globals_from_module
;
public:
public:
// The scope-analysis is done before any CFG-ization is done,
// The scope-analysis is done before any CFG-ization is done,
// but many of the queries will be done post-CFG-ization.
// but many of the queries will be done post-CFG-ization.
...
...
src/codegen/ast_interpreter.cpp
View file @
9e42fe36
...
@@ -742,7 +742,7 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
...
@@ -742,7 +742,7 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
}
}
assert
(
closure
);
assert
(
closure
);
}
}
return
boxCLFunction
(
cl
,
closure
,
is_generator
,
u
.
il
);
return
boxCLFunction
(
cl
,
closure
,
is_generator
,
globals
->
cls
==
dict_cls
?
static_cast
<
BoxedDict
*>
(
globals
)
:
NULL
,
u
.
il
);
}
}
Value
ASTInterpreter
::
visit_makeFunction
(
AST_MakeFunction
*
mkfn
)
{
Value
ASTInterpreter
::
visit_makeFunction
(
AST_MakeFunction
*
mkfn
)
{
...
@@ -778,7 +778,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
...
@@ -778,7 +778,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
BoxedClosure
*
closure
=
scope_info
->
takesClosure
()
?
created_closure
:
0
;
BoxedClosure
*
closure
=
scope_info
->
takesClosure
()
?
created_closure
:
0
;
CLFunction
*
cl
=
wrapFunction
(
node
,
nullptr
,
node
->
body
,
source_info
);
CLFunction
*
cl
=
wrapFunction
(
node
,
nullptr
,
node
->
body
,
source_info
);
Box
*
attrDict
=
runtimeCall
(
boxCLFunction
(
cl
,
closure
,
false
,
{}),
ArgPassSpec
(
0
),
0
,
0
,
0
,
0
,
0
);
Box
*
attrDict
=
runtimeCall
(
boxCLFunction
(
cl
,
closure
,
false
,
globals
->
cls
==
dict_cls
?
static_cast
<
BoxedDict
*>
(
globals
)
:
NULL
,
{}),
ArgPassSpec
(
0
),
0
,
0
,
0
,
0
,
0
);
Box
*
classobj
=
createUserClass
(
&
node
->
name
.
str
(),
basesTuple
,
attrDict
);
Box
*
classobj
=
createUserClass
(
&
node
->
name
.
str
(),
basesTuple
,
attrDict
);
...
@@ -1164,7 +1164,7 @@ Value ASTInterpreter::visit_attribute(AST_Attribute* node) {
...
@@ -1164,7 +1164,7 @@ Value ASTInterpreter::visit_attribute(AST_Attribute* node) {
const
void
*
interpreter_instr_addr
=
(
void
*
)
&
ASTInterpreter
::
execute
;
const
void
*
interpreter_instr_addr
=
(
void
*
)
&
ASTInterpreter
::
execute
;
Box
*
astInterpretFunction
(
CompiledFunction
*
cf
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
astInterpretFunction
(
CompiledFunction
*
cf
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
edDict
*
globals
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
)
{
Box
*
arg3
,
Box
**
args
)
{
if
(
unlikely
(
cf
->
times_called
>
REOPT_THRESHOLD_INTERPRETER
&&
ENABLE_REOPT
&&
!
FORCE_INTERPRETER
))
{
if
(
unlikely
(
cf
->
times_called
>
REOPT_THRESHOLD_INTERPRETER
&&
ENABLE_REOPT
&&
!
FORCE_INTERPRETER
))
{
CompiledFunction
*
optimized
=
reoptCompiledFuncInternal
(
cf
);
CompiledFunction
*
optimized
=
reoptCompiledFuncInternal
(
cf
);
...
@@ -1187,8 +1187,12 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
...
@@ -1187,8 +1187,12 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
interpreter
.
setBoxedLocals
(
new
BoxedDict
());
interpreter
.
setBoxedLocals
(
new
BoxedDict
());
}
}
assert
(
scope_info
->
areGlobalsFromModule
());
assert
((
!
globals
)
==
scope_info
->
areGlobalsFromModule
());
interpreter
.
setGlobals
(
source_info
->
parent_module
);
if
(
globals
)
{
interpreter
.
setGlobals
(
globals
);
}
else
{
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
);
...
...
src/codegen/ast_interpreter.h
View file @
9e42fe36
...
@@ -33,7 +33,7 @@ struct LineInfo;
...
@@ -33,7 +33,7 @@ struct LineInfo;
extern
const
void
*
interpreter_instr_addr
;
extern
const
void
*
interpreter_instr_addr
;
Box
*
astInterpretFunction
(
CompiledFunction
*
f
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
*
astInterpretFunction
(
CompiledFunction
*
f
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
edDict
*
globals
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
);
Box
**
args
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
BoxedDict
*
globals
,
Box
*
boxedLocals
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
BoxedDict
*
globals
,
Box
*
boxedLocals
);
Box
*
astInterpretFrom
(
CompiledFunction
*
cf
,
AST_expr
*
after_expr
,
AST_stmt
*
enclosing_stmt
,
Box
*
expr_val
,
Box
*
astInterpretFrom
(
CompiledFunction
*
cf
,
AST_expr
*
after_expr
,
AST_stmt
*
enclosing_stmt
,
Box
*
expr_val
,
...
...
src/codegen/irgen/hooks.cpp
View file @
9e42fe36
...
@@ -321,7 +321,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
...
@@ -321,7 +321,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
}
}
if
(
cf
->
is_interpreted
)
if
(
cf
->
is_interpreted
)
astInterpretFunction
(
cf
,
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
astInterpretFunction
(
cf
,
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
else
else
((
void
(
*
)())
cf
->
code
)();
((
void
(
*
)())
cf
->
code
)();
}
}
...
...
src/runtime/generator.cpp
View file @
9e42fe36
...
@@ -95,7 +95,7 @@ void generatorEntry(BoxedGenerator* g) {
...
@@ -95,7 +95,7 @@ void generatorEntry(BoxedGenerator* g) {
BoxedFunctionBase
*
func
=
g
->
function
;
BoxedFunctionBase
*
func
=
g
->
function
;
Box
**
args
=
g
->
args
?
&
g
->
args
->
elts
[
0
]
:
nullptr
;
Box
**
args
=
g
->
args
?
&
g
->
args
->
elts
[
0
]
:
nullptr
;
callCLFunc
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
callCLFunc
(
func
->
f
,
nullptr
,
func
->
f
->
numReceivedArgs
(),
func
->
closure
,
g
,
func
->
globals
,
g
->
arg1
,
g
->
arg2
,
g
->
arg3
,
args
);
}
catch
(
ExcInfo
e
)
{
}
catch
(
ExcInfo
e
)
{
// unhandled exception: propagate the exception to the caller
// unhandled exception: propagate the exception to the caller
g
->
exception
=
e
;
g
->
exception
=
e
;
...
...
src/runtime/objmodel.cpp
View file @
9e42fe36
...
@@ -2667,7 +2667,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
...
@@ -2667,7 +2667,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
if
(
!
func
->
isGenerator
)
{
if
(
!
func
->
isGenerator
)
{
if
(
argspec
.
num_keywords
==
0
&&
!
argspec
.
has_starargs
&&
!
argspec
.
has_kwargs
&&
argspec
.
num_args
==
f
->
num_args
if
(
argspec
.
num_keywords
==
0
&&
!
argspec
.
has_starargs
&&
!
argspec
.
has_kwargs
&&
argspec
.
num_args
==
f
->
num_args
&&
!
f
->
takes_varargs
&&
!
f
->
takes_kwargs
)
{
&&
!
f
->
takes_varargs
&&
!
f
->
takes_kwargs
)
{
return
callCLFunc
(
f
,
rewrite_args
,
argspec
.
num_args
,
closure
,
NULL
,
arg1
,
arg2
,
arg3
,
args
);
return
callCLFunc
(
f
,
rewrite_args
,
argspec
.
num_args
,
closure
,
NULL
,
func
->
globals
,
arg1
,
arg2
,
arg3
,
args
);
}
}
}
}
slowpath_callfunc_slowpath
.
log
();
slowpath_callfunc_slowpath
.
log
();
...
@@ -2924,19 +2924,19 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
...
@@ -2924,19 +2924,19 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
if
(
func
->
isGenerator
)
{
if
(
func
->
isGenerator
)
{
res
=
createGenerator
(
func
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
res
=
createGenerator
(
func
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
else
{
}
else
{
res
=
callCLFunc
(
f
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
res
=
callCLFunc
(
f
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
func
->
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
}
return
res
;
return
res
;
}
}
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
BoxedGenerator
*
generator
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
BoxedGenerator
*
generator
,
Box
edDict
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
)
{
CompiledFunction
*
chosen_cf
=
pickVersion
(
f
,
num_output_args
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
CompiledFunction
*
chosen_cf
=
pickVersion
(
f
,
num_output_args
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
assert
(
chosen_cf
->
is_interpreted
==
(
chosen_cf
->
code
==
NULL
));
assert
(
chosen_cf
->
is_interpreted
==
(
chosen_cf
->
code
==
NULL
));
if
(
chosen_cf
->
is_interpreted
)
{
if
(
chosen_cf
->
is_interpreted
)
{
return
astInterpretFunction
(
chosen_cf
,
num_output_args
,
closure
,
generator
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
return
astInterpretFunction
(
chosen_cf
,
num_output_args
,
closure
,
generator
,
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
}
if
(
rewrite_args
)
{
if
(
rewrite_args
)
{
...
...
src/runtime/objmodel.h
View file @
9e42fe36
...
@@ -138,7 +138,7 @@ bool isUserDefined(BoxedClass* cls);
...
@@ -138,7 +138,7 @@ bool isUserDefined(BoxedClass* cls);
Box
*
processDescriptor
(
Box
*
obj
,
Box
*
inst
,
Box
*
owner
);
Box
*
processDescriptor
(
Box
*
obj
,
Box
*
inst
,
Box
*
owner
);
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
Box
*
callCLFunc
(
CLFunction
*
f
,
CallRewriteArgs
*
rewrite_args
,
int
num_output_args
,
BoxedClosure
*
closure
,
BoxedGenerator
*
generator
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
);
BoxedGenerator
*
generator
,
Box
edDict
*
globals
,
Box
*
oarg1
,
Box
*
oarg2
,
Box
*
oarg3
,
Box
**
oargs
);
static
const
char
*
objectNewParameterTypeErrorMsg
()
{
static
const
char
*
objectNewParameterTypeErrorMsg
()
{
if
(
PYTHON_VERSION_HEX
>=
version_hex
(
2
,
7
,
4
))
{
if
(
PYTHON_VERSION_HEX
>=
version_hex
(
2
,
7
,
4
))
{
...
...
src/runtime/types.cpp
View file @
9e42fe36
...
@@ -310,9 +310,11 @@ BoxedFunction::BoxedFunction(CLFunction* f) : BoxedFunction(f, {}) {
...
@@ -310,9 +310,11 @@ BoxedFunction::BoxedFunction(CLFunction* f) : BoxedFunction(f, {}) {
}
}
BoxedFunction
::
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
BoxedFunction
::
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
bool
isGenerator
)
bool
isGenerator
,
BoxedDict
*
globals
)
:
BoxedFunctionBase
(
f
,
defaults
,
closure
,
isGenerator
)
{
:
BoxedFunctionBase
(
f
,
defaults
,
closure
,
isGenerator
)
{
this
->
globals
=
globals
;
// TODO eventually we want this to assert(f->source), I think, but there are still
// TODO eventually we want this to assert(f->source), I think, but there are still
// some builtin functions that are BoxedFunctions but really ought to be a type that
// some builtin functions that are BoxedFunctions but really ought to be a type that
// we don't have yet.
// we don't have yet.
...
@@ -355,6 +357,9 @@ extern "C" void functionGCHandler(GCVisitor* v, Box* b) {
...
@@ -355,6 +357,9 @@ extern "C" void functionGCHandler(GCVisitor* v, Box* b) {
if
(
f
->
closure
)
if
(
f
->
closure
)
v
->
visit
(
f
->
closure
);
v
->
visit
(
f
->
closure
);
if
(
f
->
globals
)
v
->
visit
(
f
->
globals
);
// It's ok for f->defaults to be NULL here even if f->ndefaults isn't,
// It's ok for f->defaults to be NULL here even if f->ndefaults isn't,
// since we could be collecting from inside a BoxedFunctionBase constructor
// since we could be collecting from inside a BoxedFunctionBase constructor
if
(
f
->
ndefaults
)
{
if
(
f
->
ndefaults
)
{
...
@@ -412,12 +417,14 @@ extern "C" void moduleGCHandler(GCVisitor* v, Box* b) {
...
@@ -412,12 +417,14 @@ extern "C" void moduleGCHandler(GCVisitor* v, Box* b) {
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// finally-blocks in scope.
// finally-blocks in scope.
// TODO: should we use C++11 `noexcept' here?
// TODO: should we use C++11 `noexcept' here?
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
BoxedDict
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
)
{
std
::
initializer_list
<
Box
*>
defaults
)
{
if
(
closure
)
if
(
closure
)
assert
(
closure
->
cls
==
closure_cls
);
assert
(
closure
->
cls
==
closure_cls
);
if
(
globals
)
assert
(
globals
->
cls
==
dict_cls
);
return
new
BoxedFunction
(
f
,
defaults
,
closure
,
isGenerator
);
return
new
BoxedFunction
(
f
,
defaults
,
closure
,
isGenerator
,
globals
);
}
}
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
)
{
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
)
{
...
...
src/runtime/types.h
View file @
9e42fe36
...
@@ -123,7 +123,7 @@ char* getWriteableStringContents(BoxedString* s);
...
@@ -123,7 +123,7 @@ char* getWriteableStringContents(BoxedString* s);
extern
"C"
void
listAppendInternal
(
Box
*
self
,
Box
*
v
);
extern
"C"
void
listAppendInternal
(
Box
*
self
,
Box
*
v
);
extern
"C"
void
listAppendArrayInternal
(
Box
*
self
,
Box
**
v
,
int
nelts
);
extern
"C"
void
listAppendArrayInternal
(
Box
*
self
,
Box
**
v
,
int
nelts
);
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
BoxedDict
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
);
std
::
initializer_list
<
Box
*>
defaults
);
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
);
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
);
extern
"C"
Box
*
createUserClass
(
const
std
::
string
*
name
,
Box
*
base
,
Box
*
attr_dict
);
extern
"C"
Box
*
createUserClass
(
const
std
::
string
*
name
,
Box
*
base
,
Box
*
attr_dict
);
...
@@ -478,7 +478,13 @@ public:
...
@@ -478,7 +478,13 @@ public:
Box
**
in_weakreflist
;
Box
**
in_weakreflist
;
CLFunction
*
f
;
CLFunction
*
f
;
// TODO these should really go in BoxedFunction but it's annoying because they don't get
// initializd until after BoxedFunctionBase's constructor is run which means they could have
// garbage values when the GC is run (BoxedFunctionBase's constructor might call the GC).
// So ick... needs to be fixed.
BoxedClosure
*
closure
;
BoxedClosure
*
closure
;
BoxedDict
*
globals
;
bool
isGenerator
;
bool
isGenerator
;
int
ndefaults
;
int
ndefaults
;
...
@@ -502,7 +508,7 @@ public:
...
@@ -502,7 +508,7 @@ public:
BoxedFunction
(
CLFunction
*
f
);
BoxedFunction
(
CLFunction
*
f
);
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
,
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
,
bool
isGenerator
=
false
);
bool
isGenerator
=
false
,
BoxedDict
*
globals
=
NULL
);
DEFAULT_CLASS
(
function_cls
);
DEFAULT_CLASS
(
function_cls
);
};
};
...
...
test/tests/exec_in_test.py
View file @
9e42fe36
...
@@ -37,3 +37,16 @@ def f():
...
@@ -37,3 +37,16 @@ def f():
c = 20
c = 20
f()
f()
"""
in
g
,
{}
"""
in
g
,
{}
print
'Test global access in comprehensions'
g
=
{
'a'
:
4
,
'b'
:
5
,
'c'
:
6
}
exec
"""
global a
global b
global c
print [a for i in xrange(1)]
print {b for i in xrange(1)}
print {i : b for i in xrange(1)}
print
"""
in
g
,
{}
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