Author: Wim Lavrijsen <[email protected]>
Branch: reflex-support
Changeset: r71119:0eff3fae1c87
Date: 2014-04-30 10:54 -0700
http://bitbucket.org/pypy/pypy/changeset/0eff3fae1c87/
Log: refactoring/cleanup
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
@@ -158,9 +158,9 @@
'converters', 'executor', '_funcaddr', 'cif_descr',
'uses_local']
_immutable_ = True
- def __init__(self, space, containing_scope, method_index, arg_defs,
args_required):
+ def __init__(self, space, declaring_scope, method_index, arg_defs,
args_required):
self.space = space
- self.scope = containing_scope
+ self.scope = declaring_scope
self.index = method_index
self.cppmethod = capi.c_get_method(self.space, self.scope,
method_index)
self.arg_defs = arg_defs
@@ -174,6 +174,12 @@
self._funcaddr = lltype.nullptr(rffi.VOIDP.TO)
self.uses_local = False
+ @staticmethod
+ def unpack_cppthis(space, w_cppinstance, declaring_scope):
+ cppinstance = space.interp_w(W_CPPInstance, w_cppinstance,
can_be_None=False)
+ cppinstance._nullcheck()
+ return cppinstance.get_cppthis(declaring_scope)
+
def _address_from_local_buffer(self, call_local, idx):
if not call_local:
return call_local
@@ -181,12 +187,6 @@
loc_idx = lltype.direct_ptradd(rffi.cast(rffi.CCHARP, call_local),
idx*stride)
return rffi.cast(rffi.VOIDP, loc_idx)
- def call_w(self, w_cppinstance, args_w):
- cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance,
can_be_None=False)
- cppinstance._nullcheck()
- cppthis = cppinstance.get_cppthis(self.scope)
- return self.call(cppthis, args_w)
-
@jit.unroll_safe
def call(self, cppthis, args_w):
assert lltype.typeOf(cppthis) == capi.C_OBJECT
@@ -413,8 +413,9 @@
_immutable_ = True
- def call_w(self, w_cppinstance, args_w):
- return CPPMethod.call(self, capi.C_NULL_OBJECT, args_w)
+ @staticmethod
+ def unpack_cppthis(space, w_cppinstance, declaring_scope):
+ return capi.C_NULL_OBJECT
def __repr__(self):
return "CPPFunction: %s" % self.signature()
@@ -426,11 +427,11 @@
_attrs_ = ['space', 'templ_args']
_immutable_ = True
- def __init__(self, space, templ_args, containing_scope, method_index,
arg_defs, args_required):
+ def __init__(self, space, templ_args, declaring_scope, method_index,
arg_defs, args_required):
self.space = space
self.templ_args = templ_args
# TODO: might have to specialize for CPPTemplatedCall on
CPPMethod/CPPFunction here
- CPPMethod.__init__(self, space, containing_scope, method_index,
arg_defs, args_required)
+ CPPMethod.__init__(self, space, declaring_scope, method_index,
arg_defs, args_required)
def call(self, cppthis, args_w):
assert lltype.typeOf(cppthis) == capi.C_OBJECT
@@ -460,19 +461,15 @@
_immutable_ = True
- def call_w(self, w_cppinstance, args_w):
- # TODO: these casts are very, very un-pretty; need to find a way of
- # re-using CPPMethod's features w/o these roundabouts
- vscope = rffi.cast(capi.C_OBJECT, self.scope.handle)
- cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance,
can_be_None=True)
- w_result = CPPMethod.call(self, vscope, args_w)
- newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result))
- if cppinstance is not None:
- cppinstance._rawobject = newthis
- memory_regulator.register(cppinstance)
- return w_cppinstance
- return wrap_cppobject(self.space, newthis, self.scope,
- do_cast=False, python_owns=True, fresh=True)
+ @staticmethod
+ def unpack_cppthis(space, w_cppinstance, declaring_scope):
+ return rffi.cast(capi.C_OBJECT, declaring_scope.handle)
+
+ def call(self, cppthis, args_w):
+ # Note: this does not return a wrapped instance, just a pointer to the
+ # new instance; the overload must still wrap it before returning. Also,
+ # cppthis is declaring_scope.handle (as per unpack_cppthis(), above).
+ return CPPMethod.call(self, cppthis, args_w)
def __repr__(self):
return "CPPConstructor: %s" % self.signature()
@@ -501,12 +498,12 @@
collection of (possibly) overloaded methods or functions. It calls these
in order and deals with error handling and reporting."""
- _attrs_ = ['space', 'scope', 'functions']
- _immutable_fields_ = ['scope', 'functions[*]']
+ _attrs_ = ['space', 'functions']
+ _immutable_fields_ = ['functions[*]']
- def __init__(self, space, containing_scope, functions):
+ def __init__(self, space, declaring_scope, functions):
self.space = space
- self.scope = containing_scope
+ self.scope = declaring_scope
assert len(functions)
from rpython.rlib import debug
self.functions = debug.make_sure_not_resized(functions)
@@ -520,6 +517,12 @@
@jit.unroll_safe
@unwrap_spec(args_w='args_w')
def call(self, w_cppinstance, args_w):
+ # instance handling is specific to the function type only, so take it
out
+ # of the loop over function overloads
+ cppthis = self.functions[0].unpack_cppthis(
+ self.space, w_cppinstance, self.functions[0].scope)
+ assert lltype.typeOf(cppthis) == capi.C_OBJECT
+
# The following code tries out each of the functions in order. If
# argument conversion fails (or simply if the number of arguments do
# not match), that will lead to an exception, The JIT will snip out
@@ -534,7 +537,7 @@
for i in range(len(self.functions)):
cppyyfunc = self.functions[i]
try:
- return cppyyfunc.call_w(w_cppinstance, args_w)
+ return cppyyfunc.call(cppthis, args_w)
except Exception:
pass
@@ -545,7 +548,7 @@
for i in range(len(self.functions)):
cppyyfunc = self.functions[i]
try:
- return cppyyfunc.call_w(w_cppinstance, args_w)
+ return cppyyfunc.call(cppthis, args_w)
except OperationError, e:
# special case if there's just one function, to prevent
clogging the error message
if len(self.functions) == 1:
@@ -577,6 +580,39 @@
)
+class W_CPPConstructorOverload(W_CPPOverload):
+ @jit.elidable_promote()
+ def is_static(self):
+ return self.space.w_False
+
+ @jit.elidable_promote()
+ def unpack_cppthis(self, w_cppinstance):
+ return rffi.cast(capi.C_OBJECT, self.scope.handle)
+
+ @jit.unroll_safe
+ @unwrap_spec(args_w='args_w')
+ def call(self, w_cppinstance, args_w):
+ w_result = W_CPPOverload.call(self, w_cppinstance, args_w)
+ newthis = rffi.cast(capi.C_OBJECT, self.space.int_w(w_result))
+ cppinstance = self.space.interp_w(W_CPPInstance, w_cppinstance,
can_be_None=True)
+ if cppinstance is not None:
+ cppinstance._rawobject = newthis
+ memory_regulator.register(cppinstance)
+ return w_cppinstance
+ return wrap_cppobject(self.space, newthis, self.functions[0].scope,
+ do_cast=False, python_owns=True, fresh=True)
+
+ def __repr__(self):
+ return "W_CPPConstructorOverload(%s)" % [f.signature() for f in
self.functions]
+
+W_CPPConstructorOverload.typedef = TypeDef(
+ 'CPPConstructorOverload',
+ is_static = interp2app(W_CPPConstructorOverload.is_static),
+ call = interp2app(W_CPPConstructorOverload.call),
+ signature = interp2app(W_CPPOverload.signature),
+)
+
+
class W_CPPBoundMethod(W_Root):
_attrs_ = ['cppthis', 'method']
@@ -597,9 +633,9 @@
_attrs_ = ['space', 'scope', 'converter', 'offset']
_immutable_fields = ['scope', 'converter', 'offset']
- def __init__(self, space, containing_scope, type_name, offset):
+ def __init__(self, space, declaring_scope, type_name, offset):
self.space = space
- self.scope = containing_scope
+ self.scope = declaring_scope
self.converter = converter.get_converter(self.space, type_name, '')
self.offset = offset
@@ -709,7 +745,10 @@
# create the overload methods from the method sets
for pyname, methods in methods_temp.iteritems():
CPPMethodSort(methods).sort()
- overload = W_CPPOverload(self.space, self, methods[:])
+ if pyname == self.name:
+ overload = W_CPPConstructorOverload(self.space, self,
methods[:])
+ else:
+ overload = W_CPPOverload(self.space, self, methods[:])
self.methods[pyname] = overload
def full_name(self):
@@ -849,14 +888,13 @@
class W_CPPClass(W_CPPScope):
- _attrs_ = ['space', 'default_constructor', 'name', 'handle', 'methods',
'datamembers']
- _immutable_fields_ = ['kind', 'default_constructor', 'methods[*]',
'datamembers[*]']
+ _attrs_ = ['space', 'name', 'handle', 'methods', 'datamembers']
+ _immutable_fields_ = ['kind', 'constructor', 'methods[*]',
'datamembers[*]']
kind = "class"
def __init__(self, space, name, opaque_handle):
W_CPPScope.__init__(self, space, name, opaque_handle)
- self.default_constructor = None
def _make_cppfunction(self, pyname, index):
num_args = capi.c_method_num_args(self.space, self, index)
@@ -868,8 +906,6 @@
arg_defs.append((arg_type, arg_dflt))
if capi.c_is_constructor(self.space, self, index):
cppfunction = CPPConstructor(self.space, self, index, arg_defs,
args_required)
- if args_required == 0:
- self.default_constructor = cppfunction
elif capi.c_method_is_template(self.space, self, index):
templ_args = capi.c_template_args(self.space, self, index)
cppfunction = CPPTemplatedCall(self.space, templ_args, self,
index, arg_defs, args_required)
@@ -897,9 +933,7 @@
self.datamembers[datamember_name] = datamember
def construct(self):
- if self.default_constructor is not None:
- return self.default_constructor.call(capi.C_NULL_OBJECT, None, [])
- raise self.missing_attribute_error("default_constructor")
+ self.get_overload(self.name).call(None, [])
def find_overload(self, name):
raise self.missing_attribute_error(name)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit