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
6a33d150
Commit
6a33d150
authored
Jul 18, 2016
by
Marius Wachtler
Committed by
GitHub
Jul 18, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1294 from sizeoftank/pr_instance_sqslots_mpslots_issue1197
Add sq_slots & mp_slots to instance (issue #1197)
parents
f71d5b36
0c37fa0f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
232 additions
and
5 deletions
+232
-5
src/runtime/classobj.cpp
src/runtime/classobj.cpp
+220
-5
test/tests/oldstyle_classes.py
test/tests/oldstyle_classes.py
+12
-0
No files found.
src/runtime/classobj.cpp
View file @
6a33d150
...
...
@@ -723,14 +723,107 @@ Box* instanceLen(Box* _inst) {
return
runtimeCall
(
len_func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
}
Box
*
instanceGetitem
(
Box
*
_inst
,
Box
*
key
)
{
// Analoguous to CPython's, used for sq_slots, mp_slots
static
Py_ssize_t
instance_length
(
PyObject
*
self
)
noexcept
{
PyObject
*
func
;
PyObject
*
res
;
Py_ssize_t
outcome
;
static
BoxedString
*
len_str
=
getStaticString
(
"__len__"
);
func
=
instance_getattro
(
self
,
len_str
);
if
(
func
==
NULL
)
return
-
1
;
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
0
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
Py_DECREF
(
func
);
if
(
res
==
NULL
)
return
-
1
;
if
(
PyInt_Check
(
res
))
{
outcome
=
PyInt_AsSsize_t
(
res
);
if
(
outcome
==
-
1
&&
PyErr_Occurred
())
{
Py_DECREF
(
res
);
return
-
1
;
}
#if SIZEOF_SIZE_T < SIZEOF_INT
/* Overflow check -- range of PyInt is more than C int */
if
(
outcome
!=
(
int
)
outcome
)
{
PyErr_SetString
(
PyExc_OverflowError
,
"__len__() should return 0 <= outcome < 2**31"
);
outcome
=
-
1
;
}
else
#endif
if
(
outcome
<
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"__len__() should return >= 0"
);
outcome
=
-
1
;
}
}
else
{
PyErr_SetString
(
PyExc_TypeError
,
"__len__() should return an int"
);
outcome
=
-
1
;
}
Py_DECREF
(
res
);
return
outcome
;
}
// Analoguous to CPython's, used for mp_slots.
static
int
instance_ass_sub
(
Box
*
inst
,
Box
*
key
,
Box
*
value
)
noexcept
{
Box
*
func
;
Box
*
res
;
static
BoxedString
*
setitem_str
=
getStaticString
(
"__setitem__"
);
static
BoxedString
*
delitem_str
=
getStaticString
(
"__delitem__"
);
if
(
value
==
NULL
)
{
func
=
instance_getattro
(
inst
,
delitem_str
);
}
else
{
func
=
instance_getattro
(
inst
,
setitem_str
);
}
if
(
func
==
NULL
)
{
return
-
1
;
}
if
(
value
==
NULL
)
{
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
1
),
key
,
NULL
,
NULL
,
NULL
,
NULL
);
}
else
{
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
2
),
key
,
value
,
NULL
,
NULL
,
NULL
);
}
Py_DECREF
(
func
);
if
(
res
==
NULL
)
return
-
1
;
Py_DECREF
(
res
);
return
0
;
}
template
<
enum
ExceptionStyle
S
>
Box
*
instanceGetitem
(
Box
*
_inst
,
Box
*
key
)
noexcept
(
S
==
CAPI
)
{
RELEASE_ASSERT
(
_inst
->
cls
==
instance_cls
,
""
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
static
BoxedString
*
getitem_str
=
getStaticString
(
"__getitem__"
);
Box
*
getitem_func
=
_instanceGetattribute
(
inst
,
getitem_str
,
true
);
Box
*
getitem_func
;
if
(
S
==
CAPI
)
{
getitem_func
=
instance_getattro
(
inst
,
getitem_str
);
if
(
getitem_func
==
NULL
)
{
return
NULL
;
}
}
else
{
getitem_func
=
_instanceGetattribute
(
inst
,
getitem_str
,
true
);
}
AUTO_DECREF
(
getitem_func
);
return
runtimeCall
(
getitem_func
,
ArgPassSpec
(
1
),
key
,
NULL
,
NULL
,
NULL
,
NULL
);
return
runtimeCallInternal
<
S
,
NOT_REWRITABLE
>
(
getitem_func
,
NULL
,
ArgPassSpec
(
1
),
key
,
NULL
,
NULL
,
NULL
,
NULL
);
}
Box
*
instance_item
(
Box
*
self
,
Py_ssize_t
i
)
noexcept
{
return
instanceGetitem
<
CAPI
>
(
self
,
autoDecref
(
boxInt
(
i
)));
}
Box
*
instanceSetitem
(
Box
*
_inst
,
Box
*
key
,
Box
*
value
)
{
...
...
@@ -743,6 +836,40 @@ Box* instanceSetitem(Box* _inst, Box* key, Box* value) {
return
runtimeCall
(
setitem_func
,
ArgPassSpec
(
2
),
key
,
value
,
NULL
,
NULL
,
NULL
);
}
static
int
instance_ass_item
(
Box
*
inst
,
Py_ssize_t
k
,
PyObject
*
item
)
noexcept
{
static
BoxedString
*
delitem_str
,
*
setitem_str
;
Box
*
func
=
NULL
,
*
res
=
NULL
;
Box
*
key
=
boxInt
(
k
);
AUTO_DECREF
(
key
);
if
(
item
==
NULL
)
{
delitem_str
=
getStaticString
(
"__delitem__"
);
func
=
instance_getattro
(
inst
,
delitem_str
);
if
(
func
==
NULL
)
return
-
1
;
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
1
),
key
,
NULL
,
NULL
,
NULL
,
NULL
);
}
else
{
setitem_str
=
getStaticString
(
"__setitem__"
);
func
=
instance_getattro
(
inst
,
setitem_str
);
if
(
func
==
NULL
)
return
-
1
;
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
2
),
key
,
(
Box
*
)
item
,
NULL
,
NULL
,
NULL
);
}
Py_DECREF
(
func
);
if
(
res
==
NULL
)
return
-
1
;
Py_DECREF
(
res
);
return
0
;
}
Box
*
instanceDelitem
(
Box
*
_inst
,
Box
*
key
)
{
RELEASE_ASSERT
(
_inst
->
cls
==
instance_cls
,
""
);
BoxedInstance
*
inst
=
static_cast
<
BoxedInstance
*>
(
_inst
);
...
...
@@ -771,7 +898,7 @@ Box* instanceGetslice(Box* _inst, Box* i, Box* j) {
if
(
getslice_func
==
NULL
)
{
Box
*
slice
=
static_cast
<
Box
*>
(
createSlice
(
i
,
j
,
None
));
AUTO_DECREF
(
slice
);
return
instanceGetitem
(
inst
,
slice
);
return
instanceGetitem
<
CXX
>
(
inst
,
slice
);
}
AUTO_DECREF
(
getslice_func
);
return
runtimeCall
(
getslice_func
,
ArgPassSpec
(
2
),
i
,
j
,
NULL
,
NULL
,
NULL
);
...
...
@@ -840,6 +967,74 @@ Box* instanceDelslice(Box* _inst, Box* i, Box* j) {
}
}
// Analoguous to CPython's, used for sq_slots.
static
int
instance_ass_slice
(
Box
*
inst
,
Py_ssize_t
i
,
Py_ssize_t
j
,
PyObject
*
value
)
{
static
BoxedString
*
delslice_str
,
*
setslice_str
,
*
delitem_str
,
*
setitem_str
;
Box
*
func
=
NULL
,
*
res
=
NULL
;
Box
*
slice
=
NULL
;
Box
*
begin
=
boxInt
(
i
);
Box
*
end
=
boxInt
(
j
);
AUTO_DECREF
(
begin
);
AUTO_DECREF
(
end
);
if
(
value
==
NULL
)
{
delslice_str
=
getStaticString
(
"__delslice__"
);
func
=
instance_getattro
(
inst
,
delslice_str
);
if
(
func
==
NULL
)
{
if
(
!
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
return
-
1
;
PyErr_Clear
();
delitem_str
=
getStaticString
(
"__delitem__"
);
func
=
instance_getattro
(
inst
,
delitem_str
);
if
(
func
==
NULL
)
return
-
1
;
slice
=
static_cast
<
Box
*>
(
createSlice
(
begin
,
end
,
None
));
AUTO_DECREF
(
slice
);
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
1
),
slice
,
NULL
,
NULL
,
NULL
,
NULL
);
}
else
{
if
(
PyErr_WarnPy3k
(
"in 3.x, __delslice__ has been removed; use __delitem__"
,
1
)
<
0
)
{
Py_DECREF
(
func
);
return
-
1
;
}
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
2
),
begin
,
end
,
NULL
,
NULL
,
NULL
);
}
}
else
{
setslice_str
=
getStaticString
(
"__setslice__"
);
func
=
instance_getattro
(
inst
,
setslice_str
);
if
(
func
==
NULL
)
{
if
(
!
PyErr_ExceptionMatches
(
PyExc_AttributeError
))
return
-
1
;
PyErr_Clear
();
setitem_str
=
getStaticString
(
"__setitem__"
);
func
=
instance_getattro
(
inst
,
setitem_str
);
if
(
func
==
NULL
)
return
-
1
;
slice
=
static_cast
<
Box
*>
(
createSlice
(
begin
,
end
,
None
));
AUTO_DECREF
(
slice
);
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
2
),
slice
,
(
Box
*
)
value
,
NULL
,
NULL
,
NULL
);
}
else
{
if
(
PyErr_WarnPy3k
(
"in 3.x, __setslice__ has been removed; use __setitem__"
,
1
)
<
0
)
{
Py_DECREF
(
func
);
return
-
1
;
}
res
=
runtimeCallCapi
(
func
,
ArgPassSpec
(
3
),
begin
,
end
,
(
Box
*
)
value
,
NULL
,
NULL
);
}
}
Py_DECREF
(
func
);
if
(
res
==
NULL
)
return
-
1
;
Py_DECREF
(
res
);
return
0
;
}
/* Try a 3-way comparison, returning an int; v is an instance. Return:
-2 for an exception;
-1 if v < w;
...
...
@@ -997,6 +1192,17 @@ Box* instanceContains(Box* _inst, Box* key) {
return
boxBool
(
nonzero
(
r
));
}
static
int
instance_contains
(
Box
*
inst
,
Box
*
key
)
noexcept
{
try
{
Box
*
res
=
instanceContains
(
inst
,
key
);
AUTO_DECREF
(
res
);
return
nonzero
(
res
);
}
catch
(
ExcInfo
e
)
{
setCAPIException
(
e
);
return
-
1
;
}
}
static
Box
*
instanceHash
(
BoxedInstance
*
inst
)
{
assert
(
inst
->
cls
==
instance_cls
);
...
...
@@ -1911,7 +2117,7 @@ void setupClassobj() {
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
instanceNonzero
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__len__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
instanceLen
,
UNKNOWN
,
1
)));
instance_cls
->
giveAttr
(
"__getitem__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
instanceGetitem
,
UNKNOWN
,
2
)));
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
instanceGetitem
<
CXX
>
,
UNKNOWN
,
2
)));
instance_cls
->
giveAttr
(
"__setitem__"
,
new
BoxedFunction
(
FunctionMetadata
::
create
((
void
*
)
instanceSetitem
,
UNKNOWN
,
3
)));
instance_cls
->
giveAttr
(
"__delitem__"
,
...
...
@@ -2014,6 +2220,15 @@ void setupClassobj() {
instance_cls
->
tp_as_number
->
nb_index
=
instance_index
;
instance_cls
->
tp_as_number
->
nb_power
=
instance_pow
;
instance_cls
->
tp_as_number
->
nb_inplace_power
=
instance_ipow
;
instance_cls
->
tp_as_sequence
->
sq_item
=
(
ssizeargfunc
)
instance_item
;
instance_cls
->
tp_as_sequence
->
sq_slice
=
instance_slice
;
instance_cls
->
tp_as_sequence
->
sq_ass_item
=
(
ssizeobjargproc
)
instance_ass_item
;
instance_cls
->
tp_as_sequence
->
sq_ass_slice
=
(
ssizessizeobjargproc
)
instance_ass_slice
;
instance_cls
->
tp_as_sequence
->
sq_length
=
(
lenfunc
)
instance_length
;
instance_cls
->
tp_as_sequence
->
sq_contains
=
(
objobjproc
)
instance_contains
;
instance_cls
->
tp_as_mapping
->
mp_length
=
(
lenfunc
)
instance_length
;
instance_cls
->
tp_as_mapping
->
mp_subscript
=
(
binaryfunc
)
instanceGetitem
<
CAPI
>
;
instance_cls
->
tp_as_mapping
->
mp_ass_subscript
=
(
objobjargproc
)
instance_ass_sub
;
}
}
test/tests/oldstyle_classes.py
View file @
6a33d150
...
...
@@ -461,8 +461,20 @@ class SeqTest:
def
__iter__
(
self
):
print
"iter"
return
SeqTest
.
Iterator
()
def
__setitem__
(
self
,
k
,
v
):
print
"setitem"
def
__getitem__
(
self
,
k
):
print
"getitem"
m
=
SeqTest
()
print
list
(
m
)
m
[
1
]
=
1
m
[
1
:
2
]
=
2
print
m
[
1
]
print
1
in
m
print
1
not
in
m
class
OldSeqTest
:
def
__getitem__
(
self
,
n
):
...
...
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