[pypy-svn] r75998 - in pypy/branch/reflex-support/pypy/module/cppyy: . include src test
wlav at codespeak.net
wlav at codespeak.net
Wed Jul 7 20:04:05 CEST 2010
Author: wlav
Date: Wed Jul 7 20:04:02 2010
New Revision: 75998
Modified:
pypy/branch/reflex-support/pypy/module/cppyy/capi.py
pypy/branch/reflex-support/pypy/module/cppyy/converter.py
pypy/branch/reflex-support/pypy/module/cppyy/executor.py
pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h
pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx
pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx
pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py
Log:
Support calls for double and char* on instances.
Modified: pypy/branch/reflex-support/pypy/module/cppyy/capi.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/capi.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/capi.py Wed Jul 7 20:04:02 2010
@@ -31,20 +31,20 @@
"callstatic_l",
[rffi.VOIDP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.LONG,
compilation_info=eci)
-c_callstatic_d = rffi.llexternal(
- "callstatic_d",
- [rffi.VOIDP, rffi.INT, rffi.INT, rffi.VOIDPP], rffi.DOUBLE,
- compilation_info=eci)
-c_construct = rffi.llexternal(
- "construct",
+c_cppyy_construct = rffi.llexternal(
+ "cppyy_construct",
[rffi.VOIDP, rffi.INT, rffi.VOIDPP], rffi.VOIDP,
compilation_info=eci)
c_cppyy_call_l = rffi.llexternal(
"cppyy_call_l",
[rffi.VOIDP, rffi.INT, rffi.VOIDP, rffi.INT, rffi.VOIDPP], rffi.LONG,
compilation_info=eci)
-c_destruct = rffi.llexternal(
- "destruct",
+c_cppyy_call_d = rffi.llexternal(
+ "cppyy_call_d",
+ [rffi.VOIDP, rffi.INT, rffi.VOIDP, rffi.INT, rffi.VOIDPP], rffi.DOUBLE,
+ compilation_info=eci)
+c_cppyy_destruct = rffi.llexternal(
+ "cppyy_destruct",
[rffi.VOIDP, rffi.VOIDP], lltype.Void,
compilation_info=eci)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/converter.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/converter.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/converter.py Wed Jul 7 20:04:02 2010
@@ -12,7 +12,7 @@
class IntConverter(TypeConverter):
def convert_argument(self, space, w_obj):
- arg = space.int_w(w_obj)
+ arg = space.c_int_w(w_obj)
x = lltype.malloc(rffi.LONGP.TO, 1, flavor='raw')
x[0] = arg
return rffi.cast(rffi.VOIDP, x)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/executor.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/executor.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/executor.py Wed Jul 7 20:04:02 2010
@@ -17,18 +17,12 @@
class DoubleExecutor(FunctionExecutor):
def execute(self, space, func, cppthis, num_args, args):
- if cppthis is not None:
- raise NotImplementedError
- else:
- result = capi.c_callstatic_d(func.cpptype.handle, func.method_index, num_args, args)
+ result = capi.c_cppyy_call_d(func.cpptype.handle, func.method_index, cppthis, num_args, args)
return space.wrap(result)
class CStringExecutor(FunctionExecutor):
def execute(self, space, func, cppthis, num_args, args):
- if cppthis is not None:
- raise NotImplementedError
- else:
- lresult = capi.c_cppyy_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
+ lresult = capi.c_cppyy_call_l(func.cpptype.handle, func.method_index, cppthis, num_args, args)
ccpresult = rffi.cast(rffi.CCHARP, lresult)
result = capi.charp2str_free(ccpresult)
return space.wrap(result)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/include/reflexcwrapper.h Wed Jul 7 20:04:02 2010
@@ -7,10 +7,10 @@
#endif // ifdef __cplusplus
void* cppyy_get_typehandle(const char* class_name);
- double callstatic_d(void* handle, int method_index, int numargs, void* args[]);
+ void* cppyy_construct(void* handle, int numargs, void* args[]);
long cppyy_call_l(void* handle, int method_index, void* self, int numargs, void* args[]);
- void* construct(void* handle, int numargs, void* args[]);
- void destruct(void* handle, void* self);
+ double cppyy_call_d(void* handle, int method_index, void* self, int numargs, void* args[]);
+ void cppyy_destruct(void* handle, void* self);
int num_methods(void* handle);
char* method_name(void* handle, int method_index);
Modified: pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/interp_cppyy.py Wed Jul 7 20:04:02 2010
@@ -113,7 +113,7 @@
def call(self, cppthis, args_w):
assert not cppthis
args = self.prepare_arguments(args_w)
- result = capi.c_construct(self.cpptype.handle, len(args_w), args)
+ result = capi.c_cppyy_construct(self.cpptype.handle, len(args_w), args)
self.free_arguments(args)
return W_CPPObject(self.cpptype, result)
@@ -208,13 +208,19 @@
self.cppclass = cppclass
self.rawobject = rawobject
+ def _nullcheck(self):
+ if not self.rawobject:
+ raise OperationError(self.space.w_ReferenceError, self.space.wrap("trying to access a NULL pointer"))
+
def invoke(self, method_name, args_w):
+ self._nullcheck()
cppclass = jit.hint(self.cppclass, promote=True)
overload = cppclass.get_overload(method_name)
return overload.call(self.rawobject, args_w)
def destruct(self):
- capi.c_destruct(self.cppclass.handle, self.rawobject)
+ capi.c_cppyy_destruct(self.cppclass.handle, self.rawobject)
+ self.rawobject = NULL_VOIDP
W_CPPObject.typedef = TypeDef(
'CPPObject',
Modified: pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx Wed Jul 7 20:04:02 2010
@@ -8,13 +8,18 @@
return Reflex::Type::ByName(class_name).Id();
}
-double callstatic_d(void* handle, int method_index, int numargs, void* args[]) {
- double result;
+
+void* cppyy_construct(void* handle, int numargs, void* args[]) {
std::vector<void*> arguments(args, args+numargs);
Reflex::Type t((Reflex::TypeName*)handle);
- Reflex::Member m = t.FunctionMemberAt(method_index);
- m.Invoke(result, arguments);
- return result;
+ std::vector<Reflex::Type> argtypes;
+ argtypes.reserve(numargs);
+ for (int i = 0; i < numargs; i++) {
+ argtypes.push_back(Reflex::Type::ByName("int"));
+ }
+ Reflex::Type constructor_type = Reflex::FunctionTypeBuilder(
+ Reflex::Type::ByName("void"), argtypes);
+ return t.Construct(constructor_type, arguments).Address();
}
long cppyy_call_l(void* handle, int method_index,
@@ -32,20 +37,22 @@
return result;
}
-void* construct(void* handle, int numargs, void* args[]) {
+double cppyy_call_d(void* handle, int method_index,
+ void* self, int numargs, void* args[]) {
+ double result;
std::vector<void*> arguments(args, args+numargs);
Reflex::Type t((Reflex::TypeName*)handle);
- std::vector<Reflex::Type> argtypes;
- argtypes.reserve(numargs);
- for (int i = 0; i < numargs; i++) {
- argtypes.push_back(Reflex::Type::ByName("int"));
+ Reflex::Member m = t.FunctionMemberAt(method_index);
+ if (self) {
+ Reflex::Object o(t, self);
+ m.Invoke(o, result, arguments);
+ } else {
+ m.Invoke(result, arguments);
}
- Reflex::Type constructor_type = Reflex::FunctionTypeBuilder(
- Reflex::Type::ByName("void"), argtypes);
- return t.Construct(constructor_type, arguments).Address();
-}
+ return result;
+}
-void destruct(void* handle, void* self) {
+void cppyy_destruct(void* handle, void* self) {
Reflex::Type t((Reflex::TypeName*)handle);
t.Destruct(self, true);
}
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/example01.cxx Wed Jul 7 20:04:02 2010
@@ -1,4 +1,6 @@
#include <iostream>
+#include <sstream>
+#include <string>
#include <stdlib.h>
#include <string.h>
@@ -28,31 +30,53 @@
count--;
}
- static int add1(int a) {
+// class methods
+ static int staticAddOneToInt(int a) {
return a + 1;
}
- static int add1(int a, int b) {
+ static int staticAddOneToInt(int a, int b) {
return a + b + 1;
}
- static double adddouble(double a) {
+ static double staticAddToDouble(double a) {
return a + 0.01;
}
- static int atoi(const char* str) {
+ static int staticAtoi(const char* str) {
return ::atoi(str);
}
- static char* strcpy(const char* strin) {
+ static char* staticStrcpy(const char* strin) {
char* strout = (char*)malloc(::strlen(strin + 1));
::strcpy(strout, strin);
return strout;
}
- static int getcount() {
+ static int getCount() {
std::cout << "getcount called" << std::endl;
return count;
}
- int add(int a) {
+
+// instance methods
+ int addDataToInt(int a) {
+ return somedata + a;
+ }
+
+ double addDataToDouble(double a) {
return somedata + a;
}
+
+ int addDataToAtoi(const char* str) {
+ return ::atoi(str) + somedata;
+ }
+
+ char* addToStringValue(const char* str) {
+ int out = ::atoi(str) + somedata;
+ std::ostringstream ss;
+ ss << out << std::ends;
+ std::string result = ss.str();
+ char* cresult = (char*)malloc(result.size()+1);
+ ::strcpy(cresult, result.c_str());
+ return cresult;
+ }
+
};
int example01::count = 0;
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py Wed Jul 7 20:04:02 2010
@@ -1,5 +1,4 @@
-import py
-import os
+import py, os
from pypy.conftest import gettestobjspace
from pypy.module.cppyy import interp_cppyy, executor
@@ -16,7 +15,7 @@
def test_class_query(self):
lib = interp_cppyy.load_lib(space, shared_lib)
w_cppyyclass = lib.type_byname("example01")
- adddouble = w_cppyyclass.function_members["adddouble"]
+ adddouble = w_cppyyclass.function_members["staticAddToDouble"]
func, = adddouble.functions
assert isinstance(func.executor, executor.DoubleExecutor)
assert func.arg_types == ["double"]
@@ -30,40 +29,95 @@
import cppyy
return cppyy.load_lib(%r)""" % (shared_lib, ))
- def test_example01static(self):
+ def test_example01static_int(self):
+ """Test passing of an int, returning of an int, and overloading on a
+ differening number of arguments."""
+ import sys
t = self.example01.type_byname("example01")
- # also tests overloading by number of args
- res = t.invoke("add1", 1)
+ res = t.invoke("staticAddOneToInt", 1)
assert res == 2
- res = t.invoke("add1", 1, 2)
+ res = t.invoke("staticAddOneToInt", 1L)
+ assert res == 2
+ res = t.invoke("staticAddOneToInt", 1, 2)
assert res == 4
- raises(TypeError, 't.invoke("add1", 1, [])')
+ res = t.invoke("staticAddOneToInt", -1)
+ assert res == 0
+ res = t.invoke("staticAddOneToInt", sys.maxint-1)
+ assert res == sys.maxint
+ res = t.invoke("staticAddOneToInt", sys.maxint)
+ assert res == -sys.maxint-1
+
+ raises(TypeError, 't.invoke("staticAddOneToInt", 1, [])')
+ raises(TypeError, 't.invoke("staticAddOneToInt", 1.)')
+ raises(OverflowError, 't.invoke("staticAddOneToInt", sys.maxint+1)')
def test_example01static_double(self):
+ """Test passing of a double and returning of a double on a static function."""
t = self.example01.type_byname("example01")
- res = t.invoke("adddouble", 0.09)
+ res = t.invoke("staticAddToDouble", 0.09)
assert res == 0.09 + 0.01
def test_example01static_constcharp(self):
+ """Test passing of a C string and returning of a C string on a static
+ function."""
t = self.example01.type_byname("example01")
- res = t.invoke("atoi", "1")
+ res = t.invoke("staticAtoi", "1")
assert res == 1
- res = t.invoke("strcpy", "aap")
+ res = t.invoke("staticStrcpy", "aap")
+ assert res == "aap"
+
+ res = t.invoke("staticStrcpy", u"aap")
assert res == "aap"
- def test_example01method(self):
+ raises(TypeError, 't.invoke("staticStrcpy", 1.)')
+
+ def test_example01method_int(self):
+ """Test passing of a int, returning of a int, and memory cleanup, on
+ a method."""
t = self.example01.type_byname("example01")
- count = t.invoke("getcount")
- assert count == 0
+ assert t.invoke("getCount") == 0
instance = t.construct(7)
- count = t.invoke("getcount")
- assert count == 1
- res = instance.invoke("add", 4)
+ assert t.invoke("getCount") == 1
+ res = instance.invoke("addDataToInt", 4)
assert res == 11
+ res = instance.invoke("addDataToInt", -4)
+ assert res == 3
+ instance.destruct()
+ assert t.invoke("getCount") == 0
+ raises(ReferenceError, 'instance.invoke("addDataToInt", 4)')
+
+ instance = t.construct(7)
+ instance2 = t.construct(8)
+ assert t.invoke("getCount") == 2
instance.destruct()
- count = t.invoke("getcount")
- assert count == 0
+ assert t.invoke("getCount") == 1
+ instance2.destruct()
+ assert t.invoke("getCount") == 0
+
+ def test_example01method_double(self):
+ """Test passing of a double and returning of double on a method"""
+ t = self.example01.type_byname("example01")
+ instance = t.construct(13)
+ res = instance.invoke("addDataToDouble", 16)
+ assert round(res-29, 8) == 0.
+ instance = t.construct(-13)
+ res = instance.invoke("addDataToDouble", 16)
+ assert round(res-3, 8) == 0.
+
+ def test_example01method_constcharp(self):
+ """Test passing of a C string and returning of a C string on a
+ method."""
+
+ t = self.example01.type_byname("example01")
+ instance = t.construct(42)
+
+ res = instance.invoke("addDataToAtoi", "13")
+ assert res == 55
+ res = instance.invoke("addToStringValue", "12")
+ assert res == "54"
+ res = instance.invoke("addToStringValue", "-12")
+ assert res == "30"
More information about the Pypy-commit
mailing list