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
c3b3f6a6
Commit
c3b3f6a6
authored
Mar 21, 2015
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
return globals() as locals() for module-level scopes
parent
2bfcd7d1
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
53 additions
and
31 deletions
+53
-31
src/analysis/scoping_analysis.cpp
src/analysis/scoping_analysis.cpp
+4
-0
src/analysis/scoping_analysis.h
src/analysis/scoping_analysis.h
+2
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+1
-10
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+10
-4
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+21
-7
test/tests/eval_test.py
test/tests/eval_test.py
+10
-10
test/tests/globals_func.py
test/tests/globals_func.py
+5
-0
No files found.
src/analysis/scoping_analysis.cpp
View file @
c3b3f6a6
...
...
@@ -105,6 +105,8 @@ public:
bool
isPassedToViaClosure
(
InternedString
name
)
override
{
return
false
;
}
bool
areLocalsFromModule
()
override
{
return
true
;
}
InternedString
mangleName
(
InternedString
id
)
override
{
return
id
;
}
InternedString
internString
(
llvm
::
StringRef
s
)
override
{
abort
();
}
};
...
...
@@ -245,6 +247,8 @@ public:
return
usage
->
got_from_closure
.
count
(
name
)
>
0
||
usage
->
passthrough_accesses
.
count
(
name
)
>
0
;
}
bool
areLocalsFromModule
()
override
{
return
false
;
}
InternedString
mangleName
(
const
InternedString
id
)
override
{
return
pyston
::
mangleName
(
id
,
usage
->
private_name
,
usage
->
scoping
->
getInternedStrings
());
}
...
...
src/analysis/scoping_analysis.h
View file @
c3b3f6a6
...
...
@@ -114,6 +114,8 @@ public:
// `exec` or `eval` scope.
virtual
bool
usesNameLookup
()
=
0
;
virtual
bool
areLocalsFromModule
()
=
0
;
virtual
InternedString
mangleName
(
InternedString
id
)
=
0
;
virtual
InternedString
internString
(
llvm
::
StringRef
)
=
0
;
};
...
...
src/codegen/ast_interpreter.cpp
View file @
c3b3f6a6
...
...
@@ -1095,15 +1095,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
return
Value
();
}
case
ScopeInfo
:
:
VarScopeType
::
NAME
:
{
assert
(
frame_info
.
boxedLocals
->
cls
==
dict_cls
);
auto
&
d
=
static_cast
<
BoxedDict
*>
(
frame_info
.
boxedLocals
)
->
d
;
auto
it
=
d
.
find
(
boxString
(
node
->
id
.
str
()));
if
(
it
!=
d
.
end
())
{
Box
*
value
=
it
->
second
;
return
value
;
}
return
getGlobal
(
source_info
->
parent_module
,
&
node
->
id
.
str
());
return
boxedLocalsGet
(
frame_info
.
boxedLocals
,
node
->
id
.
c_str
(),
source_info
->
parent_module
);
}
default:
abort
();
...
...
@@ -1170,7 +1162,6 @@ Box* astInterpretFunctionEval(CompiledFunction* cf, Box* boxedLocals) {
ASTInterpreter
interpreter
(
cf
);
interpreter
.
initArguments
(
0
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
RELEASE_ASSERT
(
boxedLocals
->
cls
==
dict_cls
,
"we don't support non-dicts here yet"
);
interpreter
.
setBoxedLocals
(
boxedLocals
);
Value
v
=
ASTInterpreter
::
execute
(
interpreter
);
...
...
src/codegen/unwinding.cpp
View file @
c3b3f6a6
...
...
@@ -638,12 +638,20 @@ Box* fastLocalsToBoxedLocals() {
for
(
PythonFrameIterator
&
frame_iter
:
unwindPythonFrames
())
{
BoxedDict
*
d
;
BoxedClosure
*
closure
;
CompiledFunction
*
cf
;
FrameInfo
*
frame_info
;
CompiledFunction
*
cf
=
frame_iter
.
getCF
();
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
if
(
scope_info
->
areLocalsFromModule
())
{
// TODO we should cache this in frame_info->locals or something so that locals()
// (and globals() too) will always return the same dict
return
makeAttrWrapper
(
getCurrentModule
());
}
if
(
frame_iter
.
getId
().
type
==
PythonFrameId
::
COMPILED
)
{
d
=
new
BoxedDict
();
cf
=
frame_iter
.
getCF
();
uint64_t
ip
=
frame_iter
.
getId
().
ip
;
assert
(
ip
>
cf
->
code_start
);
...
...
@@ -727,7 +735,6 @@ Box* fastLocalsToBoxedLocals() {
}
else
if
(
frame_iter
.
getId
().
type
==
PythonFrameId
::
INTERPRETED
)
{
d
=
localsForInterpretedFrame
((
void
*
)
frame_iter
.
getId
().
bp
,
true
);
closure
=
passedClosureForInterpretedFrame
((
void
*
)
frame_iter
.
getId
().
bp
);
cf
=
getCFForInterpretedFrame
((
void
*
)
frame_iter
.
getId
().
bp
);
frame_info
=
getFrameInfoForInterpretedFrame
((
void
*
)
frame_iter
.
getId
().
bp
);
}
else
{
abort
();
...
...
@@ -747,7 +754,6 @@ Box* fastLocalsToBoxedLocals() {
const
std
::
string
&
name
=
attr_offset
.
first
();
int
offset
=
attr_offset
.
second
;
Box
*
val
=
closure
->
attrs
.
attr_list
->
attrs
[
offset
];
ScopeInfo
*
scope_info
=
cf
->
clfunc
->
source
->
getScopeInfo
();
if
(
val
!=
NULL
&&
scope_info
->
isPassedToViaClosure
(
scope_info
->
internString
(
name
)))
{
Box
*
boxedName
=
boxString
(
name
);
if
(
d
->
d
.
count
(
boxedName
)
==
0
)
{
...
...
src/runtime/objmodel.cpp
View file @
c3b3f6a6
...
...
@@ -4450,20 +4450,34 @@ Box* coerceUnicodeToStr(Box* unicode) {
return
r
;
}
// TODO Make these fast, do inline caches and stuff
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
);
assert
(
boxedLocals
!=
NULL
);
RELEASE_ASSERT
(
boxedLocals
->
cls
==
dict_cls
,
"we don't support non-dict here yet"
);
auto
&
d
=
static_cast
<
BoxedDict
*>
(
boxedLocals
)
->
d
;
auto
it
=
d
.
find
(
boxString
(
attr
));
if
(
it
!=
d
.
end
())
{
Box
*
value
=
it
->
second
;
return
value
;
if
(
boxedLocals
->
cls
==
dict_cls
)
{
auto
&
d
=
static_cast
<
BoxedDict
*>
(
boxedLocals
)
->
d
;
auto
it
=
d
.
find
(
boxString
(
attr
));
if
(
it
!=
d
.
end
())
{
Box
*
value
=
it
->
second
;
return
value
;
}
}
else
{
try
{
return
getitem
(
boxedLocals
,
boxString
(
attr
));
}
catch
(
ExcInfo
e
)
{
// TODO should check the exact semantic here but it's something like:
// If it throws a KeyError, then the variable doesn't exist so move on
// and check the globals (below); otherwise, just propogate the exception.
if
(
!
isInstance
(
e
.
value
,
KeyError
))
{
throw
;
}
}
}
// TODO exception name?
...
...
test/tests/eval_test.py
View file @
c3b3f6a6
...
...
@@ -5,17 +5,17 @@ print eval("3 + 4")
a
=
5
print
eval
(
"a"
)
#
print eval("[b for b in range(5)]")
#
print b
print
eval
(
"[b for b in range(5)]"
)
print
b
#
c = 2
#
print eval("[c for c in range(5)]")
#
print c
c
=
2
print
eval
(
"[c for c in range(5)]"
)
print
c
#
try:
#
print eval("int('abc')")
#
except ValueError:
#
print 'got ValueError'
try
:
print
eval
(
"int('abc')"
)
except
ValueError
:
print
'got ValueError'
d
=
19
e
=
20
...
...
@@ -85,7 +85,7 @@ o = 300
print
'eval eval o'
,
eval
(
"eval('o')"
)
# This works in the global scope but not in the local scope, because o1 is a global:
#print eval("[(lambda p1 : p1 + o1)(5) for o1 in range(5)]")
#
print eval("[(lambda p1 : p1 + o1)(5) for o1 in range(5)]")
def
lambda_func
():
try
:
pass
#print eval("[(lambda p2 : p2 + o2)(5) for o2 in range(5)]")
...
...
test/tests/globals_func.py
View file @
c3b3f6a6
...
...
@@ -18,3 +18,8 @@ except NameError:
# You're allowed to assign through globals and have it affect the module:
globals
()[
'x'
]
=
1
print
x
# locals should do the same as globals
print
locals
()[
'x'
]
locals
()[
'x'
]
=
2
print
x
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