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
8364a607
Commit
8364a607
authored
Apr 29, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #477 from kmod/gflags
gflags support
parents
123aa269
66393bc6
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
291 additions
and
145 deletions
+291
-145
src/capi/modsupport.cpp
src/capi/modsupport.cpp
+1
-1
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+1
-1
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+1
-1
src/codegen/unwinding.cpp
src/codegen/unwinding.cpp
+2
-2
src/core/types.h
src/core/types.h
+9
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+2
-2
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+8
-0
src/runtime/builtin_modules/thread.cpp
src/runtime/builtin_modules/thread.cpp
+33
-4
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+2
-2
src/runtime/frame.cpp
src/runtime/frame.cpp
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+84
-48
src/runtime/stacktrace.cpp
src/runtime/stacktrace.cpp
+5
-4
src/runtime/types.cpp
src/runtime/types.cpp
+25
-16
src/runtime/types.h
src/runtime/types.h
+34
-8
test/integration/virtualenv_test.py
test/integration/virtualenv_test.py
+2
-1
test/tests/globals.py
test/tests/globals.py
+2
-0
test/tests/sys_getframe.py
test/tests/sys_getframe.py
+74
-0
test/tests/sys_getframe2.py
test/tests/sys_getframe2.py
+0
-17
test/tests/sys_getframe3.py
test/tests/sys_getframe3.py
+0
-22
test/tests/sys_getframe4.py
test/tests/sys_getframe4.py
+0
-15
test/tests/threading_local.py
test/tests/threading_local.py
+5
-0
No files found.
src/capi/modsupport.cpp
View file @
8364a607
...
...
@@ -425,7 +425,7 @@ extern "C" PyObject* PyModule_GetDict(PyObject* _m) noexcept {
BoxedModule
*
m
=
static_cast
<
BoxedModule
*>
(
_m
);
assert
(
m
->
cls
==
module_cls
);
return
m
akeAttrWrapper
(
m
);
return
m
->
getAttrWrapper
(
);
}
extern
"C"
int
PyModule_AddObject
(
PyObject
*
_m
,
const
char
*
name
,
PyObject
*
value
)
noexcept
{
...
...
src/capi/typeobject.cpp
View file @
8364a607
...
...
@@ -2706,7 +2706,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls
->
giveAttr
(
"__base__"
,
base
);
assert
(
cls
->
tp_dict
==
NULL
);
cls
->
tp_dict
=
makeAttrWrapper
(
cls
);
cls
->
tp_dict
=
cls
->
getAttrWrapper
(
);
assert
(
cls
->
tp_name
);
// tp_name
...
...
src/codegen/irgen/hooks.cpp
View file @
8364a607
...
...
@@ -516,7 +516,7 @@ Box* exec(Box* boxedCode, Box* globals, Box* locals) {
// From CPython (they set it to be f->f_builtins):
Box
*
globals_dict
=
globals
;
if
(
globals
->
cls
==
module_cls
)
globals_dict
=
makeAttrWrapper
(
globals
);
globals_dict
=
globals
->
getAttrWrapper
(
);
if
(
PyDict_GetItemString
(
globals_dict
,
"__builtins__"
)
==
NULL
)
PyDict_SetItemString
(
globals_dict
,
"__builtins__"
,
builtins_module
);
}
...
...
src/codegen/unwinding.cpp
View file @
8364a607
...
...
@@ -596,7 +596,7 @@ Box* getGlobalsDict() {
return
NULL
;
if
(
isSubclass
(
globals
->
cls
,
module_cls
))
return
makeAttrWrapper
(
globals
);
return
globals
->
getAttrWrapper
(
);
return
globals
;
}
...
...
@@ -735,7 +735,7 @@ Box* PythonFrameIterator::fastLocalsToBoxedLocals() {
// TODO we should cache this in frame_info->locals or something so that locals()
// (and globals() too) will always return the same dict
RELEASE_ASSERT
(
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
(),
""
);
return
makeAttrWrapper
(
cf
->
clfunc
->
source
->
parent_module
);
return
cf
->
clfunc
->
source
->
parent_module
->
getAttrWrapper
(
);
}
if
(
impl
->
getId
().
type
==
PythonFrameId
::
COMPILED
)
{
...
...
src/core/types.h
View file @
8364a607
...
...
@@ -430,6 +430,12 @@ class Box {
private:
BoxedDict
**
getDictPtr
();
// Adds a new attribute to a HCAttrs-backed object. Must pass in the new hidden class object
// which must be the same as the current hidden class but with the new attribute at the end.
// Swaps the hidden class, reallocates and copies and updates the attribute array.
// The value of the current hidden class should be guarded before calling this.
void
addNewHCAttr
(
HiddenClass
*
new_hcls
,
Box
*
val
,
SetattrRewriteArgs
*
rewrite_args
);
public:
// Add a no-op constructor to make sure that we don't zero-initialize cls
Box
()
{}
...
...
@@ -459,6 +465,9 @@ public:
bool
hasattr
(
const
std
::
string
&
attr
)
{
return
getattr
(
attr
)
!=
NULL
;
}
void
delattr
(
const
std
::
string
&
attr
,
DelattrRewriteArgs
*
rewrite_args
);
// Only valid for hc-backed instances:
Box
*
getAttrWrapper
();
Box
*
reprIC
();
BoxedString
*
reprICAsString
();
bool
nonzeroIC
();
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
8364a607
...
...
@@ -81,7 +81,7 @@ extern "C" Box* vars(Box* obj) {
if
(
!
obj
)
return
fastLocalsToBoxedLocals
();
return
makeAttrWrapper
(
obj
);
return
obj
->
getAttrWrapper
(
);
}
extern
"C"
Box
*
abs_
(
Box
*
x
)
{
...
...
@@ -587,7 +587,7 @@ public:
RELEASE_ASSERT
(
isSubclass
(
self
->
cls
,
BaseException
),
""
);
BoxedException
*
exc
=
static_cast
<
BoxedException
*>
(
self
);
return
BoxedTuple
::
create
({
self
->
cls
,
EmptyTuple
,
makeAttrWrapper
(
self
)
});
return
BoxedTuple
::
create
({
self
->
cls
,
EmptyTuple
,
self
->
getAttrWrapper
(
)
});
}
};
...
...
src/runtime/builtin_modules/sys.cpp
View file @
8364a607
...
...
@@ -126,6 +126,10 @@ Box* sysGetFilesystemEncoding() {
return
None
;
}
Box
*
sysGetRecursionLimit
()
{
return
PyInt_FromLong
(
Py_GetRecursionLimit
());
}
extern
"C"
int
PySys_SetObject
(
const
char
*
name
,
PyObject
*
v
)
noexcept
{
try
{
if
(
!
v
)
{
...
...
@@ -426,6 +430,10 @@ void setupSys() {
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
sysGetFilesystemEncoding
,
STR
,
0
),
"getfilesystemencoding"
));
sys_module
->
giveAttr
(
"getrecursionlimit"
,
new
BoxedBuiltinFunctionOrMethod
(
boxRTFunction
((
void
*
)
sysGetRecursionLimit
,
UNKNOWN
,
0
),
"getrecursionlimit"
));
sys_module
->
giveAttr
(
"meta_path"
,
new
BoxedList
());
sys_module
->
giveAttr
(
"path_hooks"
,
new
BoxedList
());
sys_module
->
giveAttr
(
"path_importer_cache"
,
new
BoxedDict
());
...
...
src/runtime/builtin_modules/thread.cpp
View file @
8364a607
...
...
@@ -18,8 +18,10 @@
#include "Python.h"
#include "pythread.h"
#include "capi/typeobject.h"
#include "core/threading.h"
#include "core/types.h"
#include "runtime/capi.h"
#include "runtime/objmodel.h"
#include "runtime/types.h"
...
...
@@ -165,13 +167,27 @@ public:
return
tls_obj
;
}
static
int
setattr
(
Box
*
obj
,
char
*
name
,
Box
*
val
)
{
static
Box
*
setattrPyston
(
Box
*
obj
,
Box
*
name
,
Box
*
val
)
noexcept
{
if
(
isSubclass
(
name
->
cls
,
str_cls
)
&&
static_cast
<
BoxedString
*>
(
name
)
->
s
==
"__dict__"
)
{
raiseExcHelper
(
AttributeError
,
"'%.50s' object attribute '__dict__' is read-only"
,
Py_TYPE
(
obj
)
->
tp_name
);
}
Box
*
tls_obj
=
getThreadLocalObject
(
obj
);
setitem
(
tls_obj
,
boxString
(
name
),
val
);
setitem
(
tls_obj
,
name
,
val
);
return
None
;
}
static
int
setattr
(
Box
*
obj
,
char
*
name
,
Box
*
val
)
noexcept
{
try
{
setattrPyston
(
obj
,
boxString
(
name
),
val
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
-
1
;
}
return
0
;
}
static
Box
*
getattr
(
Box
*
obj
,
char
*
name
)
{
static
Box
*
getattr
(
Box
*
obj
,
char
*
name
)
noexcept
{
Box
*
tls_obj
=
getThreadLocalObject
(
obj
);
if
(
!
strcmp
(
name
,
"__dict__"
))
return
tls_obj
;
...
...
@@ -179,8 +195,19 @@ public:
try
{
return
getitem
(
tls_obj
,
boxString
(
name
));
}
catch
(
ExcInfo
e
)
{
raiseExcHelper
(
AttributeError
,
"'%.50s' object has no attribute '%.400s'"
,
obj
->
cls
->
tp_name
,
name
);
}
try
{
Box
*
r
=
getattrInternalGeneric
(
obj
,
name
,
NULL
,
false
,
false
,
NULL
,
NULL
);
if
(
r
)
return
r
;
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
}
PyErr_Format
(
PyExc_AttributeError
,
"'%.50s' object has no attribute '%.400s'"
,
Py_TYPE
(
obj
)
->
tp_name
,
name
);
return
NULL
;
}
static
Box
*
hash
(
Box
*
obj
)
{
return
boxInt
(
PyThread_get_thread_ident
());
}
...
...
@@ -227,6 +254,8 @@ void setupThread() {
thread_local_cls
->
giveAttr
(
"__module__"
,
boxStrConstant
(
"thread"
));
thread_local_cls
->
giveAttr
(
"__hash__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedThreadLocal
::
hash
,
BOXED_INT
,
1
)));
thread_local_cls
->
giveAttr
(
"__setattr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedThreadLocal
::
setattrPyston
,
UNKNOWN
,
3
)));
thread_local_cls
->
freeze
();
thread_module
->
giveAttr
(
"_local"
,
thread_local_cls
);
...
...
src/runtime/classobj.cpp
View file @
8364a607
...
...
@@ -150,7 +150,7 @@ static Box* classobjGetattribute(Box* _cls, Box* _attr) {
// These are special cases in CPython as well:
if
(
attr
->
s
[
0
]
==
'_'
&&
attr
->
s
[
1
]
==
'_'
)
{
if
(
attr
->
s
==
"__dict__"
)
return
makeAttrWrapper
(
cls
);
return
cls
->
getAttrWrapper
(
);
if
(
attr
->
s
==
"__bases__"
)
return
cls
->
bases
;
...
...
@@ -255,7 +255,7 @@ static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing)
// These are special cases in CPython as well:
if
(
attr
->
s
[
0
]
==
'_'
&&
attr
->
s
[
1
]
==
'_'
)
{
if
(
attr
->
s
==
"__dict__"
)
return
makeAttrWrapper
(
inst
);
return
inst
->
getAttrWrapper
(
);
if
(
attr
->
s
==
"__class__"
)
return
inst
->
inst_cls
;
...
...
src/runtime/frame.cpp
View file @
8364a607
...
...
@@ -125,7 +125,7 @@ Box* getFrame(int depth) {
auto
cf
=
it
.
getCF
();
BoxedFrame
*
f
=
fi
->
frame_obj
=
new
BoxedFrame
(
std
::
move
(
it
));
assert
(
cf
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
());
f
->
_globals
=
makeAttrWrapper
(
cf
->
clfunc
->
source
->
parent_module
);
f
->
_globals
=
cf
->
clfunc
->
source
->
parent_module
->
getAttrWrapper
(
);
f
->
_code
=
codeForCLFunction
(
cf
->
clfunc
);
}
...
...
src/runtime/objmodel.cpp
View file @
8364a607
...
...
@@ -400,7 +400,7 @@ void BoxedClass::finishInitialization() {
}
assert
(
!
this
->
tp_dict
);
this
->
tp_dict
=
makeAttrWrapper
(
this
);
this
->
tp_dict
=
this
->
getAttrWrapper
(
);
commonClassSetup
(
this
);
}
...
...
@@ -490,19 +490,31 @@ HiddenClass* HiddenClass::getOrMakeChild(const std::string& attr) {
HiddenClass
*
rtn
=
new
HiddenClass
(
this
);
this
->
children
[
attr
]
=
rtn
;
rtn
->
attr_offsets
[
attr
]
=
attr_offsets
.
size
();
rtn
->
attr_offsets
[
attr
]
=
this
->
attributeArraySize
();
assert
(
rtn
->
attributeArraySize
()
==
this
->
attributeArraySize
()
+
1
);
return
rtn
;
}
HiddenClass
*
HiddenClass
::
getAttrwrapperChild
()
{
assert
(
type
==
NORMAL
);
if
(
!
attrwrapper_child
)
{
attrwrapper_child
=
new
HiddenClass
(
this
);
attrwrapper_child
->
attrwrapper_offset
=
this
->
attributeArraySize
();
assert
(
attrwrapper_child
->
attributeArraySize
()
==
this
->
attributeArraySize
()
+
1
);
}
return
attrwrapper_child
;
}
/**
* del attr from current HiddenClass,
pertain the orders of
remaining attrs
* del attr from current HiddenClass,
maintaining the order of the
remaining attrs
*/
HiddenClass
*
HiddenClass
::
delAttrToMakeHC
(
const
std
::
string
&
attr
)
{
assert
(
type
==
NORMAL
);
int
idx
=
getOffset
(
attr
);
assert
(
idx
>=
0
);
std
::
vector
<
std
::
string
>
new_attrs
(
attr
_offsets
.
s
ize
()
-
1
);
std
::
vector
<
std
::
string
>
new_attrs
(
attr
ibuteArrayS
ize
()
-
1
);
for
(
auto
it
=
attr_offsets
.
begin
();
it
!=
attr_offsets
.
end
();
++
it
)
{
if
(
it
->
second
<
idx
)
new_attrs
[
it
->
second
]
=
it
->
first
();
...
...
@@ -511,11 +523,20 @@ HiddenClass* HiddenClass::delAttrToMakeHC(const std::string& attr) {
}
}
int
new_attrwrapper_offset
=
attrwrapper_offset
;
if
(
new_attrwrapper_offset
>
idx
)
new_attrwrapper_offset
--
;
// TODO we can first locate the parent HiddenClass of the deleted
// attribute and hence avoid creation of its ancestors.
HiddenClass
*
cur
=
root_hcls
;
int
curidx
=
0
;
for
(
const
auto
&
attr
:
new_attrs
)
{
cur
=
cur
->
getOrMakeChild
(
attr
);
if
(
curidx
==
new_attrwrapper_offset
)
cur
=
cur
->
getAttrwrapperChild
();
else
cur
=
cur
->
getOrMakeChild
(
attr
);
curidx
++
;
}
return
cur
;
}
...
...
@@ -648,6 +669,58 @@ Box* Box::getattr(const std::string& attr, GetattrRewriteArgs* rewrite_args) {
return
NULL
;
}
void
Box
::
addNewHCAttr
(
HiddenClass
*
new_hcls
,
Box
*
new_attr
,
SetattrRewriteArgs
*
rewrite_args
)
{
assert
(
cls
->
instancesHaveHCAttrs
());
HCAttrs
*
attrs
=
getHCAttrsPtr
();
HiddenClass
*
hcls
=
attrs
->
hcls
;
#ifndef NDEBUG
// make sure we don't need to rearrange the attributes
assert
(
new_hcls
->
attributeArraySize
()
==
hcls
->
attributeArraySize
()
+
1
);
for
(
const
auto
&
p
:
hcls
->
getStrAttrOffsets
())
{
assert
(
new_hcls
->
getStrAttrOffsets
().
lookup
(
p
.
first
())
==
p
.
second
);
}
if
(
hcls
->
getAttrwrapperOffset
()
!=
-
1
)
assert
(
hcls
->
getAttrwrapperOffset
()
==
new_hcls
->
getAttrwrapperOffset
());
#endif
int
numattrs
=
hcls
->
attributeArraySize
();
RewriterVar
*
r_new_array2
=
NULL
;
int
new_size
=
sizeof
(
HCAttrs
::
AttrList
)
+
sizeof
(
Box
*
)
*
(
numattrs
+
1
);
if
(
numattrs
==
0
)
{
attrs
->
attr_list
=
(
HCAttrs
::
AttrList
*
)
gc_alloc
(
new_size
,
gc
::
GCKind
::
PRECISE
);
if
(
rewrite_args
)
{
RewriterVar
*
r_newsize
=
rewrite_args
->
rewriter
->
loadConst
(
new_size
,
Location
::
forArg
(
0
));
RewriterVar
*
r_kind
=
rewrite_args
->
rewriter
->
loadConst
((
int
)
gc
::
GCKind
::
PRECISE
,
Location
::
forArg
(
1
));
r_new_array2
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
gc
::
gc_alloc
,
r_newsize
,
r_kind
);
}
}
else
{
attrs
->
attr_list
=
(
HCAttrs
::
AttrList
*
)
gc
::
gc_realloc
(
attrs
->
attr_list
,
new_size
);
if
(
rewrite_args
)
{
RewriterVar
*
r_oldarray
=
rewrite_args
->
obj
->
getAttr
(
cls
->
attrs_offset
+
HCATTRS_ATTRS_OFFSET
,
Location
::
forArg
(
0
));
RewriterVar
*
r_newsize
=
rewrite_args
->
rewriter
->
loadConst
(
new_size
,
Location
::
forArg
(
1
));
r_new_array2
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
gc
::
gc_realloc
,
r_oldarray
,
r_newsize
);
}
}
// Don't set the new hcls until after we do the allocation for the new attr_list;
// that allocation can cause a collection, and we want the collector to always
// see a consistent state between the hcls and the attr_list
attrs
->
hcls
=
new_hcls
;
if
(
rewrite_args
)
{
r_new_array2
->
setAttr
(
numattrs
*
sizeof
(
Box
*
)
+
ATTRLIST_ATTRS_OFFSET
,
rewrite_args
->
attrval
);
rewrite_args
->
obj
->
setAttr
(
cls
->
attrs_offset
+
HCATTRS_ATTRS_OFFSET
,
r_new_array2
);
RewriterVar
*
r_hcls
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
new_hcls
);
rewrite_args
->
obj
->
setAttr
(
cls
->
attrs_offset
+
HCATTRS_HCLS_OFFSET
,
r_hcls
);
rewrite_args
->
out_success
=
true
;
}
attrs
->
attr_list
->
attrs
[
numattrs
]
=
new_attr
;
}
void
Box
::
setattr
(
const
std
::
string
&
attr
,
Box
*
val
,
SetattrRewriteArgs
*
rewrite_args
)
{
assert
(
gc
::
isValidGCObject
(
val
));
...
...
@@ -681,7 +754,6 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite
}
assert
(
hcls
->
type
==
HiddenClass
::
NORMAL
);
int
numattrs
=
hcls
->
getAttrOffsets
().
size
();
int
offset
=
hcls
->
getOffset
(
attr
);
...
...
@@ -691,7 +763,7 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite
}
if
(
offset
>=
0
)
{
assert
(
offset
<
numattrs
);
assert
(
offset
<
hcls
->
attributeArraySize
()
);
Box
*
prev
=
attrs
->
attr_list
->
attrs
[
offset
];
attrs
->
attr_list
->
attrs
[
offset
]
=
val
;
...
...
@@ -711,47 +783,11 @@ void Box::setattr(const std::string& attr, Box* val, SetattrRewriteArgs* rewrite
assert
(
offset
==
-
1
);
HiddenClass
*
new_hcls
=
hcls
->
getOrMakeChild
(
attr
);
// TODO need to make sure we don't need to rearrange the attributes
assert
(
new_hcls
->
getAttrOffsets
().
lookup
(
attr
)
==
numattrs
);
#ifndef NDEBUG
for
(
const
auto
&
p
:
hcls
->
getAttrOffsets
())
{
assert
(
new_hcls
->
getAttrOffsets
().
lookup
(
p
.
first
())
==
p
.
second
);
}
#endif
RewriterVar
*
r_new_array2
=
NULL
;
int
new_size
=
sizeof
(
HCAttrs
::
AttrList
)
+
sizeof
(
Box
*
)
*
(
numattrs
+
1
);
if
(
numattrs
==
0
)
{
attrs
->
attr_list
=
(
HCAttrs
::
AttrList
*
)
gc_alloc
(
new_size
,
gc
::
GCKind
::
PRECISE
);
if
(
rewrite_args
)
{
RewriterVar
*
r_newsize
=
rewrite_args
->
rewriter
->
loadConst
(
new_size
,
Location
::
forArg
(
0
));
RewriterVar
*
r_kind
=
rewrite_args
->
rewriter
->
loadConst
((
int
)
gc
::
GCKind
::
PRECISE
,
Location
::
forArg
(
1
));
r_new_array2
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
gc
::
gc_alloc
,
r_newsize
,
r_kind
);
}
}
else
{
attrs
->
attr_list
=
(
HCAttrs
::
AttrList
*
)
gc
::
gc_realloc
(
attrs
->
attr_list
,
new_size
);
if
(
rewrite_args
)
{
RewriterVar
*
r_oldarray
=
rewrite_args
->
obj
->
getAttr
(
cls
->
attrs_offset
+
HCATTRS_ATTRS_OFFSET
,
Location
::
forArg
(
0
));
RewriterVar
*
r_newsize
=
rewrite_args
->
rewriter
->
loadConst
(
new_size
,
Location
::
forArg
(
1
));
r_new_array2
=
rewrite_args
->
rewriter
->
call
(
true
,
(
void
*
)
gc
::
gc_realloc
,
r_oldarray
,
r_newsize
);
}
}
// Don't set the new hcls until after we do the allocation for the new attr_list;
// that allocation can cause a collection, and we want the collector to always
// see a consistent state between the hcls and the attr_list
attrs
->
hcls
=
new_hcls
;
if
(
rewrite_args
)
{
r_new_array2
->
setAttr
(
numattrs
*
sizeof
(
Box
*
)
+
ATTRLIST_ATTRS_OFFSET
,
rewrite_args
->
attrval
);
rewrite_args
->
obj
->
setAttr
(
cls
->
attrs_offset
+
HCATTRS_ATTRS_OFFSET
,
r_new_array2
);
// make sure we don't need to rearrange the attributes
assert
(
new_hcls
->
getStrAttrOffsets
().
lookup
(
attr
)
==
hcls
->
attributeArraySize
());
RewriterVar
*
r_hcls
=
rewrite_args
->
rewriter
->
loadConst
((
intptr_t
)
new_hcls
);
rewrite_args
->
obj
->
setAttr
(
cls
->
attrs_offset
+
HCATTRS_HCLS_OFFSET
,
r_hcls
);
addNewHCAttr
(
new_hcls
,
val
,
rewrite_args
);
rewrite_args
->
out_success
=
true
;
}
attrs
->
attr_list
->
attrs
[
numattrs
]
=
val
;
return
;
}
...
...
@@ -3727,7 +3763,7 @@ void Box::delattr(const std::string& attr, DelattrRewriteArgs* rewrite_args) {
// The order of attributes is pertained as delAttrToMakeHC constructs
// the new HiddenClass by invoking getOrMakeChild in the prevous order
// of remaining attributes
int
num_attrs
=
hcls
->
getAttrOffsets
().
s
ize
();
int
num_attrs
=
hcls
->
attributeArrayS
ize
();
int
offset
=
hcls
->
getOffset
(
attr
);
assert
(
offset
>=
0
);
Box
**
start
=
attrs
->
attr_list
->
attrs
;
...
...
@@ -4499,7 +4535,7 @@ extern "C" Box* importStar(Box* _from_module, BoxedModule* to_module) {
}
HCAttrs
*
module_attrs
=
from_module
->
getHCAttrsPtr
();
for
(
auto
&
p
:
module_attrs
->
hcls
->
getAttrOffsets
())
{
for
(
auto
&
p
:
module_attrs
->
hcls
->
get
Str
AttrOffsets
())
{
if
(
p
.
first
()[
0
]
==
'_'
)
continue
;
...
...
src/runtime/stacktrace.cpp
View file @
8364a607
...
...
@@ -157,10 +157,11 @@ void _printStacktrace() {
extern
"C"
void
abort
()
{
static
void
(
*
libc_abort
)()
=
(
void
(
*
)())
dlsym
(
RTLD_NEXT
,
"abort"
);
// In case
something calls abort down the line
:
// In case
displaying the traceback recursively calls abort
:
static
bool
recursive
=
false
;
// If object_cls is NULL, then we somehow died early on, and won't be able to display a traceback.
if
(
!
recursive
&&
object_cls
)
{
// If traceback_cls is NULL, then we somehow died early on, and won't be able to display a traceback.
if
(
!
recursive
&&
traceback_cls
)
{
recursive
=
true
;
fprintf
(
stderr
,
"Someone called abort!
\n
"
);
...
...
@@ -178,7 +179,7 @@ extern "C" void abort() {
}
// Cancel the alarm.
// This is helpful for when running in a debugger, since the debugger will catch the
// This is helpful for when running in a debugger, since
otherwise
the debugger will catch the
// abort and let you investigate, but the alarm will still come back to kill the program.
alarm
(
0
);
}
...
...
src/runtime/types.cpp
View file @
8364a607
...
...
@@ -477,7 +477,7 @@ extern "C" void typeGCHandler(GCVisitor* v, Box* b) {
static
Box
*
typeDict
(
Box
*
obj
,
void
*
context
)
{
if
(
obj
->
cls
->
instancesHaveHCAttrs
())
return
makeAttrWrapper
(
obj
);
return
obj
->
getAttrWrapper
(
);
if
(
obj
->
cls
->
instancesHaveDictAttrs
())
return
obj
->
getDict
();
abort
();
...
...
@@ -1311,7 +1311,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
bool
first
=
true
;
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
if
(
!
first
)
os
<<
", "
;
first
=
false
;
...
...
@@ -1343,7 +1343,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
listAppend
(
rtn
,
boxString
(
p
.
first
()));
}
return
rtn
;
...
...
@@ -1357,7 +1357,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
listAppend
(
rtn
,
attrs
->
attr_list
->
attrs
[
p
.
second
]);
}
return
rtn
;
...
...
@@ -1371,7 +1371,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
BoxedTuple
*
t
=
BoxedTuple
::
create
({
boxString
(
p
.
first
()),
attrs
->
attr_list
->
attrs
[
p
.
second
]
});
listAppend
(
rtn
,
t
);
}
...
...
@@ -1386,7 +1386,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
rtn
->
d
[
boxString
(
p
.
first
())]
=
attrs
->
attr_list
->
attrs
[
p
.
second
];
}
return
rtn
;
...
...
@@ -1398,7 +1398,7 @@ public:
HCAttrs
*
attrs
=
self
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
return
boxInt
(
attrs
->
hcls
->
getAttrOffsets
().
size
());
return
boxInt
(
attrs
->
hcls
->
get
Str
AttrOffsets
().
size
());
}
static
Box
*
update
(
Box
*
_self
,
Box
*
_container
)
{
...
...
@@ -1410,7 +1410,7 @@ public:
HCAttrs
*
attrs
=
container
->
b
->
getHCAttrsPtr
();
RELEASE_ASSERT
(
attrs
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
for
(
const
auto
&
p
:
attrs
->
hcls
->
getAttrOffsets
())
{
for
(
const
auto
&
p
:
attrs
->
hcls
->
get
Str
AttrOffsets
())
{
self
->
b
->
setattr
(
p
.
first
(),
attrs
->
attr_list
->
attrs
[
p
.
second
],
NULL
);
}
}
else
if
(
_container
->
cls
==
dict_cls
)
{
...
...
@@ -1439,7 +1439,7 @@ AttrWrapperIter::AttrWrapperIter(AttrWrapper* aw) {
hcls
=
aw
->
b
->
getHCAttrsPtr
()
->
hcls
;
assert
(
hcls
);
RELEASE_ASSERT
(
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
it
=
hcls
->
getAttrOffsets
().
begin
();
it
=
hcls
->
get
Str
AttrOffsets
().
begin
();
}
Box
*
AttrWrapperIter
::
hasnext
(
Box
*
_self
)
{
...
...
@@ -1447,7 +1447,7 @@ Box* AttrWrapperIter::hasnext(Box* _self) {
AttrWrapperIter
*
self
=
static_cast
<
AttrWrapperIter
*>
(
_self
);
RELEASE_ASSERT
(
self
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
return
boxBool
(
self
->
it
!=
self
->
hcls
->
getAttrOffsets
().
end
());
return
boxBool
(
self
->
it
!=
self
->
hcls
->
get
Str
AttrOffsets
().
end
());
}
Box
*
AttrWrapperIter
::
next
(
Box
*
_self
)
{
...
...
@@ -1455,19 +1455,28 @@ Box* AttrWrapperIter::next(Box* _self) {
AttrWrapperIter
*
self
=
static_cast
<
AttrWrapperIter
*>
(
_self
);
RELEASE_ASSERT
(
self
->
hcls
->
type
==
HiddenClass
::
NORMAL
,
""
);
assert
(
self
->
it
!=
self
->
hcls
->
getAttrOffsets
().
end
());
assert
(
self
->
it
!=
self
->
hcls
->
get
Str
AttrOffsets
().
end
());
Box
*
r
=
boxString
(
self
->
it
->
first
());
++
self
->
it
;
return
r
;
}
Box
*
makeAttrWrapper
(
Box
*
b
)
{
assert
(
b
->
cls
->
instancesHaveHCAttrs
());
if
(
b
->
getHCAttrsPtr
()
->
hcls
->
type
==
HiddenClass
::
DICT_BACKED
)
{
return
b
->
getHCAttrsPtr
()
->
attr_list
->
attrs
[
0
];
Box
*
Box
::
getAttrWrapper
()
{
assert
(
cls
->
instancesHaveHCAttrs
());
HCAttrs
*
attrs
=
getHCAttrsPtr
();
HiddenClass
*
hcls
=
attrs
->
hcls
;
if
(
hcls
->
type
==
HiddenClass
::
DICT_BACKED
)
{
return
attrs
->
attr_list
->
attrs
[
0
];
}
return
new
AttrWrapper
(
b
);
int
offset
=
hcls
->
getAttrwrapperOffset
();
if
(
offset
==
-
1
)
{
Box
*
aw
=
new
AttrWrapper
(
this
);
addNewHCAttr
(
hcls
->
getAttrwrapperChild
(),
aw
,
NULL
);
return
aw
;
}
return
attrs
->
attr_list
->
attrs
[
offset
];
}
Box
*
unwrapAttrWrapper
(
Box
*
b
)
{
...
...
src/runtime/types.h
View file @
8364a607
...
...
@@ -283,16 +283,19 @@ public:
private:
HiddenClass
(
HCType
type
)
:
type
(
type
)
{}
HiddenClass
(
HiddenClass
*
parent
)
:
type
(
NORMAL
),
attr_offsets
()
{
HiddenClass
(
HiddenClass
*
parent
)
:
type
(
NORMAL
),
attr_offsets
()
,
attrwrapper_offset
(
parent
->
attrwrapper_offset
)
{
assert
(
parent
->
type
==
NORMAL
);
for
(
auto
&
p
:
parent
->
attr_offsets
)
{
this
->
attr_offsets
.
insert
(
&
p
);
}
}
//
Only makes sense for NORMAL hidden classes. Clients should access through getAttrOffsets()
:
//
These fields only make sense for NORMAL hidden classes
:
llvm
::
StringMap
<
int
>
attr_offsets
;
ContiguousMap
<
llvm
::
StringRef
,
HiddenClass
*
,
llvm
::
StringMap
<
int
>>
children
;
// If >= 0, is the offset where we stored an attrwrapper object
int
attrwrapper_offset
=
-
1
;
HiddenClass
*
attrwrapper_child
=
NULL
;
public:
static
HiddenClass
*
makeRoot
()
{
...
...
@@ -315,18 +318,35 @@ public:
void
gc_visit
(
GCVisitor
*
visitor
)
{
// Visit children even for the dict-backed case, since children will just be empty
visitor
->
visitRange
((
void
*
const
*
)
&
children
.
vector
()[
0
],
(
void
*
const
*
)
&
children
.
vector
()[
children
.
size
()]);
if
(
attrwrapper_child
)
visitor
->
visit
(
attrwrapper_child
);
}
// Only makes sense for NORMAL hidden classes:
const
llvm
::
StringMap
<
int
>&
getAttrOffsets
()
{
// The total size of the attribute array. The slots in the attribute array may not correspond 1:1 to Python
// attributes.
int
attributeArraySize
()
{
if
(
type
==
DICT_BACKED
)
return
1
;
ASSERT
(
type
==
NORMAL
,
"%d"
,
type
);
int
r
=
attr_offsets
.
size
();
if
(
attrwrapper_offset
!=
-
1
)
r
+=
1
;
return
r
;
}
// The mapping from string attribute names to attribute offsets. There may be other objects in the attributes
// array.
// Only valid for NORMAL hidden classes
const
llvm
::
StringMap
<
int
>&
getStrAttrOffsets
()
{
assert
(
type
==
NORMAL
);
return
attr_offsets
;
}
// Only
makes sense
for NORMAL hidden classes:
// Only
valid
for NORMAL hidden classes:
HiddenClass
*
getOrMakeChild
(
const
std
::
string
&
attr
);
// Only
makes sense
for NORMAL hidden classes:
// Only
valid
for NORMAL hidden classes:
int
getOffset
(
const
std
::
string
&
attr
)
{
assert
(
type
==
NORMAL
);
auto
it
=
attr_offsets
.
find
(
attr
);
...
...
@@ -335,7 +355,14 @@ public:
return
it
->
second
;
}
// Only makes sense for NORMAL hidden classes:
int
getAttrwrapperOffset
()
{
assert
(
type
==
NORMAL
);
return
attrwrapper_offset
;
}
HiddenClass
*
getAttrwrapperChild
();
// Only valid for NORMAL hidden classes:
HiddenClass
*
delAttrToMakeHC
(
const
std
::
string
&
attr
);
};
...
...
@@ -803,7 +830,6 @@ extern "C" void boxGCHandler(GCVisitor* v, Box* b);
Box
*
objectNewNoArgs
(
BoxedClass
*
cls
);
Box
*
objectSetattr
(
Box
*
obj
,
Box
*
attr
,
Box
*
value
);
Box
*
makeAttrWrapper
(
Box
*
b
);
Box
*
unwrapAttrWrapper
(
Box
*
b
);
Box
*
attrwrapperKeys
(
Box
*
b
);
void
attrwrapperDel
(
Box
*
b
,
const
std
::
string
&
attr
);
...
...
test/integration/virtualenv_test.py
View file @
8364a607
...
...
@@ -21,8 +21,9 @@ set -e
set -ux
python -c 'import __future__'
python -c 'import sys; print sys.executable'
pip install bcrypt==1.1.0
pip install bcrypt==1.1.0
python-gflags==2.0
python -c 'import bcrypt; assert bcrypt.__version__ == "1.1.0"; assert bcrypt.hashpw("password1", "$2a$12$0123456789012345678901").endswith("I1hdtg4K"); print "bcrypt seems to work"'
python -c 'import gflags; print "gflags imports"'
"""
.
strip
()
# print sh_script
...
...
test/tests/globals.py
View file @
8364a607
...
...
@@ -13,3 +13,5 @@ x = 2
z
=
2
True
=
"new_true"
f
()
assert
globals
()
is
globals
()
test/tests/sys_getframe
1
.py
→
test/tests/sys_getframe.py
View file @
8364a607
...
...
@@ -11,7 +11,64 @@ def interpolate(templateStr):
t
=
Template
(
templateStr
)
return
t
.
substitute
(
**
framedict
)
name
=
'Feihong'
place
=
'Chicago'
print
interpolate
(
"My name is ${name}. I work in ${place}."
)
def
f1
():
def
sysframetest
():
return
sys
.
_getframe
(
0
)
def
sysframetestwrapper
():
return
sysframetest
()
fr
=
sysframetest
()
print
sysframetest
.
__name__
print
fr
.
f_code
.
co_name
print
fr
.
f_code
.
co_filename
fr
=
sysframetestwrapper
()
print
sysframetestwrapper
.
__name__
print
fr
.
f_code
.
co_name
print
fr
.
f_code
.
co_filename
f1
()
# Make sure we can throw exceptions through frame we called _getframe
def
f2
():
def
g
():
sys
.
_getframe
(
1
)
1
/
0
def
f
():
g
()
try
:
f
()
except
Exception
as
e
:
print
e
f2
()
def
f3
():
fr
=
sys
.
_getframe
(
0
)
print
fr
.
f_lineno
print
fr
.
f_lineno
print
sorted
(
fr
.
f_locals
.
keys
())
a
=
1
print
sorted
(
fr
.
f_locals
.
keys
())
f3
()
def
f4
():
f1
=
sys
.
_getframe
(
0
)
# trigger osr:
for
i
in
xrange
(
20000
):
pass
assert
f1
is
sys
.
_getframe
(
0
)
f4
()
assert
sys
.
_getframe
(
0
).
f_globals
is
globals
()
def
f5
():
assert
sys
.
_getframe
(
0
).
f_globals
is
globals
()
f5
()
test/tests/sys_getframe2.py
deleted
100644 → 0
View file @
123aa269
import
sys
def
sysframetest
():
return
sys
.
_getframe
(
0
)
def
sysframetestwrapper
():
return
sysframetest
()
fr
=
sysframetest
()
print
sysframetest
.
__name__
print
fr
.
f_code
.
co_name
print
fr
.
f_code
.
co_filename
fr
=
sysframetestwrapper
()
print
sysframetestwrapper
.
__name__
print
fr
.
f_code
.
co_name
print
fr
.
f_code
.
co_filename
test/tests/sys_getframe3.py
deleted
100644 → 0
View file @
123aa269
import
sys
def
f
():
fr
=
sys
.
_getframe
(
0
)
print
fr
.
f_lineno
print
fr
.
f_lineno
print
sorted
(
fr
.
f_locals
.
keys
())
a
=
1
print
sorted
(
fr
.
f_locals
.
keys
())
f
()
assert
sys
.
_getframe
(
0
)
is
sys
.
_getframe
(
0
)
def
f2
():
f1
=
sys
.
_getframe
(
0
)
# trigger osr:
for
i
in
xrange
(
20000
):
pass
assert
f1
is
sys
.
_getframe
(
0
)
f2
()
test/tests/sys_getframe4.py
deleted
100644 → 0
View file @
123aa269
# Make sure we can throw exceptions through frame we called _getframe
import
sys
def
g
():
sys
.
_getframe
(
1
)
1
/
0
def
f
():
g
()
try
:
f
()
except
Exception
as
e
:
print
e
test/tests/threading_local.py
View file @
8364a607
...
...
@@ -19,3 +19,8 @@ def test():
for
i
in
xrange
(
10
):
test
()
gc
.
collect
()
print
a
.
x
a
.
__setattr__
(
'x'
,
5
)
print
a
.
x
print
sorted
(
a
.
__dict__
.
items
())
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