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

Reply via email to