[pypy-commit] pypy ffi-backend: Elide the W_Field lookup on getattr and setattr.

arigo noreply at buildbot.pypy.org
Wed Aug 1 17:13:16 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56523:0fe7a645a58f
Date: 2012-08-01 17:05 +0200
http://bitbucket.org/pypy/pypy/changeset/0fe7a645a58f/

Log:	Elide the W_Field lookup on getattr and setattr.

diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -168,21 +168,7 @@
         return self._add_or_sub(w_other, -1)
 
     def getcfield(self, w_attr):
-        from pypy.module._cffi_backend import ctypeptr, ctypestruct
-        space = self.space
-        ctype = self.ctype
-        attr = space.str_w(w_attr)
-        if isinstance(ctype, ctypeptr.W_CTypePointer):
-            ctype = ctype.ctitem
-        if (isinstance(ctype, ctypestruct.W_CTypeStructOrUnion) and
-                ctype.fields_dict is not None):
-            try:
-                return ctype.fields_dict[attr]
-            except KeyError:
-                pass
-        raise operationerrfmt(space.w_AttributeError,
-                              "cdata '%s' has no attribute '%s'",
-                              ctype.name, attr)
+        return self.ctype.getcfield(self.space.str_w(w_attr))
 
     def getattr(self, w_attr):
         w_res = self.getcfield(w_attr).read(self._cdata)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -156,6 +156,12 @@
     def get_vararg_type(self):
         return self
 
+    def getcfield(self, attr):
+        space = self.space
+        raise operationerrfmt(space.w_AttributeError,
+                              "cdata '%s' has no attribute '%s'",
+                              self.name, attr)
+
 
 W_CType.typedef = TypeDef(
     'CTypeDescr',
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -263,3 +263,6 @@
             set_mustfree_flag(cdata, False)
             self.convert_from_object(cdata, w_ob)
             return False
+
+    def getcfield(self, attr):
+        return self.ctitem.getcfield(attr)
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -8,6 +8,7 @@
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib.rarithmetic import r_ulonglong, r_longlong, intmask
+from pypy.rlib import jit
 
 from pypy.module._cffi_backend.ctypeobj import W_CType
 from pypy.module._cffi_backend import cdataobj, ctypeprim, misc
@@ -115,6 +116,18 @@
             raise self._convert_error("list or tuple or dict or struct-cdata",
                                       w_ob)
 
+    @jit.elidable_promote()
+    def _getcfield_const(self, attr):
+        return self.fields_dict[attr]
+
+    def getcfield(self, attr):
+        if self.fields_dict is not None:
+            try:
+                return self._getcfield_const(attr)
+            except KeyError:
+                pass
+        return W_CType.getcfield(self, attr)
+
 
 class W_CTypeStruct(W_CTypeStructOrUnion):
     kind = "struct"


More information about the pypy-commit mailing list