[pypy-commit] pypy cpyext-gc-support-2: port some dict logic from cpyext-gc-support
arigo
pypy.commits at gmail.com
Sun Feb 14 05:42:46 EST 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support-2
Changeset: r82234:439d7f2b1660
Date: 2016-02-14 11:40 +0100
http://bitbucket.org/pypy/pypy/changeset/439d7f2b1660/
Log: port some dict logic from cpyext-gc-support
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
@@ -2,7 +2,7 @@
from pypy.module.cpyext.api import (
cpython_api, CANNOT_FAIL, build_type_checkers, Py_ssize_t,
Py_ssize_tP, CONST_STRING)
-from pypy.module.cpyext.pyobject import PyObject, PyObjectP, borrow_from
+from pypy.module.cpyext.pyobject import PyObject, PyObjectP, as_pyobj
from pypy.module.cpyext.pyobject import RefcountState
from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
from pypy.interpreter.error import OperationError
@@ -50,7 +50,8 @@
else:
PyErr_BadInternalCall(space)
- at cpython_api([PyObject, CONST_STRING], PyObject, error=CANNOT_FAIL)
+ at cpython_api([PyObject, CONST_STRING], PyObject, error=CANNOT_FAIL,
+ result_borrowed=True)
def PyDict_GetItemString(space, w_dict, key):
"""This is the same as PyDict_GetItem(), but key is specified as a
char*, rather than a PyObject*."""
@@ -58,9 +59,10 @@
w_res = space.finditem_str(w_dict, rffi.charp2str(key))
except:
w_res = None
- if w_res is None:
- return None
- return borrow_from(w_dict, w_res)
+ # NOTE: this works so far because all our dict strategies store
+ # *values* as full objects, which stay alive as long as the dict is
+ # alive and not modified.
+ return w_res
@cpython_api([PyObject, CONST_STRING], rffi.INT_real, error=-1)
def PyDict_DelItemString(space, w_dict, key_ptr):
@@ -173,10 +175,13 @@
if w_dict is None:
return 0
- # Note: this is not efficient. Storing an iterator would probably
+ # XXX XXX PyDict_Next is not efficient. Storing an iterator would probably
# work, but we can't work out how to not leak it if iteration does
- # not complete.
+ # not complete. Alternatively, we could add some RPython-only
+ # dict-iterator method to move forward by N steps.
+ w_dict.ensure_object_strategy() # make sure both keys and values can
+ # be borrwed
try:
w_iter = space.call_method(space.w_dict, "iteritems", w_dict)
pos = ppos[0]
@@ -186,11 +191,10 @@
w_item = space.call_method(w_iter, "next")
w_key, w_value = space.fixedview(w_item, 2)
- state = space.fromcache(RefcountState)
if pkey:
- pkey[0] = state.make_borrowed(w_dict, w_key)
+ pkey[0] = as_pyobj(space, w_key)
if pvalue:
- pvalue[0] = state.make_borrowed(w_dict, w_value)
+ pvalue[0] = as_pyobj(space, w_value)
ppos[0] += 1
except OperationError, e:
if not e.match(space, space.w_StopIteration):
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -350,6 +350,12 @@
F: D[k] = F[k]"""
init_or_update(space, self, __args__, 'dict.update')
+ def ensure_object_strategy(self): # for cpyext
+ object_strategy = self.space.fromcache(ObjectDictStrategy)
+ strategy = self.get_strategy()
+ if strategy is not object_strategy:
+ strategy.switch_to_object_strategy(self)
+
class W_DictObject(W_DictMultiObject):
""" a regular dict object """
More information about the pypy-commit
mailing list