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
9c78c3d4
Commit
9c78c3d4
authored
Mar 28, 2015
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
basic functionality working
parent
39afd252
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
171 additions
and
47 deletions
+171
-47
src/analysis/scoping_analysis.cpp
src/analysis/scoping_analysis.cpp
+11
-6
src/analysis/scoping_analysis.h
src/analysis/scoping_analysis.h
+3
-2
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+51
-6
src/codegen/ast_interpreter.h
src/codegen/ast_interpreter.h
+1
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+7
-5
src/core/types.h
src/core/types.h
+2
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+51
-23
src/runtime/objmodel.h
src/runtime/objmodel.h
+6
-3
test/tests/exec_in_test.py
test/tests/exec_in_test.py
+39
-0
No files found.
src/analysis/scoping_analysis.cpp
View file @
9c78c3d4
...
@@ -104,6 +104,7 @@ public:
...
@@ -104,6 +104,7 @@ public:
bool
usesNameLookup
()
override
{
return
false
;
}
bool
usesNameLookup
()
override
{
return
false
;
}
bool
areLocalsFromModule
()
override
{
return
true
;
}
bool
areLocalsFromModule
()
override
{
return
true
;
}
bool
areGlobalsFromModule
()
override
{
return
true
;
}
DerefInfo
getDerefInfo
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
DerefInfo
getDerefInfo
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
size_t
getClosureOffset
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
size_t
getClosureOffset
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
...
@@ -142,10 +143,12 @@ private:
...
@@ -142,10 +143,12 @@ private:
}
}
};
};
bool
globals_from_module
;
public:
public:
EvalExprScopeInfo
()
{}
EvalExprScopeInfo
(
bool
globals_from_module
)
:
globals_from_module
(
globals_from_module
)
{}
EvalExprScopeInfo
(
AST
*
node
)
{
EvalExprScopeInfo
(
AST
*
node
,
bool
globals_from_module
)
:
globals_from_module
(
globals_from_module
)
{
// Find all the global statements in the node's scope (not delving into FuncitonDefs
// Find all the global statements in the node's scope (not delving into FuncitonDefs
// or ClassDefs) and put the names in `forced_globals`.
// or ClassDefs) and put the names in `forced_globals`.
GlobalStmtVisitor
visitor
(
forced_globals
);
GlobalStmtVisitor
visitor
(
forced_globals
);
...
@@ -170,6 +173,7 @@ public:
...
@@ -170,6 +173,7 @@ public:
bool
usesNameLookup
()
override
{
return
true
;
}
bool
usesNameLookup
()
override
{
return
true
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areGlobalsFromModule
()
override
{
return
globals_from_module
;
}
DerefInfo
getDerefInfo
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
DerefInfo
getDerefInfo
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
size_t
getClosureOffset
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
size_t
getClosureOffset
(
InternedString
)
override
{
RELEASE_ASSERT
(
0
,
"This should never get called"
);
}
...
@@ -321,6 +325,7 @@ public:
...
@@ -321,6 +325,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
true
;
}
DerefInfo
getDerefInfo
(
InternedString
name
)
override
{
DerefInfo
getDerefInfo
(
InternedString
name
)
override
{
assert
(
getScopeTypeOfName
(
name
)
==
VarScopeType
::
DEREF
);
assert
(
getScopeTypeOfName
(
name
)
==
VarScopeType
::
DEREF
);
...
@@ -881,12 +886,12 @@ ScopingAnalysis::ScopingAnalysis(AST_Module* m) : parent_module(m), interned_str
...
@@ -881,12 +886,12 @@ ScopingAnalysis::ScopingAnalysis(AST_Module* m) : parent_module(m), interned_str
scopes
[
m
]
=
new
ModuleScopeInfo
();
scopes
[
m
]
=
new
ModuleScopeInfo
();
}
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Expression
*
e
)
:
interned_strings
(
*
e
->
interned_strings
.
get
())
{
ScopingAnalysis
::
ScopingAnalysis
(
AST_Expression
*
e
,
bool
globals_from_module
)
:
interned_strings
(
*
e
->
interned_strings
.
get
())
{
// 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
();
scopes
[
e
]
=
new
EvalExprScopeInfo
(
globals_from_module
);
}
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
{
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
{
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
);
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
,
globals_from_module
);
}
}
}
}
src/analysis/scoping_analysis.h
View file @
9c78c3d4
...
@@ -92,6 +92,7 @@ public:
...
@@ -92,6 +92,7 @@ public:
virtual
bool
usesNameLookup
()
=
0
;
virtual
bool
usesNameLookup
()
=
0
;
virtual
bool
areLocalsFromModule
()
=
0
;
virtual
bool
areLocalsFromModule
()
=
0
;
virtual
bool
areGlobalsFromModule
()
=
0
;
// For a variable with DEREF lookup, return the DerefInfo used to lookup
// For a variable with DEREF lookup, return the DerefInfo used to lookup
// the variable in a passed closure.
// the variable in a passed closure.
...
@@ -169,8 +170,8 @@ public:
...
@@ -169,8 +170,8 @@ public:
void
registerScopeReplacement
(
AST
*
original_node
,
AST
*
new_node
);
void
registerScopeReplacement
(
AST
*
original_node
,
AST
*
new_node
);
ScopingAnalysis
(
AST_Module
*
m
);
ScopingAnalysis
(
AST_Module
*
m
);
ScopingAnalysis
(
AST_Expression
*
e
);
ScopingAnalysis
(
AST_Expression
*
e
,
bool
globals_from_module
);
ScopingAnalysis
(
AST_Suite
*
s
);
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
);
ScopeInfo
*
getScopeInfoForNode
(
AST
*
node
);
ScopeInfo
*
getScopeInfoForNode
(
AST
*
node
);
InternedStringPool
&
getInternedStrings
();
InternedStringPool
&
getInternedStrings
();
...
...
src/codegen/ast_interpreter.cpp
View file @
9c78c3d4
...
@@ -141,6 +141,9 @@ private:
...
@@ -141,6 +141,9 @@ private:
unsigned
edgecount
;
unsigned
edgecount
;
FrameInfo
frame_info
;
FrameInfo
frame_info
;
// This is either a module or a dict
Box
*
globals
;
public:
public:
AST_stmt
*
getCurrentStatement
()
{
AST_stmt
*
getCurrentStatement
()
{
assert
(
current_inst
);
assert
(
current_inst
);
...
@@ -159,6 +162,7 @@ public:
...
@@ -159,6 +162,7 @@ public:
void
setCreatedClosure
(
Box
*
closure
);
void
setCreatedClosure
(
Box
*
closure
);
void
setBoxedLocals
(
Box
*
);
void
setBoxedLocals
(
Box
*
);
void
setFrameInfo
(
const
FrameInfo
*
frame_info
);
void
setFrameInfo
(
const
FrameInfo
*
frame_info
);
void
setGlobals
(
Box
*
globals
);
void
gcVisit
(
GCVisitor
*
visitor
);
void
gcVisit
(
GCVisitor
*
visitor
);
};
};
...
@@ -195,6 +199,13 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
...
@@ -195,6 +199,13 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
this
->
frame_info
=
*
frame_info
;
this
->
frame_info
=
*
frame_info
;
}
}
void
ASTInterpreter
::
setGlobals
(
Box
*
globals
)
{
this
->
globals
=
globals
;
if
(
globals
->
cls
==
dict_cls
)
{
frame_info
.
globals
=
static_cast
<
BoxedDict
*>
(
globals
);
}
}
void
ASTInterpreter
::
gcVisit
(
GCVisitor
*
visitor
)
{
void
ASTInterpreter
::
gcVisit
(
GCVisitor
*
visitor
)
{
visitor
->
visitRange
((
void
*
const
*
)
&
sym_table
.
vector
()[
0
],
(
void
*
const
*
)
&
sym_table
.
vector
()[
sym_table
.
size
()]);
visitor
->
visitRange
((
void
*
const
*
)
&
sym_table
.
vector
()[
0
],
(
void
*
const
*
)
&
sym_table
.
vector
()[
sym_table
.
size
()]);
if
(
passed_closure
)
if
(
passed_closure
)
...
@@ -205,6 +216,8 @@ void ASTInterpreter::gcVisit(GCVisitor* visitor) {
...
@@ -205,6 +216,8 @@ void ASTInterpreter::gcVisit(GCVisitor* visitor) {
visitor
->
visit
(
generator
);
visitor
->
visit
(
generator
);
if
(
frame_info
.
boxedLocals
)
if
(
frame_info
.
boxedLocals
)
visitor
->
visit
(
frame_info
.
boxedLocals
);
visitor
->
visit
(
frame_info
.
boxedLocals
);
if
(
frame_info
.
globals
)
visitor
->
visit
(
frame_info
.
globals
);
}
}
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
...
@@ -217,6 +230,7 @@ ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
...
@@ -217,6 +230,7 @@ ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
source_info
->
cfg
=
computeCFG
(
f
->
source
,
f
->
source
->
body
);
source_info
->
cfg
=
computeCFG
(
f
->
source
,
f
->
source
->
body
);
scope_info
=
source_info
->
getScopeInfo
();
scope_info
=
source_info
->
getScopeInfo
();
assert
(
scope_info
);
assert
(
scope_info
);
}
}
...
@@ -345,7 +359,12 @@ Value ASTInterpreter::doBinOp(Box* left, Box* right, int op, BinExpType exp_type
...
@@ -345,7 +359,12 @@ Value ASTInterpreter::doBinOp(Box* left, Box* right, int op, BinExpType exp_type
void
ASTInterpreter
::
doStore
(
InternedString
name
,
Value
value
)
{
void
ASTInterpreter
::
doStore
(
InternedString
name
,
Value
value
)
{
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
name
);
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
name
);
if
(
vst
==
ScopeInfo
::
VarScopeType
::
GLOBAL
)
{
if
(
vst
==
ScopeInfo
::
VarScopeType
::
GLOBAL
)
{
setattr
(
source_info
->
parent_module
,
name
.
c_str
(),
value
.
o
);
if
(
globals
->
cls
==
module_cls
)
{
setattr
(
static_cast
<
BoxedModule
*>
(
globals
),
name
.
c_str
(),
value
.
o
);
}
else
{
assert
(
globals
->
cls
==
dict_cls
);
static_cast
<
BoxedDict
*>
(
globals
)
->
d
[
boxString
(
name
.
str
())]
=
value
.
o
;
}
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
assert
(
frame_info
.
boxedLocals
!=
NULL
);
assert
(
frame_info
.
boxedLocals
!=
NULL
);
// TODO should probably pre-box the names when it's a scope that usesNameLookup
// TODO should probably pre-box the names when it's a scope that usesNameLookup
...
@@ -819,7 +838,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
...
@@ -819,7 +838,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
target
->
id
);
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
target
->
id
);
if
(
vst
==
ScopeInfo
::
VarScopeType
::
GLOBAL
)
{
if
(
vst
==
ScopeInfo
::
VarScopeType
::
GLOBAL
)
{
// Can't use delattr since the errors are different:
// Can't use delattr since the errors are different:
delGlobal
(
source_info
->
parent_module
,
&
target
->
id
.
str
());
delGlobal
(
globals
,
&
target
->
id
.
str
());
continue
;
continue
;
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
assert
(
frame_info
.
boxedLocals
!=
NULL
);
assert
(
frame_info
.
boxedLocals
!=
NULL
);
...
@@ -1084,7 +1103,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
...
@@ -1084,7 +1103,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
switch
(
node
->
lookup_type
)
{
switch
(
node
->
lookup_type
)
{
case
ScopeInfo
:
:
VarScopeType
::
GLOBAL
:
case
ScopeInfo
:
:
VarScopeType
::
GLOBAL
:
return
getGlobal
(
source_info
->
parent_module
,
&
node
->
id
.
str
());
return
getGlobal
(
globals
,
&
node
->
id
.
str
());
case
ScopeInfo
:
:
VarScopeType
::
DEREF
:
{
case
ScopeInfo
:
:
VarScopeType
::
DEREF
:
{
DerefInfo
deref_info
=
scope_info
->
getDerefInfo
(
node
->
id
);
DerefInfo
deref_info
=
scope_info
->
getDerefInfo
(
node
->
id
);
assert
(
passed_closure
);
assert
(
passed_closure
);
...
@@ -1109,7 +1128,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
...
@@ -1109,7 +1128,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
return
Value
();
return
Value
();
}
}
case
ScopeInfo
:
:
VarScopeType
::
NAME
:
{
case
ScopeInfo
:
:
VarScopeType
::
NAME
:
{
return
boxedLocalsGet
(
frame_info
.
boxedLocals
,
node
->
id
.
c_str
(),
source_info
->
parent_module
);
return
boxedLocalsGet
(
frame_info
.
boxedLocals
,
node
->
id
.
c_str
(),
globals
);
}
}
default:
default:
abort
();
abort
();
...
@@ -1161,22 +1180,39 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
...
@@ -1161,22 +1180,39 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
++
cf
->
times_called
;
++
cf
->
times_called
;
ASTInterpreter
interpreter
(
cf
);
ASTInterpreter
interpreter
(
cf
);
if
(
unlikely
(
cf
->
clfunc
->
source
->
getScopeInfo
()
->
usesNameLookup
()))
{
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
;
if
(
unlikely
(
scope_info
->
usesNameLookup
()))
{
interpreter
.
setBoxedLocals
(
new
BoxedDict
());
interpreter
.
setBoxedLocals
(
new
BoxedDict
());
}
}
assert
(
scope_info
->
areGlobalsFromModule
());
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
;
}
}
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
boxedLocals
)
{
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
edDict
*
globals
,
Box
*
boxedLocals
)
{
++
cf
->
times_called
;
++
cf
->
times_called
;
ASTInterpreter
interpreter
(
cf
);
ASTInterpreter
interpreter
(
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
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
;
if
(
scope_info
->
areGlobalsFromModule
())
{
assert
(
!
globals
);
interpreter
.
setGlobals
(
source_info
->
parent_module
);
}
else
{
assert
(
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
;
...
@@ -1192,6 +1228,15 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
...
@@ -1192,6 +1228,15 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
ASTInterpreter
interpreter
(
cf
);
ASTInterpreter
interpreter
(
cf
);
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
SourceInfo
*
source_info
=
cf
->
clfunc
->
source
;
if
(
scope_info
->
areGlobalsFromModule
())
{
interpreter
.
setGlobals
(
source_info
->
parent_module
);
}
else
{
assert
(
frame_state
.
frame_info
->
globals
);
interpreter
.
setGlobals
(
frame_state
.
frame_info
->
globals
);
}
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
);
std
::
string
name
=
static_cast
<
BoxedString
*>
(
p
.
first
)
->
s
;
std
::
string
name
=
static_cast
<
BoxedString
*>
(
p
.
first
)
->
s
;
...
...
src/codegen/ast_interpreter.h
View file @
9c78c3d4
...
@@ -35,7 +35,7 @@ extern const void* interpreter_instr_addr;
...
@@ -35,7 +35,7 @@ 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
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
Box
**
args
);
Box
**
args
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
boxedLocals
);
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
edDict
*
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
,
FrameStackState
frame_state
);
FrameStackState
frame_state
);
...
...
src/codegen/irgen/hooks.cpp
View file @
9c78c3d4
...
@@ -327,7 +327,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
...
@@ -327,7 +327,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
}
}
template
<
typename
AST_Type
>
template
<
typename
AST_Type
>
Box
*
evalOrExec
(
AST_Type
*
source
,
std
::
vector
<
AST_stmt
*>&
body
,
BoxedModule
*
bm
,
Box
*
boxedLocals
)
{
Box
*
evalOrExec
(
AST_Type
*
source
,
std
::
vector
<
AST_stmt
*>&
body
,
BoxedModule
*
bm
,
Box
edDict
*
globals
,
Box
*
boxedLocals
)
{
CompiledFunction
*
cf
;
CompiledFunction
*
cf
;
{
// scope for limiting the locked region:
{
// scope for limiting the locked region:
...
@@ -335,7 +335,7 @@ Box* evalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, BoxedModule* bm,
...
@@ -335,7 +335,7 @@ Box* evalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, BoxedModule* bm,
Timer
_t
(
"for evalOrExec()"
);
Timer
_t
(
"for evalOrExec()"
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
source
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
source
,
globals
==
NULL
);
SourceInfo
*
si
=
new
SourceInfo
(
bm
,
scoping
,
source
,
body
);
SourceInfo
*
si
=
new
SourceInfo
(
bm
,
scoping
,
source
,
body
);
CLFunction
*
cl_f
=
new
CLFunction
(
0
,
0
,
false
,
false
,
si
);
CLFunction
*
cl_f
=
new
CLFunction
(
0
,
0
,
false
,
false
,
si
);
...
@@ -352,7 +352,7 @@ Box* evalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, BoxedModule* bm,
...
@@ -352,7 +352,7 @@ Box* evalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, BoxedModule* bm,
assert
(
cf
->
clfunc
->
versions
.
size
());
assert
(
cf
->
clfunc
->
versions
.
size
());
}
}
return
astInterpretFunctionEval
(
cf
,
boxedLocals
);
return
astInterpretFunctionEval
(
cf
,
globals
,
boxedLocals
);
}
}
// Main entrypoints for eval and exec.
// Main entrypoints for eval and exec.
...
@@ -376,7 +376,7 @@ Box* eval(Box* boxedCode) {
...
@@ -376,7 +376,7 @@ Box* eval(Box* boxedCode) {
stmt
->
value
=
parsedExpr
->
body
;
stmt
->
value
=
parsedExpr
->
body
;
std
::
vector
<
AST_stmt
*>
body
=
{
stmt
};
std
::
vector
<
AST_stmt
*>
body
=
{
stmt
};
return
evalOrExec
<
AST_Expression
>
(
parsedExpr
,
body
,
module
,
boxedLocals
);
return
evalOrExec
<
AST_Expression
>
(
parsedExpr
,
body
,
module
,
NULL
,
boxedLocals
);
}
}
Box
*
exec
(
Box
*
boxedCode
,
Box
*
globals
,
Box
*
locals
)
{
Box
*
exec
(
Box
*
boxedCode
,
Box
*
globals
,
Box
*
locals
)
{
...
@@ -392,6 +392,8 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
...
@@ -392,6 +392,8 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
BoxedModule
*
module
=
getCurrentModule
();
BoxedModule
*
module
=
getCurrentModule
();
assert
(
!
globals
||
globals
->
cls
==
dict_cls
);
// TODO same issues as in `eval`
// TODO same issues as in `eval`
RELEASE_ASSERT
(
boxedCode
->
cls
==
str_cls
,
""
);
RELEASE_ASSERT
(
boxedCode
->
cls
==
str_cls
,
""
);
const
char
*
code
=
static_cast
<
BoxedString
*>
(
boxedCode
)
->
s
.
c_str
();
const
char
*
code
=
static_cast
<
BoxedString
*>
(
boxedCode
)
->
s
.
c_str
();
...
@@ -399,7 +401,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
...
@@ -399,7 +401,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
AST_Suite
*
parsedSuite
=
new
AST_Suite
(
std
::
move
(
parsedModule
->
interned_strings
));
AST_Suite
*
parsedSuite
=
new
AST_Suite
(
std
::
move
(
parsedModule
->
interned_strings
));
parsedSuite
->
body
=
parsedModule
->
body
;
parsedSuite
->
body
=
parsedModule
->
body
;
return
evalOrExec
<
AST_Suite
>
(
parsedSuite
,
parsedSuite
->
body
,
module
,
locals
);
return
evalOrExec
<
AST_Suite
>
(
parsedSuite
,
parsedSuite
->
body
,
module
,
static_cast
<
BoxedDict
*>
(
globals
),
locals
);
}
}
// If a function version keeps failing its speculations, kill it (remove it
// If a function version keeps failing its speculations, kill it (remove it
...
...
src/core/types.h
View file @
9c78c3d4
...
@@ -567,8 +567,9 @@ struct FrameInfo {
...
@@ -567,8 +567,9 @@ struct FrameInfo {
ExcInfo
exc
;
ExcInfo
exc
;
Box
*
boxedLocals
;
Box
*
boxedLocals
;
BoxedDict
*
globals
;
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
)
{}
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
)
,
globals
(
NULL
)
{}
};
};
struct
CallattrFlags
{
struct
CallattrFlags
{
...
...
src/runtime/objmodel.cpp
View file @
9c78c3d4
...
@@ -4245,14 +4245,24 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
...
@@ -4245,14 +4245,24 @@ Box* typeCall(Box* obj, BoxedTuple* vararg, BoxedDict* kwargs) {
return
typeCallInternal
(
NULL
,
NULL
,
ArgPassSpec
(
n
+
1
,
0
,
false
,
true
),
arg1
,
arg2
,
arg3
,
args
,
NULL
);
return
typeCallInternal
(
NULL
,
NULL
,
ArgPassSpec
(
n
+
1
,
0
,
false
,
true
),
arg1
,
arg2
,
arg3
,
args
,
NULL
);
}
}
extern
"C"
void
delGlobal
(
BoxedModule
*
m
,
const
std
::
string
*
name
)
{
extern
"C"
void
delGlobal
(
Box
*
globals
,
const
std
::
string
*
name
)
{
if
(
globals
->
cls
==
module_cls
)
{
BoxedModule
*
m
=
static_cast
<
BoxedModule
*>
(
globals
);
if
(
!
m
->
getattr
(
*
name
))
{
if
(
!
m
->
getattr
(
*
name
))
{
raiseExcHelper
(
NameError
,
"name '%s' is not defined"
,
name
->
c_str
());
raiseExcHelper
(
NameError
,
"name '%s' is not defined"
,
name
->
c_str
());
}
}
m
->
delattr
(
*
name
,
NULL
);
m
->
delattr
(
*
name
,
NULL
);
}
else
{
assert
(
globals
->
cls
==
dict_cls
);
BoxedDict
*
d
=
static_cast
<
BoxedDict
*>
(
globals
);
auto
it
=
d
->
d
.
find
(
boxString
(
*
name
));
assertNameDefined
(
it
!=
d
->
d
.
end
(),
name
->
c_str
(),
NameError
,
false
/* local_var_msg */
);
d
->
d
.
erase
(
it
);
}
}
}
extern
"C"
Box
*
getGlobal
(
Box
edModule
*
m
,
const
std
::
string
*
name
)
{
extern
"C"
Box
*
getGlobal
(
Box
*
globals
,
const
std
::
string
*
name
)
{
static
StatCounter
slowpath_getglobal
(
"slowpath_getglobal"
);
static
StatCounter
slowpath_getglobal
(
"slowpath_getglobal"
);
slowpath_getglobal
.
log
();
slowpath_getglobal
.
log
();
static
StatCounter
nopatch_getglobal
(
"nopatch_getglobal"
);
static
StatCounter
nopatch_getglobal
(
"nopatch_getglobal"
);
...
@@ -4270,10 +4280,17 @@ extern "C" Box* getGlobal(BoxedModule* m, const std::string* name) {
...
@@ -4270,10 +4280,17 @@ extern "C" Box* getGlobal(BoxedModule* m, const std::string* name) {
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
3
,
"getGlobal"
));
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
3
,
"getGlobal"
));
Box
*
r
;
Box
*
r
;
if
(
globals
->
cls
==
module_cls
)
{
BoxedModule
*
m
=
static_cast
<
BoxedModule
*>
(
globals
);
if
(
rewriter
.
get
())
{
if
(
rewriter
.
get
())
{
// rewriter->trap(
);
RewriterVar
*
r_mod
=
rewriter
->
getArg
(
0
);
GetattrRewriteArgs
rewrite_args
(
rewriter
.
get
(),
rewriter
->
getArg
(
0
),
rewriter
->
getReturnDestination
());
// Guard on it being a module rather than a dict
// TODO is this guard necessary? I'm being conservative now, but I think we can just
// insist that the type passed in is fixed for any given instance of a getGlobal call.
r_mod
->
addAttrGuard
(
BOX_CLS_OFFSET
,
(
intptr_t
)
module_cls
);
GetattrRewriteArgs
rewrite_args
(
rewriter
.
get
(),
r_mod
,
rewriter
->
getReturnDestination
());
r
=
m
->
getattr
(
*
name
,
&
rewrite_args
);
r
=
m
->
getattr
(
*
name
,
&
rewrite_args
);
if
(
!
rewrite_args
.
out_success
)
{
if
(
!
rewrite_args
.
out_success
)
{
rewriter
.
reset
(
NULL
);
rewriter
.
reset
(
NULL
);
...
@@ -4291,6 +4308,18 @@ extern "C" Box* getGlobal(BoxedModule* m, const std::string* name) {
...
@@ -4291,6 +4308,18 @@ extern "C" Box* getGlobal(BoxedModule* m, const std::string* name) {
return
r
;
return
r
;
}
}
}
}
}
else
{
assert
(
globals
->
cls
==
dict_cls
);
BoxedDict
*
d
=
static_cast
<
BoxedDict
*>
(
globals
);
rewriter
.
reset
(
NULL
);
REWRITE_ABORTED
(
"Rewriting not implemented for getGlobals with a dict globals yet"
);
auto
it
=
d
->
d
.
find
(
boxString
(
*
name
));
if
(
it
!=
d
->
d
.
end
())
{
return
it
->
second
;
}
}
static
StatCounter
stat_builtins
(
"getglobal_builtins"
);
static
StatCounter
stat_builtins
(
"getglobal_builtins"
);
stat_builtins
.
log
();
stat_builtins
.
log
();
...
@@ -4408,8 +4437,7 @@ extern "C" void boxedLocalsSet(Box* boxedLocals, const char* attr, Box* val) {
...
@@ -4408,8 +4437,7 @@ extern "C" void boxedLocalsSet(Box* boxedLocals, const char* attr, Box* val) {
setitem
(
boxedLocals
,
boxString
(
attr
),
val
);
setitem
(
boxedLocals
,
boxString
(
attr
),
val
);
}
}
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
BoxedModule
*
parent_module
)
{
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
*
globals
)
{
assert
(
parent_module
->
cls
==
module_cls
);
assert
(
boxedLocals
!=
NULL
);
assert
(
boxedLocals
!=
NULL
);
if
(
boxedLocals
->
cls
==
dict_cls
)
{
if
(
boxedLocals
->
cls
==
dict_cls
)
{
...
@@ -4434,7 +4462,7 @@ extern "C" Box* boxedLocalsGet(Box* boxedLocals, const char* attr, BoxedModule*
...
@@ -4434,7 +4462,7 @@ extern "C" Box* boxedLocalsGet(Box* boxedLocals, const char* attr, BoxedModule*
// TODO exception name?
// TODO exception name?
std
::
string
attr_string
(
attr
);
std
::
string
attr_string
(
attr
);
return
getGlobal
(
parent_module
,
&
attr_string
);
return
getGlobal
(
globals
,
&
attr_string
);
}
}
extern
"C"
void
boxedLocalsDel
(
Box
*
boxedLocals
,
const
char
*
attr
)
{
extern
"C"
void
boxedLocalsDel
(
Box
*
boxedLocals
,
const
char
*
attr
)
{
...
...
src/runtime/objmodel.h
View file @
9c78c3d4
...
@@ -72,8 +72,6 @@ extern "C" BoxedInt* len(Box* obj);
...
@@ -72,8 +72,6 @@ extern "C" BoxedInt* len(Box* obj);
extern
"C"
i64
unboxedLen
(
Box
*
obj
);
extern
"C"
i64
unboxedLen
(
Box
*
obj
);
extern
"C"
Box
*
binop
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
);
extern
"C"
Box
*
binop
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
);
extern
"C"
Box
*
augbinop
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
);
extern
"C"
Box
*
augbinop
(
Box
*
lhs
,
Box
*
rhs
,
int
op_type
);
extern
"C"
Box
*
getGlobal
(
BoxedModule
*
m
,
const
std
::
string
*
name
);
extern
"C"
void
delGlobal
(
BoxedModule
*
m
,
const
std
::
string
*
name
);
extern
"C"
Box
*
getitem
(
Box
*
value
,
Box
*
slice
);
extern
"C"
Box
*
getitem
(
Box
*
value
,
Box
*
slice
);
extern
"C"
void
setitem
(
Box
*
target
,
Box
*
slice
,
Box
*
value
);
extern
"C"
void
setitem
(
Box
*
target
,
Box
*
slice
,
Box
*
value
);
extern
"C"
void
delitem
(
Box
*
target
,
Box
*
slice
);
extern
"C"
void
delitem
(
Box
*
target
,
Box
*
slice
);
...
@@ -168,8 +166,13 @@ inline std::tuple<Box*, Box*, Box*, Box**> getTupleFromArgsArray(Box** args, int
...
@@ -168,8 +166,13 @@ inline std::tuple<Box*, Box*, Box*, Box**> getTupleFromArgsArray(Box** args, int
return
std
::
make_tuple
(
arg1
,
arg2
,
arg3
,
argtuple
);
return
std
::
make_tuple
(
arg1
,
arg2
,
arg3
,
argtuple
);
}
}
// The `globals` argument can be either a BoxedModule or a BoxedDict
extern
"C"
Box
*
getGlobal
(
Box
*
globals
,
const
std
::
string
*
name
);
extern
"C"
void
delGlobal
(
Box
*
globals
,
const
std
::
string
*
name
);
extern
"C"
void
boxedLocalsSet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
*
val
);
extern
"C"
void
boxedLocalsSet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
*
val
);
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
edModule
*
parent_module
);
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
*
globals
);
extern
"C"
void
boxedLocalsDel
(
Box
*
boxedLocals
,
const
char
*
attr
);
extern
"C"
void
boxedLocalsDel
(
Box
*
boxedLocals
,
const
char
*
attr
);
}
}
#endif
#endif
test/tests/exec_in_test.py
0 → 100644
View file @
9c78c3d4
print
'Test getting'
g
=
{
'a'
:
1
}
l
=
{
'b'
:
2
}
exec
"""global a
print a
print b"""
in
g
,
l
print
'Test setting'
g
=
{}
l
=
{}
exec
"""global a
a = 1
b = 2"""
in
g
,
l
print
g
print
l
print
'Test deleting'
g
=
{
'a'
:
1
}
l
=
{
'b'
:
2
}
exec
"""global a
del a
del b"""
in
g
,
l
print
g
print
l
print
'Test global access in a function'
g
=
{
'a'
:
4
,
'b'
:
5
}
exec
"""
def f():
global a, b, c
print 'a =', a
del b
c = 20
f()
"""
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