Author: Wim Lavrijsen <[email protected]>
Branch: cling-support
Changeset: r86208:7f130da8dc67
Date: 2016-08-15 17:09 -0700
http://bitbucket.org/pypy/pypy/changeset/7f130da8dc67/
Log: from Aditi (modified): allow passing of strings with \0 in them
diff --git a/pypy/module/cppyy/capi/builtin_capi.py
b/pypy/module/cppyy/capi/builtin_capi.py
--- a/pypy/module/cppyy/capi/builtin_capi.py
+++ b/pypy/module/cppyy/capi/builtin_capi.py
@@ -158,11 +158,15 @@
return _c_call_r(cppmethod, cppobject, nargs, args)
_c_call_s = rffi.llexternal(
"cppyy_call_s",
- [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP], rffi.CCHARP,
+ [C_METHOD, C_OBJECT, rffi.INT, rffi.VOIDP, rffi.INTP], rffi.CCHARP,
releasegil=ts_call,
compilation_info=backend.eci)
def c_call_s(space, cppmethod, cppobject, nargs, args):
- return _c_call_s(cppmethod, cppobject, nargs, args)
+ length = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+ cstr = _c_call_s(cppmethod, cppobject, nargs, args, length)
+ cstr_len = int(length[0])
+ lltype.free(length, flavor='raw')
+ return cstr, cstr_len
_c_constructor = rffi.llexternal(
"cppyy_constructor",
diff --git a/pypy/module/cppyy/capi/loadable_capi.py
b/pypy/module/cppyy/capi/loadable_capi.py
--- a/pypy/module/cppyy/capi/loadable_capi.py
+++ b/pypy/module/cppyy/capi/loadable_capi.py
@@ -146,7 +146,8 @@
'call_d' : ([c_method, c_object, c_int, c_voidp],
c_double),
'call_r' : ([c_method, c_object, c_int, c_voidp], c_voidp),
- 'call_s' : ([c_method, c_object, c_int, c_voidp],
c_ccharp),
+ # call_s actually takes an intp as last parameter, but this will do
+ 'call_s' : ([c_method, c_object, c_int, c_voidp, c_voidp],
c_ccharp),
'constructor' : ([c_method, c_object, c_int, c_voidp],
c_object),
'call_o' : ([c_method, c_object, c_int, c_voidp, c_type],
c_object),
@@ -336,8 +337,12 @@
args = [_Arg(h=cppmethod), _Arg(h=cppobject), _Arg(l=nargs),
_Arg(vp=cargs)]
return _cdata_to_ptr(space, call_capi(space, 'call_r', args))
def c_call_s(space, cppmethod, cppobject, nargs, cargs):
- args = [_Arg(h=cppmethod), _Arg(h=cppobject), _Arg(l=nargs),
_Arg(vp=cargs)]
- return call_capi(space, 'call_s', args)
+ length = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+ args = [_Arg(h=cppmethod), _Arg(h=cppobject), _Arg(l=nargs),
_Arg(vp=cargs), _Args(vp=length)]
+ cstr = call_capi(space, 'call_s', args)
+ cstr_len = int(length[0])
+ lltype.free(length, flavor='raw')
+ return cstr, cstr_len
def c_constructor(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(h=cppmethod), _Arg(h=cppobject), _Arg(l=nargs),
_Arg(vp=cargs)]
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
@@ -195,8 +195,10 @@
class StdStringExecutor(InstancePtrExecutor):
def execute(self, space, cppmethod, cppthis, num_args, args):
- cstr_result = capi.c_call_s(space, cppmethod, cppthis, num_args, args)
- return space.wrap(capi.charp2str_free(space, cstr_result))
+ cstr, cstr_len = capi.c_call_s(space, cppmethod, cppthis, num_args,
args)
+ string = rffi.charpsize2str(cstr, cstr_len)
+ capi.c_free(rffi.cast(rffi.VOIDP, cstr))
+ return space.wrap(string)
def execute_libffi(self, space, cif_descr, funcaddr, buffer):
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h
--- a/pypy/module/cppyy/include/capi.h
+++ b/pypy/module/cppyy/include/capi.h
@@ -59,7 +59,7 @@
RPY_EXTERN
void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args);
RPY_EXTERN
- char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args);
+ char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args, int* length);
RPY_EXTERN
cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t
klass, int nargs, void* args);
diff --git a/pypy/module/cppyy/include/cpp_cppyy.h
b/pypy/module/cppyy/include/cpp_cppyy.h
--- a/pypy/module/cppyy/include/cpp_cppyy.h
+++ b/pypy/module/cppyy/include/cpp_cppyy.h
@@ -62,7 +62,7 @@
Double_t CallD( TCppMethod_t method, TCppObject_t self, void* args );
LongDouble_t CallLD( TCppMethod_t method, TCppObject_t self, void* args );
void* CallR( TCppMethod_t method, TCppObject_t self, void* args );
- Char_t* CallS( TCppMethod_t method, TCppObject_t self, void* args );
+ Char_t* CallS( TCppMethod_t method, TCppObject_t self, void* args,
int* length );
TCppObject_t CallConstructor( TCppMethod_t method, TCppType_t type, void*
args );
void CallDestructor( TCppType_t type, TCppObject_t self );
TCppObject_t CallO( TCppMethod_t method, TCppObject_t self, void* args,
TCppType_t result_type );
diff --git a/pypy/module/cppyy/src/clingcwrapper.cxx
b/pypy/module/cppyy/src/clingcwrapper.cxx
--- a/pypy/module/cppyy/src/clingcwrapper.cxx
+++ b/pypy/module/cppyy/src/clingcwrapper.cxx
@@ -113,10 +113,10 @@
}
static inline
-char* cppstring_to_cstring( const std::string& name ) {
- char* name_char = (char*)malloc(name.size() + 1 );
- strcpy( name_char, name.c_str() );
- return name_char;
+char* cppstring_to_cstring( const std::string& cppstr ) {
+ char* cstr = (char*)malloc( cppstr.size() + 1 );
+ memcpy( cstr, cppstr.c_str(), cppstr.size() + 1 );
+ return cstr;
}
@@ -478,12 +478,20 @@
return nullptr;
}
-Char_t* Cppyy::CallS( TCppMethod_t method, TCppObject_t self, void* args )
+Char_t* Cppyy::CallS(
+ TCppMethod_t method, TCppObject_t self, void* args, int* length )
{
- Char_t* s = nullptr;
- if ( FastCall( method, args, (void*)self, &s ) )
- return s;
- return nullptr;
+ char* cstr = nullptr;
+ TClassRef cr("std::string");
+ std::string* cppresult = (std::string*)malloc( sizeof(std::string) );
+ if ( FastCall( method, args, self, (void*)cppresult ) ) {
+ cstr = cppstring_to_cstring( *cppresult );
+ *length = cppresult->size();
+ cppresult->std::string::~string();
+ } else
+ *length = 0;
+ free( (void*)cppresult );
+ return cstr;
}
Cppyy::TCppObject_t Cppyy::CallConstructor(
@@ -1188,20 +1196,20 @@
return (double)Cppyy::CallD(method, (void*)self, &parvec);
}
-void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args) {
+void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args) {
std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
return (void*)Cppyy::CallR(method, (void*)self, &parvec);
}
-char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs,
void* args) {
+char* cppyy_call_s(
+ cppyy_method_t method, cppyy_object_t self, int nargs, void* args,
int* length) {
std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
- return cppstring_to_cstring(Cppyy::CallS(method, (void*)self, &parvec));
+ return Cppyy::CallS(method, (void*)self, &parvec, length);
}
cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t klass,
int nargs, void* args) {
std::vector<TParameter> parvec = vsargs_to_parvec(args, nargs);
return cppyy_object_t(Cppyy::CallConstructor(method, klass, &parvec));
-// return cppyy_object_t(Cppyy::CallConstructor(method, klass, args));
}
cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int
nargs, void* args, cppyy_type_t result_type) {
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit