[pypy-commit] pypy reflex-support: second waypoint towards a loadable capi
wlav
noreply at buildbot.pypy.org
Fri Apr 5 03:11:15 CEST 2013
Author: Wim Lavrijsen <WLavrijsen at lbl.gov>
Branch: reflex-support
Changeset: r63042:4fd9f26c848e
Date: 2013-04-03 20:57 -0700
http://bitbucket.org/pypy/pypy/changeset/4fd9f26c848e/
Log: second waypoint towards a loadable capi
diff --git a/pypy/module/cppyy/capi/__init__.py b/pypy/module/cppyy/capi/__init__.py
--- a/pypy/module/cppyy/capi/__init__.py
+++ b/pypy/module/cppyy/capi/__init__.py
@@ -9,8 +9,8 @@
# the selection of the desired backend (default is Reflex).
# choose C-API access method:
-#from pypy.module.cppyy.capi.loadable_capi import *
-from pypy.module.cppyy.capi.builtin_capi import *
+from pypy.module.cppyy.capi.loadable_capi import *
+#from pypy.module.cppyy.capi.builtin_capi import *
from pypy.module.cppyy.capi.capi_types import C_OBJECT,\
C_NULL_TYPE, C_NULL_OBJECT
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
@@ -191,44 +191,56 @@
threadsafe=ts_reflect,
compilation_info=backend.eci,
elidable_function=True)
-def c_get_methptr_getter(cppscope, index):
+def c_get_methptr_getter(space, cppscope, index):
return _c_get_methptr_getter(cppscope.handle, index)
# handling of function argument buffer ---------------------------------------
-c_allocate_function_args = rffi.llexternal(
+_c_allocate_function_args = rffi.llexternal(
"cppyy_allocate_function_args",
[rffi.SIZE_T], rffi.VOIDP,
threadsafe=ts_memory,
compilation_info=backend.eci)
-c_deallocate_function_args = rffi.llexternal(
+def c_allocate_function_args(space, size):
+ return _c_allocate_function_args(size)
+_c_deallocate_function_args = rffi.llexternal(
"cppyy_deallocate_function_args",
[rffi.VOIDP], lltype.Void,
threadsafe=ts_memory,
compilation_info=backend.eci)
-c_function_arg_sizeof = rffi.llexternal(
+def c_deallocate_function_args(space, args):
+ _c_deallocate_function_args(args)
+_c_function_arg_sizeof = rffi.llexternal(
"cppyy_function_arg_sizeof",
[], rffi.SIZE_T,
threadsafe=ts_memory,
compilation_info=backend.eci,
elidable_function=True)
-c_function_arg_typeoffset = rffi.llexternal(
+def c_function_arg_sizeof(space):
+ return _c_function_arg_sizeof()
+_c_function_arg_typeoffset = rffi.llexternal(
"cppyy_function_arg_typeoffset",
[], rffi.SIZE_T,
threadsafe=ts_memory,
compilation_info=backend.eci,
elidable_function=True)
+def c_function_arg_typeoffset(space):
+ return _c_function_arg_typeoffset()
# scope reflection information -----------------------------------------------
-c_is_namespace = rffi.llexternal(
+_c_is_namespace = rffi.llexternal(
"cppyy_is_namespace",
[C_SCOPE], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-c_is_enum = rffi.llexternal(
+def c_is_namespace(space, scope):
+ return _c_is_namespace(scope)
+_c_is_enum = rffi.llexternal(
"cppyy_is_enum",
[rffi.CCHARP], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
+def c_is_enum(space, name):
+ return _c_is_enum(name)
# type/class reflection information ------------------------------------------
_c_final_name = rffi.llexternal(
@@ -273,7 +285,7 @@
compilation_info=backend.eci,
elidable_function=True)
@jit.elidable_promote()
-def c_is_subtype(derived, base):
+def c_is_subtype(space, derived, base):
if derived == base:
return 1
return _c_is_subtype(derived.handle, base.handle)
@@ -285,11 +297,12 @@
compilation_info=backend.eci,
elidable_function=True)
@jit.elidable_promote()
-def c_base_offset(derived, base, address, direction):
+def c_base_offset(space, derived, base, address, direction):
if derived == base:
return 0
return _c_base_offset(derived.handle, base.handle, address, direction)
-def c_base_offset1(derived_h, base, address, direction):
+ at jit.elidable_promote()
+def c_base_offset1(space, derived_h, base, address, direction):
return _c_base_offset(derived_h, base.handle, address, direction)
# method/function reflection information -------------------------------------
@@ -298,14 +311,14 @@
[C_SCOPE], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_num_methods(cppscope):
+def c_num_methods(space, cppscope):
return _c_num_methods(cppscope.handle)
_c_method_index_at = rffi.llexternal(
"cppyy_method_index_at",
[C_SCOPE, rffi.INT], C_INDEX,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-def c_method_index_at(cppscope, imethod):
+def c_method_index_at(space, cppscope, imethod):
return _c_method_index_at(cppscope.handle, imethod)
_c_method_indices_from_name = rffi.llexternal(
"cppyy_method_indices_from_name",
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,14 +1,13 @@
-import atexit
-
from rpython.rtyper.lltypesystem import rffi, lltype
-from rpython.rlib import jit, rdynload, objectmodel
+from rpython.rlib import jit, jit_libffi, rdynload, objectmodel
from rpython.tool import leakfinder
from pypy.interpreter.error import OperationError
+from pypy.module._cffi_backend import ctypefunc, ctypeprim, ctypeptr, 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, C_METHPTRGETTER_PTR
+ C_METHOD, C_INDEX, C_INDEX_ARRAY, WLAVC_INDEX, C_METHPTRGETTER_PTR
import reflex_capi as backend
@@ -17,6 +16,69 @@
def identify():
return 'loadable_capi'
+class _Arg: # poor man's union
+ _immutable_ = True
+ def __init__(self, l = 0, s = '', vp = rffi.cast(rffi.VOIDP, 0) ):
+ self._long = l
+ self._string = s
+ self._voidp = vp
+
+# For the loadable CAPI, the calls start and end in RPython. Therefore, the standard
+# _call of W_CTypeFunc, which expects wrapped objects, does not quite work: some
+# vars (e.g. void* equivalent) can not be wrapped, and others (such as rfloat) risk
+# rounding problems. This W_RCTypeFun then, takes args, instead of args_w. Note that
+# rcall() is a new method, so as to not interfere with the base class call and _call
+# when rtyping. It is also called directly (see call_capi below).
+class W_RCTypeFunc(ctypefunc.W_CTypeFunc):
+ @jit.unroll_safe
+ def rcall(self, funcaddr, args):
+ assert self.cif_descr
+ self = jit.promote(self)
+ # no checking of len(args) needed, as calls in this context are not dynamic
+
+ # The following code is functionally similar to W_CTypeFunc._call, but its
+ # implementation is tailored to the restricted use (include memory handling)
+ # of the CAPI calls.
+ space = self.space
+ cif_descr = self.cif_descr
+ size = cif_descr.exchange_size
+ raw_string = rffi.cast(rffi.CCHARP, 0) # only ever have one in the CAPI
+ buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
+ try:
+ for i in range(len(args)):
+ data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
+ obj = args[i]
+ argtype = self.fargs[i]
+ # the following is clumsy, but the data types used as arguments are
+ # very limited, so it'll do for now
+ if isinstance(argtype, ctypeprim.W_CTypePrimitiveSigned):
+ misc.write_raw_integer_data(data, rffi.cast(rffi.LONG, obj._long), argtype.size)
+ elif isinstance(argtype, ctypeprim.W_CTypePrimitiveUnsigned):
+ misc.write_raw_integer_data(data, rffi.cast(rffi.ULONG, obj._long), argtype.size)
+ elif obj._voidp != rffi.cast(rffi.VOIDP, 0):
+ data = rffi.cast(rffi.VOIDPP, data)
+ data[0] = obj._voidp
+ else: # only other use is sring
+ n = len(obj._string)
+ assert raw_string == rffi.cast(rffi.CCHARP, 0)
+ raw_string = lltype.malloc(rffi.CCHARP.TO, n+1, flavor='raw')
+ for j in range(n):
+ raw_string[j] = obj._string[j]
+ raw_string[n] = '\x00'
+ data = rffi.cast(rffi.CCHARPP, data)
+ data[0] = raw_string
+
+ jit_libffi.jit_ffi_call(cif_descr,
+ rffi.cast(rffi.VOIDP, funcaddr),
+ buffer)
+
+ resultdata = rffi.ptradd(buffer, cif_descr.exchange_result)
+ finally:
+ if raw_string != rffi.cast(rffi.CCHARP, 0):
+ lltype.free(raw_string, flavor='raw')
+ lltype.free(buffer, flavor='raw')
+ return rffi.cast(rffi.LONGP, resultdata)
+
std_string_name = backend.std_string_name
ts_reflect = backend.ts_reflect
@@ -54,7 +116,10 @@
c_double = nt.new_primitive_type(space, 'double')
c_ccharp = nt.new_pointer_type(space, c_char)
- c_voidp = nt.new_primitive_type(space, 'unsigned long') # b/c voidp can not be wrapped
+ c_index_array = nt.new_primitive_type(space, 'unsigned long') # likewise ...
+
+ c_voidp = nt.new_pointer_type(space, c_void)
+ c_size_t = nt.new_primitive_type(space, 'size_t')
self.capi_call_ifaces = {
# name to opaque C++ scope representation
@@ -88,23 +153,42 @@
'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),
+ 'get_methptr_getter' : ([c_scope, c_index], c_voidp), # TODO: verify
+
+ # handling of function argument buffer
+ 'allocate_function_args' : ([c_size_t], c_voidp),
+ 'deallocate_function_args' : ([c_voidp], c_void),
+ 'function_arg_sizeof' : ([], c_size_t),
+ 'function_arg_typeoffset' : ([], c_size_t),
+
+ # scope reflection information
+ 'is_namespace' : ([c_scope], c_int),
+ 'is_enum' : ([c_ccharp], c_int),
+
# type/class reflection information
'final_name' : ([c_type], c_ccharp),
'scoped_final_name' : ([c_type], c_ccharp),
'has_complex_hierarchy' : ([c_type], c_int),
'num_bases' : ([c_type], c_int),
'base_name' : ([c_type, c_int], c_ccharp),
+ 'is_subtype' : ([c_type, c_type], c_int),
+
+ 'base_offset' : ([c_type, c_type, c_object, c_int], c_long),
# method/function reflection information
+ 'num_methods' : ([c_scope], c_int),
+ 'method_index_at' : ([c_scope, c_int], c_index),
+ 'method_indices_from_name' : ([c_scope, c_ccharp], c_index_array),
'method_name' : ([c_scope, c_index], c_ccharp),
'method_result_type' : ([c_scope, c_index], c_ccharp),
+ 'method_num_args' : ([c_scope, c_index], c_int),
'method_arg_type' : ([c_scope, c_index, c_int], c_ccharp),
'method_arg_default' : ([c_scope, c_index, c_int], c_ccharp),
'method_signature' : ([c_scope, c_index], c_ccharp),
- 'method_template_arg_name' : ([c_scope, c_index, c_index], c_ccharp),
+ 'method_template_arg_name' : ([c_scope, c_index, c_index], c_ccharp),
# data member reflection information
'datamember_name' : ([c_scope, c_int], c_ccharp),
@@ -131,7 +215,7 @@
return False
return True
-def call_capi(space, name, args_w):
+def call_capi(space, name, args):
state = space.fromcache(State)
try:
c_call = state.capi_calls[name]
@@ -139,216 +223,149 @@
if state.library is None:
load_reflection_library(space)
iface = state.capi_call_ifaces[name]
- from pypy.module._cffi_backend.ctypefunc import W_CTypeFunc
- cfunc = W_CTypeFunc(space, iface[0], iface[1], False)
+ cfunc = W_RCTypeFunc(space, iface[0], iface[1], False)
c_call = state.library.load_function(cfunc, 'cppyy_'+name)
# TODO: there must be a better way to trick the leakfinder ...
if not objectmodel.we_are_translated():
leakfinder.remember_free(c_call.ctype.cif_descr._obj0)
state.capi_calls[name] = c_call
- return c_call.call(args_w)
+ return c_call.ctype.rcall(c_call._cdata, args)
+def _longptr_to_int(longptr):
+ return int(rffi.cast(rffi.INTP, longptr)[0])
# name to opaque C++ scope representation ------------------------------------
def c_num_scopes(space, cppscope):
- args_w = [space.wrap(cppscope.handle)]
- return space.int_w(call_capi(space, 'num_scopes', args_w))
+ return call_capi(space, 'num_scopes', [_Arg(l=cppscope.handle)])[0]
def c_scope_name(space, cppscope, iscope):
- args_w = [space.wrap(cppscope.handle), space.wrap(iscope)]
- return charp2str_free(space, call_capi(space, 'scope_name', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=iscope)]
+ return charp2str_free(space, call_capi(space, 'scope_name', args))
def c_resolve_name(space, name):
- args_w = [space.wrap(name)]
- return charp2str_free(space, call_capi(space, 'resolve_name', args_w))
+ return charp2str_free(space, call_capi(space, 'resolve_name', [_Arg(s=name)]))
def c_get_scope_opaque(space, name):
- args_w = [space.wrap(name)]
- return rffi.cast(C_SCOPE, space.int_w(call_capi(space, 'get_scope', args_w)))
+ return rffi.cast(C_SCOPE, call_capi(space, 'get_scope', [_Arg(s=name)])[0])
def c_get_template(space, name):
- args_w = [space.wrap(name)]
- return rffi.cast(C_TYPE, space.int_w(call_capi(space, 'get_template', args_w)))
+ return rffi.cast(C_TYPE, call_capi(space, 'get_template', [_Arg(s=name)])[0])
def c_actual_class(space, cppclass, cppobj):
- args_w = [space.wrap(cppclass.handle), space.wrap(cppobj)]
- return rffi.cast(C_TYPE, space.int_w(call_capi(space, 'actual_class', args_w)))
+ args = [_Arg(l=cppclass.handle), _Arg(l=cppobj)]
+ return rffi.cast(C_TYPE, call_capi(space, 'actual_class', args)[0])
# memory management ----------------------------------------------------------
def c_allocate(space, cppclass):
- args_w = [space.wrap(cppclass.handle)]
- return rffi.cast(C_OBJECT, space.int_w(call_capi(space, 'allocate', args_w)))
+ return rffi.cast(C_OBJECT, call_capi(space, 'allocate', [_Arg(l=cppclass.handle)])[0])
def c_deallocate(space, cppclass, cppobject):
- args_w = [space.wrap(cppclass.handle), space.wrap(cppobject)]
- call_capi(space, 'deallocate', args_w)
+ call_capi(space, 'deallocate', [_Arg(l=cppclass.handle), _Arg(l=cppobject)])
def c_destruct(space, cppclass, cppobject):
- args_w = [space.wrap(cppclass.handle), space.wrap(cppobject)]
- call_capi(space, 'destruct', args_w)
+ call_capi(space, 'destruct', [_Arg(l=cppclass.handle), _Arg(l=cppobject)])
# method/function dispatching ------------------------------------------------
-def c_call_v(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- call_capi(space, 'call_v', args_w)
-# TODO: these method do not actually need unwrapping, as the excutors simply
-# wrap the values again, but the other backends expect that ...
-def c_call_b(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.UCHAR, space.int_w(call_capi(space, 'call_b', args_w)))
-def c_call_c(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.CHAR, space.str_w(call_capi(space, 'call_c', args_w)))
-def c_call_h(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.SHORT, space.int_w(call_capi(space, 'call_h', args_w)))
-def c_call_i(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.INT, space.int_w(call_capi(space, 'call_i', args_w)))
-def c_call_l(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.LONG, space.int_w(call_capi(space, 'call_l', args_w)))
-def c_call_ll(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.LONGLONG, space.int_w(call_capi(space, 'call_ll', args_w)))
-def c_call_f(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.FLOAT, space.float_w(call_capi(space, 'call_f', args_w)))
-def c_call_d(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.DOUBLE, space.float_w(call_capi(space, 'call_d', args_w)))
+def c_call_v(space, cppmethod, cppobject, nargs, cargs):
+ args = [_Arg(l=cppmethod), _Arg(l=cppobject), _Arg(l=nargs), _Arg(vp=cargs)]
+ 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]
+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]
+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]
+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]
+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]
+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]
+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]
+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]
-def c_call_r(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(rffi.VOIDP, space.int_w(call_capi(space, 'call_r', args_w)))
-def c_call_s(space, cppmethod, cppobject, nargs, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return call_capi(space, 'call_s', args_w)
+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]
+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, args):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args))]
- return rffi.cast(C_OBJECT, space.int_w(call_capi(space, 'constructor', args_w)))
-def c_call_o(space, cppmethod, cppobject, nargs, args, cppclass):
- args_w = [space.wrap(cppmethod), space.wrap(cppobject),
- space.wrap(nargs), space.wrap(rffi.cast(rffi.ULONG, args)),
- space.wrap(cppclass.handle)]
- return rffi.cast(C_OBJECT, space.int_w(call_capi(space, 'call_o', args_w)))
+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])
+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])
-_c_get_methptr_getter = rffi.llexternal(
- "cppyy_get_methptr_getter",
- [C_SCOPE, C_INDEX], C_METHPTRGETTER_PTR,
- threadsafe=ts_reflect,
- compilation_info=backend.eci,
- elidable_function=True)
-def c_get_methptr_getter(cppscope, index):
- return _c_get_methptr_getter(cppscope.handle, index)
+ at 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])
# handling of function argument buffer ---------------------------------------
-c_allocate_function_args = rffi.llexternal(
- "cppyy_allocate_function_args",
- [rffi.SIZE_T], rffi.VOIDP,
- threadsafe=ts_memory,
- compilation_info=backend.eci)
-c_deallocate_function_args = rffi.llexternal(
- "cppyy_deallocate_function_args",
- [rffi.VOIDP], lltype.Void,
- threadsafe=ts_memory,
- compilation_info=backend.eci)
-c_function_arg_sizeof = rffi.llexternal(
- "cppyy_function_arg_sizeof",
- [], rffi.SIZE_T,
- threadsafe=ts_memory,
- compilation_info=backend.eci,
- elidable_function=True)
-c_function_arg_typeoffset = rffi.llexternal(
- "cppyy_function_arg_typeoffset",
- [], rffi.SIZE_T,
- threadsafe=ts_memory,
- compilation_info=backend.eci,
- elidable_function=True)
+def c_allocate_function_args(space, size):
+ return rffi.cast(rffi.VOIDP, call_capi(space, 'allocate_function_args', [_Arg(l=size)])[0])
+def c_deallocate_function_args(space, cargs):
+ call_capi(space, 'deallocate_function_args', [_Arg(vp=cargs)])
+ at jit.elidable_promote()
+def c_function_arg_sizeof(space):
+ return rffi.cast(rffi.SIZE_T, call_capi(space, 'function_arg_sizeof', [])[0])
+ at jit.elidable_promote()
+def c_function_arg_typeoffset(space):
+ return rffi.cast(rffi.SIZE_T, call_capi(space, 'function_arg_typeoffset', [])[0])
# scope reflection information -----------------------------------------------
-c_is_namespace = rffi.llexternal(
- "cppyy_is_namespace",
- [C_SCOPE], rffi.INT,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
-c_is_enum = rffi.llexternal(
- "cppyy_is_enum",
- [rffi.CCHARP], rffi.INT,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
+def c_is_namespace(space, scope):
+ return _longptr_to_int(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)]))
# type/class reflection information ------------------------------------------
def c_final_name(space, cpptype):
- args_w = [space.wrap(cpptype)]
- return charp2str_free(space, call_capi(space, 'final_name', args_w))
+ return charp2str_free(space, call_capi(space, 'final_name', [_Arg(l=cpptype)]))
def c_scoped_final_name(space, cpptype):
- args_w = [space.wrap(cpptype)]
- return charp2str_free(space, call_capi(space, 'scoped_final_name', args_w))
+ return charp2str_free(space, call_capi(space, 'scoped_final_name', [_Arg(l=cpptype)]))
def c_has_complex_hierarchy(space, handle):
- args_w = [space.wrap(handle)]
- return space.int_w(call_capi(space, 'has_complex_hierarchy', args_w))
+ return _longptr_to_int(call_capi(space, 'has_complex_hierarchy', [_Arg(l=handle)]))
def c_num_bases(space, cppclass):
- args_w = [space.wrap(cppclass.handle)]
- return space.int_w(call_capi(space, 'num_bases', args_w))
+ return _longptr_to_int(call_capi(space, 'num_bases', [_Arg(l=cppclass.handle)]))
def c_base_name(space, cppclass, base_index):
- args_w = [space.wrap(cppclass.handle), space.wrap(base_index)]
- return charp2str_free(space, call_capi(space, 'base_name', args_w))
-_c_is_subtype = rffi.llexternal(
- "cppyy_is_subtype",
- [C_TYPE, C_TYPE], rffi.INT,
- threadsafe=ts_reflect,
- compilation_info=backend.eci,
- elidable_function=True)
+ 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(derived, base):
+def c_is_subtype(space, derived, base):
if derived == base:
return 1
- return _c_is_subtype(derived.handle, base.handle)
+ return _longptr_to_int(call_capi(space, 'is_subtype', [_Arg(l=derived.handle), _Arg(l=base.handle)]))
-_c_base_offset = rffi.llexternal(
- "cppyy_base_offset",
- [C_TYPE, C_TYPE, C_OBJECT, rffi.INT], rffi.SIZE_T,
- threadsafe=ts_reflect,
- compilation_info=backend.eci,
- elidable_function=True)
@jit.elidable_promote()
-def c_base_offset(derived, base, address, direction):
+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])
+ at jit.elidable_promote()
+def c_base_offset(space, derived, base, address, direction):
if derived == base:
return 0
- return _c_base_offset(derived.handle, base.handle, address, direction)
-def c_base_offset1(derived_h, base, address, direction):
- return _c_base_offset(derived_h, base.handle, address, direction)
+ return _c_base_offset(space, derived.handle, base.handle, address, direction)
+ at jit.elidable_promote()
+def c_base_offset1(space, derived_h, base, address, direction):
+ return _c_base_offset(space, derived_h, base.handle, address, direction)
# method/function reflection information -------------------------------------
-_c_num_methods = rffi.llexternal(
- "cppyy_num_methods",
- [C_SCOPE], rffi.INT,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
-def c_num_methods(cppscope):
- return _c_num_methods(cppscope.handle)
-_c_method_index_at = rffi.llexternal(
- "cppyy_method_index_at",
- [C_SCOPE, rffi.INT], C_INDEX,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
-def c_method_index_at(cppscope, imethod):
- return _c_method_index_at(cppscope.handle, imethod)
-_c_method_indices_from_name = rffi.llexternal(
- "cppyy_method_indices_from_name",
- [C_SCOPE, rffi.CCHARP], C_INDEX_ARRAY,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
+def c_num_methods(space, cppscope):
+ args = [_Arg(l=cppscope.handle)]
+ return _longptr_to_int(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]
def c_method_indices_from_name(space, cppscope, name):
- indices = _c_method_indices_from_name(cppscope.handle, name)
+ args = [_Arg(l=cppscope.handle), _Arg(s=name)]
+ indices = rffi.cast(C_INDEX_ARRAY, call_capi(space, 'method_indices_from_name', args)[0])
if not indices:
return []
py_indices = []
@@ -362,17 +379,18 @@
return py_indices
def c_method_name(space, cppscope, index):
- args_w = [space.wrap(cppscope.handle), space.wrap(index)]
- return charp2str_free(space, call_capi(space, 'method_name', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=index)]
+ return charp2str_free(space, call_capi(space, 'method_name', args))
def c_method_result_type(space, cppscope, index):
- args_w = [space.wrap(cppscope.handle), space.wrap(index)]
- return charp2str_free(space, call_capi(space, 'method_result_type', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=index)]
+ return charp2str_free(space, call_capi(space, 'method_result_type', args))
_c_method_num_args = rffi.llexternal(
"cppyy_method_num_args",
[C_SCOPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
def c_method_num_args(cppscope, index):
+ args = [_Arg(l=cppscope.handle), _Arg(l=index)]
return _c_method_num_args(cppscope.handle, index)
_c_method_req_args = rffi.llexternal(
"cppyy_method_req_args",
@@ -382,14 +400,14 @@
def c_method_req_args(cppscope, index):
return _c_method_req_args(cppscope.handle, index)
def c_method_arg_type(space, cppscope, index, arg_index):
- args_w = [space.wrap(cppscope.handle), space.wrap(index), space.wrap(arg_index)]
- return charp2str_free(space, call_capi(space, 'method_arg_type', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=index), _Arg(l=arg_index)]
+ return charp2str_free(space, call_capi(space, 'method_arg_type', args))
def c_method_arg_default(space, cppscope, index, arg_index):
- args_w = [space.wrap(cppscope.handle), space.wrap(index), space.wrap(arg_index)]
- return charp2str_free(space, call_capi(space, 'method_arg_default', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=index), _Arg(l=arg_index)]
+ return charp2str_free(space, call_capi(space, 'method_arg_default', args))
def c_method_signature(space, cppscope, index):
- args_w = [space.wrap(cppscope.handle), space.wrap(index)]
- return charp2str_free(space, call_capi(space, 'method_signature', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=index)]
+ return charp2str_free(space, call_capi(space, 'method_signature', args))
_c_method_is_template = rffi.llexternal(
"cppyy_method_is_template",
@@ -403,17 +421,12 @@
[C_SCOPE, C_INDEX], rffi.INT,
threadsafe=ts_reflect,
compilation_info=backend.eci)
-_c_method_template_arg_name = rffi.llexternal(
- "cppyy_method_template_arg_name",
- [C_SCOPE, C_INDEX, C_INDEX], rffi.CCHARP,
- threadsafe=ts_reflect,
- compilation_info=backend.eci)
def c_template_args(space, cppscope, index):
nargs = _c_method_num_template_args(cppscope.handle, index)
+ arg1 = _Arg(l=cppscope.handle)
+ arg2 = _Arg(l=index)
args = [c_resolve_name(space, charp2str_free(space,
- call_capi(space, 'method_template_arg_name',
- [space.wrap(cppscope.handle), space.wrap(index), space.wrap(iarg)])
- )
+ call_capi(space, 'method_template_arg_name', [arg1, arg2, _Arg(l=iarg)]))
) for iarg in range(nargs)]
return args
@@ -464,16 +477,16 @@
threadsafe=ts_reflect,
compilation_info=backend.eci)
def c_datamember_name(space, cppscope, datamember_index):
- args_w = [space.wrap(cppscope.handle), space.wrap(datamember_index)]
- return charp2str_free(space, call_capi(space, 'datamember_name', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
+ return charp2str_free(space, call_capi(space, 'datamember_name', args))
_c_datamember_type = rffi.llexternal(
"cppyy_datamember_type",
[C_SCOPE, rffi.INT], rffi.CCHARP,
threadsafe=ts_reflect,
compilation_info=backend.eci)
def c_datamember_type(space, cppscope, datamember_index):
- args_w = [space.wrap(cppscope.handle), space.wrap(datamember_index)]
- return charp2str_free(space, call_capi(space, 'datamember_type', args_w))
+ args = [_Arg(l=cppscope.handle), _Arg(l=datamember_index)]
+ return charp2str_free(space, call_capi(space, 'datamember_type', args))
_c_datamember_offset = rffi.llexternal(
"cppyy_datamember_offset",
[C_SCOPE, rffi.INT], rffi.SIZE_T,
@@ -518,14 +531,12 @@
threadsafe=ts_helper,
compilation_info=backend.eci)
def c_free(space, voidp):
- args_w = [space.wrap(rffi.cast(rffi.ULONG, voidp))]
- call_capi(space, 'free', args_w)
+ call_capi(space, 'free', [_Arg(vp=voidp)])
def charp2str_free(space, cdata):
- charp = rffi.cast(rffi.CCHARP, cdata._cdata)
+ charp = rffi.cast(rffi.CCHARPP, cdata)[0]
pystr = rffi.charp2str(charp)
- voidp = rffi.cast(rffi.VOIDP, charp)
- c_free(space, voidp)
+ c_free(space, rffi.cast(rffi.VOIDP, charp))
return pystr
c_charp2stdstring = rffi.llexternal(
diff --git a/pypy/module/cppyy/converter.py b/pypy/module/cppyy/converter.py
--- a/pypy/module/cppyy/converter.py
+++ b/pypy/module/cppyy/converter.py
@@ -178,7 +178,7 @@
raise OperationError(space.w_TypeError,
space.wrap("raw buffer interface not supported"))
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'o'
+ ba[capi.c_function_arg_typeoffset(space)] = 'o'
def from_memory(self, space, w_obj, w_pycppclass, offset):
# read access, so no copy needed
@@ -249,7 +249,7 @@
x = rffi.cast(self.c_ptrtype, address)
x[0] = self._unwrap_object(space, w_obj)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = self.typecode
+ ba[capi.c_function_arg_typeoffset(space)] = self.typecode
class VoidConverter(TypeConverter):
@@ -352,7 +352,7 @@
arg = space.str_w(w_obj)
x[0] = rffi.cast(rffi.LONG, rffi.str2charp(arg))
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'o'
+ ba[capi.c_function_arg_typeoffset(space)] = 'o'
def from_memory(self, space, w_obj, w_pycppclass, offset):
address = self._get_raw_address(space, w_obj, offset)
@@ -379,7 +379,7 @@
x = rffi.cast(rffi.VOIDPP, address)
x[0] = self._unwrap_object(space, w_obj)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'o'
+ ba[capi.c_function_arg_typeoffset(space)] = 'o'
def convert_argument_libffi(self, space, w_obj, address, call_local):
x = rffi.cast(rffi.VOIDPP, address)
@@ -399,7 +399,7 @@
except TypeError:
r[0] = rffi.cast(rffi.VOIDP, get_rawobject(space, w_obj))
x[0] = rffi.cast(rffi.VOIDP, call_local)
- ba[capi.c_function_arg_typeoffset()] = 'a'
+ ba[capi.c_function_arg_typeoffset(space)] = 'a'
def finalize_call(self, space, w_obj, call_local):
r = rffi.cast(rffi.VOIDPP, call_local)
@@ -425,9 +425,9 @@
def _unwrap_object(self, space, w_obj):
from pypy.module.cppyy.interp_cppyy import W_CPPInstance
if isinstance(w_obj, W_CPPInstance):
- if capi.c_is_subtype(w_obj.cppclass, self.cppclass):
+ if capi.c_is_subtype(space, w_obj.cppclass, self.cppclass):
rawobject = w_obj.get_rawobject()
- offset = capi.c_base_offset(w_obj.cppclass, self.cppclass, rawobject, 1)
+ offset = capi.c_base_offset(space, w_obj.cppclass, self.cppclass, rawobject, 1)
obj_address = capi.direct_ptradd(rawobject, offset)
return rffi.cast(capi.C_OBJECT, obj_address)
raise OperationError(space.w_TypeError,
@@ -439,7 +439,7 @@
x[0] = rffi.cast(rffi.VOIDP, self._unwrap_object(space, w_obj))
address = rffi.cast(capi.C_OBJECT, address)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'o'
+ ba[capi.c_function_arg_typeoffset(space)] = 'o'
def convert_argument_libffi(self, space, w_obj, address, call_local):
x = rffi.cast(rffi.VOIDPP, address)
@@ -481,7 +481,7 @@
x[0] = rffi.cast(rffi.VOIDP, call_local)
address = rffi.cast(capi.C_OBJECT, address)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'o'
+ ba[capi.c_function_arg_typeoffset(space)] = 'o'
def convert_argument_libffi(self, space, w_obj, address, call_local):
# TODO: finalize_call not yet called for fast call (see interp_cppyy.py)
@@ -556,7 +556,7 @@
x = rffi.cast(rffi.VOIDPP, address)
x[0] = rffi.cast(rffi.VOIDP, ref)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = 'a'
+ ba[capi.c_function_arg_typeoffset(space)] = 'a'
def convert_argument_libffi(self, space, w_obj, address, call_local):
# TODO: free_argument not yet called for fast call (see interp_cppyy.py)
@@ -638,7 +638,7 @@
return InstancePtrPtrConverter(space, cppclass)
elif compound == "":
return InstanceConverter(space, cppclass)
- elif capi.c_is_enum(clean_name):
+ elif capi.c_is_enum(space, clean_name):
return _converters['unsigned'](space, default)
# 5) void converter, which fails on use
@@ -711,7 +711,7 @@
x = rffi.cast(self.c_ptrtype, address)
x[0] = self._unwrap_object(space, w_obj)
ba = rffi.cast(rffi.CCHARP, address)
- ba[capi.c_function_arg_typeoffset()] = self.typecode
+ ba[capi.c_function_arg_typeoffset(space)] = self.typecode
for name in names:
_converters[name] = BasicConverter
_converters["const "+name+"&"] = ConstRefConverter
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
@@ -200,8 +200,8 @@
class StdStringExecutor(InstancePtrExecutor):
def execute(self, space, cppmethod, cppthis, num_args, args):
- charp_result = capi.c_call_s(space, cppmethod, cppthis, num_args, args)
- return space.wrap(capi.charp2str_free(space, charp_result))
+ cstr_result = capi.c_call_s(space, cppmethod, cppthis, num_args, args)
+ return space.wrap(capi.charp2str_free(space, cstr_result))
def execute_libffi(self, space, cif_descr, funcaddr, buffer):
from pypy.module.cppyy.interp_cppyy import FastCallNotPossible
@@ -281,7 +281,7 @@
return InstancePtrExecutor(space, cppclass)
elif compound == '**' or compound == '*&':
return InstancePtrPtrExecutor(space, cppclass)
- elif capi.c_is_enum(clean_name):
+ elif capi.c_is_enum(space, clean_name):
return _executors['unsigned int'](space, None)
# 4) additional special cases
diff --git a/pypy/module/cppyy/interp_cppyy.py b/pypy/module/cppyy/interp_cppyy.py
--- a/pypy/module/cppyy/interp_cppyy.py
+++ b/pypy/module/cppyy/interp_cppyy.py
@@ -62,7 +62,7 @@
assert lltype.typeOf(opaque_handle) == capi.C_SCOPE
if opaque_handle:
final_name = capi.c_final_name(space, opaque_handle)
- if capi.c_is_namespace(opaque_handle):
+ if capi.c_is_namespace(space, opaque_handle):
cppscope = W_CPPNamespace(space, final_name, opaque_handle)
elif capi.c_has_complex_hierarchy(space, opaque_handle):
cppscope = W_ComplexCPPClass(space, final_name, opaque_handle)
@@ -246,7 +246,7 @@
# Each CPPMethod corresponds one-to-one to a C++ equivalent and cppthis
# has been offset to the matching class. Hence, the libffi pointer is
# uniquely defined and needs to be setup only once.
- methgetter = capi.c_get_methptr_getter(self.scope, self.index)
+ methgetter = capi.c_get_methptr_getter(self.space, self.scope, self.index)
if methgetter and cppthis: # methods only for now
cif_descr = lltype.nullptr(jit_libffi.CIF_DESCRIPTION)
try:
@@ -328,8 +328,8 @@
@jit.unroll_safe
def prepare_arguments(self, args_w, call_local):
- args = capi.c_allocate_function_args(len(args_w))
- stride = capi.c_function_arg_sizeof()
+ args = capi.c_allocate_function_args(self.space, len(args_w))
+ stride = capi.c_function_arg_sizeof(self.space)
for i in range(len(args_w)):
conv = self.converters[i]
w_arg = args_w[i]
@@ -344,20 +344,20 @@
arg_j = lltype.direct_ptradd(rffi.cast(rffi.CCHARP, args), j*stride)
loc_j = self._address_from_local_buffer(call_local, j)
conv.free_argument(self.space, rffi.cast(capi.C_OBJECT, arg_j), loc_j)
- capi.c_deallocate_function_args(args)
+ capi.c_deallocate_function_args(self.space, args)
raise
return args
@jit.unroll_safe
def finalize_call(self, args, args_w, call_local):
- stride = capi.c_function_arg_sizeof()
+ stride = capi.c_function_arg_sizeof(self.space)
for i in range(len(args_w)):
conv = self.converters[i]
arg_i = lltype.direct_ptradd(rffi.cast(rffi.CCHARP, args), i*stride)
loc_i = self._address_from_local_buffer(call_local, i)
conv.finalize_call(self.space, args_w[i], loc_i)
conv.free_argument(self.space, rffi.cast(capi.C_OBJECT, arg_i), loc_i)
- capi.c_deallocate_function_args(args)
+ capi.c_deallocate_function_args(self.space, args)
def signature(self):
return capi.c_method_signature(self.space, self.scope, self.index)
@@ -584,7 +584,7 @@
def _get_offset(self, cppinstance):
if cppinstance:
assert lltype.typeOf(cppinstance.cppclass.handle) == lltype.typeOf(self.scope.handle)
- offset = self.offset + capi.c_base_offset(
+ offset = self.offset + capi.c_base_offset(self.space,
cppinstance.cppclass, self.scope, cppinstance.get_rawobject(), 1)
else:
offset = self.offset
@@ -659,8 +659,8 @@
def _build_methods(self):
assert len(self.methods) == 0
methods_temp = {}
- for i in range(capi.c_num_methods(self)):
- idx = capi.c_method_index_at(self, i)
+ for i in range(capi.c_num_methods(self.space, self)):
+ idx = capi.c_method_index_at(self.space, self, i)
pyname = helper.map_operator_name(self.space,
capi.c_method_name(self.space, self, idx),
capi.c_method_num_args(self, idx),
@@ -799,8 +799,8 @@
sname = capi.c_scope_name(self.space, self, i)
if sname: alldir.append(self.space.wrap(sname))
allmeth = {}
- for i in range(capi.c_num_methods(self)):
- idx = capi.c_method_index_at(self, i)
+ for i in range(capi.c_num_methods(self.space, self)):
+ idx = capi.c_method_index_at(self.space, self, i)
mname = capi.c_method_name(self.space, self, idx)
if mname: allmeth.setdefault(mname, 0)
for m in allmeth.keys():
@@ -915,7 +915,8 @@
def get_cppthis(self, cppinstance, calling_scope):
assert self == cppinstance.cppclass
- offset = capi.c_base_offset(self, calling_scope, cppinstance.get_rawobject(), 1)
+ offset = capi.c_base_offset(self.space,
+ self, calling_scope, cppinstance.get_rawobject(), 1)
return capi.direct_ptradd(cppinstance.get_rawobject(), offset)
W_ComplexCPPClass.typedef = TypeDef(
@@ -1143,7 +1144,7 @@
if actual != cppclass.handle:
try:
w_pycppclass = get_pythonized_cppclass(space, actual)
- offset = capi.c_base_offset1(actual, cppclass, rawobject, -1)
+ offset = capi.c_base_offset1(space, actual, cppclass, rawobject, -1)
rawobject = capi.direct_ptradd(rawobject, offset)
w_cppclass = space.findattr(w_pycppclass, space.wrap("_cpp_proxy"))
cppclass = space.interp_w(W_CPPClass, w_cppclass, can_be_None=False)
@@ -1164,7 +1165,7 @@
# fresh creation
w_cppinstance = space.allocate_instance(W_CPPInstance, w_pycppclass)
- cppinstance = space.interp_w(W_CPPInstance, w_cppinstance)
+ cppinstance = space.interp_w(W_CPPInstance, w_cppinstance, can_be_None=False)
cppinstance.__init__(space, cppclass, rawobject, is_ref, python_owns)
memory_regulator.register(cppinstance)
return w_cppinstance
More information about the pypy-commit
mailing list