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
d5ba641b
Commit
d5ba641b
authored
Dec 13, 2014
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'getitem'
parents
15e86e4f
01a0b1a7
Changes
22
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
883 additions
and
109 deletions
+883
-109
Makefile
Makefile
+1
-0
src/capi/modsupport.cpp
src/capi/modsupport.cpp
+145
-9
src/capi/typeobject.cpp
src/capi/typeobject.cpp
+459
-15
src/capi/types.h
src/capi/types.h
+6
-7
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+5
-4
src/runtime/builtin_modules/sys.cpp
src/runtime/builtin_modules/sys.cpp
+1
-1
src/runtime/capi.cpp
src/runtime/capi.cpp
+14
-6
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+4
-4
src/runtime/dict.cpp
src/runtime/dict.cpp
+1
-1
src/runtime/generator.cpp
src/runtime/generator.cpp
+2
-2
src/runtime/inline/xrange.cpp
src/runtime/inline/xrange.cpp
+3
-3
src/runtime/iterobject.cpp
src/runtime/iterobject.cpp
+1
-1
src/runtime/list.cpp
src/runtime/list.cpp
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+16
-2
src/runtime/set.cpp
src/runtime/set.cpp
+1
-1
src/runtime/str.cpp
src/runtime/str.cpp
+1
-1
src/runtime/super.cpp
src/runtime/super.cpp
+1
-1
src/runtime/tuple.cpp
src/runtime/tuple.cpp
+2
-1
src/runtime/types.cpp
src/runtime/types.cpp
+32
-29
src/runtime/types.h
src/runtime/types.h
+26
-4
test/test_extension/slots_test.c
test/test_extension/slots_test.c
+142
-12
test/tests/capi_slots.py
test/tests/capi_slots.py
+19
-4
No files found.
Makefile
View file @
d5ba641b
...
@@ -142,6 +142,7 @@ COMMON_CXXFLAGS += -fexceptions -fno-rtti
...
@@ -142,6 +142,7 @@ COMMON_CXXFLAGS += -fexceptions -fno-rtti
COMMON_CXXFLAGS
+=
-Wno-invalid-offsetof
# allow the use of "offsetof", and we'll just have to make sure to only use it legally.
COMMON_CXXFLAGS
+=
-Wno-invalid-offsetof
# allow the use of "offsetof", and we'll just have to make sure to only use it legally.
COMMON_CXXFLAGS
+=
-DENABLE_INTEL_JIT_EVENTS
=
$(ENABLE_INTEL_JIT_EVENTS)
COMMON_CXXFLAGS
+=
-DENABLE_INTEL_JIT_EVENTS
=
$(ENABLE_INTEL_JIT_EVENTS)
COMMON_CXXFLAGS
+=
-I
$(DEPS_DIR)
/pypa-install/include
COMMON_CXXFLAGS
+=
-I
$(DEPS_DIR)
/pypa-install/include
COMMON_CXXFLAGS
+=
-Wno-comment
ifeq
($(ENABLE_VALGRIND),0)
ifeq
($(ENABLE_VALGRIND),0)
COMMON_CXXFLAGS
+=
-DNVALGRIND
COMMON_CXXFLAGS
+=
-DNVALGRIND
...
...
src/capi/modsupport.cpp
View file @
d5ba641b
...
@@ -32,24 +32,160 @@ namespace pyston {
...
@@ -32,24 +32,160 @@ namespace pyston {
#define FLAG_SIZE_T 1
#define FLAG_SIZE_T 1
static
PyObject
*
va_build_value
(
const
char
*
fmt
,
va_list
va
,
int
flags
)
{
static
int
countformat
(
const
char
*
format
,
int
endchar
)
{
int
len
=
strlen
(
fmt
);
int
count
=
0
;
if
(
len
==
0
)
int
level
=
0
;
return
None
;
while
(
level
>
0
||
*
format
!=
endchar
)
{
switch
(
*
format
)
{
case
'\0'
:
/* Premature end */
PyErr_SetString
(
PyExc_SystemError
,
"unmatched paren in format"
);
return
-
1
;
case
'('
:
case
'['
:
case
'{'
:
if
(
level
==
0
)
count
++
;
level
++
;
break
;
case
')'
:
case
']'
:
case
'}'
:
level
--
;
break
;
case
'#'
:
case
'&'
:
case
','
:
case
':'
:
case
' '
:
case
'\t'
:
break
;
default:
if
(
level
==
0
)
count
++
;
}
format
++
;
}
return
count
;
}
static
PyObject
*
do_mktuple
(
const
char
**
,
va_list
*
,
int
,
int
,
int
)
noexcept
;
// static PyObject *do_mklist(const char**, va_list *, int, int, int) noexcept;
// static PyObject *do_mkdict(const char**, va_list *, int, int, int) noexcept;
static
PyObject
*
do_mkvalue
(
const
char
**
,
va_list
*
,
int
)
noexcept
;
static
PyObject
*
do_mkvalue
(
const
char
**
p_format
,
va_list
*
p_va
,
int
flags
)
noexcept
{
for
(;;)
{
switch
(
*
(
*
p_format
)
++
)
{
case
'('
:
return
do_mktuple
(
p_format
,
p_va
,
')'
,
countformat
(
*
p_format
,
')'
),
flags
);
#if 0
case '[':
return do_mklist(p_format, p_va, ']', countformat(*p_format, ']'), flags);
case '{':
return do_mkdict(p_format, p_va, '}', countformat(*p_format, '}'), flags);
#endif
if
(
len
==
1
)
{
switch
(
*
fmt
)
{
case
'b'
:
case
'b'
:
case
'B'
:
case
'B'
:
case
'h'
:
case
'h'
:
case
'i'
:
case
'i'
:
return
PyInt_FromLong
((
long
)
va_arg
(
va
,
int
));
return
PyInt_FromLong
((
long
)
va_arg
(
*
p_va
,
int
));
case
'H'
:
return
PyInt_FromLong
((
long
)
va_arg
(
*
p_va
,
unsigned
int
));
case
'N'
:
case
'S'
:
case
'O'
:
if
(
**
p_format
==
'&'
)
{
typedef
PyObject
*
(
*
converter
)(
void
*
);
converter
func
=
va_arg
(
*
p_va
,
converter
);
void
*
arg
=
va_arg
(
*
p_va
,
void
*
);
++*
p_format
;
return
(
*
func
)(
arg
);
}
else
{
PyObject
*
v
;
v
=
va_arg
(
*
p_va
,
PyObject
*
);
if
(
v
!=
NULL
)
{
if
(
*
(
*
p_format
-
1
)
!=
'N'
)
Py_INCREF
(
v
);
}
else
if
(
!
PyErr_Occurred
())
/* If a NULL was passed
* because a call that should
* have constructed a value
* failed, that's OK, and we
* pass the error on; but if
* no error occurred it's not
* clear that the caller knew
* what she was doing. */
PyErr_SetString
(
PyExc_SystemError
,
"NULL object passed to Py_BuildValue"
);
return
v
;
}
default:
default:
RELEASE_ASSERT
(
0
,
"%c"
,
*
fmt
);
RELEASE_ASSERT
(
0
,
"%c"
,
*
((
*
p_format
)
-
1
)
);
}
}
}
}
abort
();
}
static
PyObject
*
do_mktuple
(
const
char
**
p_format
,
va_list
*
p_va
,
int
endchar
,
int
n
,
int
flags
)
noexcept
{
PyObject
*
v
;
int
i
;
int
itemfailed
=
0
;
if
(
n
<
0
)
return
NULL
;
if
((
v
=
PyTuple_New
(
n
))
==
NULL
)
return
NULL
;
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
for
(
i
=
0
;
i
<
n
;
i
++
)
{
PyObject
*
w
=
do_mkvalue
(
p_format
,
p_va
,
flags
);
if
(
w
==
NULL
)
{
itemfailed
=
1
;
Py_INCREF
(
Py_None
);
w
=
Py_None
;
}
PyTuple_SET_ITEM
(
v
,
i
,
w
);
}
if
(
itemfailed
)
{
/* do_mkvalue() should have already set an error */
Py_DECREF
(
v
);
return
NULL
;
}
if
(
**
p_format
!=
endchar
)
{
Py_DECREF
(
v
);
PyErr_SetString
(
PyExc_SystemError
,
"Unmatched paren in format"
);
return
NULL
;
}
if
(
endchar
)
++*
p_format
;
return
v
;
}
static
PyObject
*
va_build_value
(
const
char
*
fmt
,
va_list
va
,
int
flags
)
{
int
n
=
countformat
(
fmt
,
'\0'
);
if
(
n
<
0
)
return
NULL
;
if
(
n
==
0
)
return
None
;
va_list
lva
;
__va_copy
(
lva
,
va
);
if
(
n
==
1
)
return
do_mkvalue
(
&
fmt
,
&
lva
,
flags
);
return
do_mktuple
(
&
fmt
,
&
lva
,
'\0'
,
n
,
flags
);
}
RELEASE_ASSERT
(
0
,
""
);
extern
"C"
PyObject
*
Py_VaBuildValue
(
const
char
*
format
,
va_list
va
)
{
return
va_build_value
(
format
,
va
,
0
);
}
}
extern
"C"
PyObject
*
_Py_BuildValue_SizeT
(
const
char
*
fmt
,
...)
{
extern
"C"
PyObject
*
_Py_BuildValue_SizeT
(
const
char
*
fmt
,
...)
{
...
...
src/capi/typeobject.cpp
View file @
d5ba641b
This diff is collapsed.
Click to expand it.
src/capi/types.h
View file @
d5ba641b
...
@@ -27,7 +27,7 @@ struct wrapper_def {
...
@@ -27,7 +27,7 @@ struct wrapper_def {
int
offset
;
int
offset
;
void
*
function
;
// "generic" handler that gets put in the tp_* slot which proxies to the python version
void
*
function
;
// "generic" handler that gets put in the tp_* slot which proxies to the python version
wrapperfunc
wrapper
;
// "wrapper" that ends up getting called by the Python-visible WrapperDescr
wrapperfunc
wrapper
;
// "wrapper" that ends up getting called by the Python-visible WrapperDescr
// exists in CPython: const char* doc
const
char
*
doc
;
int
flags
;
int
flags
;
// exists in CPython: PyObject *name_strobj
// exists in CPython: PyObject *name_strobj
};
};
...
@@ -83,8 +83,9 @@ class BoxedWrapperDescriptor : public Box {
...
@@ -83,8 +83,9 @@ class BoxedWrapperDescriptor : public Box {
public:
public:
const
wrapper_def
*
wrapper
;
const
wrapper_def
*
wrapper
;
BoxedClass
*
type
;
BoxedClass
*
type
;
BoxedWrapperDescriptor
(
const
wrapper_def
*
wrapper
,
BoxedClass
*
type
)
void
*
wrapped
;
:
Box
(
wrapperdescr_cls
),
wrapper
(
wrapper
),
type
(
type
)
{}
BoxedWrapperDescriptor
(
const
wrapper_def
*
wrapper
,
BoxedClass
*
type
,
void
*
wrapped
)
:
Box
(
wrapperdescr_cls
),
wrapper
(
wrapper
),
type
(
type
),
wrapped
(
wrapped
)
{}
static
Box
*
__get__
(
BoxedWrapperDescriptor
*
self
,
Box
*
inst
,
Box
*
owner
);
static
Box
*
__get__
(
BoxedWrapperDescriptor
*
self
,
Box
*
inst
,
Box
*
owner
);
};
};
...
@@ -104,14 +105,12 @@ public:
...
@@ -104,14 +105,12 @@ public:
int
flags
=
self
->
descr
->
wrapper
->
flags
;
int
flags
=
self
->
descr
->
wrapper
->
flags
;
wrapperfunc
wrapper
=
self
->
descr
->
wrapper
->
wrapper
;
wrapperfunc
wrapper
=
self
->
descr
->
wrapper
->
wrapper
;
assert
(
self
->
descr
->
wrapper
->
offset
>
0
);
assert
(
self
->
descr
->
wrapper
->
offset
>
0
);
char
*
ptr
=
(
char
*
)
self
->
descr
->
type
+
self
->
descr
->
wrapper
->
offset
;
void
*
wrapped
=
*
reinterpret_cast
<
void
**>
(
ptr
);
if
(
flags
&
PyWrapperFlag_KEYWORDS
)
{
if
(
flags
&
PyWrapperFlag_KEYWORDS
)
{
wrapperfunc_kwds
wk
=
(
wrapperfunc_kwds
)
wrapper
;
wrapperfunc_kwds
wk
=
(
wrapperfunc_kwds
)
wrapper
;
return
(
*
wk
)(
self
->
obj
,
args
,
wrapped
,
kwds
);
return
(
*
wk
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
,
kwds
);
}
else
{
}
else
{
return
(
*
wrapper
)(
self
->
obj
,
args
,
wrapped
);
return
(
*
wrapper
)(
self
->
obj
,
args
,
self
->
descr
->
wrapped
);
}
}
abort
();
abort
();
}
}
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
d5ba641b
...
@@ -497,7 +497,7 @@ Box* exceptionRepr(Box* b) {
...
@@ -497,7 +497,7 @@ Box* exceptionRepr(Box* b) {
static
BoxedClass
*
makeBuiltinException
(
BoxedClass
*
base
,
const
char
*
name
)
{
static
BoxedClass
*
makeBuiltinException
(
BoxedClass
*
base
,
const
char
*
name
)
{
BoxedClass
*
cls
BoxedClass
*
cls
=
new
BoxedClass
(
type_cls
,
base
,
NULL
,
offsetof
(
BoxedException
,
attrs
),
sizeof
(
BoxedException
),
false
);
=
new
Boxed
Heap
Class
(
type_cls
,
base
,
NULL
,
offsetof
(
BoxedException
,
attrs
),
sizeof
(
BoxedException
),
false
);
cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
name
));
cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
name
));
cls
->
giveAttr
(
"__module__"
,
boxStrConstant
(
"exceptions"
));
cls
->
giveAttr
(
"__module__"
,
boxStrConstant
(
"exceptions"
));
...
@@ -521,7 +521,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
...
@@ -521,7 +521,7 @@ extern "C" PyObject* PyErr_NewException(char* name, PyObject* _base, PyObject* d
try
{
try
{
BoxedClass
*
base
=
Exception
;
BoxedClass
*
base
=
Exception
;
BoxedClass
*
cls
BoxedClass
*
cls
=
new
BoxedClass
(
type_cls
,
base
,
NULL
,
offsetof
(
BoxedException
,
attrs
),
sizeof
(
BoxedException
),
true
);
=
new
Boxed
Heap
Class
(
type_cls
,
base
,
NULL
,
offsetof
(
BoxedException
,
attrs
),
sizeof
(
BoxedException
),
true
);
char
*
dot_pos
=
strchr
(
name
,
'.'
);
char
*
dot_pos
=
strchr
(
name
,
'.'
);
RELEASE_ASSERT
(
dot_pos
,
""
);
RELEASE_ASSERT
(
dot_pos
,
""
);
...
@@ -702,7 +702,7 @@ void setupBuiltins() {
...
@@ -702,7 +702,7 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"print"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
print
,
NONE
,
0
,
0
,
true
,
true
)));
builtins_module
->
giveAttr
(
"print"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
print
,
NONE
,
0
,
0
,
true
,
true
)));
notimplemented_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
notimplemented_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
notimplemented_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"NotImplementedType"
));
notimplemented_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"NotImplementedType"
));
notimplemented_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
notimplementedRepr
,
STR
,
1
)));
notimplemented_cls
->
giveAttr
(
"__repr__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
notimplementedRepr
,
STR
,
1
)));
notimplemented_cls
->
freeze
();
notimplemented_cls
->
freeze
();
...
@@ -795,7 +795,8 @@ void setupBuiltins() {
...
@@ -795,7 +795,8 @@ void setupBuiltins() {
builtins_module
->
giveAttr
(
"issubclass"
,
issubclass_obj
);
builtins_module
->
giveAttr
(
"issubclass"
,
issubclass_obj
);
enumerate_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
BoxedEnumerate
::
gcHandler
,
0
,
sizeof
(
BoxedEnumerate
),
false
);
enumerate_cls
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
&
BoxedEnumerate
::
gcHandler
,
0
,
sizeof
(
BoxedEnumerate
),
false
);
enumerate_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"enumerate"
));
enumerate_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"enumerate"
));
enumerate_cls
->
giveAttr
(
enumerate_cls
->
giveAttr
(
"__new__"
,
"__new__"
,
...
...
src/runtime/builtin_modules/sys.cpp
View file @
d5ba641b
...
@@ -126,7 +126,7 @@ void setupSys() {
...
@@ -126,7 +126,7 @@ void setupSys() {
sys_module
->
giveAttr
(
"maxint"
,
boxInt
(
PYSTON_INT_MAX
));
sys_module
->
giveAttr
(
"maxint"
,
boxInt
(
PYSTON_INT_MAX
));
sys_flags_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
BoxedSysFlags
::
gcHandler
,
0
,
sizeof
(
BoxedSysFlags
),
false
);
sys_flags_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
BoxedSysFlags
::
gcHandler
,
0
,
sizeof
(
BoxedSysFlags
),
false
);
sys_flags_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"flags"
));
sys_flags_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"flags"
));
sys_flags_cls
->
giveAttr
(
"__new__"
,
sys_flags_cls
->
giveAttr
(
"__new__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedSysFlags
::
__new__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedSysFlags
::
__new__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
...
...
src/runtime/capi.cpp
View file @
d5ba641b
...
@@ -322,7 +322,10 @@ extern "C" int PyObject_Not(PyObject* o) {
...
@@ -322,7 +322,10 @@ extern "C" int PyObject_Not(PyObject* o) {
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
{
extern
"C"
PyObject
*
PyObject_Call
(
PyObject
*
callable_object
,
PyObject
*
args
,
PyObject
*
kw
)
{
try
{
try
{
return
runtimeCall
(
callable_object
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
args
,
kw
,
NULL
,
NULL
,
NULL
);
if
(
kw
)
return
runtimeCall
(
callable_object
,
ArgPassSpec
(
0
,
0
,
true
,
true
),
args
,
kw
,
NULL
,
NULL
,
NULL
);
else
return
runtimeCall
(
callable_object
,
ArgPassSpec
(
0
,
0
,
true
,
false
),
args
,
NULL
,
NULL
,
NULL
,
NULL
);
}
catch
(
Box
*
b
)
{
}
catch
(
Box
*
b
)
{
Py_FatalError
(
"unimplemented"
);
Py_FatalError
(
"unimplemented"
);
}
}
...
@@ -699,7 +702,12 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) {
...
@@ -699,7 +702,12 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) {
}
}
extern
"C"
Py_ssize_t
PyNumber_AsSsize_t
(
PyObject
*
o
,
PyObject
*
exc
)
{
extern
"C"
Py_ssize_t
PyNumber_AsSsize_t
(
PyObject
*
o
,
PyObject
*
exc
)
{
Py_FatalError
(
"unimplemented"
);
RELEASE_ASSERT
(
o
->
cls
!=
long_cls
,
"unhandled"
);
RELEASE_ASSERT
(
o
->
cls
==
int_cls
,
"??"
);
int64_t
n
=
static_cast
<
BoxedInt
*>
(
o
)
->
n
;
static_assert
(
sizeof
(
n
)
==
sizeof
(
Py_ssize_t
),
""
);
return
n
;
}
}
extern
"C"
Py_ssize_t
PyUnicode_GET_SIZE
(
PyObject
*
)
{
extern
"C"
Py_ssize_t
PyUnicode_GET_SIZE
(
PyObject
*
)
{
...
@@ -753,7 +761,7 @@ BoxedModule* importTestExtension(const std::string& name) {
...
@@ -753,7 +761,7 @@ BoxedModule* importTestExtension(const std::string& name) {
}
}
void
setupCAPI
()
{
void
setupCAPI
()
{
capifunc_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedCApiFunction
),
false
);
capifunc_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedCApiFunction
),
false
);
capifunc_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"capifunc"
));
capifunc_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"capifunc"
));
capifunc_cls
->
giveAttr
(
"__repr__"
,
capifunc_cls
->
giveAttr
(
"__repr__"
,
...
@@ -765,7 +773,7 @@ void setupCAPI() {
...
@@ -765,7 +773,7 @@ void setupCAPI() {
capifunc_cls
->
freeze
();
capifunc_cls
->
freeze
();
method_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedMethodDescriptor
),
false
);
method_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedMethodDescriptor
),
false
);
method_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"method"
));
method_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"method"
));
method_cls
->
giveAttr
(
"__get__"
,
method_cls
->
giveAttr
(
"__get__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__get__
,
UNKNOWN
,
3
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedMethodDescriptor
::
__get__
,
UNKNOWN
,
3
)));
...
@@ -773,13 +781,13 @@ void setupCAPI() {
...
@@ -773,13 +781,13 @@ void setupCAPI() {
0
,
true
,
true
)));
0
,
true
,
true
)));
method_cls
->
freeze
();
method_cls
->
freeze
();
wrapperdescr_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedWrapperDescriptor
),
false
);
wrapperdescr_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedWrapperDescriptor
),
false
);
wrapperdescr_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"wrapper_descriptor"
));
wrapperdescr_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"wrapper_descriptor"
));
wrapperdescr_cls
->
giveAttr
(
"__get__"
,
wrapperdescr_cls
->
giveAttr
(
"__get__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperDescriptor
::
__get__
,
UNKNOWN
,
3
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperDescriptor
::
__get__
,
UNKNOWN
,
3
)));
wrapperdescr_cls
->
freeze
();
wrapperdescr_cls
->
freeze
();
wrapperobject_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedWrapperObject
),
false
);
wrapperobject_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedWrapperObject
),
false
);
wrapperobject_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"method-wrapper"
));
wrapperobject_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"method-wrapper"
));
wrapperobject_cls
->
giveAttr
(
wrapperobject_cls
->
giveAttr
(
"__call__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperObject
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
"__call__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedWrapperObject
::
__call__
,
UNKNOWN
,
1
,
0
,
true
,
true
)));
...
...
src/runtime/classobj.cpp
View file @
d5ba641b
...
@@ -241,10 +241,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
...
@@ -241,10 +241,10 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
}
}
void
setupClassobj
()
{
void
setupClassobj
()
{
classobj_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
BoxedClassobj
::
gcHandler
,
offsetof
(
BoxedClassobj
,
attrs
),
classobj_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
BoxedClassobj
::
gcHandler
,
offsetof
(
BoxedClassobj
,
attrs
),
sizeof
(
BoxedClassobj
),
false
);
sizeof
(
BoxedClassobj
),
false
);
instance_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
BoxedInstance
::
gcHandler
,
offsetof
(
BoxedInstance
,
attrs
),
instance_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
BoxedInstance
::
gcHandler
,
offsetof
(
BoxedInstance
,
attrs
),
sizeof
(
BoxedInstance
),
false
);
sizeof
(
BoxedInstance
),
false
);
classobj_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"classobj"
));
classobj_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"classobj"
));
...
...
src/runtime/dict.cpp
View file @
d5ba641b
...
@@ -378,7 +378,7 @@ extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
...
@@ -378,7 +378,7 @@ extern "C" void dictIteratorGCHandler(GCVisitor* v, Box* b) {
}
}
void
setupDict
()
{
void
setupDict
()
{
dict_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
dictIteratorGCHandler
,
0
,
sizeof
(
BoxedDict
),
false
);
dict_iterator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
dictIteratorGCHandler
,
0
,
sizeof
(
BoxedDict
),
false
);
dict_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"dict"
));
dict_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"dict"
));
dict_cls
->
giveAttr
(
"__len__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictLen
,
BOXED_INT
,
1
)));
dict_cls
->
giveAttr
(
"__len__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
dictLen
,
BOXED_INT
,
1
)));
...
...
src/runtime/generator.cpp
View file @
d5ba641b
...
@@ -177,8 +177,8 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
...
@@ -177,8 +177,8 @@ extern "C" void generatorGCHandler(GCVisitor* v, Box* b) {
void
setupGenerator
()
{
void
setupGenerator
()
{
generator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
generatorGCHandler
,
offsetof
(
BoxedGenerator
,
attrs
),
generator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
generatorGCHandler
,
offsetof
(
BoxedGenerator
,
attrs
),
sizeof
(
BoxedGenerator
),
false
);
sizeof
(
BoxedGenerator
),
false
);
generator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"generator"
));
generator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"generator"
));
generator_cls
->
giveAttr
(
"__iter__"
,
generator_cls
->
giveAttr
(
"__iter__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
generatorIter
,
typeFromClass
(
generator_cls
),
1
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
generatorIter
,
typeFromClass
(
generator_cls
),
1
)));
...
...
src/runtime/inline/xrange.cpp
View file @
d5ba641b
...
@@ -113,10 +113,10 @@ Box* xrangeIter(Box* self) {
...
@@ -113,10 +113,10 @@ Box* xrangeIter(Box* self) {
}
}
void
setupXrange
()
{
void
setupXrange
()
{
xrange_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedXrange
),
false
);
xrange_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedXrange
),
false
);
xrange_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"xrange"
));
xrange_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"xrange"
));
xrange_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
BoxedXrangeIterator
::
xrangeIteratorGCHandler
,
0
,
xrange_iterator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
BoxedXrangeIterator
::
xrangeIteratorGCHandler
,
0
,
sizeof
(
BoxedXrangeIterator
),
false
);
sizeof
(
BoxedXrangeIterator
),
false
);
xrange_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"rangeiterator"
));
xrange_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"rangeiterator"
));
xrange_cls
->
giveAttr
(
xrange_cls
->
giveAttr
(
...
...
src/runtime/iterobject.cpp
View file @
d5ba641b
...
@@ -57,7 +57,7 @@ Box* seqiterNext(Box* s) {
...
@@ -57,7 +57,7 @@ Box* seqiterNext(Box* s) {
}
}
void
setupIter
()
{
void
setupIter
()
{
seqiter_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedSeqIter
),
false
);
seqiter_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedSeqIter
),
false
);
seqiter_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"iterator"
));
seqiter_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"iterator"
));
seqiter_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
seqiterNext
,
UNKNOWN
,
1
)));
seqiter_cls
->
giveAttr
(
"next"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
seqiterNext
,
UNKNOWN
,
1
)));
...
...
src/runtime/list.cpp
View file @
d5ba641b
...
@@ -553,7 +553,7 @@ Box* listEq(BoxedList* self, Box* rhs) {
...
@@ -553,7 +553,7 @@ Box* listEq(BoxedList* self, Box* rhs) {
}
}
void
setupList
()
{
void
setupList
()
{
list_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
listIteratorGCHandler
,
0
,
sizeof
(
BoxedList
),
false
);
list_iterator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
listIteratorGCHandler
,
0
,
sizeof
(
BoxedList
),
false
);
list_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"list"
));
list_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"list"
));
...
...
src/runtime/objmodel.cpp
View file @
d5ba641b
...
@@ -389,6 +389,20 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
...
@@ -389,6 +389,20 @@ BoxedClass::BoxedClass(BoxedClass* metaclass, BoxedClass* base, gcvisit_func gc_
gc
::
registerPermanentRoot
(
this
);
gc
::
registerPermanentRoot
(
this
);
}
}
BoxedHeapClass
::
BoxedHeapClass
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
gcvisit_func
gc_visit
,
int
attrs_offset
,
int
instance_size
,
bool
is_user_defined
)
:
BoxedClass
(
metaclass
,
base
,
gc_visit
,
attrs_offset
,
instance_size
,
is_user_defined
),
ht_name
(
NULL
),
ht_slots
(
NULL
)
{
tp_as_number
=
&
as_number
;
tp_as_mapping
=
&
as_mapping
;
tp_as_sequence
=
&
as_sequence
;
tp_as_buffer
=
&
as_buffer
;
// just make sure these get zero-initialized:
assert
(
as_sequence
.
sq_item
==
NULL
);
}
std
::
string
getFullNameOfClass
(
BoxedClass
*
cls
)
{
std
::
string
getFullNameOfClass
(
BoxedClass
*
cls
)
{
Box
*
b
=
cls
->
getattr
(
"__name__"
);
Box
*
b
=
cls
->
getattr
(
"__name__"
);
assert
(
b
);
assert
(
b
);
...
@@ -3272,10 +3286,10 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
...
@@ -3272,10 +3286,10 @@ Box* typeNew(Box* _cls, Box* arg1, Box* arg2, Box** _args) {
BoxedClass
*
made
;
BoxedClass
*
made
;
if
(
base
->
instancesHaveAttrs
())
{
if
(
base
->
instancesHaveAttrs
())
{
made
=
new
BoxedClass
(
cls
,
base
,
NULL
,
base
->
attrs_offset
,
base
->
tp_basicsize
,
true
);
made
=
new
Boxed
Heap
Class
(
cls
,
base
,
NULL
,
base
->
attrs_offset
,
base
->
tp_basicsize
,
true
);
}
else
{
}
else
{
assert
(
base
->
tp_basicsize
%
sizeof
(
void
*
)
==
0
);
assert
(
base
->
tp_basicsize
%
sizeof
(
void
*
)
==
0
);
made
=
new
BoxedClass
(
cls
,
base
,
NULL
,
base
->
tp_basicsize
,
base
->
tp_basicsize
+
sizeof
(
HCAttrs
),
true
);
made
=
new
Boxed
Heap
Class
(
cls
,
base
,
NULL
,
base
->
tp_basicsize
,
base
->
tp_basicsize
+
sizeof
(
HCAttrs
),
true
);
}
}
made
->
giveAttr
(
"__module__"
,
boxString
(
getCurrentModule
()
->
name
()));
made
->
giveAttr
(
"__module__"
,
boxString
(
getCurrentModule
()
->
name
()));
...
...
src/runtime/set.cpp
View file @
d5ba641b
...
@@ -216,7 +216,7 @@ void setupSet() {
...
@@ -216,7 +216,7 @@ void setupSet() {
set_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"set"
));
set_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"set"
));
frozenset_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"frozenset"
));
frozenset_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"frozenset"
));
set_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
setIteratorGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
set_iterator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
setIteratorGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
set_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"setiterator"
));
set_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"setiterator"
));
set_iterator_cls
->
giveAttr
(
"__hasnext__"
,
set_iterator_cls
->
giveAttr
(
"__hasnext__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setiteratorHasnext
,
BOXED_BOOL
,
1
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
setiteratorHasnext
,
BOXED_BOOL
,
1
)));
...
...
src/runtime/str.cpp
View file @
d5ba641b
...
@@ -1037,7 +1037,7 @@ static PyBufferProcs string_as_buffer = {
...
@@ -1037,7 +1037,7 @@ static PyBufferProcs string_as_buffer = {
};
};
void
setupStr
()
{
void
setupStr
()
{
str_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
strIteratorGCHandler
,
0
,
sizeof
(
BoxedString
),
false
);
str_iterator_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
strIteratorGCHandler
,
0
,
sizeof
(
BoxedString
),
false
);
str_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"striterator"
));
str_iterator_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"striterator"
));
str_iterator_cls
->
giveAttr
(
"__hasnext__"
,
str_iterator_cls
->
giveAttr
(
"__hasnext__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedStringIterator
::
hasnext
,
BOXED_BOOL
,
1
)));
new
BoxedFunction
(
boxRTFunction
((
void
*
)
BoxedStringIterator
::
hasnext
,
BOXED_BOOL
,
1
)));
...
...
src/runtime/super.cpp
View file @
d5ba641b
...
@@ -125,7 +125,7 @@ Box* superNew(Box* _cls, Box* _type, Box* obj) {
...
@@ -125,7 +125,7 @@ Box* superNew(Box* _cls, Box* _type, Box* obj) {
}
}
void
setupSuper
()
{
void
setupSuper
()
{
super_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
BoxedSuper
::
gcHandler
,
0
,
sizeof
(
BoxedSuper
),
false
);
super_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
BoxedSuper
::
gcHandler
,
0
,
sizeof
(
BoxedSuper
),
false
);
super_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"super"
));
super_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"super"
));
...
...
src/runtime/tuple.cpp
View file @
d5ba641b
...
@@ -382,7 +382,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
...
@@ -382,7 +382,8 @@ extern "C" void tupleIteratorGCHandler(GCVisitor* v, Box* b) {
void
setupTuple
()
{
void
setupTuple
()
{
tuple_iterator_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
tupleIteratorGCHandler
,
0
,
sizeof
(
BoxedTuple
),
false
);
tuple_iterator_cls
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
&
tupleIteratorGCHandler
,
0
,
sizeof
(
BoxedTuple
),
false
);
tuple_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"tuple"
));
tuple_cls
->
giveAttr
(
"__name__"
,
boxStrConstant
(
"tuple"
));
...
...
src/runtime/types.cpp
View file @
d5ba641b
...
@@ -780,21 +780,22 @@ void setupRuntime() {
...
@@ -780,21 +780,22 @@ void setupRuntime() {
root_hcls
=
HiddenClass
::
makeRoot
();
root_hcls
=
HiddenClass
::
makeRoot
();
gc
::
registerPermanentRoot
(
root_hcls
);
gc
::
registerPermanentRoot
(
root_hcls
);
object_cls
=
new
BoxedClass
(
NULL
,
NULL
,
&
boxGCHandler
,
0
,
sizeof
(
Box
),
false
);
object_cls
=
new
BoxedHeapClass
(
NULL
,
NULL
,
&
boxGCHandler
,
0
,
sizeof
(
Box
),
false
);
type_cls
=
new
BoxedClass
(
NULL
,
object_cls
,
&
typeGCHandler
,
offsetof
(
BoxedClass
,
attrs
),
sizeof
(
BoxedClass
),
false
);
type_cls
=
new
BoxedHeapClass
(
NULL
,
object_cls
,
&
typeGCHandler
,
offsetof
(
BoxedClass
,
attrs
),
sizeof
(
BoxedClass
),
false
);
type_cls
->
cls
=
type_cls
;
type_cls
->
cls
=
type_cls
;
object_cls
->
cls
=
type_cls
;
object_cls
->
cls
=
type_cls
;
none_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
none_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
None
=
new
Box
(
none_cls
);
None
=
new
Box
(
none_cls
);
gc
::
registerPermanentRoot
(
None
);
gc
::
registerPermanentRoot
(
None
);
// You can't actually have an instance of basestring
// You can't actually have an instance of basestring
basestring_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
basestring_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
Box
),
false
);
// TODO we leak all the string data!
// TODO we leak all the string data!
str_cls
=
new
BoxedClass
(
type_cls
,
basestring_cls
,
NULL
,
0
,
sizeof
(
BoxedString
),
false
);
str_cls
=
new
Boxed
Heap
Class
(
type_cls
,
basestring_cls
,
NULL
,
0
,
sizeof
(
BoxedString
),
false
);
unicode_cls
=
new
BoxedClass
(
type_cls
,
basestring_cls
,
NULL
,
0
,
sizeof
(
BoxedUnicode
),
false
);
unicode_cls
=
new
Boxed
Heap
Class
(
type_cls
,
basestring_cls
,
NULL
,
0
,
sizeof
(
BoxedUnicode
),
false
);
// It wasn't safe to add __base__ attributes until object+type+str are set up, so do that now:
// It wasn't safe to add __base__ attributes until object+type+str are set up, so do that now:
type_cls
->
giveAttr
(
"__base__"
,
object_cls
);
type_cls
->
giveAttr
(
"__base__"
,
object_cls
);
...
@@ -804,40 +805,42 @@ void setupRuntime() {
...
@@ -804,40 +805,42 @@ void setupRuntime() {
object_cls
->
giveAttr
(
"__base__"
,
None
);
object_cls
->
giveAttr
(
"__base__"
,
None
);
tuple_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
tupleGCHandler
,
0
,
sizeof
(
BoxedTuple
),
false
);
tuple_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
tupleGCHandler
,
0
,
sizeof
(
BoxedTuple
),
false
);
EmptyTuple
=
new
BoxedTuple
({});
EmptyTuple
=
new
BoxedTuple
({});
gc
::
registerPermanentRoot
(
EmptyTuple
);
gc
::
registerPermanentRoot
(
EmptyTuple
);
module_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
sizeof
(
BoxedModule
),
false
);
module_cls
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
NULL
,
offsetof
(
BoxedModule
,
attrs
),
sizeof
(
BoxedModule
),
false
);
// TODO it'd be nice to be able to do these in the respective setupType methods,
// TODO it'd be nice to be able to do these in the respective setupType methods,
// but those setup methods probably want access to these objects.
// but those setup methods probably want access to these objects.
// We could have a multi-stage setup process, but that seems overkill for now.
// We could have a multi-stage setup process, but that seems overkill for now.
bool_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedBool
),
false
);
bool_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedBool
),
false
);
int_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedInt
),
false
);
int_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedInt
),
false
);
complex_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedComplex
),
false
);
complex_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedComplex
),
false
);
// TODO we're leaking long memory!
// TODO we're leaking long memory!
long_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedLong
),
false
);
long_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedLong
),
false
);
float_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedFloat
),
false
);
float_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedFloat
),
false
);
function_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
functionGCHandler
,
offsetof
(
BoxedFunction
,
attrs
),
function_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
functionGCHandler
,
offsetof
(
BoxedFunction
,
attrs
),
sizeof
(
BoxedFunction
),
false
);
sizeof
(
BoxedFunction
),
false
);
instancemethod_cls
instancemethod_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
instancemethodGCHandler
,
0
,
sizeof
(
BoxedInstanceMethod
),
false
);
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
instancemethodGCHandler
,
0
,
sizeof
(
BoxedInstanceMethod
),
false
);
list_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
listGCHandler
,
0
,
sizeof
(
BoxedList
),
false
);
list_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
listGCHandler
,
0
,
sizeof
(
BoxedList
),
false
);
slice_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
sliceGCHandler
,
0
,
sizeof
(
BoxedSlice
),
false
);
slice_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
sliceGCHandler
,
0
,
sizeof
(
BoxedSlice
),
false
);
dict_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
dictGCHandler
,
0
,
sizeof
(
BoxedDict
),
false
);
dict_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
dictGCHandler
,
0
,
sizeof
(
BoxedDict
),
false
);
file_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedFile
),
false
);
file_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedFile
),
false
);
set_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
setGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
set_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
setGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
frozenset_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
setGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
frozenset_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
setGCHandler
,
0
,
sizeof
(
BoxedSet
),
false
);
member_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
);
member_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
NULL
,
0
,
sizeof
(
BoxedMemberDescriptor
),
false
);
closure_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
closureGCHandler
,
offsetof
(
BoxedClosure
,
attrs
),
closure_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
closureGCHandler
,
offsetof
(
BoxedClosure
,
attrs
),
sizeof
(
BoxedClosure
),
false
);
sizeof
(
BoxedClosure
),
false
);
property_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
propertyGCHandler
,
0
,
sizeof
(
BoxedProperty
),
false
);
property_cls
=
new
Boxed
Heap
Class
(
type_cls
,
object_cls
,
&
propertyGCHandler
,
0
,
sizeof
(
BoxedProperty
),
false
);
staticmethod_cls
staticmethod_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
staticmethodGCHandler
,
0
,
sizeof
(
BoxedStaticmethod
),
false
);
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
&
staticmethodGCHandler
,
0
,
sizeof
(
BoxedStaticmethod
),
false
);
classmethod_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
classmethodGCHandler
,
0
,
sizeof
(
BoxedClassmethod
),
false
);
classmethod_cls
attrwrapper_cls
=
new
BoxedClass
(
type_cls
,
object_cls
,
&
AttrWrapper
::
gcHandler
,
0
,
sizeof
(
AttrWrapper
),
false
);
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
&
classmethodGCHandler
,
0
,
sizeof
(
BoxedClassmethod
),
false
);
attrwrapper_cls
=
new
BoxedHeapClass
(
type_cls
,
object_cls
,
&
AttrWrapper
::
gcHandler
,
0
,
sizeof
(
AttrWrapper
),
false
);
STR
=
typeFromClass
(
str_cls
);
STR
=
typeFromClass
(
str_cls
);
BOXED_INT
=
typeFromClass
(
int_cls
);
BOXED_INT
=
typeFromClass
(
int_cls
);
...
...
src/runtime/types.h
View file @
d5ba641b
...
@@ -172,6 +172,13 @@ class conservative_unordered_map
...
@@ -172,6 +172,13 @@ class conservative_unordered_map
:
public
std
::
unordered_map
<
K
,
V
,
Hash
,
KeyEqual
,
StlCompatAllocator
<
std
::
pair
<
const
K
,
V
>
>
>
{};
:
public
std
::
unordered_map
<
K
,
V
,
Hash
,
KeyEqual
,
StlCompatAllocator
<
std
::
pair
<
const
K
,
V
>
>
>
{};
class
BoxedClass
:
public
BoxVar
{
class
BoxedClass
:
public
BoxVar
{
public:
typedef
void
(
*
gcvisit_func
)(
GCVisitor
*
,
Box
*
);
protected:
BoxedClass
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
gcvisit_func
gc_visit
,
int
attrs_offset
,
int
instance_size
,
bool
is_user_defined
);
public:
public:
PyTypeObject_BODY
;
PyTypeObject_BODY
;
...
@@ -195,7 +202,6 @@ public:
...
@@ -195,7 +202,6 @@ public:
// Is NULL iff this is object_cls
// Is NULL iff this is object_cls
BoxedClass
*
base
;
BoxedClass
*
base
;
typedef
void
(
*
gcvisit_func
)(
GCVisitor
*
,
Box
*
);
gcvisit_func
gc_visit
;
gcvisit_func
gc_visit
;
// Offset of the HCAttrs object or 0 if there are no hcattrs.
// Offset of the HCAttrs object or 0 if there are no hcattrs.
...
@@ -217,12 +223,21 @@ public:
...
@@ -217,12 +223,21 @@ public:
// will need to update this once we support tp_getattr-style overriding:
// will need to update this once we support tp_getattr-style overriding:
bool
hasGenericGetattr
()
{
return
true
;
}
bool
hasGenericGetattr
()
{
return
true
;
}
BoxedClass
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
gcvisit_func
gc_visit
,
int
attrs_offset
,
int
instance_size
,
bool
is_user_defined
);
void
freeze
();
void
freeze
();
};
};
class
BoxedHeapClass
:
public
BoxedClass
{
public:
PyNumberMethods
as_number
;
PyMappingMethods
as_mapping
;
PySequenceMethods
as_sequence
;
PyBufferProcs
as_buffer
;
PyObject
*
ht_name
,
*
ht_slots
;
BoxedHeapClass
(
BoxedClass
*
metaclass
,
BoxedClass
*
base
,
gcvisit_func
gc_visit
,
int
attrs_offset
,
int
instance_size
,
bool
is_user_defined
);
};
static_assert
(
sizeof
(
pyston
::
Box
)
==
sizeof
(
struct
_object
),
""
);
static_assert
(
sizeof
(
pyston
::
Box
)
==
sizeof
(
struct
_object
),
""
);
static_assert
(
offsetof
(
pyston
::
Box
,
cls
)
==
offsetof
(
struct
_object
,
ob_type
),
""
);
static_assert
(
offsetof
(
pyston
::
Box
,
cls
)
==
offsetof
(
struct
_object
,
ob_type
),
""
);
...
@@ -234,6 +249,13 @@ static_assert(offsetof(pyston::BoxedClass, base) == offsetof(struct _typeobject,
...
@@ -234,6 +249,13 @@ static_assert(offsetof(pyston::BoxedClass, base) == offsetof(struct _typeobject,
static_assert
(
offsetof
(
pyston
::
BoxedClass
,
gc_visit
)
==
offsetof
(
struct
_typeobject
,
_gcvisit_func
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedClass
,
gc_visit
)
==
offsetof
(
struct
_typeobject
,
_gcvisit_func
),
""
);
static_assert
(
sizeof
(
pyston
::
BoxedClass
)
==
sizeof
(
struct
_typeobject
),
""
);
static_assert
(
sizeof
(
pyston
::
BoxedClass
)
==
sizeof
(
struct
_typeobject
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedHeapClass
,
base
)
==
offsetof
(
PyHeapTypeObject
,
ht_type
.
_base
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedHeapClass
,
as_number
)
==
offsetof
(
PyHeapTypeObject
,
as_number
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedHeapClass
,
as_mapping
)
==
offsetof
(
PyHeapTypeObject
,
as_mapping
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedHeapClass
,
as_sequence
)
==
offsetof
(
PyHeapTypeObject
,
as_sequence
),
""
);
static_assert
(
offsetof
(
pyston
::
BoxedHeapClass
,
as_buffer
)
==
offsetof
(
PyHeapTypeObject
,
as_buffer
),
""
);
static_assert
(
sizeof
(
pyston
::
BoxedHeapClass
)
==
sizeof
(
PyHeapTypeObject
),
""
);
class
HiddenClass
:
public
ConservativeGCObject
{
class
HiddenClass
:
public
ConservativeGCObject
{
private:
private:
...
...
test/test_extension/slots_test.c
View file @
d5ba641b
...
@@ -29,7 +29,7 @@ slots_tester_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -29,7 +29,7 @@ slots_tester_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
}
static
PyObject
*
static
PyObject
*
slots_tester_repr
(
slots_tester_object
*
obj
)
slots_tester_
seq_
repr
(
slots_tester_object
*
obj
)
{
{
char
buf
[
80
];
char
buf
[
80
];
snprintf
(
buf
,
sizeof
(
buf
),
"<my custom repr: %d>"
,
obj
->
n
);
snprintf
(
buf
,
sizeof
(
buf
),
"<my custom repr: %d>"
,
obj
->
n
);
...
@@ -37,7 +37,7 @@ slots_tester_repr(slots_tester_object *obj)
...
@@ -37,7 +37,7 @@ slots_tester_repr(slots_tester_object *obj)
}
}
static
PyObject
*
static
PyObject
*
slots_tester_call
(
slots_tester_object
*
obj
,
PyObject
*
args
,
PyObject
*
kw
)
slots_tester_
seq_
call
(
slots_tester_object
*
obj
,
PyObject
*
args
,
PyObject
*
kw
)
{
{
if
(
!
PyArg_ParseTuple
(
args
,
""
))
if
(
!
PyArg_ParseTuple
(
args
,
""
))
return
NULL
;
return
NULL
;
...
@@ -45,11 +45,33 @@ slots_tester_call(slots_tester_object *obj, PyObject *args, PyObject *kw)
...
@@ -45,11 +45,33 @@ slots_tester_call(slots_tester_object *obj, PyObject *args, PyObject *kw)
return
PyInt_FromLong
(
obj
->
n
);
return
PyInt_FromLong
(
obj
->
n
);
}
}
PyDoc_STRVAR
(
slots_tester_doc
,
"slots_tester doc"
);
static
PyObject
*
slots_tester_seq_item
(
slots_tester_object
*
obj
,
Py_ssize_t
i
)
{
if
(
i
<
0
||
i
>=
5
)
{
PyErr_SetString
(
PyExc_IndexError
,
"tuple index out of range"
);
return
NULL
;
}
return
PyInt_FromLong
(
i
+
obj
->
n
);
}
PyDoc_STRVAR
(
slots_tester_seq_doc
,
"slots_tester_seq doc"
);
static
PyTypeObject
slots_tester
=
{
static
PySequenceMethods
slots_tester_seq_as_sequence
=
{
(
lenfunc
)
0
,
(
binaryfunc
)
0
,
/* sq_concat */
(
ssizeargfunc
)
0
,
/* sq_repeat */
(
ssizeargfunc
)
slots_tester_seq_item
,
/* sq_item */
(
ssizessizeargfunc
)
0
,
/* sq_slice */
0
,
/* sq_ass_item */
0
,
/* sq_ass_slice */
(
objobjproc
)
0
,
/* sq_contains */
};
static
PyTypeObject
slots_tester_seq
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"slots_test.slots_tester"
,
/* tp_name */
"slots_test.slots_tester
_seq
"
,
/* tp_name */
sizeof
(
slots_tester_object
),
/* tp_basicsize */
sizeof
(
slots_tester_object
),
/* tp_basicsize */
0
,
/* tp_itemsize */
0
,
/* tp_itemsize */
/* methods */
/* methods */
...
@@ -58,18 +80,83 @@ static PyTypeObject slots_tester = {
...
@@ -58,18 +80,83 @@ static PyTypeObject slots_tester = {
0
,
/* tp_getattr */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_compare */
(
reprfunc
)
slots_tester_repr
,
/* tp_repr */
(
reprfunc
)
slots_tester_
seq_
repr
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
&
slots_tester_seq_as_sequence
,
/* tp_as_sequence */
0
,
/* tp_as_mapping */
0
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_hash */
(
ternaryfunc
)
slots_tester_call
,
/* tp_call */
(
ternaryfunc
)
slots_tester_seq_call
,
/* tp_call */
0
,
/* tp_str */
0
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
,
/* tp_flags */
slots_tester_seq_doc
,
/* tp_doc */
0
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_weaklistoffset */
0
,
/* tp_iter */
0
,
/* tp_iternext */
0
,
/* tp_methods */
0
,
/* tp_members */
0
,
/* tp_getset */
0
,
/* tp_base */
0
,
/* tp_dict */
0
,
/* tp_descr_get */
0
,
/* tp_descr_set */
0
,
/* tp_dictoffset */
0
,
/* tp_init */
0
,
/* tp_alloc */
slots_tester_new
,
/* tp_new */
0
,
/* tp_free */
};
static
Py_ssize_t
slots_tester_map_length
(
slots_tester_object
*
obj
)
{
return
obj
->
n
;
}
static
PyObject
*
slots_tester_map_subscript
(
slots_tester_object
*
obj
,
PyObject
*
key
)
{
int
n2
=
PyInt_AsLong
(
key
);
return
PyInt_FromLong
(
n2
+
obj
->
n
);
}
static
int
slots_tester_map_ass_sub
(
slots_tester_object
*
obj
,
PyObject
*
key
,
PyObject
*
value
)
{
int
n2
=
PyInt_AsLong
(
key
);
printf
(
"Assigning to subscript for object with n=%d, key=%d, set/delete=%d
\n
"
,
obj
->
n
,
n2
,
!!
value
);
return
0
;
}
static
PyMappingMethods
slots_tester_map_asmapping
=
{
(
lenfunc
)
slots_tester_map_length
,
/*mp_length*/
(
binaryfunc
)
slots_tester_map_subscript
,
/*mp_subscript*/
(
objobjargproc
)
slots_tester_map_ass_sub
,
/*mp_ass_subscript*/
};
static
PyTypeObject
slots_tester_map
=
{
PyVarObject_HEAD_INIT
(
NULL
,
0
)
"slots_test.slots_tester_map"
,
/* tp_name */
sizeof
(
slots_tester_object
),
/* tp_basicsize */
0
,
/* tp_itemsize */
/* methods */
0
,
/* tp_dealloc */
0
,
/* tp_print */
0
,
/* tp_getattr */
0
,
/* tp_setattr */
0
,
/* tp_compare */
0
,
/* tp_repr */
0
,
/* tp_as_number */
0
,
/* tp_as_sequence */
&
slots_tester_map_asmapping
,
/* tp_as_mapping */
0
,
/* tp_hash */
0
,
/* tp_call */
0
,
/* tp_str */
0
,
/* tp_str */
0
,
/* tp_getattro */
0
,
/* tp_getattro */
0
,
/* tp_setattro */
0
,
/* tp_setattro */
0
,
/* tp_as_buffer */
0
,
/* tp_as_buffer */
Py_TPFLAGS_DEFAULT
,
/* tp_flags */
Py_TPFLAGS_DEFAULT
,
/* tp_flags */
slots_tester_doc
,
/* tp_doc */
0
,
/* tp_doc */
0
,
/* tp_traverse */
0
,
/* tp_traverse */
0
,
/* tp_clear */
0
,
/* tp_clear */
0
,
/* tp_richcompare */
0
,
/* tp_richcompare */
...
@@ -120,6 +207,44 @@ call_funcs(PyObject* _module, PyObject* args) {
...
@@ -120,6 +207,44 @@ call_funcs(PyObject* _module, PyObject* args) {
printf
(
"tp_call doesnt exist
\n
"
);
printf
(
"tp_call doesnt exist
\n
"
);
}
}
if
(
cls
->
tp_as_mapping
)
{
printf
(
"tp_as_mapping exists
\n
"
);
PyMappingMethods
*
map
=
cls
->
tp_as_mapping
;
if
(
map
->
mp_subscript
)
{
PyObject
*
rtn
=
map
->
mp_subscript
(
obj
,
PyInt_FromLong
(
1
));
printf
(
"mp_subscript exists and returned
\n
"
);
Py_DECREF
(
rtn
);
}
else
{
printf
(
"mp_subscript does not exist
\n
"
);
}
if
(
map
->
mp_length
)
{
Py_ssize_t
rtn
=
map
->
mp_length
(
obj
);
printf
(
"mp_length exists and returned %ld
\n
"
,
rtn
);
}
}
else
{
printf
(
"tp_as_mapping doesnt exist
\n
"
);
}
if
(
cls
->
tp_as_sequence
)
{
printf
(
"tp_as_sequence exists
\n
"
);
PySequenceMethods
*
seq
=
cls
->
tp_as_sequence
;
if
(
seq
->
sq_length
)
{
Py_ssize_t
rtn
=
seq
->
sq_length
(
obj
);
printf
(
"sq_length exists and returned %ld
\n
"
,
rtn
);
}
if
(
seq
->
sq_item
)
{
PyObject
*
rtn
=
cls
->
tp_as_sequence
->
sq_item
(
obj
,
1
);
printf
(
"sq_item exists and returned
\n
"
);
Py_DECREF
(
rtn
);
}
}
else
{
printf
(
"tp_as_sequence doesnt exist
\n
"
);
}
Py_DECREF
(
obj
);
Py_DECREF
(
obj
);
Py_RETURN_NONE
;
Py_RETURN_NONE
;
...
@@ -139,12 +264,17 @@ initslots_test(void)
...
@@ -139,12 +264,17 @@ initslots_test(void)
if
(
m
==
NULL
)
if
(
m
==
NULL
)
return
;
return
;
int
res
=
PyType_Ready
(
&
slots_tester
);
int
res
=
PyType_Ready
(
&
slots_tester_seq
);
if
(
res
<
0
)
return
;
res
=
PyType_Ready
(
&
slots_tester_map
);
if
(
res
<
0
)
if
(
res
<
0
)
return
;
return
;
// Not sure if the result of PyInt_FromLong needs to be decref'd
// Not sure if the result of PyInt_FromLong needs to be decref'd
PyDict_SetItemString
(
slots_tester
.
tp_dict
,
"set_through_tpdict"
,
PyInt_FromLong
(
123
));
PyDict_SetItemString
(
slots_tester
_seq
.
tp_dict
,
"set_through_tpdict"
,
PyInt_FromLong
(
123
));
PyModule_AddObject
(
m
,
"SlotsTester"
,
(
PyObject
*
)
&
slots_tester
);
PyModule_AddObject
(
m
,
"SlotsTesterSeq"
,
(
PyObject
*
)
&
slots_tester_seq
);
PyModule_AddObject
(
m
,
"SlotsTesterMap"
,
(
PyObject
*
)
&
slots_tester_map
);
}
}
test/tests/capi_slots.py
View file @
d5ba641b
import
slots_test
import
slots_test
for
i
in
xrange
(
3
):
for
i
in
xrange
(
3
):
t
=
slots_test
.
SlotsTester
(
i
+
5
)
t
=
slots_test
.
SlotsTester
Seq
(
i
+
5
)
print
t
,
repr
(
t
),
t
()
print
t
,
repr
(
t
),
t
()
,
t
[
2
]
print
slots_test
.
SlotsTester
.
set_through_tpdict
,
slots_test
.
SlotsTester
(
5
).
set_through_tpdict
# print slots_test.SlotsTesterSeq.__doc__
print
slots_test
.
SlotsTesterSeq
.
set_through_tpdict
,
slots_test
.
SlotsTesterSeq
(
5
).
set_through_tpdict
for
i
in
xrange
(
3
):
t
=
slots_test
.
SlotsTesterMap
(
i
+
5
)
print
len
(
t
),
t
[
2
]
t
[
1
]
=
5
del
t
[
2
]
class
C
(
object
):
class
C
(
object
):
def
__repr__
(
self
):
def
__repr__
(
self
):
print
"__repr__()"
print
"__repr__()"
return
"<C object>"
return
"<C object>"
def
__getitem__
(
self
,
idx
):
print
"__getitem__"
,
idx
return
idx
-
5
def
__len__
(
self
):
print
"__len__"
return
3
slots_test
.
call_funcs
(
C
())
slots_test
.
call_funcs
(
C
())
# Test to make sure that updating an existing class also updates the tp_* slots:
# Test to make sure that updating an existing class also updates the tp_* slots:
def
repr2
(
self
):
def
repr2
(
self
):
return
"repr2()"
return
"repr2()"
C
.
repr2
=
repr2
C
.
__repr__
=
repr2
slots_test
.
call_funcs
(
C
())
slots_test
.
call_funcs
(
C
())
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