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
7199f0e3
Commit
7199f0e3
authored
Nov 13, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
proper dealloc (with free), and imports
parent
3a2c0407
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
221 additions
and
128 deletions
+221
-128
from_cpython/Include/dictobject.h
from_cpython/Include/dictobject.h
+2
-2
from_cpython/Include/moduleobject.h
from_cpython/Include/moduleobject.h
+1
-1
from_cpython/Include/tupleobject.h
from_cpython/Include/tupleobject.h
+2
-2
from_cpython/Objects/exceptions.c
from_cpython/Objects/exceptions.c
+5
-0
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+3
-4
src/core/types.h
src/core/types.h
+1
-1
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+1
-3
src/runtime/dict.cpp
src/runtime/dict.cpp
+1
-1
src/runtime/import.cpp
src/runtime/import.cpp
+11
-8
src/runtime/iterobject.cpp
src/runtime/iterobject.cpp
+1
-2
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+152
-59
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+4
-0
src/runtime/types.cpp
src/runtime/types.cpp
+32
-40
src/runtime/types.h
src/runtime/types.h
+5
-5
No files found.
from_cpython/Include/dictobject.h
View file @
7199f0e3
...
...
@@ -133,7 +133,7 @@ PyAPI_DATA(PyTypeObject*) dictvalues_cls;
(PyDictKeys_Check(op) || PyDictItems_Check(op))
PyAPI_FUNC
(
PyObject
*
)
PyDict_New
(
void
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyDict_GetItem
(
PyObject
*
mp
,
PyObject
*
key
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
BORROWED
(
PyObject
*
)
)
PyDict_GetItem
(
PyObject
*
mp
,
PyObject
*
key
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyDict_SetItem
(
PyObject
*
mp
,
PyObject
*
key
,
PyObject
*
item
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyDict_DelItem
(
PyObject
*
mp
,
PyObject
*
key
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
void
)
PyDict_Clear
(
PyObject
*
mp
)
PYSTON_NOEXCEPT
;
...
...
@@ -172,7 +172,7 @@ PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
PyObject
*
seq2
,
int
override
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyDict_GetItemString
(
PyObject
*
dp
,
const
char
*
key
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
BORROWED
(
PyObject
*
)
)
PyDict_GetItemString
(
PyObject
*
dp
,
const
char
*
key
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyDict_SetItemString
(
PyObject
*
dp
,
const
char
*
key
,
PyObject
*
item
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyDict_DelItemString
(
PyObject
*
dp
,
const
char
*
key
)
PYSTON_NOEXCEPT
;
...
...
from_cpython/Include/moduleobject.h
View file @
7199f0e3
...
...
@@ -17,7 +17,7 @@ PyAPI_DATA(PyTypeObject*) module_cls;
#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type)
PyAPI_FUNC
(
PyObject
*
)
PyModule_New
(
const
char
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyModule_GetDict
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
BORROWED
(
PyObject
*
)
)
PyModule_GetDict
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
char
*
)
PyModule_GetName
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
char
*
)
PyModule_GetFilename
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
void
)
_PyModule_Clear
(
PyObject
*
)
PYSTON_NOEXCEPT
;
...
...
from_cpython/Include/tupleobject.h
View file @
7199f0e3
...
...
@@ -42,8 +42,8 @@ PyAPI_DATA(PyTypeObject*) tuple_cls;
PyAPI_FUNC
(
PyObject
*
)
PyTuple_New
(
Py_ssize_t
size
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
Py_ssize_t
)
PyTuple_Size
(
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyTuple_GetItem
(
PyObject
*
,
Py_ssize_t
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyTuple_SetItem
(
PyObject
*
,
Py_ssize_t
,
PyObject
*
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
BORROWED
(
PyObject
*
)
)
PyTuple_GetItem
(
PyObject
*
,
Py_ssize_t
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
PyTuple_SetItem
(
PyObject
*
,
Py_ssize_t
,
STOLEN
(
PyObject
*
)
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyTuple_GetSlice
(
PyObject
*
,
Py_ssize_t
,
Py_ssize_t
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
int
)
_PyTuple_Resize
(
PyObject
**
,
Py_ssize_t
)
PYSTON_NOEXCEPT
;
PyAPI_FUNC
(
PyObject
*
)
PyTuple_Pack
(
Py_ssize_t
,
...)
PYSTON_NOEXCEPT
;
...
...
from_cpython/Objects/exceptions.c
View file @
7199f0e3
...
...
@@ -2249,12 +2249,17 @@ _PyExc_Init(void)
PyExc_MemoryErrorInst
=
BaseException_new
(
&
_PyExc_MemoryError
,
NULL
,
NULL
);
if
(
!
PyExc_MemoryErrorInst
)
Py_FatalError
(
"Cannot pre-allocate MemoryError instance"
);
// Pyston addition:
PyGC_RegisterStaticConstant
(
PyExc_MemoryErrorInst
);
PyExc_RecursionErrorInst
=
BaseException_new
(
&
_PyExc_RuntimeError
,
NULL
,
NULL
);
if
(
!
PyExc_RecursionErrorInst
)
Py_FatalError
(
"Cannot pre-allocate RuntimeError instance for "
"recursion errors"
);
else
{
// Pyston addition:
PyGC_RegisterStaticConstant
(
PyExc_RecursionErrorInst
);
PyBaseExceptionObject
*
err_inst
=
(
PyBaseExceptionObject
*
)
PyExc_RecursionErrorInst
;
PyObject
*
args_tuple
;
...
...
src/capi/typeobject.cpp
View file @
7199f0e3
...
...
@@ -2965,8 +2965,7 @@ static void inherit_slots(PyTypeObject* type, PyTypeObject* base) noexcept {
* didn't define tp_free, and the base uses the
* default non-gc tp_free.
*/
// Pyston change: don't do this:
// type->tp_free = PyObject_GC_Del;
type
->
tp_free
=
PyObject_GC_Del
;
}
/* else they didn't agree about gc, and there isn't something
* obvious to be done -- the type is on its own.
...
...
@@ -3379,7 +3378,7 @@ extern "C" void PyType_RequestHcAttrs(PyTypeObject* cls, int offset) noexcept {
extern
"C"
void
PyType_GiveHcAttrsDictDescr
(
PyTypeObject
*
cls
)
noexcept
{
static
BoxedString
*
dict_str
=
getStaticString
(
"__dict__"
);
assert
(
!
cls
->
hasattr
(
dict_str
));
cls
->
giveAttr
(
dict_str
,
dict_descr
);
cls
->
giveAttr
(
incref
(
dict_str
),
incref
(
dict_descr
)
);
}
extern
"C"
int
PyType_Ready
(
PyTypeObject
*
cls
)
noexcept
{
...
...
@@ -3422,7 +3421,7 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
cls
->
giveAttrBorrowed
(
"__base__"
,
base
);
assert
(
cls
->
tp_dict
==
NULL
);
cls
->
tp_dict
=
cls
->
getAttrWrapper
(
);
cls
->
tp_dict
=
incref
(
cls
->
getAttrWrapper
()
);
assert
(
cls
->
tp_name
);
...
...
src/core/types.h
View file @
7199f0e3
...
...
@@ -661,7 +661,7 @@ public:
void
delattr
(
BoxedString
*
attr
,
DelattrRewriteArgs
*
rewrite_args
);
// Only valid for hc-backed instances:
B
ox
*
getAttrWrapper
();
B
ORROWED
(
Box
*
)
getAttrWrapper
();
Box
*
reprIC
();
BoxedString
*
reprICAsString
();
...
...
src/runtime/builtin_modules/sys.cpp
View file @
7199f0e3
...
...
@@ -712,8 +712,7 @@ void setupSys() {
sys_module
->
giveAttr
(
"maxint"
,
boxInt
(
PYSTON_INT_MAX
));
sys_module
->
giveAttr
(
"maxsize"
,
boxInt
(
PY_SSIZE_T_MAX
));
sys_flags_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedSysFlags
),
false
,
"flags"
);
sys_flags_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedSysFlags
),
false
,
"flags"
);
sys_flags_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
BoxedSysFlags
::
__new__
,
UNKNOWN
,
1
,
true
,
true
)));
sys_flags_cls
->
tp_dealloc
=
(
destructor
)
BoxedSysFlags
::
dealloc
;
...
...
@@ -730,7 +729,6 @@ void setupSys() {
#ifdef Py_USING_UNICODE
SET_SYS_FROM_STRING
(
"maxunicode"
,
PyInt_FromLong
(
PyUnicode_GetMax
()));
#endif
sys_flags_cls
->
tp_mro
=
BoxedTuple
::
create
({
sys_flags_cls
,
object_cls
});
sys_flags_cls
->
freeze
();
for
(
auto
&
md
:
sys_methods
)
{
...
...
src/runtime/dict.cpp
View file @
7199f0e3
...
...
@@ -313,7 +313,7 @@ extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* ite
abort
();
}
return
PyDict_SetItem
(
mp
,
key_s
,
item
);
return
PyDict_SetItem
(
mp
,
autoDecref
(
key_s
)
,
item
);
}
extern
"C"
PyObject
*
PyDict_GetItem
(
PyObject
*
dict
,
PyObject
*
key
)
noexcept
{
...
...
src/runtime/import.cpp
View file @
7199f0e3
...
...
@@ -384,14 +384,14 @@ static Box* getParent(Box* globals, int level, std::string& buf) {
static
Box
*
importSub
(
const
std
::
string
&
name
,
BoxedString
*
full_name
,
Box
*
parent_module
)
{
BoxedDict
*
sys_modules
=
getSysModulesDict
();
if
(
sys_modules
->
d
.
find
(
full_name
)
!=
sys_modules
->
d
.
end
())
{
return
sys_modules
->
d
[
full_name
]
;
return
incref
(
sys_modules
->
d
[
full_name
])
;
}
BoxedList
*
path_list
;
if
(
parent_module
==
NULL
||
parent_module
==
None
)
{
path_list
=
NULL
;
}
else
{
static
BoxedString
*
path_str
=
internStringImmortal
(
"__path__"
);
static
BoxedString
*
path_str
=
getStaticString
(
"__path__"
);
path_list
=
static_cast
<
BoxedList
*>
(
getattrInternal
<
ExceptionStyle
::
CXX
>
(
parent_module
,
path_str
));
if
(
path_list
==
NULL
||
path_list
->
cls
!=
list_cls
)
{
return
None
;
...
...
@@ -472,10 +472,10 @@ static bool loadNext(Box* mod, Box* altmod, std::string& name, std::string& buf,
std
::
string
subname
(
local_name
.
substr
(
0
,
len
));
buf
+=
subname
;
result
=
importSub
(
subname
,
boxString
(
buf
),
mod
);
result
=
importSub
(
subname
,
autoDecref
(
boxString
(
buf
)
),
mod
);
if
(
result
==
None
&&
altmod
!=
mod
)
{
/* Here, altmod must be None and mod must not be None */
result
=
importSub
(
subname
,
boxString
(
subname
),
altmod
);
result
=
importSub
(
subname
,
autoDecref
(
boxString
(
subname
)
),
altmod
);
if
(
result
!=
NULL
&&
result
!=
None
)
{
markMiss
(
buf
);
...
...
@@ -566,7 +566,7 @@ extern "C" PyObject* PyImport_ImportModuleLevel(const char* name, PyObject* glob
}
static
void
ensureFromlist
(
Box
*
module
,
Box
*
fromlist
,
std
::
string
&
buf
,
bool
recursive
)
{
static
BoxedString
*
path_str
=
internStringImmortal
(
"__path__"
);
static
BoxedString
*
path_str
=
getStaticString
(
"__path__"
);
Box
*
pathlist
=
NULL
;
try
{
pathlist
=
getattrInternal
<
ExceptionStyle
::
CXX
>
(
module
,
path_str
);
...
...
@@ -579,6 +579,9 @@ static void ensureFromlist(Box* module, Box* fromlist, std::string& buf, bool re
// If it's not a package, then there's no sub-importing to do
return
;
}
Py_DECREF
(
pathlist
);
RELEASE_ASSERT
(
0
,
"check the refcounting here"
);
for
(
Box
*
_s
:
fromlist
->
pyElements
())
{
RELEASE_ASSERT
(
PyString_Check
(
_s
),
""
);
...
...
@@ -614,8 +617,8 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
try
{
// TODO: check if this has the same behaviour as the cpython implementation
BoxedList
*
silly_list
=
new
BoxedList
();
listAppendInternal
(
silly_list
,
boxString
(
"__doc__"
));
return
import
(
0
,
silly_list
,
((
BoxedString
*
)
module_name
)
->
s
());
listAppendInternal
(
silly_list
,
autoDecref
(
boxString
(
"__doc__"
)
));
return
import
(
0
,
autoDecref
(
silly_list
)
,
((
BoxedString
*
)
module_name
)
->
s
());
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
NULL
;
...
...
@@ -623,7 +626,7 @@ extern "C" PyObject* PyImport_Import(PyObject* module_name) noexcept {
}
extern
"C"
PyObject
*
PyImport_ImportModule
(
const
char
*
name
)
noexcept
{
return
PyImport_Import
(
boxString
(
name
));
return
PyImport_Import
(
autoDecref
(
boxString
(
name
)
));
}
extern
"C"
PyObject
*
PyImport_GetModuleDict
(
void
)
noexcept
{
...
...
src/runtime/iterobject.cpp
View file @
7199f0e3
...
...
@@ -189,8 +189,7 @@ bool calliter_hasnext(Box* b) {
void
setupIter
()
{
seqiter_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedSeqIter
),
false
,
"iterator"
);
seqiter_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedSeqIter
),
false
,
"iterator"
);
seqiter_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
seqiterNext
,
UNKNOWN
,
1
)));
seqiter_cls
->
giveAttr
(
"__hasnext__"
,
...
...
src/runtime/objmodel.cpp
View file @
7199f0e3
...
...
@@ -154,7 +154,7 @@ extern "C" bool softspace(Box* b, bool newval) {
return
(
bool
)
r
;
}
static
BoxedString
*
softspace_str
=
internStringImmortal
(
"softspace"
);
static
BoxedString
*
softspace_str
=
getStaticString
(
"softspace"
);
bool
r
;
Box
*
gotten
=
NULL
;
...
...
@@ -179,9 +179,9 @@ extern "C" bool softspace(Box* b, bool newval) {
}
extern
"C"
void
printHelper
(
Box
*
dest
,
Box
*
var
,
bool
nl
)
{
static
BoxedString
*
write_str
=
internStringImmortal
(
"write"
);
static
BoxedString
*
newline_str
=
internStringImmortal
(
"
\n
"
);
static
BoxedString
*
space_str
=
internStringImmortal
(
" "
);
static
BoxedString
*
write_str
=
getStaticString
(
"write"
);
static
BoxedString
*
newline_str
=
getStaticString
(
"
\n
"
);
static
BoxedString
*
space_str
=
getStaticString
(
" "
);
if
(
dest
==
None
)
dest
=
getSysStdout
();
...
...
@@ -399,8 +399,8 @@ void BoxedClass::freeze() {
}
std
::
vector
<
BoxedClass
*>
classes
;
BoxedClass
::
BoxedClass
(
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
nam
e
)
BoxedClass
::
BoxedClass
(
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
,
destructor
dealloc
,
freefunc
fre
e
)
:
attrs
(
HiddenClass
::
makeSingleton
()),
attrs_offset
(
attrs_offset
),
is_constant
(
false
),
...
...
@@ -452,21 +452,24 @@ BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset,
assert
(
cls
==
type_cls
||
PyType_Check
(
this
));
}
if
(
is_user_defined
)
{
tp_dealloc
=
subtype_dealloc
;
}
else
{
// We don't want default types like dict to have subtype_dealloc as a destructor.
// In CPython, they would have their custom tp_dealloc, except that we don't
// need them in Pyston due to GC.
//
// What's the problem with having subtype_dealloc? In some cases like defdict_dealloc,
// the destructor calls another destructor thinking it's the parent, but ends up in the
// same destructor again (since child destructors are found first by subtype_dealloc)
// causing an infinite recursion loop.
tp_dealloc
=
dealloc_null
;
has_safe_tp_dealloc
=
true
;
if
(
dealloc
)
tp_dealloc
=
dealloc
;
else
{
assert
(
base
&&
base
->
tp_dealloc
);
tp_dealloc
=
base
->
tp_dealloc
;
}
tp_free
=
default_free
;
if
(
PyType_IS_GC
(
this
))
assert
(
tp_free
!=
PyObject_Del
);
if
(
free
)
tp_free
=
free
;
else
{
assert
(
base
&&
base
->
tp_free
);
tp_free
=
base
->
tp_free
;
}
assert
(
tp_dealloc
);
assert
(
tp_free
);
if
(
!
base
)
{
assert
(
this
==
object_cls
);
...
...
@@ -490,11 +493,12 @@ BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset,
}
}
BoxedClass
*
BoxedClass
::
create
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
)
{
BoxedClass
*
BoxedClass
::
create
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
,
destructor
dealloc
,
freefunc
free
)
{
assert
(
!
is_user_defined
);
BoxedClass
*
made
=
new
(
metaclass
,
0
)
BoxedClass
(
base
,
attrs_offset
,
weaklist_offset
,
instance_size
,
is_user_defined
,
name
);
BoxedClass
(
base
,
attrs_offset
,
weaklist_offset
,
instance_size
,
is_user_defined
,
name
,
dealloc
,
free
);
// While it might be ok if these were set, it'd indicate a difference in
// expectations as to who was going to calculate them:
...
...
@@ -517,19 +521,101 @@ void BoxedClass::finishInitialization() {
}
assert
(
!
this
->
tp_dict
);
this
->
tp_dict
=
this
->
getAttrWrapper
(
);
this
->
tp_dict
=
incref
(
this
->
getAttrWrapper
()
);
commonClassSetup
(
this
);
tp_flags
|=
Py_TPFLAGS_READY
;
}
static
int
subtype_traverse
(
PyObject
*
self
,
visitproc
visit
,
void
*
arg
)
{
Py_FatalError
(
"unimplemented"
);
#if 0
PyTypeObject *type, *base;
traverseproc basetraverse;
/* Find the nearest base with a different tp_traverse,
and traverse slots while we're at it */
type = Py_TYPE(self);
base = type;
while ((basetraverse = base->tp_traverse) == subtype_traverse) {
if (Py_SIZE(base)) {
int err = traverse_slots(base, self, visit, arg);
if (err)
return err;
}
base = base->tp_base;
assert(base);
}
if (type->tp_dictoffset != base->tp_dictoffset) {
PyObject **dictptr = _PyObject_GetDictPtr(self);
if (dictptr && *dictptr)
Py_VISIT(*dictptr);
}
if (type->tp_flags & Py_TPFLAGS_HEAPTYPE)
/* For a heaptype, the instances count as references
to the type. Traverse the type so the collector
can find cycles involving this link. */
Py_VISIT(type);
if (basetraverse)
return basetraverse(self, visit, arg);
return 0;
#endif
}
static
int
subtype_clear
(
PyObject
*
self
)
{
Py_FatalError
(
"unimplemented"
);
#if 0
PyTypeObject *type, *base;
inquiry baseclear;
/* Find the nearest base with a different tp_clear
and clear slots while we're at it */
type = Py_TYPE(self);
base = type;
while ((baseclear = base->tp_clear) == subtype_clear) {
if (Py_SIZE(base))
clear_slots(base, self);
base = base->tp_base;
assert(base);
}
/* Clear the instance dict (if any), to break cycles involving only
__dict__ slots (as in the case 'self.__dict__ is self'). */
if (type->tp_dictoffset != base->tp_dictoffset) {
PyObject **dictptr = _PyObject_GetDictPtr(self);
if (dictptr && *dictptr)
Py_CLEAR(*dictptr);
}
if (baseclear)
return baseclear(self);
return 0;
#endif
}
BoxedHeapClass
::
BoxedHeapClass
(
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
BoxedString
*
name
)
:
BoxedClass
(
base
,
attrs_offset
,
weaklist_offset
,
instance_size
,
is_user_defined
,
name
->
data
()),
:
BoxedClass
(
base
,
attrs_offset
,
weaklist_offset
,
instance_size
,
is_user_defined
,
name
->
data
()
,
subtype_dealloc
,
NULL
),
ht_name
(
name
),
ht_slots
(
NULL
)
{
assert
(
is_user_defined
);
/* Always override allocation strategy to use regular heap */
this
->
tp_alloc
=
PyType_GenericAlloc
;
if
(
this
->
tp_flags
&
Py_TPFLAGS_HAVE_GC
)
{
this
->
tp_free
=
PyObject_GC_Del
;
this
->
tp_traverse
=
subtype_traverse
;
this
->
tp_clear
=
subtype_clear
;
}
else
this
->
tp_free
=
PyObject_Del
;
tp_as_number
=
&
as_number
;
tp_as_mapping
=
&
as_mapping
;
tp_as_sequence
=
&
as_sequence
;
...
...
@@ -566,7 +652,7 @@ BoxedHeapClass* BoxedHeapClass::create(BoxedClass* metaclass, BoxedClass* base,
}
std
::
string
getFullNameOfClass
(
BoxedClass
*
cls
)
{
static
BoxedString
*
module_str
=
internStringImmortal
(
"__module__"
);
static
BoxedString
*
module_str
=
getStaticString
(
"__module__"
);
Box
*
b
=
cls
->
getattr
(
module_str
);
if
(
!
b
)
return
cls
->
tp_name
;
...
...
@@ -1733,7 +1819,7 @@ return gotten;
// came from the class or not.
Box
*
processDescriptorOrNull
(
Box
*
obj
,
Box
*
inst
,
Box
*
owner
)
{
if
(
DEBUG
>=
2
)
{
static
BoxedString
*
get_str
=
internStringImmortal
(
"__get__"
);
static
BoxedString
*
get_str
=
getStaticString
(
"__get__"
);
assert
((
obj
->
cls
->
tp_descr_get
==
NULL
)
==
(
typeLookup
(
obj
->
cls
,
get_str
)
==
NULL
));
}
if
(
obj
->
cls
->
tp_descr_get
)
{
...
...
@@ -1756,7 +1842,6 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) {
template
<
bool
IsType
,
Rewritable
rewritable
>
Box
*
getattrInternalGeneric
(
Box
*
obj
,
BoxedString
*
attr
,
GetattrRewriteArgs
*
rewrite_args
,
bool
cls_only
,
bool
for_call
,
Box
**
bind_obj_out
,
RewriterVar
**
r_bind_obj_out
)
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting here
\n
"
);
if
(
rewritable
==
NOT_REWRITABLE
)
{
assert
(
!
rewrite_args
);
rewrite_args
=
NULL
;
...
...
@@ -1774,8 +1859,8 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
assert
(
obj
->
cls
!=
closure_cls
);
static
BoxedString
*
get_str
=
internStringImmortal
(
"__get__"
);
static
BoxedString
*
set_str
=
internStringImmortal
(
"__set__"
);
static
BoxedString
*
get_str
=
getStaticString
(
"__get__"
);
static
BoxedString
*
set_str
=
getStaticString
(
"__set__"
);
// Handle descriptor logic here.
// A descriptor is either a data descriptor or a non-data descriptor.
...
...
@@ -1810,6 +1895,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
}
else
{
descr
=
typeLookup
(
obj
->
cls
,
attr
);
}
RELEASE_ASSERT
(
!
descr
,
"need to check the refcounting for this"
);
// Check if it's a data descriptor
descrgetfunc
descr_get
=
NULL
;
...
...
@@ -1818,6 +1904,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
Box
*
_get_
=
NULL
;
RewriterVar
*
r_get
=
NULL
;
if
(
descr
)
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting for this"
);
descr_get
=
descr
->
cls
->
tp_descr_get
;
if
(
rewrite_args
)
...
...
@@ -1928,6 +2015,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
if
(
unlikely
(
rewrite_args
&&
!
descr
&&
obj
->
cls
!=
instancemethod_cls
&&
rewrite_args
->
rewriter
->
aggressiveness
()
<
40
&&
attr
->
interned_state
==
SSTATE_INTERNED_IMMORTAL
))
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting for this"
);
class
Helper
{
public:
static
Box
*
call
(
Box
*
obj
,
BoxedString
*
attr
)
{
return
obj
->
getattr
(
attr
);
}
...
...
@@ -1942,6 +2030,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
Box
*
val
;
if
(
rewrite_args
)
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting for this"
);
GetattrRewriteArgs
hrewrite_args
(
rewrite_args
->
rewriter
,
rewrite_args
->
obj
,
rewrite_args
->
destination
);
val
=
obj
->
getattr
(
attr
,
&
hrewrite_args
);
...
...
@@ -1956,9 +2045,12 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
val
=
obj
->
getattr
(
attr
);
}
if
(
val
)
if
(
val
)
{
Py_INCREF
(
val
);
return
val
;
}
}
else
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting for this"
);
// More complicated when obj is a type
// We have to look up the attr in the entire
// class hierarchy, and we also have to check if it is a descriptor,
...
...
@@ -2022,6 +2114,7 @@ Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rew
// If descr and __get__ exist, then call __get__
if
(
descr
)
{
RELEASE_ASSERT
(
0
,
"need to check the refcounting for this"
);
// Special cases first
Box
*
res
=
nondataDescriptorInstanceSpecialCases
<
rewritable
>
(
rewrite_args
,
obj
,
descr
,
r_descr
,
for_call
,
bind_obj_out
,
r_bind_obj_out
);
...
...
@@ -2302,7 +2395,7 @@ void setattrGeneric(Box* obj, BoxedString* attr, Box* val, SetattrRewriteArgs* r
assert
(
val
);
static
BoxedString
*
set_str
=
internStringImmortal
(
"__set__"
);
static
BoxedString
*
set_str
=
getStaticString
(
"__set__"
);
// TODO this should be in type_setattro
if
(
obj
->
cls
==
type_cls
)
{
...
...
@@ -2389,7 +2482,7 @@ void setattrGeneric(Box* obj, BoxedString* attr, Box* val, SetattrRewriteArgs* r
if
(
PyType_Check
(
obj
))
{
BoxedClass
*
self
=
static_cast
<
BoxedClass
*>
(
obj
);
static
BoxedString
*
base_str
=
internStringImmortal
(
"__base__"
);
static
BoxedString
*
base_str
=
getStaticString
(
"__base__"
);
if
(
attr
->
s
()
==
"__base__"
&&
self
->
getattr
(
base_str
))
raiseExcHelper
(
TypeError
,
"readonly attribute"
);
...
...
@@ -2456,7 +2549,7 @@ extern "C" void setattr(Box* obj, BoxedString* attr, Box* attr_val) {
return
;
}
else
if
(
tp_setattro
!=
PyObject_GenericSetAttr
)
{
static
BoxedString
*
setattr_str
=
internStringImmortal
(
"__setattr__"
);
static
BoxedString
*
setattr_str
=
getStaticString
(
"__setattr__"
);
if
(
rewriter
.
get
())
{
GetattrRewriteArgs
rewrite_args
(
rewriter
.
get
(),
rewriter
->
getArg
(
0
)
->
getAttr
(
offsetof
(
Box
,
cls
)),
Location
::
any
());
...
...
@@ -2477,7 +2570,7 @@ extern "C" void setattr(Box* obj, BoxedString* attr, Box* attr_val) {
// We should probably add this as a GC root, but we can cheat a little bit since
// we know it's not going to get deallocated:
static
Box
*
object_setattr
=
object_cls
->
getattr
(
internStringImmortal
(
"__setattr__"
));
static
Box
*
object_setattr
=
object_cls
->
getattr
(
getStaticString
(
"__setattr__"
));
assert
(
object_setattr
);
// I guess this check makes it ok for us to just rely on having guarded on the value of setattr without
...
...
@@ -2623,8 +2716,8 @@ extern "C" bool nonzero(Box* obj) {
return
r
;
}
static
BoxedString
*
nonzero_str
=
internStringImmortal
(
"__nonzero__"
);
static
BoxedString
*
len_str
=
internStringImmortal
(
"__len__"
);
static
BoxedString
*
nonzero_str
=
getStaticString
(
"__nonzero__"
);
static
BoxedString
*
len_str
=
getStaticString
(
"__len__"
);
// try __nonzero__
CallattrRewriteArgs
crewrite_args
(
rewriter
.
get
(),
r_obj
,
...
...
@@ -2752,7 +2845,7 @@ BoxedInt* lenInternal(Box* obj, LenRewriteArgs* rewrite_args) noexcept(S == CAPI
rewrite_args
=
NULL
;
}
static
BoxedString
*
len_str
=
internStringImmortal
(
"__len__"
);
static
BoxedString
*
len_str
=
getStaticString
(
"__len__"
);
if
(
S
==
CAPI
)
{
assert
(
!
rewrite_args
&&
"implement me"
);
...
...
@@ -4211,7 +4304,7 @@ Box* runtimeCallInternal(Box* obj, CallRewriteArgs* rewrite_args, ArgPassSpec ar
Box
*
rtn
;
static
BoxedString
*
call_str
=
internStringImmortal
(
"__call__"
);
static
BoxedString
*
call_str
=
getStaticString
(
"__call__"
);
if
(
DEBUG
>=
2
)
{
assert
((
obj
->
cls
->
tp_call
==
NULL
)
==
(
typeLookup
<
rewritable
>
(
obj
->
cls
,
call_str
,
NULL
)
==
NULL
));
...
...
@@ -4732,7 +4825,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
}
if
(
op_type
==
AST_TYPE
::
In
||
op_type
==
AST_TYPE
::
NotIn
)
{
static
BoxedString
*
contains_str
=
internStringImmortal
(
"__contains__"
);
static
BoxedString
*
contains_str
=
getStaticString
(
"__contains__"
);
// The checks for this branch are taken from CPython's PySequence_Contains
if
(
PyType_HasFeature
(
rhs
->
cls
,
Py_TPFLAGS_HAVE_SEQUENCE_IN
))
{
...
...
@@ -4940,7 +5033,7 @@ Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrit
if
(
rrtn
!=
NULL
&&
rrtn
!=
NotImplemented
)
return
rrtn
;
static
BoxedString
*
cmp_str
=
internStringImmortal
(
"__cmp__"
);
static
BoxedString
*
cmp_str
=
getStaticString
(
"__cmp__"
);
lrtn
=
callattrInternal1
<
CXX
,
NOT_REWRITABLE
>
(
lhs
,
cmp_str
,
CLASS_ONLY
,
NULL
,
ArgPassSpec
(
1
),
rhs
);
if
(
lrtn
&&
lrtn
!=
NotImplemented
)
{
return
boxBool
(
convert3wayCompareResultToBool
(
lrtn
,
op_type
));
...
...
@@ -5294,8 +5387,8 @@ Box* getitemInternal(Box* target, Box* slice, GetitemRewriteArgs* rewrite_args)
return
r
;
}
static
BoxedString
*
getitem_str
=
internStringImmortal
(
"__getitem__"
);
static
BoxedString
*
getslice_str
=
internStringImmortal
(
"__getslice__"
);
static
BoxedString
*
getitem_str
=
getStaticString
(
"__getitem__"
);
static
BoxedString
*
getslice_str
=
getStaticString
(
"__getslice__"
);
Box
*
rtn
;
try
{
...
...
@@ -5438,8 +5531,8 @@ extern "C" void setitem(Box* target, Box* slice, Box* value) {
std
::
unique_ptr
<
Rewriter
>
rewriter
(
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
3
,
"setitem"
));
static
BoxedString
*
setitem_str
=
internStringImmortal
(
"__setitem__"
);
static
BoxedString
*
setslice_str
=
internStringImmortal
(
"__setslice__"
);
static
BoxedString
*
setitem_str
=
getStaticString
(
"__setitem__"
);
static
BoxedString
*
setslice_str
=
getStaticString
(
"__setslice__"
);
auto
&&
m
=
target
->
cls
->
tp_as_mapping
;
if
(
m
&&
m
->
mp_ass_subscript
&&
m
->
mp_ass_subscript
!=
slot_mp_ass_subscript
)
{
...
...
@@ -5491,8 +5584,8 @@ extern "C" void delitem(Box* target, Box* slice) {
std
::
unique_ptr
<
Rewriter
>
rewriter
(
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
2
,
"delitem"
));
static
BoxedString
*
delitem_str
=
internStringImmortal
(
"__delitem__"
);
static
BoxedString
*
delslice_str
=
internStringImmortal
(
"__delslice__"
);
static
BoxedString
*
delitem_str
=
getStaticString
(
"__delitem__"
);
static
BoxedString
*
delslice_str
=
getStaticString
(
"__delslice__"
);
Box
*
rtn
;
if
(
rewriter
.
get
())
{
...
...
@@ -5571,7 +5664,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
// first check whether the deleting attribute is a descriptor
Box
*
clsAttr
=
typeLookup
(
obj
->
cls
,
attr
);
if
(
clsAttr
!=
NULL
)
{
static
BoxedString
*
delete_str
=
internStringImmortal
(
"__delete__"
);
static
BoxedString
*
delete_str
=
getStaticString
(
"__delete__"
);
Box
*
delAttr
=
typeLookup
(
static_cast
<
BoxedClass
*>
(
clsAttr
->
cls
),
delete_str
);
if
(
delAttr
!=
NULL
)
{
...
...
@@ -5600,7 +5693,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
if
(
PyType_Check
(
obj
))
{
BoxedClass
*
self
=
static_cast
<
BoxedClass
*>
(
obj
);
static
BoxedString
*
base_str
=
internStringImmortal
(
"__base__"
);
static
BoxedString
*
base_str
=
getStaticString
(
"__base__"
);
if
(
attr
->
s
()
==
"__base__"
&&
self
->
getattr
(
base_str
))
raiseExcHelper
(
TypeError
,
"readonly attribute"
);
...
...
@@ -5617,7 +5710,7 @@ extern "C" void delattrGeneric(Box* obj, BoxedString* attr, DelattrRewriteArgs*
}
extern
"C"
void
delattrInternal
(
Box
*
obj
,
BoxedString
*
attr
,
DelattrRewriteArgs
*
rewrite_args
)
{
static
BoxedString
*
delattr_str
=
internStringImmortal
(
"__delattr__"
);
static
BoxedString
*
delattr_str
=
getStaticString
(
"__delattr__"
);
Box
*
delAttr
=
typeLookup
(
obj
->
cls
,
delattr_str
);
if
(
delAttr
!=
NULL
)
{
Box
*
rtn
=
runtimeCallInternal
<
CXX
,
NOT_REWRITABLE
>
(
delAttr
,
NULL
,
ArgPassSpec
(
2
),
obj
,
attr
,
NULL
,
NULL
,
NULL
);
...
...
@@ -5655,7 +5748,7 @@ extern "C" Box* createBoxedIterWrapperIfNeeded(Box* o) {
std
::
unique_ptr
<
Rewriter
>
rewriter
(
Rewriter
::
createRewriter
(
__builtin_extract_return_addr
(
__builtin_return_address
(
0
)),
1
,
"createBoxedIterWrapperIfNeeded"
));
static
BoxedString
*
hasnext_str
=
internStringImmortal
(
"__hasnext__"
);
static
BoxedString
*
hasnext_str
=
getStaticString
(
"__hasnext__"
);
if
(
rewriter
.
get
())
{
RewriterVar
*
r_o
=
rewriter
->
getArg
(
0
);
...
...
@@ -5768,7 +5861,7 @@ Box* _typeNew(BoxedClass* metatype, BoxedString* name, BoxedTuple* bases, BoxedD
"of the metaclasses of all its bases"
);
}
static
BoxedString
*
new_box
=
internStringImmortal
(
new_str
.
c_str
());
static
BoxedString
*
new_box
=
getStaticString
(
new_str
.
c_str
());
if
(
winner
!=
metatype
)
{
if
(
getattr
(
winner
,
new_box
)
!=
getattr
(
type_cls
,
new_box
))
{
CallattrFlags
callattr_flags
...
...
@@ -5787,7 +5880,7 @@ Box* _typeNew(BoxedClass* metatype, BoxedString* name, BoxedTuple* bases, BoxedD
assert
(
PyType_Check
(
base
));
// Handle slots
static
BoxedString
*
slots_str
=
internStringImmortal
(
"__slots__"
);
static
BoxedString
*
slots_str
=
getStaticString
(
"__slots__"
);
Box
*
boxedSlots
=
PyDict_GetItem
(
attr_dict
,
slots_str
);
int
add_dict
=
0
;
int
add_weak
=
0
;
...
...
@@ -5961,7 +6054,7 @@ Box* _typeNew(BoxedClass* metatype, BoxedString* name, BoxedTuple* bases, BoxedD
}
if
(
made
->
instancesHaveHCAttrs
()
||
made
->
instancesHaveDictAttrs
())
{
static
BoxedString
*
dict_str
=
internStringImmortal
(
"__dict__"
);
static
BoxedString
*
dict_str
=
getStaticString
(
"__dict__"
);
made
->
setattr
(
dict_str
,
dict_descr
,
NULL
);
}
...
...
@@ -5974,16 +6067,16 @@ Box* _typeNew(BoxedClass* metatype, BoxedString* name, BoxedTuple* bases, BoxedD
made
->
setattr
(
s
,
p
.
second
,
NULL
);
}
static
BoxedString
*
module_str
=
internStringImmortal
(
"__module__"
);
static
BoxedString
*
module_str
=
getStaticString
(
"__module__"
);
if
(
!
made
->
hasattr
(
module_str
))
{
Box
*
gl
=
getGlobalsDict
();
static
BoxedString
*
name_str
=
internStringImmortal
(
"__name__"
);
static
BoxedString
*
name_str
=
getStaticString
(
"__name__"
);
Box
*
attr
=
PyDict_GetItem
(
gl
,
name_str
);
if
(
attr
)
made
->
giveAttr
(
module_str
,
attr
);
}
static
BoxedString
*
doc_str
=
internStringImmortal
(
"__doc__"
);
static
BoxedString
*
doc_str
=
getStaticString
(
"__doc__"
);
if
(
!
made
->
hasattr
(
doc_str
))
made
->
giveAttr
(
doc_str
,
None
);
...
...
@@ -6273,11 +6366,11 @@ extern "C" Box* importStar(Box* _from_module, Box* to_globals) {
RELEASE_ASSERT
(
PyModule_Check
(
_from_module
),
"%s"
,
_from_module
->
cls
->
tp_name
);
BoxedModule
*
from_module
=
static_cast
<
BoxedModule
*>
(
_from_module
);
static
BoxedString
*
all_str
=
internStringImmortal
(
"__all__"
);
static
BoxedString
*
all_str
=
getStaticString
(
"__all__"
);
Box
*
all
=
from_module
->
getattr
(
all_str
);
if
(
all
)
{
static
BoxedString
*
getitem_str
=
internStringImmortal
(
"__getitem__"
);
static
BoxedString
*
getitem_str
=
getStaticString
(
"__getitem__"
);
Box
*
all_getitem
=
typeLookup
(
all
->
cls
,
getitem_str
);
if
(
!
all_getitem
)
raiseExcHelper
(
TypeError
,
"'%s' object does not support indexing"
,
getTypeName
(
all
));
...
...
src/runtime/tuple.cpp
View file @
7199f0e3
...
...
@@ -382,7 +382,10 @@ extern "C" int PyTuple_SetItem(PyObject* op, Py_ssize_t i, PyObject* newitem) no
BoxedTuple
*
t
=
static_cast
<
BoxedTuple
*>
(
op
);
RELEASE_ASSERT
(
i
>=
0
&&
i
<
t
->
size
(),
""
);
auto
olditem
=
t
->
elts
[
i
];
t
->
elts
[
i
]
=
newitem
;
Py_XDECREF
(
olditem
);
return
0
;
}
...
...
@@ -399,6 +402,7 @@ extern "C" PyObject* PyTuple_Pack(Py_ssize_t n, ...) noexcept {
for
(
Py_ssize_t
i
=
0
;
i
<
n
;
i
++
)
{
PyObject
*
o
=
va_arg
(
vargs
,
PyObject
*
);
Py_INCREF
(
o
);
PyTuple_SetItem
(
result
,
i
,
o
);
}
va_end
(
vargs
);
...
...
src/runtime/types.cpp
View file @
7199f0e3
...
...
@@ -2498,11 +2498,13 @@ Box* Box::getAttrWrapper() {
auto
new_hcls
=
hcls
->
getAttrwrapperChild
();
appendNewHCAttr
(
aw
,
NULL
);
attrs
->
hcls
=
new_hcls
;
Py_DECREF
(
aw
);
return
aw
;
}
else
{
assert
(
hcls
->
type
==
HiddenClass
::
SINGLETON
);
appendNewHCAttr
(
aw
,
NULL
);
hcls
->
appendAttrwrapper
();
Py_DECREF
(
aw
);
return
aw
;
}
}
...
...
@@ -3223,12 +3225,6 @@ extern "C" PyUnicodeObject* _PyUnicode_New(Py_ssize_t length) noexcept {
return
unicode
;
}
// We don't need CPython's version of tp_free since we have GC.
// We still need to set tp_free to something and not a NULL pointer,
// because C extensions might still call tp_free from tp_dealloc.
void
default_free
(
void
*
)
{
}
void
dealloc_null
(
Box
*
box
)
{
assert
(
box
->
cls
->
tp_del
==
NULL
);
}
...
...
@@ -3423,6 +3419,10 @@ void BoxedClass::dealloc(Box* b) noexcept {
#endif
}
static
void
object_dealloc
(
PyObject
*
self
)
{
Py_TYPE
(
self
)
->
tp_free
(
self
);
}
#ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS()
...
...
@@ -3448,15 +3448,14 @@ void setupRuntime() {
type_cls
=
static_cast
<
BoxedClass
*>
(
PyObject_MALLOC
(
sizeof
(
BoxedClass
)));
PyObject_INIT
(
object_cls
,
type_cls
);
PyObject_INIT
(
type_cls
,
type_cls
);
::
new
(
object_cls
)
BoxedClass
(
NULL
,
0
,
0
,
sizeof
(
Box
),
false
,
"object"
);
::
new
(
object_cls
)
BoxedClass
(
NULL
,
0
,
0
,
sizeof
(
Box
),
false
,
"object"
,
object_dealloc
,
PyObject_Del
);
object_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
::
new
(
type_cls
)
BoxedClass
(
object_cls
,
offsetof
(
BoxedClass
,
attrs
),
offsetof
(
BoxedClass
,
tp_weaklist
),
sizeof
(
BoxedHeapClass
),
false
,
"type"
);
::
new
(
type_cls
)
BoxedClass
(
object_cls
,
offsetof
(
BoxedClass
,
attrs
),
offsetof
(
BoxedClass
,
tp_weaklist
),
sizeof
(
BoxedHeapClass
),
false
,
"type"
,
BoxedClass
::
dealloc
,
PyObject_GC_Del
);
type_cls
->
has_safe_tp_dealloc
=
false
;
type_cls
->
tp_flags
|=
Py_TPFLAGS_TYPE_SUBCLASS
;
type_cls
->
tp_itemsize
=
sizeof
(
BoxedHeapClass
::
SlotOffset
);
type_cls
->
tp_dealloc
=
BoxedClass
::
dealloc
;
// XXX silly that we have to set this again
new
(
&
object_cls
->
attrs
)
HCAttrs
(
HiddenClass
::
makeSingleton
());
...
...
@@ -3468,18 +3467,18 @@ void setupRuntime() {
object_cls
->
tp_new
=
object_new
;
type_cls
->
tp_getattro
=
type_getattro
;
none_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
Box
),
false
,
"NoneType"
);
none_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
Box
),
false
,
"NoneType"
,
NULL
,
NULL
);
None
=
new
(
none_cls
)
Box
();
constants
.
push_back
(
None
);
assert
(
None
->
cls
);
// You can't actually have an instance of basestring
basestring_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
Box
),
false
,
"basestring"
);
basestring_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
Box
),
false
,
"basestring"
,
NULL
,
NULL
);
// We add 1 to the tp_basicsize of the BoxedString in order to hold the null byte at the end.
// We use offsetof(BoxedString, s_data) as opposed to sizeof(BoxedString) so that we can
// use the extra padding bytes at the end of the BoxedString.
str_cls
=
new
(
0
)
BoxedClass
(
basestring_cls
,
0
,
0
,
offsetof
(
BoxedString
,
s_data
)
+
1
,
false
,
"str"
);
str_cls
=
new
(
0
)
BoxedClass
(
basestring_cls
,
0
,
0
,
offsetof
(
BoxedString
,
s_data
)
+
1
,
false
,
"str"
,
NULL
,
NULL
);
str_cls
->
tp_flags
|=
Py_TPFLAGS_STRING_SUBCLASS
;
str_cls
->
tp_itemsize
=
sizeof
(
char
);
...
...
@@ -3498,61 +3497,55 @@ void setupRuntime() {
// Not sure why CPython defines sizeof(PyTupleObject) to include one element,
// but we copy that, which means we have to subtract that extra pointer to get the tp_basicsize:
tuple_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedTuple
)
-
sizeof
(
Box
*
),
false
,
"tuple"
);
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedTuple
)
-
sizeof
(
Box
*
),
false
,
"tuple"
,
(
destructor
)
tupledealloc
,
NULL
);
tuple_cls
->
tp_dealloc
=
(
destructor
)
tupledealloc
;
tuple_cls
->
tp_flags
|=
Py_TPFLAGS_TUPLE_SUBCLASS
;
tuple_cls
->
tp_itemsize
=
sizeof
(
Box
*
);
tuple_cls
->
tp_mro
=
BoxedTuple
::
create
({
tuple_cls
,
object_cls
});
EmptyTuple
=
BoxedTuple
::
create
({});
constants
.
push_back
(
EmptyTuple
);
list_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedList
),
false
,
"list"
);
list_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedList
),
false
,
"list"
,
BoxedList
::
dealloc
,
NULL
);
list_cls
->
tp_flags
|=
Py_TPFLAGS_LIST_SUBCLASS
;
list_cls
->
tp_dealloc
=
BoxedList
::
dealloc
;
pyston_getset_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
"getset_descriptor"
);
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedGetsetDescriptor
),
false
,
"getset_descriptor"
,
NULL
,
NULL
);
attrwrapper_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
AttrWrapper
),
false
,
"attrwrapper"
);
dict_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedDict
),
false
,
"dict"
);
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
AttrWrapper
),
false
,
"attrwrapper"
,
NULL
,
NULL
);
dict_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedDict
),
false
,
"dict"
,
BoxedDict
::
dealloc
,
NULL
);
dict_cls
->
tp_flags
|=
Py_TPFLAGS_DICT_SUBCLASS
;
dict_cls
->
tp_dealloc
=
BoxedDict
::
dealloc
;
file_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
offsetof
(
BoxedFile
,
weakreflist
),
sizeof
(
BoxedFile
),
false
,
"file"
);
file_cls
->
tp_dealloc
=
file_dealloc
;
int_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedInt
),
false
,
"int"
);
sizeof
(
BoxedFile
),
false
,
"file"
,
file_dealloc
,
NULL
);
int_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedInt
),
false
,
"int"
,
NULL
,
NULL
);
int_cls
->
tp_flags
|=
Py_TPFLAGS_INT_SUBCLASS
;
int_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
bool_cls
=
new
(
0
)
BoxedClass
(
int_cls
,
0
,
0
,
sizeof
(
BoxedBool
),
false
,
"bool"
);
bool_cls
=
new
(
0
)
BoxedClass
(
int_cls
,
0
,
0
,
sizeof
(
BoxedBool
),
false
,
"bool"
,
NULL
,
NULL
);
bool_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
complex_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedComplex
),
false
,
"complex"
);
complex_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedComplex
),
false
,
"complex"
,
NULL
,
NULL
);
complex_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
long_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedLong
),
false
,
"long"
);
long_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedLong
),
false
,
"long"
,
NULL
,
NULL
);
long_cls
->
tp_flags
|=
Py_TPFLAGS_LONG_SUBCLASS
;
long_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
float_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedFloat
),
false
,
"float"
);
float_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedFloat
),
false
,
"float"
,
NULL
,
NULL
);
float_cls
->
tp_flags
&=
~
Py_TPFLAGS_HAVE_GC
;
function_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
offsetof
(
BoxedFunction
,
attrs
),
offsetof
(
BoxedFunction
,
weakreflist
),
sizeof
(
BoxedFunction
),
false
,
"function"
);
offsetof
(
BoxedFunction
,
weakreflist
),
sizeof
(
BoxedFunction
),
false
,
"function"
,
functionDtor
,
NULL
);
builtin_function_or_method_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
offsetof
(
BoxedBuiltinFunctionOrMethod
,
weakreflist
),
sizeof
(
BoxedBuiltinFunctionOrMethod
),
false
,
"builtin_function_or_method"
);
function_cls
->
tp_dealloc
=
builtin_function_or_method_cls
->
tp_dealloc
=
functionDtor
;
sizeof
(
BoxedBuiltinFunctionOrMethod
),
false
,
"builtin_function_or_method"
,
functionDtor
,
NULL
);
function_cls
->
has_safe_tp_dealloc
=
builtin_function_or_method_cls
->
has_safe_tp_dealloc
=
true
;
module_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
offsetof
(
BoxedModule
,
attrs
),
0
,
sizeof
(
BoxedModule
),
false
,
"module"
);
module_cls
->
tp_dealloc
=
BoxedModule
::
dealloc
;
sizeof
(
BoxedModule
),
false
,
"module"
,
BoxedModule
::
dealloc
,
NULL
);
member_descriptor_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
,
"member_descriptor"
);
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
,
"member_descriptor"
,
NULL
,
NULL
);
capifunc_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedCApiFunction
),
false
,
"capifunc"
);
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedCApiFunction
),
false
,
"capifunc"
,
NULL
,
NULL
);
method_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedMethodDescriptor
),
false
,
"method_descriptor"
);
false
,
"method_descriptor"
,
NULL
,
NULL
);
wrapperobject_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedWrapperObject
),
false
,
"method-wrapper"
);
false
,
"method-wrapper"
,
NULL
,
NULL
);
wrapperdescr_cls
=
new
(
0
)
BoxedClass
(
object_cls
,
0
,
0
,
sizeof
(
BoxedWrapperDescriptor
),
false
,
"wrapper_descriptor"
);
sizeof
(
BoxedWrapperDescriptor
),
false
,
"wrapper_descriptor"
,
NULL
,
NULL
);
EmptyString
=
new
(
0
)
BoxedString
(
""
);
constants
.
push_back
(
EmptyString
);
...
...
@@ -3660,8 +3653,7 @@ void setupRuntime() {
instancemethod_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
offsetof
(
BoxedInstanceMethod
,
im_weakreflist
),
sizeof
(
BoxedInstanceMethod
),
false
,
"instancemethod"
);
instancemethod_cls
->
tp_dealloc
=
BoxedInstanceMethod
::
dealloc
;
false
,
"instancemethod"
,
BoxedInstanceMethod
::
dealloc
);
slice_cls
=
BoxedClass
::
create
(
type_cls
,
object_cls
,
0
,
0
,
sizeof
(
BoxedSlice
),
false
,
"slice"
);
...
...
src/runtime/types.h
View file @
7199f0e3
...
...
@@ -68,7 +68,7 @@ void setupImport();
void
setupAST
();
void
setupSysEnd
();
B
oxedDict
*
getSysModulesDict
();
B
ORROWED
(
BoxedDict
*
)
getSysModulesDict
();
BoxedList
*
getSysPath
();
extern
"C"
Box
*
getSysStdout
();
...
...
@@ -173,7 +173,6 @@ struct ExcInfo;
void
setCAPIException
(
const
ExcInfo
&
e
);
// Finalizer-related
void
default_free
(
void
*
);
void
dealloc_null
(
Box
*
box
);
void
file_dealloc
(
Box
*
)
noexcept
;
...
...
@@ -276,11 +275,12 @@ public:
SlotOffset
*
slotOffsets
()
{
return
(
BoxedClass
::
SlotOffset
*
)((
char
*
)
this
+
this
->
cls
->
tp_basicsize
);
}
// These should only be used for builtin types:
static
BoxedClass
*
create
(
BoxedClass
*
metatype
,
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
);
static
BoxedClass
*
create
(
BoxedClass
*
metatype
,
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
,
destructor
dealloc
=
NULL
,
freefunc
free
=
NULL
);
BoxedClass
(
BoxedClass
*
base
,
int
attrs_offset
,
int
weaklist_offset
,
int
instance_size
,
bool
is_user_defined
,
const
char
*
name
);
bool
is_user_defined
,
const
char
*
name
,
destructor
dealloc
,
freefunc
free
);
DEFAULT_CLASS_VAR
(
type_cls
,
sizeof
(
SlotOffset
));
...
...
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