[pypy-svn] r76460 - in pypy/branch/reflex-support/pypy/module/cppyy: . include src test
wlav at codespeak.net
wlav at codespeak.net
Tue Aug 3 23:22:06 CEST 2010
Author: wlav
Date: Tue Aug 3 23:22:05 2010
New Revision: 76460
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/helper.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/pythonify.py
pypy/branch/reflex-support/pypy/module/cppyy/src/reflexcwrapper.cxx
pypy/branch/reflex-support/pypy/module/cppyy/test/test_cppyy.py
pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
Log:
Support for public data members of type (unsigned) char and renaming various names for consistency.
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 Tue Aug 3 23:22:05 2010
@@ -85,19 +85,36 @@
"cppyy_method_name",
[C_TYPEHANDLE, rffi.INT], rffi.CCHARP,
compilation_info=eci)
-c_result_type_method = rffi.llexternal(
- "cppyy_result_type_method",
+c_method_result_type = rffi.llexternal(
+ "cppyy_method_result_type",
[C_TYPEHANDLE, rffi.INT], rffi.CCHARP,
compilation_info=eci)
-c_num_args_method = rffi.llexternal(
- "cppyy_num_args_method",
+c_method_num_args = rffi.llexternal(
+ "cppyy_method_num_args",
[C_TYPEHANDLE, rffi.INT], rffi.INT,
compilation_info=eci)
-c_arg_type_method = rffi.llexternal(
- "cppyy_arg_type_method",
+c_method_arg_type = rffi.llexternal(
+ "cppyy_method_arg_type",
[C_TYPEHANDLE, rffi.INT, rffi.INT], rffi.CCHARP,
compilation_info=eci)
+c_num_data_members = rffi.llexternal(
+ "cppyy_num_data_members",
+ [C_TYPEHANDLE], rffi.INT,
+ compilation_info=eci)
+c_data_member_name = rffi.llexternal(
+ "cppyy_data_member_name",
+ [C_TYPEHANDLE, rffi.INT], rffi.CCHARP,
+ compilation_info=eci)
+c_data_member_type = rffi.llexternal(
+ "cppyy_data_member_type",
+ [C_TYPEHANDLE, rffi.INT], rffi.CCHARP,
+ compilation_info=eci)
+c_data_member_offset = rffi.llexternal(
+ "cppyy_data_member_offset",
+ [C_TYPEHANDLE, rffi.INT], rffi.INT,
+ compilation_info=eci)
+
c_is_constructor = rffi.llexternal(
"cppyy_is_constructor",
[C_TYPEHANDLE, rffi.INT], rffi.INT,
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 Tue Aug 3 23:22:05 2010
@@ -10,6 +10,9 @@
def convert_argument(self, space, w_obj):
raise NotImplementedError("abstract base class")
+ def from_memory(self, space, w_obj, offset):
+ raise NotImplementedError("abstract base class")
+
def free_argument(self, arg):
lltype.free(arg, flavor='raw')
@@ -41,6 +44,17 @@
x = rffi.str2charp(arg)
return rffi.cast(rffi.VOIDP, x)
+ def from_memory(self, space, w_obj, offset):
+ obj = space.interpclass_w(space.findattr(w_obj, space.wrap("_cppinstance")))
+ fieldptr = lltype.direct_ptradd(obj.rawobject, offset)
+ return space.wrap(fieldptr[0])
+
+ def to_memory(self, space, w_obj, w_value, offset):
+ obj = space.interpclass_w(space.findattr(w_obj, space.wrap("_cppinstance")))
+ fieldptr = lltype.direct_ptradd(obj.rawobject, offset)
+ print w_value
+ fieldptr[0] = space.str_w(w_value)
+
class IntConverter(TypeConverter):
def convert_argument(self, space, w_obj):
arg = space.c_int_w(w_obj)
@@ -87,6 +101,7 @@
space.wrap("cannot pass %s as %s" % (
space.type(w_obj).getname(space, "?"),
self.cpptype.name)))
+
def free_argument(self, arg):
pass
Modified: pypy/branch/reflex-support/pypy/module/cppyy/helper.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/helper.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/helper.py Tue Aug 3 23:22:05 2010
@@ -3,17 +3,25 @@
def compound(name):
name = "".join(rstring.split(name, "const")) # poor man's replace
i = _find_qualifier_index(name)
+ if name[-1] == "]": # array type
+ return "*"
return "".join(name[i:].split(" "))
def _find_qualifier_index(name):
i = len(name)
for i in range(len(name) - 1, -1, -1):
c = name[i]
- if c.isalnum() or c == ">":
+ if c.isalnum() or c == ">" or c == "]":
break
return i + 1
def clean_type(name):
assert name.find("const") == -1
i = _find_qualifier_index(name)
- return name[:i].strip(' ')
+ name = name[:i].strip(' ')
+ if name[-1] == "]":
+ for i in range(len(name) - 1, -1, -1):
+ c = name[i]
+ if c == "[":
+ return name[:i]
+ return name
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 Tue Aug 3 23:22:05 2010
@@ -14,6 +14,7 @@
void* cppyy_allocate(cppyy_typehandle_t handle);
void cppyy_deallocate(cppyy_typehandle_t handle, cppyy_object_t instance);
+ /* method/function dispatching */
void cppyy_call_v(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]);
int cppyy_call_b(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]);
char cppyy_call_c(cppyy_typehandle_t handle, int method_index, cppyy_object_t self, int numargs, void* args[]);
@@ -24,11 +25,18 @@
void cppyy_destruct(cppyy_typehandle_t handle, cppyy_object_t self);
cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_typehandle_t handle, int method_index);
+ /* method/function reflection information */
int cppyy_num_methods(cppyy_typehandle_t handle);
char* cppyy_method_name(cppyy_typehandle_t handle, int method_index);
- char* cppyy_result_type_method(cppyy_typehandle_t handle, int method_index);
- int cppyy_num_args_method(cppyy_typehandle_t handle, int method_index);
- char* cppyy_arg_type_method(cppyy_typehandle_t handle, int method_index, int index);
+ char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index);
+ int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index);
+ char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int index);
+
+ /* data member reflection information */
+ int cppyy_num_data_members(cppyy_typehandle_t handle);
+ char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index);
+ char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index);
+ size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index);
int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index);
int cppyy_is_static(cppyy_typehandle_t 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 Tue Aug 3 23:22:05 2010
@@ -35,7 +35,8 @@
if handle:
cpptype = W_CPPType(space, name, handle)
state.cpptype_cache[name] = cpptype
- cpptype._find_func_members()
+ cpptype._find_methods()
+ cpptype._find_data_members()
return cpptype
raise OperationError(space.w_TypeError, space.wrap("no such C++ class %s" % name))
@@ -213,6 +214,28 @@
)
+class W_CPPDataMember(Wrappable):
+ _immutable_fields_ = ["converter", "offset"]
+
+ def __init__(self, space, cpptype, offset):
+ self.space = space
+ self.converter = converter.get_converter(self.space, cpptype)
+ self.offset = offset
+
+ def __get__(self, args_w):
+ return self.converter.from_memory(self.space, args_w[0], self.offset)
+
+ def __set__(self, args_w):
+ self.converter.to_memory(self.space, args_w[0], args_w[1], self.offset)
+ return None
+
+W_CPPDataMember.typedef = TypeDef(
+ 'CPPDataMember',
+ __get__ = interp2app(W_CPPDataMember.__get__, unwrap_spec=['self', 'args_w']),
+ __set__ = interp2app(W_CPPDataMember.__set__, unwrap_spec=['self', 'args_w']),
+)
+
+
class W_CPPType(Wrappable):
_immutable_fields_ = ["name","handle"]
@@ -220,30 +243,33 @@
self.space = space
self.name = name
self.handle = handle
- self.function_members = {}
- # Do not call "self._find_func_members()" here, so that a distinction can be
- # made between testing for existence (i.e. existence in the cache of classes)
- # and actual use. Point being that a class can use itself, e.g. as a return
- # type or an argument to one of its methods.
+ self.methods = {}
+ # Do not call "self._find_methods()" here, so that a distinction can
+ # be made between testing for existence (i.e. existence in the cache
+ # of classes) and actual use. Point being that a class can use itself,
+ # e.g. as a return type or an argument to one of its methods.
+
+ self.data_members = {}
+ # Idem self.methods: a type could hold itself by pointer.
- def _find_func_members(self):
- num_func_members = capi.c_num_methods(self.handle)
+ def _find_methods(self):
+ num_methods = capi.c_num_methods(self.handle)
args_temp = {}
- for i in range(num_func_members):
- func_member_name = capi.charp2str_free(capi.c_method_name(self.handle, i))
+ for i in range(num_methods):
+ method_name = capi.charp2str_free(capi.c_method_name(self.handle, i))
cppfunction = self._make_cppfunction(i)
- overload = args_temp.setdefault(func_member_name, [])
+ overload = args_temp.setdefault(method_name, [])
overload.append(cppfunction)
for name, functions in args_temp.iteritems():
overload = W_CPPOverload(self.space, name, functions[:])
- self.function_members[name] = overload
+ self.methods[name] = overload
def _make_cppfunction(self, method_index):
- result_type = capi.charp2str_free(capi.c_result_type_method(self.handle, method_index))
- num_args = capi.c_num_args_method(self.handle, method_index)
+ result_type = capi.charp2str_free(capi.c_method_result_type(self.handle, method_index))
+ num_args = capi.c_method_num_args(self.handle, method_index)
argtypes = []
for i in range(num_args):
- argtype = capi.charp2str_free(capi.c_arg_type_method(self.handle, method_index, i))
+ argtype = capi.charp2str_free(capi.c_method_arg_type(self.handle, method_index, i))
argtypes.append(argtype)
if capi.c_is_constructor(self.handle, method_index):
cls = CPPConstructor
@@ -253,12 +279,28 @@
cls = CPPMethod
return cls(self, method_index, result_type, argtypes)
- def get_function_members(self):
- return self.space.newlist([self.space.wrap(name) for name in self.function_members])
+ def _find_data_members(self):
+ num_data_members = capi.c_num_data_members(self.handle)
+ for i in range(num_data_members):
+ data_member_name = capi.charp2str_free(capi.c_data_member_name(self.handle, i))
+ cpptype = capi.charp2str_free(capi.c_data_member_type(self.handle, i))
+ offset = capi.c_data_member_offset(self.handle, i)
+ data_member = W_CPPDataMember(self.space, cpptype, offset)
+ self.data_members[data_member_name] = data_member
+
+ def get_method_names(self):
+ return self.space.newlist([self.space.wrap(name) for name in self.methods])
@jit.purefunction
def get_overload(self, name):
- return self.function_members[name]
+ return self.methods[name]
+
+ def get_data_member_names(self):
+ return self.space.newlist([self.space.wrap(name) for name in self.data_members])
+
+ @jit.purefunction
+ def get_data_member(self, name):
+ return self.data_members[name]
def invoke(self, name, args_w):
overload = self.get_overload(name)
@@ -270,8 +312,10 @@
W_CPPType.typedef = TypeDef(
'CPPType',
- get_function_members = interp2app(W_CPPType.get_function_members, unwrap_spec=['self']),
+ get_method_names = interp2app(W_CPPType.get_method_names, unwrap_spec=['self']),
get_overload = interp2app(W_CPPType.get_overload, unwrap_spec=['self', str]),
+ get_data_member_names = interp2app(W_CPPType.get_data_member_names, unwrap_spec=['self']),
+ get_data_member = interp2app(W_CPPType.get_data_member, unwrap_spec=['self', str]),
invoke = interp2app(W_CPPType.invoke, unwrap_spec=['self', str, 'args_w']),
construct = interp2app(W_CPPType.construct, unwrap_spec=['self', 'args_w']),
)
Modified: pypy/branch/reflex-support/pypy/module/cppyy/pythonify.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/pythonify.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/pythonify.py Tue Aug 3 23:22:05 2010
@@ -54,13 +54,16 @@
# TODO: handle base classes
cpptype = cppyy._type_byname(name)
d = {"_cppyyclass" : cpptype}
- for f in cpptype.get_function_members():
+ for f in cpptype.get_method_names():
cppol = cpptype.get_overload(f)
if cppol.is_static():
d[f] = make_static_function(cpptype, f, cppol.get_returntype())
else:
d[f] = make_method(f, cppol.get_returntype())
+ for dm in cpptype.get_data_member_names():
+ d[dm] = cpptype.get_data_member(dm)
+
pycpptype = CppyyClass(name, (CppyyObject,), d)
return pycpptype
@@ -77,6 +80,7 @@
self.__dict__[attr] = cppclass
return cppclass
except TypeError, e:
+ import traceback
raise AttributeError("'gbl' object has no attribute '%s'" % attr)
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 Tue Aug 3 23:22:05 2010
@@ -18,6 +18,7 @@
}
+/* method/function dispatching -------------------------------------------- */
void cppyy_call_v(cppyy_typehandle_t handle, int method_index,
cppyy_object_t self, int numargs, void* args[]) {
std::vector<void*> arguments(args, args+numargs);
@@ -96,6 +97,7 @@
}
+/* method/function reflection information --------------------------------- */
int cppyy_num_methods(cppyy_typehandle_t handle) {
Reflex::Type t((Reflex::TypeName*)handle);
// for (int i = 0; i < (int)t.FunctionMemberSize(); i++) {
@@ -120,7 +122,7 @@
return name_char;
}
-char* cppyy_result_type_method(cppyy_typehandle_t handle, int method_index) {
+char* cppyy_method_result_type(cppyy_typehandle_t handle, int method_index) {
Reflex::Type t((Reflex::TypeName*)handle);
Reflex::Member m = t.FunctionMemberAt(method_index);
Reflex::Type rt = m.TypeOf().ReturnType();
@@ -130,13 +132,13 @@
return name_char;
}
-int cppyy_num_args_method(cppyy_typehandle_t handle, int method_index) {
+int cppyy_method_num_args(cppyy_typehandle_t handle, int method_index) {
Reflex::Type t((Reflex::TypeName*)handle);
Reflex::Member m = t.FunctionMemberAt(method_index);
return m.FunctionParameterSize();
}
-char* cppyy_arg_type_method(cppyy_typehandle_t handle, int method_index, int arg_index) {
+char* cppyy_method_arg_type(cppyy_typehandle_t handle, int method_index, int arg_index) {
Reflex::Type t((Reflex::TypeName*)handle);
Reflex::Member m = t.FunctionMemberAt(method_index);
Reflex::Type at = m.TypeOf().FunctionParameterAt(arg_index);
@@ -147,6 +149,37 @@
}
+/* data member reflection information ------------------------------------- */
+int cppyy_num_data_members(cppyy_typehandle_t handle) {
+ Reflex::Type t((Reflex::TypeName*)handle);
+ return t.DataMemberSize();
+}
+
+char* cppyy_data_member_name(cppyy_typehandle_t handle, int data_member_index) {
+ Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Member m = t.DataMemberAt(data_member_index);
+ std::string name = m.Name();
+ char* name_char = (char*)malloc(name.size() + 1);
+ strcpy(name_char, name.c_str());
+ return name_char;
+}
+
+char* cppyy_data_member_type(cppyy_typehandle_t handle, int data_member_index) {
+ Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Member m = t.DataMemberAt(data_member_index);
+ std::string name = m.TypeOf().Name(Reflex::FINAL|Reflex::SCOPED|Reflex::QUALIFIED);
+ char* name_char = (char*)malloc(name.size() + 1);
+ strcpy(name_char, name.c_str());
+ return name_char;
+}
+
+size_t cppyy_data_member_offset(cppyy_typehandle_t handle, int data_member_index) {
+ Reflex::Type t((Reflex::TypeName*)handle);
+ Reflex::Member m = t.DataMemberAt(data_member_index);
+ return m.Offset();
+}
+
+
int cppyy_is_constructor(cppyy_typehandle_t handle, int method_index) {
Reflex::Type t((Reflex::TypeName*)handle);
Reflex::Member m = t.FunctionMemberAt(method_index);
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 Tue Aug 3 23:22:05 2010
@@ -21,7 +21,7 @@
w_cppyyclass = interp_cppyy.type_byname(space, "example01")
w_cppyyclass2 = interp_cppyy.type_byname(space, "example01")
assert space.is_w(w_cppyyclass, w_cppyyclass2)
- adddouble = w_cppyyclass.function_members["staticAddToDouble"]
+ adddouble = w_cppyyclass.methods["staticAddToDouble"]
func, = adddouble.functions
assert isinstance(func.executor, executor.DoubleExecutor)
assert func.arg_types == ["double"]
Modified: pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py
==============================================================================
--- pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py (original)
+++ pypy/branch/reflex-support/pypy/module/cppyy/test/test_datatypes.py Tue Aug 3 23:22:05 2010
@@ -53,19 +53,19 @@
"""
raises(TypeError, 'c.set_bool(10)')
+ # char types through functions
c.set_char('c'); assert c.get_char() == 'c'
c.set_uchar('e'); assert c.get_uchar() == 'e'
- """
- # char types
+
+ # char types through data members
c.m_char = 'b'; assert c.get_char() == 'b'
- c.m_char = 40; assert c.get_char() == chr(40)
+ #c.m_char = 40; assert c.get_char() == chr(40)
c.set_char('c'); assert c.m_char == 'c'
- c.set_char(41); assert c.m_char == chr(41)
+ #c.set_char(41); assert c.m_char == chr(41)
c.m_uchar = 'd'; assert c.get_uchar() == 'd'
- c.m_uchar = 42; assert c.get_uchar() == chr(42)
+ #c.m_uchar = 42; assert c.get_uchar() == chr(42)
c.set_uchar('e'); assert c.m_uchar == 'e'
- c.set_uchar(43); assert c.m_uchar == chr(43)
- """
+ #c.set_uchar(43); assert c.m_uchar == chr(43)
raises(TypeError, 'c.set_char("string")')
# raises(TypeError, 'c.set_uchar(-1)')
More information about the Pypy-commit
mailing list