[pypy-commit] pypy default: add slot definitions for __len__, __setitem__, __delitem__, avoid crash in PyDict_Next
mattip
pypy.commits at gmail.com
Tue May 16 06:54:32 EDT 2017
Author: Matti Picus <matti.picus at gmail.com>
Branch:
Changeset: r91311:fbcdfc92a521
Date: 2017-05-16 13:52 +0300
http://bitbucket.org/pypy/pypy/changeset/fbcdfc92a521/
Log: add slot definitions for __len__, __setitem__, __delitem__, avoid
crash in PyDict_Next
diff --git a/pypy/module/cpyext/dictobject.py b/pypy/module/cpyext/dictobject.py
--- a/pypy/module/cpyext/dictobject.py
+++ b/pypy/module/cpyext/dictobject.py
@@ -257,7 +257,8 @@
if w_dict is None:
return 0
-
+ if not space.isinstance_w(w_dict, space.w_dict):
+ return 0
pos = ppos[0]
py_obj = as_pyobj(space, w_dict)
py_dict = rffi.cast(PyDictObject, py_obj)
@@ -268,6 +269,9 @@
py_dict.c__tmpkeys = create_ref(space, w_keys)
Py_IncRef(space, py_dict.c__tmpkeys)
else:
+ if not py_dict.c__tmpkeys:
+ # pos should have been 0, cannot fail so return 0
+ return 0;
w_keys = from_ref(space, py_dict.c__tmpkeys)
ppos[0] += 1
if pos >= space.len_w(w_keys):
diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py
--- a/pypy/module/cpyext/slotdefs.py
+++ b/pypy/module/cpyext/slotdefs.py
@@ -14,7 +14,7 @@
ssizessizeargfunc, ssizeobjargproc, iternextfunc, initproc, richcmpfunc,
cmpfunc, hashfunc, descrgetfunc, descrsetfunc, objobjproc, objobjargproc,
readbufferproc, getbufferproc, releasebufferproc, ssizessizeobjargproc)
-from pypy.module.cpyext.pyobject import make_ref, decref, as_pyobj
+from pypy.module.cpyext.pyobject import make_ref, decref, as_pyobj, from_ref
from pypy.module.cpyext.pyerrors import PyErr_Occurred
from pypy.module.cpyext.memoryobject import fill_Py_buffer
from pypy.module.cpyext.state import State
@@ -265,7 +265,7 @@
check_num_args(space, w_args, 1)
args_w = space.fixedview(w_args)
index = space.int_w(space.index(args_w[0]))
- null = lltype.nullptr(PyObject.TO)
+ null = rffi.cast(PyObject, 0)
res = generic_cpy_call(space, func_target, w_self, index, null)
if rffi.cast(lltype.Signed, res) == -1:
space.fromcache(State).check_and_raise_exception(always=True)
@@ -294,7 +294,8 @@
func_target = rffi.cast(objobjargproc, func)
check_num_args(space, w_args, 1)
w_key, = space.fixedview(w_args)
- res = generic_cpy_call(space, func_target, w_self, w_key, None)
+ null = rffi.cast(PyObject, 0)
+ res = generic_cpy_call(space, func_target, w_self, w_key, null)
if rffi.cast(lltype.Signed, res) == -1:
space.fromcache(State).check_and_raise_exception(always=True)
return space.w_None
@@ -612,6 +613,8 @@
handled = True
for tp_name, attr in [('tp_hash', '__hash__'),
+ ('tp_as_sequence.c_sq_length', '__len__'),
+ ('tp_as_mapping.c_mp_length', '__len__'),
]:
if name == tp_name:
slot_fn = w_type.getdictvalue(space, attr)
@@ -637,7 +640,8 @@
('tp_as_number.c_nb_xor', '__xor__'),
('tp_as_number.c_nb_or', '__or__'),
('tp_as_sequence.c_sq_concat', '__add__'),
- ('tp_as_sequence.c_sq_inplace_concat', '__iadd__')
+ ('tp_as_sequence.c_sq_inplace_concat', '__iadd__'),
+ ('tp_as_mapping.c_mp_subscript', '__getitem__'),
]:
if name == tp_name:
slot_fn = w_type.getdictvalue(space, attr)
@@ -651,7 +655,7 @@
handled = True
# binary-with-Py_ssize_t-type
- for tp_name, attr in [('tp_as_sequence.c_sq_item', '__getitem'),
+ for tp_name, attr in [('tp_as_sequence.c_sq_item', '__getitem__'),
('tp_as_sequence.c_sq_repeat', '__mul__'),
('tp_as_sequence.c_sq_repeat', '__mul__'),
('tp_as_sequence.c_sq_inplace_repeat', '__imul__'),
@@ -680,7 +684,48 @@
def slot_func(space, w_self, w_arg1, w_arg2):
return space.call_function(slot_fn, w_self, w_arg1, w_arg2)
handled = True
+ # ternary-with-void returning-Py_size_t-type
+ for tp_name, attr in [('tp_as_mapping.c_mp_ass_subscript', '__setitem__'),
+ ]:
+ if name == tp_name:
+ slot_ass = w_type.getdictvalue(space, attr)
+ if slot_ass is None:
+ return
+ slot_del = w_type.getdictvalue(space, '__delitem__')
+ if slot_del is None:
+ return
+ @slot_function([PyObject, PyObject, PyObject], rffi.INT_real, error=-1)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
+ def slot_func(space, w_self, w_arg1, arg2):
+ if arg2:
+ w_arg2 = from_ref(space, rffi.cast(PyObject, arg2))
+ space.call_function(slot_ass, w_self, w_arg1, w_arg2)
+ else:
+ space.call_function(slot_del, w_self, w_arg1)
+ return 0
+ handled = True
+ # ternary-Py_size_t-void returning-Py_size_t-type
+ for tp_name, attr in [('tp_as_sequence.c_sq_ass_item', '__setitem__'),
+ ]:
+ if name == tp_name:
+ slot_ass = w_type.getdictvalue(space, attr)
+ if slot_ass is None:
+ return
+ slot_del = w_type.getdictvalue(space, '__delitem__')
+ if slot_del is None:
+ return
+
+ @slot_function([PyObject, lltype.Signed, PyObject], rffi.INT_real, error=-1)
+ @func_renamer("cpyext_%s_%s" % (name.replace('.', '_'), typedef.name))
+ def slot_func(space, w_self, arg1, arg2):
+ if arg2:
+ w_arg2 = from_ref(space, rffi.cast(PyObject, arg2))
+ space.call_function(slot_ass, w_self, space.newint(arg1), w_arg2)
+ else:
+ space.call_function(slot_del, w_self, space.newint(arg1))
+ return 0
+ handled = True
if handled:
pass
elif name == 'tp_setattro':
More information about the pypy-commit
mailing list