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
Hide 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:
bool
usesNameLookup
()
override
{
return
false
;
}
bool
areLocalsFromModule
()
override
{
return
true
;
}
bool
areGlobalsFromModule
()
override
{
return
true
;
}
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"
);
}
...
...
@@ -142,10 +143,12 @@ private:
}
};
bool
globals_from_module
;
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
// or ClassDefs) and put the names in `forced_globals`.
GlobalStmtVisitor
visitor
(
forced_globals
);
...
...
@@ -170,6 +173,7 @@ public:
bool
usesNameLookup
()
override
{
return
true
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areGlobalsFromModule
()
override
{
return
globals_from_module
;
}
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"
);
}
...
...
@@ -321,6 +325,7 @@ public:
bool
usesNameLookup
()
override
{
return
usesNameLookup_
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
bool
areGlobalsFromModule
()
override
{
return
true
;
}
DerefInfo
getDerefInfo
(
InternedString
name
)
override
{
assert
(
getScopeTypeOfName
(
name
)
==
VarScopeType
::
DEREF
);
...
...
@@ -881,12 +886,12 @@ ScopingAnalysis::ScopingAnalysis(AST_Module* m) : parent_module(m), interned_str
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
scopes
[
e
]
=
new
EvalExprScopeInfo
();
scopes
[
e
]
=
new
EvalExprScopeInfo
(
globals_from_module
);
}
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
{
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
);
ScopingAnalysis
::
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
)
:
interned_strings
(
*
s
->
interned_strings
.
get
())
{
scopes
[
s
]
=
new
EvalExprScopeInfo
(
s
,
globals_from_module
);
}
}
src/analysis/scoping_analysis.h
View file @
9c78c3d4
...
...
@@ -92,6 +92,7 @@ public:
virtual
bool
usesNameLookup
()
=
0
;
virtual
bool
areLocalsFromModule
()
=
0
;
virtual
bool
areGlobalsFromModule
()
=
0
;
// For a variable with DEREF lookup, return the DerefInfo used to lookup
// the variable in a passed closure.
...
...
@@ -169,8 +170,8 @@ public:
void
registerScopeReplacement
(
AST
*
original_node
,
AST
*
new_node
);
ScopingAnalysis
(
AST_Module
*
m
);
ScopingAnalysis
(
AST_Expression
*
e
);
ScopingAnalysis
(
AST_Suite
*
s
);
ScopingAnalysis
(
AST_Expression
*
e
,
bool
globals_from_module
);
ScopingAnalysis
(
AST_Suite
*
s
,
bool
globals_from_module
);
ScopeInfo
*
getScopeInfoForNode
(
AST
*
node
);
InternedStringPool
&
getInternedStrings
();
...
...
src/codegen/ast_interpreter.cpp
View file @
9c78c3d4
...
...
@@ -141,6 +141,9 @@ private:
unsigned
edgecount
;
FrameInfo
frame_info
;
// This is either a module or a dict
Box
*
globals
;
public:
AST_stmt
*
getCurrentStatement
()
{
assert
(
current_inst
);
...
...
@@ -159,6 +162,7 @@ public:
void
setCreatedClosure
(
Box
*
closure
);
void
setBoxedLocals
(
Box
*
);
void
setFrameInfo
(
const
FrameInfo
*
frame_info
);
void
setGlobals
(
Box
*
globals
);
void
gcVisit
(
GCVisitor
*
visitor
);
};
...
...
@@ -195,6 +199,13 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* 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
)
{
visitor
->
visitRange
((
void
*
const
*
)
&
sym_table
.
vector
()[
0
],
(
void
*
const
*
)
&
sym_table
.
vector
()[
sym_table
.
size
()]);
if
(
passed_closure
)
...
...
@@ -205,6 +216,8 @@ void ASTInterpreter::gcVisit(GCVisitor* visitor) {
visitor
->
visit
(
generator
);
if
(
frame_info
.
boxedLocals
)
visitor
->
visit
(
frame_info
.
boxedLocals
);
if
(
frame_info
.
globals
)
visitor
->
visit
(
frame_info
.
globals
);
}
ASTInterpreter
::
ASTInterpreter
(
CompiledFunction
*
compiled_function
)
...
...
@@ -217,6 +230,7 @@ ASTInterpreter::ASTInterpreter(CompiledFunction* compiled_function)
source_info
->
cfg
=
computeCFG
(
f
->
source
,
f
->
source
->
body
);
scope_info
=
source_info
->
getScopeInfo
();
assert
(
scope_info
);
}
...
...
@@ -345,7 +359,12 @@ Value ASTInterpreter::doBinOp(Box* left, Box* right, int op, BinExpType exp_type
void
ASTInterpreter
::
doStore
(
InternedString
name
,
Value
value
)
{
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
name
);
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
)
{
assert
(
frame_info
.
boxedLocals
!=
NULL
);
// 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) {
ScopeInfo
::
VarScopeType
vst
=
scope_info
->
getScopeTypeOfName
(
target
->
id
);
if
(
vst
==
ScopeInfo
::
VarScopeType
::
GLOBAL
)
{
// Can't use delattr since the errors are different:
delGlobal
(
source_info
->
parent_module
,
&
target
->
id
.
str
());
delGlobal
(
globals
,
&
target
->
id
.
str
());
continue
;
}
else
if
(
vst
==
ScopeInfo
::
VarScopeType
::
NAME
)
{
assert
(
frame_info
.
boxedLocals
!=
NULL
);
...
...
@@ -1084,7 +1103,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
switch
(
node
->
lookup_type
)
{
case
ScopeInfo
:
:
VarScopeType
::
GLOBAL
:
return
getGlobal
(
source_info
->
parent_module
,
&
node
->
id
.
str
());
return
getGlobal
(
globals
,
&
node
->
id
.
str
());
case
ScopeInfo
:
:
VarScopeType
::
DEREF
:
{
DerefInfo
deref_info
=
scope_info
->
getDerefInfo
(
node
->
id
);
assert
(
passed_closure
);
...
...
@@ -1109,7 +1128,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
return
Value
();
}
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:
abort
();
...
...
@@ -1161,22 +1180,39 @@ Box* astInterpretFunction(CompiledFunction* cf, int nargs, Box* closure, Box* ge
++
cf
->
times_called
;
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
());
}
assert
(
scope_info
->
areGlobalsFromModule
());
interpreter
.
setGlobals
(
source_info
->
parent_module
);
interpreter
.
initArguments
(
nargs
,
(
BoxedClosure
*
)
closure
,
(
BoxedGenerator
*
)
generator
,
arg1
,
arg2
,
arg3
,
args
);
Value
v
=
ASTInterpreter
::
execute
(
interpreter
);
return
v
.
o
?
v
.
o
:
None
;
}
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
*
boxedLocals
)
{
Box
*
astInterpretFunctionEval
(
CompiledFunction
*
cf
,
Box
edDict
*
globals
,
Box
*
boxedLocals
)
{
++
cf
->
times_called
;
ASTInterpreter
interpreter
(
cf
);
interpreter
.
initArguments
(
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
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
);
return
v
.
o
?
v
.
o
:
None
;
...
...
@@ -1192,6 +1228,15 @@ Box* astInterpretFrom(CompiledFunction* cf, AST_expr* after_expr, AST_stmt* encl
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
)
{
assert
(
p
.
first
->
cls
==
str_cls
);
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;
Box
*
astInterpretFunction
(
CompiledFunction
*
f
,
int
nargs
,
Box
*
closure
,
Box
*
generator
,
Box
*
arg1
,
Box
*
arg2
,
Box
*
arg3
,
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
,
FrameStackState
frame_state
);
...
...
src/codegen/irgen/hooks.cpp
View file @
9c78c3d4
...
...
@@ -327,7 +327,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
}
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
;
{
// scope for limiting the locked region:
...
...
@@ -335,7 +335,7 @@ Box* evalOrExec(AST_Type* source, std::vector<AST_stmt*>& body, BoxedModule* bm,
Timer
_t
(
"for evalOrExec()"
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
source
);
ScopingAnalysis
*
scoping
=
new
ScopingAnalysis
(
source
,
globals
==
NULL
);
SourceInfo
*
si
=
new
SourceInfo
(
bm
,
scoping
,
source
,
body
);
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,
assert
(
cf
->
clfunc
->
versions
.
size
());
}
return
astInterpretFunctionEval
(
cf
,
boxedLocals
);
return
astInterpretFunctionEval
(
cf
,
globals
,
boxedLocals
);
}
// Main entrypoints for eval and exec.
...
...
@@ -376,7 +376,7 @@ Box* eval(Box* boxedCode) {
stmt
->
value
=
parsedExpr
->
body
;
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
)
{
...
...
@@ -392,6 +392,8 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
BoxedModule
*
module
=
getCurrentModule
();
assert
(
!
globals
||
globals
->
cls
==
dict_cls
);
// TODO same issues as in `eval`
RELEASE_ASSERT
(
boxedCode
->
cls
==
str_cls
,
""
);
const
char
*
code
=
static_cast
<
BoxedString
*>
(
boxedCode
)
->
s
.
c_str
();
...
...
@@ -399,7 +401,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
AST_Suite
*
parsedSuite
=
new
AST_Suite
(
std
::
move
(
parsedModule
->
interned_strings
));
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
...
...
src/core/types.h
View file @
9c78c3d4
...
...
@@ -567,8 +567,9 @@ struct FrameInfo {
ExcInfo
exc
;
Box
*
boxedLocals
;
BoxedDict
*
globals
;
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
)
{}
FrameInfo
(
ExcInfo
exc
)
:
exc
(
exc
),
boxedLocals
(
NULL
)
,
globals
(
NULL
)
{}
};
struct
CallattrFlags
{
...
...
src/runtime/objmodel.cpp
View file @
9c78c3d4
...
...
@@ -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
);
}
extern
"C"
void
delGlobal
(
BoxedModule
*
m
,
const
std
::
string
*
name
)
{
if
(
!
m
->
getattr
(
*
name
))
{
raiseExcHelper
(
NameError
,
"name '%s' is not defined"
,
name
->
c_str
());
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
))
{
raiseExcHelper
(
NameError
,
"name '%s' is not defined"
,
name
->
c_str
());
}
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
);
}
m
->
delattr
(
*
name
,
NULL
);
}
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"
);
slowpath_getglobal
.
log
();
static
StatCounter
nopatch_getglobal
(
"nopatch_getglobal"
);
...
...
@@ -4270,25 +4280,44 @@ extern "C" Box* getGlobal(BoxedModule* m, const std::string* name) {
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
3
,
"getGlobal"
));
Box
*
r
;
if
(
rewriter
.
get
())
{
// rewriter->trap();
if
(
globals
->
cls
==
module_cls
)
{
BoxedModule
*
m
=
static_cast
<
BoxedModule
*>
(
globals
);
if
(
rewriter
.
get
())
{
RewriterVar
*
r_mod
=
rewriter
->
getArg
(
0
);
GetattrRewriteArgs
rewrite_args
(
rewriter
.
get
(),
rewriter
->
getArg
(
0
),
rewriter
->
getReturnDestination
());
r
=
m
->
getattr
(
*
name
,
&
rewrite_args
);
if
(
!
rewrite_args
.
out_success
)
{
rewriter
.
reset
(
NULL
);
}
if
(
r
)
{
if
(
rewriter
.
get
())
{
rewriter
->
commitReturning
(
rewrite_args
.
out_rtn
);
// 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
);
if
(
!
rewrite_args
.
out_success
)
{
rewriter
.
reset
(
NULL
);
}
if
(
r
)
{
if
(
rewriter
.
get
())
{
rewriter
->
commitReturning
(
rewrite_args
.
out_rtn
);
}
return
r
;
}
}
else
{
r
=
m
->
getattr
(
*
name
,
NULL
);
nopatch_getglobal
.
log
();
if
(
r
)
{
return
r
;
}
return
r
;
}
}
else
{
r
=
m
->
getattr
(
*
name
,
NULL
);
nopatch_getglobal
.
log
();
if
(
r
)
{
return
r
;
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
;
}
}
...
...
@@ -4408,8 +4437,7 @@ extern "C" void boxedLocalsSet(Box* boxedLocals, const char* attr, Box* val) {
setitem
(
boxedLocals
,
boxString
(
attr
),
val
);
}
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
BoxedModule
*
parent_module
)
{
assert
(
parent_module
->
cls
==
module_cls
);
extern
"C"
Box
*
boxedLocalsGet
(
Box
*
boxedLocals
,
const
char
*
attr
,
Box
*
globals
)
{
assert
(
boxedLocals
!=
NULL
);
if
(
boxedLocals
->
cls
==
dict_cls
)
{
...
...
@@ -4434,7 +4462,7 @@ extern "C" Box* boxedLocalsGet(Box* boxedLocals, const char* attr, BoxedModule*
// TODO exception name?
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
)
{
...
...
src/runtime/objmodel.h
View file @
9c78c3d4
...
...
@@ -72,8 +72,6 @@ extern "C" BoxedInt* len(Box* obj);
extern
"C"
i64
unboxedLen
(
Box
*
obj
);
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
*
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"
void
setitem
(
Box
*
target
,
Box
*
slice
,
Box
*
value
);
extern
"C"
void
delitem
(
Box
*
target
,
Box
*
slice
);
...
...
@@ -168,8 +166,13 @@ inline std::tuple<Box*, Box*, Box*, Box**> getTupleFromArgsArray(Box** args, int
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"
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
);
}
#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