Author: Wim Lavrijsen <wlavrij...@lbl.gov>
Branch: reflex-support
Changeset: r56019:881244349a73
Date: 2012-07-09 14:36 -0700
http://bitbucket.org/pypy/pypy/changeset/881244349a73/

Log:    o) first attempt at getting __setitem__ right o) more doc/comment
        strings

diff --git a/pypy/module/cppyy/executor.py b/pypy/module/cppyy/executor.py
--- a/pypy/module/cppyy/executor.py
+++ b/pypy/module/cppyy/executor.py
@@ -202,6 +202,32 @@
         result = libffifunc.call(argchain, rffi.INTP)
         return space.wrap(result[0])
 
+class IntRefExecutor(FunctionExecutor):
+    _immutable_ = True
+    libffitype = libffi.types.pointer
+
+    def __init__(self, space, extra):
+        FunctionExecutor.__init__(self, space, extra)
+        self.do_assign = False
+        self.item = rffi.cast(rffi.INT, 0)
+
+    def set_item(self, space, w_item):
+        self.item = rffi.cast(rffi.INT, space.c_int_w(w_item))
+        self.do_assign = True
+
+    def _wrap_result(self, space, intptr):
+        if self.do_assign:
+            intptr[0] = self.item
+        return space.wrap(intptr[0])    # all paths, for rtyper
+
+    def execute(self, space, cppmethod, cppthis, num_args, args):
+        result = rffi.cast(rffi.INTP, capi.c_call_r(cppmethod, cppthis, 
num_args, args))
+        return self._wrap_result(space, result)
+
+    def execute_libffi(self, space, libffifunc, argchain):
+        result = libffifunc.call(argchain, rffi.INTP)
+        return self._wrap_result(space, result)
+
 class ConstLongRefExecutor(ConstIntRefExecutor):
     _immutable_ = True
     libffitype = libffi.types.pointer
@@ -412,7 +438,7 @@
 _executors["unsigned short"]      = ShortExecutor
 _executors["int"]                 = IntExecutor
 _executors["const int&"]          = ConstIntRefExecutor
-_executors["int&"]                = ConstIntRefExecutor
+_executors["int&"]                = IntRefExecutor
 _executors["unsigned"]            = UnsignedIntExecutor
 _executors["long"]                = LongExecutor
 _executors["unsigned long"]       = UnsignedLongExecutor
diff --git a/pypy/module/cppyy/interp_cppyy.py 
b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -109,7 +109,10 @@
 
 
 class CPPMethod(object):
-    """ A concrete function after overloading has been resolved """
+    """Dispatcher of methods. Checks the arguments, find the corresponding FFI
+    function if available, makes the call, and returns the wrapped result. It
+    also takes care of offset casting and recycling of known objects through
+    the memory_regulator."""
     _immutable_ = True
     
     def __init__(self, space, containing_scope, method_index, arg_defs, 
args_required):
@@ -255,6 +258,9 @@
 
 
 class CPPFunction(CPPMethod):
+    """Global (namespaced) function dispatcher. For now, the base class has
+    all the needed functionality, by allowing the C++ this pointer to be null
+    in the call. An optimization is expected there, however."""
     _immutable_ = True
 
     def __repr__(self):
@@ -262,6 +268,9 @@
 
 
 class CPPConstructor(CPPMethod):
+    """Method dispatcher that constructs new objects. In addition to the call,
+    it allocates memory for the newly constructed object and sets ownership
+    to Python."""
     _immutable_ = True
 
     def call(self, cppthis, args_w):
@@ -279,7 +288,27 @@
         return "CPPConstructor: %s" % self.signature()
 
 
+class CPPSetItem(CPPMethod):
+    """Method dispatcher specific to Python's __setitem__ mapped onto C++'s
+    operator[](int). The former function takes an extra argument to assign to
+    the return type of the latter."""
+    _immutable_ = True
+
+    def call(self, cppthis, args_w):
+        end = len(args_w)-1
+        if 0 <= end:
+            w_item = args_w[end]
+            args_w = args_w[:end]
+            if self.converters is None:
+                self._setup(cppthis)
+            self.executor.set_item(self.space, w_item) # TODO: what about 
threads?
+        CPPMethod.call(self, cppthis, args_w)
+
+
 class W_CPPOverload(Wrappable):
+    """Dispatcher that is actually available at the app-level: it is a
+    collection of (possibly) overloaded methods or functions. It calls these
+    in order and deals with error handling and reporting."""
     _immutable_ = True
 
     def __init__(self, space, containing_scope, functions):
@@ -429,7 +458,7 @@
                 capi.c_method_name(self, idx),
                 capi.c_method_num_args(self, idx),
                 capi.c_method_result_type(self, idx))
-            cppmethod = self._make_cppfunction(idx)
+            cppmethod = self._make_cppfunction(pyname, idx)
             methods_temp.setdefault(pyname, []).append(cppmethod)
         for pyname, methods in methods_temp.iteritems():
             overload = W_CPPOverload(self.space, self, methods[:])
@@ -487,7 +516,7 @@
     _immutable_ = True
     kind = "namespace"
 
-    def _make_cppfunction(self, index):
+    def _make_cppfunction(self, pyname, index):
         num_args = capi.c_method_num_args(self, index)
         args_required = capi.c_method_req_args(self, index)
         arg_defs = []
@@ -518,7 +547,7 @@
         meth_idx = capi.c_method_index_from_name(self, meth_name)
         if meth_idx == -1:
             raise self.missing_attribute_error(meth_name)
-        cppfunction = self._make_cppfunction(meth_idx)
+        cppfunction = self._make_cppfunction(meth_name, meth_idx)
         overload = W_CPPOverload(self.space, self, [cppfunction])
         return overload
 
@@ -569,7 +598,7 @@
     _immutable_ = True
     kind = "class"
 
-    def _make_cppfunction(self, index):
+    def _make_cppfunction(self, pyname, index):
         num_args = capi.c_method_num_args(self, index)
         args_required = capi.c_method_req_args(self, index)
         arg_defs = []
@@ -581,6 +610,8 @@
             cls = CPPConstructor
         elif capi.c_is_staticmethod(self, index):
             cls = CPPFunction
+        elif pyname == "__setitem__":
+            cls = CPPSetItem
         else:
             cls = CPPMethod
         return cls(self.space, self, index, arg_defs, args_required)
@@ -718,7 +749,7 @@
         meth_idx = capi.c_get_global_operator(self.cppclass, other.cppclass, 
"==")
         if meth_idx != -1:
             gbl = scope_byname(self.space, "")
-            f = gbl._make_cppfunction(meth_idx)
+            f = gbl._make_cppfunction("operator==", meth_idx)
             ol = W_CPPOverload(self.space, scope_byname(self.space, ""), [f])
             # TODO: cache this operator (currently cached by JIT in 
capi/__init__.py)
             return ol.call(self, [self, w_other])
diff --git a/pypy/module/cppyy/test/test_stltypes.py 
b/pypy/module/cppyy/test/test_stltypes.py
--- a/pypy/module/cppyy/test/test_stltypes.py
+++ b/pypy/module/cppyy/test/test_stltypes.py
@@ -51,9 +51,9 @@
 
         #-----
         for i in range(self.N):
-          #  v[i] = i
-          #  assert v[i] == i
-          #  assert v.at(i) == i
+            v[i] = i
+            assert v[i] == i
+            assert v.at(i) == i
             pass
 
         assert v.size() == self.N
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to