Author: Wim Lavrijsen <wlavrij...@lbl.gov> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit