[pypy-commit] pypy reflex-support: doh, don't touch memory after free-ing it ...
wlav
noreply at buildbot.pypy.org
Fri Apr 5 23:36:47 CEST 2013
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r63071:7b2dc9dd0300
Date: 2013-04-05 14:33 -0700
http://bitbucket.org/pypy/pypy/changeset/7b2dc9dd0300/
Log: doh, don't touch memory after free-ing it ...
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
@@ -1,10 +1,11 @@
from rpython.rtyper.lltypesystem import rffi, lltype
from rpython.rlib import jit, jit_libffi, libffi, rdynload, objectmodel
+from rpython.rlib.rarithmetic import r_singlefloat
from rpython.tool import leakfinder
from pypy.interpreter.error import OperationError
-from pypy.module._cffi_backend import ctypefunc, ctypeprim, ctypeptr, misc
+from pypy.module._cffi_backend import ctypefunc, ctypeprim, cdataobj, misc
from pypy.module.cppyy.capi.capi_types import C_SCOPE, C_TYPE, C_OBJECT,\
C_METHOD, C_INDEX, C_INDEX_ARRAY, WLAVC_INDEX, C_METHPTRGETTER_PTR
@@ -72,11 +73,14 @@
buffer)
resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
+ # this wrapping is unnecessary, but the assumption is that given the
+ # immediate unwrapping, the round-trip is removed
+ w_res = self.ctitem.copy_and_convert_to_object(resultdata)
finally:
if raw_string != rffi.cast(rffi.CCHARP, 0):
rffi.free_charp(raw_string)
lltype.free(buffer, flavor='raw')
- return rffi.cast(rffi.LONGP, resultdata)
+ return w_res
class State(object):
def __init__(self, space):
@@ -107,7 +111,7 @@
c_double = nt.new_primitive_type(space, 'double')
c_ccharp = nt.new_pointer_type(space, c_char)
- c_index_array = nt.new_primitive_type(space, 'unsigned long') # likewise ...
+ c_index_array = nt.new_pointer_type(space, c_void)
c_voidp = nt.new_pointer_type(space, c_void)
c_size_t = nt.new_primitive_type(space, 'size_t')
@@ -247,16 +251,22 @@
state.capi_calls[name] = c_call
return c_call.ctype.rcall(c_call._cdata, args)
-def _longptr_to_int(longptr):
- # TODO: not understanding why this should be rffi.LONGP instead of rffi.INTP ??
- return int(rffi.cast(rffi.LONGP, longptr)[0])
+def _cdata_to_cobject(space, w_cdata):
+ return rffi.cast(C_OBJECT, space.int_w(w_cdata))
+
+def _cdata_to_size_t(space, w_cdata):
+ return rffi.cast(rffi.SIZE_T, space.int_w(w_cdata))
+
+def _cdata_to_ptr(space, w_cdata): # TODO: this is both a hack and dreadfully slow
+ return rffi.cast(rffi.VOIDP,
+ space.interp_w(cdataobj.W_CData, w_cdata, can_be_None=False)._cdata)
def c_load_dictionary(name):
return libffi.CDLL(name)
# name to opaque C++ scope representation ------------------------------------
def c_num_scopes(space, cppscope):
- return call_capi(space, 'num_scopes', [_Arg(l=cppscope.handle)])[0]
+ return space.int_w(call_capi(space, 'num_scopes', [_Arg(l=cppscope.handle)]))
def c_scope_name(space, cppscope, iscope):
args = [_Arg(l=cppscope.handle), _Arg(l=iscope)]
return charp2str_free(space, call_capi(space, 'scope_name', args))
@@ -264,16 +274,16 @@
def c_resolve_name(space, name):
return charp2str_free(space, call_capi(space, 'resolve_name', [_Arg(s=name)]))
def c_get_scope_opaque(space, name):
- return rffi.cast(C_SCOPE, call_capi(space, 'get_scope', [_Arg(s=name)])[0])
+ return rffi.cast(C_SCOPE, space.int_w(call_capi(space, 'get_scope', [_Arg(s=name)])))
def c_get_template(space, name):
- return rffi.cast(C_TYPE, call_capi(space, 'get_template', [_Arg(s=name)])[0])
+ return rffi.cast(C_TYPE, space.int_w(call_capi(space, 'get_template', [_Arg(s=name)])))
def c_actual_class(space, cppclass, cppobj):
args = [_Arg(l=cppclass.handle), _Arg(l=cppobj)]
- return rffi.cast(C_TYPE, call_capi(space, 'actual_class', args)[0])
+ return rffi.cast(C_TYPE, space.int_w(call_capi(space, 'actual_class', args)))
# memory management ----------------------------------------------------------
def c_allocate(space, cppclass):
- return rffi.cast(C_OBJECT, call_capi(space, 'allocate', [_Arg(l=cppclass.handle)])[0])
+ return _cdata_to_cobject(space, call_capi(space, 'allocate', [_Arg(l=cppclass.handle)]))
def c_deallocate(space, cppclass, cppobject):
call_capi(space, 'deallocate', [_Arg(l=cppclass.handle), _Arg(l=cppobject)])
def c_destruct(space, cppclass, cppobject):
@@ -285,65 +295,66 @@
call_capi(space, 'call_v', args)
def c_call_b(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.UCHARP, call_capi(space, 'call_b', args))[0]
+ return rffi.cast(rffi.UCHAR, space.c_int_w(call_capi(space, 'call_b', args)))
def c_call_c(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.CCHARP, call_capi(space, 'call_c', args))[0]
+ return rffi.cast(rffi.CHAR, space.str_w(call_capi(space, 'call_c', args))[0])
def c_call_h(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.SHORTP, call_capi(space, 'call_h', args))[0]
+ return rffi.cast(rffi.SHORT, space.int_w(call_capi(space, 'call_h', args)))
def c_call_i(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.INTP, call_capi(space, 'call_i', args))[0] # TODO: should this be LONGP, too?
+ return rffi.cast(rffi.INT, space.c_int_w(call_capi(space, 'call_i', args)))
def c_call_l(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.LONGP, call_capi(space, 'call_l', args))[0]
+ return rffi.cast(rffi.LONG, space.int_w(call_capi(space, 'call_l', args)))
def c_call_ll(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.LONGLONGP, call_capi(space, 'call_ll', args))[0]
+ return rffi.cast(rffi.LONGLONG, space.r_longlong_w(call_capi(space, 'call_ll', args)))
def c_call_f(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.FLOATP, call_capi(space, 'call_f', args))[0]
+ return rffi.cast(rffi.FLOAT, r_singlefloat(space.float_w(call_capi(space, 'call_f', args))))
def c_call_d(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.DOUBLEP, call_capi(space, 'call_d', args))[0]
+ return rffi.cast(rffi.DOUBLE, space.float_w(call_capi(space, 'call_d', args)))
def c_call_r(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(rffi.VOIDPP, call_capi(space, 'call_r', args))[0]
+ return _cdata_to_ptr(space, call_capi(space, 'call_r', args))
def c_call_s(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
return call_capi(space, 'call_s', args)
def c_constructor(space, cppmethod, cppobject, nargs, cargs):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
- return rffi.cast(C_OBJECT, call_capi(space, 'constructor', args)[0])
+ return _cdata_to_cobject(space, call_capi(space, 'constructor', args))
def c_call_o(space, cppmethod, cppobject, nargs, cargs, cppclass):
args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs), _Arg(l=cppclass.handle)]
- return rffi.cast(C_OBJECT, call_capi(space, 'call_o', args)[0])
+ return _cdata_to_cobject(space, call_capi(space, 'call_o', args))
@jit.elidable_promote()
def c_get_methptr_getter(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return rffi.cast(C_METHPTRGETTER_PTR, call_capi(space, 'get_methptr_getter', args)[0])
+ return rffi.cast(C_METHPTRGETTER_PTR,
+ _cdata_to_ptr(space, call_capi(space, 'get_methptr_getter', args)))
# handling of function argument buffer ---------------------------------------
def c_allocate_function_args(space, size):
- return rffi.cast(rffi.VOIDP, call_capi(space, 'allocate_function_args', [_Arg(l=size)])[0])
+ return _cdata_to_ptr(space, call_capi(space, 'allocate_function_args', [_Arg(l=size)]))
def c_deallocate_function_args(space, cargs):
call_capi(space, 'deallocate_function_args', [_Arg(vp=cargs)])
@jit.elidable_promote()
def c_function_arg_sizeof(space):
- return rffi.cast(rffi.SIZE_T, call_capi(space, 'function_arg_sizeof', [])[0])
+ return _cdata_to_size_t(space, call_capi(space, 'function_arg_sizeof', []))
@jit.elidable_promote()
def c_function_arg_typeoffset(space):
- return rffi.cast(rffi.SIZE_T, call_capi(space, 'function_arg_typeoffset', [])[0])
+ return _cdata_to_size_t(space, call_capi(space, 'function_arg_typeoffset', []))
# scope reflection information -----------------------------------------------
def c_is_namespace(space, scope):
- return _longptr_to_int(call_capi(space, 'is_namespace', [_Arg(l=scope)]))
+ return space.bool_w(call_capi(space, 'is_namespace', [_Arg(l=scope)]))
def c_is_enum(space, name):
- return _longptr_to_int(call_capi(space, 'is_enum', [_Arg(s=name)]))
+ return space.bool_w(call_capi(space, 'is_enum', [_Arg(s=name)]))
# type/class reflection information ------------------------------------------
def c_final_name(space, cpptype):
@@ -351,26 +362,26 @@
def c_scoped_final_name(space, cpptype):
return charp2str_free(space, call_capi(space, 'scoped_final_name', [_Arg(l=cpptype)]))
def c_has_complex_hierarchy(space, handle):
- return _longptr_to_int(call_capi(space, 'has_complex_hierarchy', [_Arg(l=handle)]))
+ return space.bool_w(call_capi(space, 'has_complex_hierarchy', [_Arg(l=handle)]))
def c_num_bases(space, cppclass):
- return _longptr_to_int(call_capi(space, 'num_bases', [_Arg(l=cppclass.handle)]))
+ return space.int_w(call_capi(space, 'num_bases', [_Arg(l=cppclass.handle)]))
def c_base_name(space, cppclass, base_index):
args = [_Arg(l=cppclass.handle), _Arg(l=base_index)]
return charp2str_free(space, call_capi(space, 'base_name', args))
@jit.elidable_promote()
def c_is_subtype(space, derived, base):
if derived == base:
- return 1
- return _longptr_to_int(call_capi(space, 'is_subtype', [_Arg(l=derived.handle), _Arg(l=base.handle)]))
+ return bool(1)
+ return space.bool_w(call_capi(space, 'is_subtype', [_Arg(l=derived.handle), _Arg(l=base.handle)]))
@jit.elidable_promote()
def _c_base_offset(space, derived_h, base_h, address, direction):
args = [_Arg(l=derived_h), _Arg(l=base_h), _Arg(l=address), _Arg(l=direction)]
- return rffi.cast(rffi.SIZE_T, rffi.cast(rffi.ULONGP, call_capi(space, 'base_offset', args))[0])
+ return _cdata_to_size_t(space, call_capi(space, 'base_offset', args))
@jit.elidable_promote()
def c_base_offset(space, derived, base, address, direction):
if derived == base:
- return 0
+ return rffi.cast(rffi.SIZE_T, 0)
return _c_base_offset(space, derived.handle, base.handle, address, direction)
@jit.elidable_promote()
def c_base_offset1(space, derived_h, base, address, direction):
@@ -379,13 +390,14 @@
# method/function reflection information -------------------------------------
def c_num_methods(space, cppscope):
args = [_Arg(l=cppscope.handle)]
- return _longptr_to_int(call_capi(space, 'num_methods', args))
+ return space.int_w(call_capi(space, 'num_methods', args))
def c_method_index_at(space, cppscope, imethod):
args = [_Arg(l=cppscope.handle), _Arg(l=imethod)]
- return call_capi(space, 'method_index_at', args)[0]
+ return space.int_w(call_capi(space, 'method_index_at', args))
def c_method_indices_from_name(space, cppscope, name):
args = [_Arg(l=cppscope.handle), _Arg(s=name)]
- indices = rffi.cast(C_INDEX_ARRAY, call_capi(space, 'method_indices_from_name', args)[0])
+ indices = rffi.cast(C_INDEX_ARRAY,
+ _cdata_to_ptr(space, call_capi(space, 'method_indices_from_name', args)))
if not indices:
return []
py_indices = []
@@ -406,10 +418,10 @@
return charp2str_free(space, call_capi(space, 'method_result_type', args))
def c_method_num_args(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'method_num_args', args))
+ return space.int_w(call_capi(space, 'method_num_args', args))
def c_method_req_args(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'method_req_args', args))
+ return space.int_w(call_capi(space, 'method_req_args', args))
def c_method_arg_type(space, cppscope, index, arg_index):
args = [_Arg(l=cppscope.handle), _Arg(l=index), _Arg(l=arg_index)]
return charp2str_free(space, call_capi(space, 'method_arg_type', args))
@@ -422,10 +434,10 @@
def c_method_is_template(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'method_is_template', args))
+ return space.bool_w(call_capi(space, 'method_is_template', args))
def _c_method_num_template_args(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'method_num_template_args', args))
+ return space.int_w(call_capi(space, 'method_num_template_args', args))
def c_template_args(space, cppscope, index):
nargs = _c_method_num_template_args(space, cppscope, index)
arg1 = _Arg(l=cppscope.handle)
@@ -437,69 +449,69 @@
def c_get_method(space, cppscope, index):
args = [_Arg(l=cppscope.handle), _Arg(l=index)]
- return rffi.cast(C_METHOD, call_capi(space, 'get_method', args)[0])
+ return rffi.cast(C_METHOD, space.int_w(call_capi(space, 'get_method', args)))
def c_get_global_operator(space, nss, lc, rc, op):
if nss is not None:
args = [_Arg(l=nss.handle), _Arg(l=lc.handle), _Arg(l=rc.handle), _Arg(s=op)]
- return rffi.cast(WLAVC_INDEX, call_capi(space, 'get_global_operator', args)[0])
+ return rffi.cast(WLAVC_INDEX, space.int_w(call_capi(space, 'get_global_operator', args)))
return rffi.cast(WLAVC_INDEX, -1)
# method properties ----------------------------------------------------------
def c_is_constructor(space, cppclass, index):
args = [_Arg(l=cppclass.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'is_constructor', args))
+ return space.bool_w(call_capi(space, 'is_constructor', args))
def c_is_staticmethod(space, cppclass, index):
args = [_Arg(l=cppclass.handle), _Arg(l=index)]
- return _longptr_to_int(call_capi(space, 'is_staticmethod', args))
+ return space.bool_w(call_capi(space, 'is_staticmethod', args))
# data member reflection information -----------------------------------------
def c_num_datamembers(space, cppscope):
- return _longptr_to_int(call_capi(space, 'num_datamembers', [_Arg(l=cppscope.handle)]))
+ return space.int_w(call_capi(space, 'num_datamembers', [_Arg(l=cppscope.handle)]))
def c_datamember_name(space, cppscope, datamember_index):
args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
return charp2str_free(space, call_capi(space, 'datamember_name', args))
def c_datamember_type(space, cppscope, datamember_index):
args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
- return charp2str_free(space, call_capi(space, 'datamember_type', args))
+ return charp2str_free(space, call_capi(space, 'datamember_type', args))
def c_datamember_offset(space, cppscope, datamember_index):
args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
- return rffi.cast(rffi.SIZE_T, rffi.cast(rffi.ULONGP, call_capi(space, 'datamember_offset', args))[0])
+ return _cdata_to_size_t(space, call_capi(space, 'datamember_offset', args))
def c_datamember_index(space, cppscope, name):
args = [_Arg(l=cppscope.handle), _Arg(s=name)]
- return _longptr_to_int(call_capi(space, 'datamember_index', args))
+ return space.int_w(call_capi(space, 'datamember_index', args))
# data member properties -----------------------------------------------------
def c_is_publicdata(space, cppscope, datamember_index):
args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
- return _longptr_to_int(call_capi(space, 'is_publicdata', args))
+ return space.bool_w(call_capi(space, 'is_publicdata', args))
def c_is_staticdata(space, cppscope, datamember_index):
args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
- return _longptr_to_int(call_capi(space, 'is_staticdata', args))
+ return space.bool_w(call_capi(space, 'is_staticdata', args))
# misc helpers ---------------------------------------------------------------
def c_strtoll(space, svalue):
- return rffi.cast(rffi.LONGLONGP, call_capi(space, 'strtoll', [_Arg(s=svalue)]))[0]
+ return space.r_longlong_w(call_capi(space, 'strtoll', [_Arg(s=svalue)]))
def c_strtoull(space, svalue):
- return rffi.cast(rffi.ULONGLONGP, call_capi(space, 'strtoull', [_Arg(s=svalue)]))[0]
+ return space.r_ulonglong_w(call_capi(space, 'strtoull', [_Arg(s=svalue)]))
def c_free(space, voidp):
call_capi(space, 'free', [_Arg(vp=voidp)])
def charp2str_free(space, cdata):
- charp = rffi.cast(rffi.CCHARPP, cdata)[0]
+ charp = rffi.cast(rffi.CCHARP, _cdata_to_ptr(space, cdata))
pystr = rffi.charp2str(charp)
c_free(space, rffi.cast(rffi.VOIDP, charp))
return pystr
def c_charp2stdstring(space, svalue):
- return rffi.cast(C_OBJECT, call_capi(space, 'charp2stdstring', [_Arg(s=svalue)])[0])
+ return _cdata_to_cobject(space, call_capi(space, 'charp2stdstring', [_Arg(s=svalue)]))
def c_stdstring2stdstring(space, cppobject):
- return rffi.cast(C_OBJECT, call_capi(space, 'stdstring2stdstring', [_Arg(l=cppobject)])[0])
+ return _cdata_to_cobject(space, call_capi(space, 'stdstring2stdstring', [_Arg(l=cppobject)]))
def c_assign2stdstring(space, cppobject, svalue):
args = [_Arg(l=cppobject), _Arg(s=svalue)]
- return rffi.cast(C_OBJECT, call_capi(space, 'assign2stdstring', args)[0])
+ call_capi(space, 'assign2stdstring', args)
def c_free_stdstring(space, cppobject):
- call_capi(space, 'free_stdstring', [_Arg(l=cppobject)])[0]
+ call_capi(space, 'free_stdstring', [_Arg(l=cppobject)])
# loadable-capi-specific pythonizations (none, as the capi isn't known until runtime)
def register_pythonizations(space):
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
@@ -91,7 +91,6 @@
return self._wrap_object(space, rffi.cast(self.c_type, result))
def execute_libffi(self, space, cif_descr, funcaddr, buffer):
- data = rffi.ptradd(buffer, cif_descr.exchange_args[1])
jit_libffi.jit_ffi_call(cif_descr, funcaddr, buffer)
result = rffi.ptradd(buffer, cif_descr.exchange_result)
return self._wrap_object(space, rffi.cast(self.c_ptrtype, result)[0])
More information about the pypy-commit
mailing list