[pypy-svn] r26412 - in pypy/dist/pypy/translator/c: . src test winproj/extension
tismer at codespeak.net
tismer at codespeak.net
Thu Apr 27 09:55:21 CEST 2006
Author: tismer
Date: Thu Apr 27 09:55:16 2006
New Revision: 26412
Modified:
pypy/dist/pypy/translator/c/genc.py
pypy/dist/pypy/translator/c/pyobj.py
pypy/dist/pypy/translator/c/src/module.h
pypy/dist/pypy/translator/c/test/test_wrapping.py
pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj
pypy/dist/pypy/translator/c/wrapper.py
Log:
added support for creation of real PyCFunction based methods, for speed
Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py (original)
+++ pypy/dist/pypy/translator/c/genc.py Thu Apr 27 09:55:16 2006
@@ -33,7 +33,7 @@
self.libraries = libraries
self.exports = {}
- def build_database(self, exports=[]):
+ def build_database(self, exports=[], pyobj_options=None):
translator = self.translator
db = LowLevelDatabase(translator, standalone=self.standalone,
gcpolicy=self.gcpolicy, thread_enabled=self.thread_enabled)
@@ -43,6 +43,11 @@
db.stacklessdata = StacklessData(db)
db.use_stackless_transformation = self.use_stackless_transformation
+ # pass extra options into pyobjmaker
+ if pyobj_options:
+ for key, value in pyobj_options.items():
+ setattr(db.pyobjmaker, key, value)
+
# we need a concrete gcpolicy to do this
self.libraries += db.gcpolicy.gc_libraries()
@@ -720,6 +725,7 @@
pyobjnode = database.containernodes[pyobjptr._obj]
print >> f, '\tPyModule_AddObject(m, "%s", %s);' % (publicname,
pyobjnode.name)
+ print >> f, '\tcall_postsetup(m);'
print >> f, '}'
f.close()
Modified: pypy/dist/pypy/translator/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py (original)
+++ pypy/dist/pypy/translator/c/pyobj.py Thu Apr 27 09:55:16 2006
@@ -39,6 +39,8 @@
self.import_hints = {} # I don't seem to need it any longer.
# leaving the import support intact, doesn't hurt.
self.name_for_meth = {} # get nicer wrapper names
+ self.is_method = {}
+ self.use_true_methods = False # may be overridden
def nameof(self, obj, debug=None):
if debug:
@@ -212,7 +214,8 @@
return self.skipped_function(func)
fwrapper = gen_wrapper(func, self.translator,
- newname=self.name_for_meth.get(func, func.__name__))
+ newname=self.name_for_meth.get(func, func.__name__),
+ as_method=func in self.is_method)
pycfunctionobj = self.uniquename('gfunc_' + func.__name__)
self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper), func.__doc__
return pycfunctionobj
@@ -574,6 +577,7 @@
if ann.binding(graph.getargs()[0]).classdef is not clsdef:
value = new_method_graph(graph, clsdef, fname, self.translator)
self.name_for_meth[value] = fname
+ self.is_method[value] = self.use_true_methods
yield '%s.%s = %s' % (name, key, self.nameof(value))
if not init_seen:
log.WARNING('No __init__ found for %s - you cannot build instances' %
Modified: pypy/dist/pypy/translator/c/src/module.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/module.h (original)
+++ pypy/dist/pypy/translator/c/src/module.h Thu Apr 27 09:55:16 2006
@@ -60,8 +60,10 @@
/* helper-hook for post-setup */
static globalfunctiondef_t *globalfunctiondefsptr;
-static PyObject *postsetup_get_type_dict(PyObject *tp);
+static PyObject *postsetup_get_typedict(PyObject *tp);
+static PyObject *postsetup_get_methodname(int funcidx);
static PyObject *postsetup_build_method(int funcidx, PyObject *type);
+int call_postsetup(PyObject *m);
/* implementations */
@@ -145,7 +147,7 @@
return 0;
}
-static PyObject *postsetup_get_type_dict(PyObject *tp)
+static PyObject *postsetup_get_typedict(PyObject *tp)
{
PyTypeObject *type = (PyTypeObject *)tp;
PyObject *ret;
@@ -155,11 +157,39 @@
return ret;
}
+static PyObject *postsetup_get_methodname(int funcidx)
+{
+ globalfunctiondef_t *gfuncdef = &globalfunctiondefsptr[funcidx];
+
+ if (gfuncdef->p)
+ return PyString_FromString(gfuncdef->gfunc_name);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
static PyObject *postsetup_build_method(int funcidx, PyObject *type)
{
globalfunctiondef_t *gfuncdef = &globalfunctiondefsptr[funcidx];
- return PyDescr_NewMethod((PyTypeObject *)type, &gfuncdef->ml);
+ if (gfuncdef->p)
+ return PyDescr_NewMethod((PyTypeObject *)type, &gfuncdef->ml);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+int call_postsetup(PyObject *m)
+{
+ PyObject *init, *ret;
+
+ init = PyDict_GetItemString(this_module_globals, "__init__");
+ if (init == NULL) {
+ PyErr_Clear();
+ return 0;
+ }
+ ret = PyObject_CallFunction(init, "O", m);
+ if (ret == NULL)
+ return -1;
+ return 0;
}
#endif /* PYPY_NOT_MAIN_FILE */
Modified: pypy/dist/pypy/translator/c/test/test_wrapping.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_wrapping.py (original)
+++ pypy/dist/pypy/translator/c/test/test_wrapping.py Thu Apr 27 09:55:16 2006
@@ -9,7 +9,7 @@
import sys, types
-P = not False # debug printing
+P = False # debug printing
def get_annotation(func):
argstypelist = []
@@ -68,7 +68,10 @@
cbuilder = CExtModuleBuilder(t, func, gcpolicy=gcpolicy)
# explicit build of database
- db = cbuilder.build_database(exports=exports)
+ pyobj_options = {
+ 'use_true_methods': '__init__' in exports
+ }
+ db = cbuilder.build_database(exports=exports, pyobj_options=pyobj_options)
cbuilder.generate_source(db)
if view:
t.viewcg()
@@ -238,38 +241,70 @@
exec src
del __builtin__, name, obj, src
-def setup_new_module(mod, modname):
- # note the name clash with py.test on setup_module
+
+def get_methodname(funcidx):
+ pass
+
+class Entry(ExtRegistryEntry):
+ _about_ = get_methodname
+ s_result_annotation = annmodel.SomeObject()
+
+ def specialize_call(self, hop):
+ v_idx, = hop.inputargs(*hop.args_r)
+ v_res = hop.llops.gencapicall('postsetup_get_methodname', [v_idx],
+ resulttype=robject.pyobj_repr)
+ return v_res
+
+def build_method(funcidx):
+ pass
+
+class Entry(ExtRegistryEntry):
+ _about_ = build_method
+ s_result_annotation = annmodel.SomeObject()
+
+ def specialize_call(self, hop):
+ v_idx, v_type = hop.inputargs(*hop.args_r)
+ v_res = hop.llops.gencapicall('postsetup_build_method', [v_idx, v_type],
+ resulttype=robject.pyobj_repr)
+ return v_res
+
+def get_typedict(cls):
+ pass
+
+class Entry(ExtRegistryEntry):
+ _about_ = get_typedict
+ s_result_annotation = annmodel.SomeObject()
+
+ def specialize_call(self, hop):
+ v_type, = hop.inputargs(*hop.args_r)
+ v_res = hop.llops.gencapicall('postsetup_get_typedict', [v_type],
+ resulttype=robject.pyobj_repr)
+ return v_res
+
+def __init__(mod):
import types
- m = types.ModuleType(modname)
- allobjs = mod.__dict__.values()
- funcs = eval('[]') # or import list from __builtin__
- # one alternative
- #bltn = BuiltinHelper()
- # less code:
import __builtin__ as bltn
- if P:print bltn.list('hallo')
- #from twisted.internet import reactor
- #print dir(reactor)
- #whow this works
- isinstance = eval('isinstance')
- # above is possible, this is probably a better compromise:
+ hasattr = bltn.hasattr
isinstance = bltn.isinstance
- for obj in allobjs:
- if isinstance(obj, types.BuiltinFunctionType):
- funcs.append( (obj.__name__, obj) )
- if P:print 'funcs=', funcs
- if P:print funcs[3:]
- #funcs += [2, 3, 5]
- # not yet
- stuff = bltn.range(10)
- if P:print stuff[3:]
- if P:print stuff[:3]
- if P:print stuff[3:7]
- if P:print stuff[:-1]
- funcs.sort()
- return m
-
+ classes = []
+ x = 0
+ for name in mod.__all__:
+ obj = getattr(mod, name)
+ if isinstance(obj, type) and hasattr(obj, '__self__'):
+ classes.append(obj)
+ idx = 0
+ while 1:
+ name = get_methodname(idx)
+ if not name:
+ break
+ func = getattr(mod, name)
+ for cls in classes:
+ dic = get_typedict(cls)
+ for methname, value in dic.items():
+ if func is value:
+ meth = build_method(idx, cls)
+ dic[methname] = meth
+ idx += 1
# creating an object, wrapping, unwrapping, call function, check whether __del__ is called
def test_wrap_call_dtor():
@@ -281,7 +316,7 @@
# exposing and using classes from a generasted extension module
def test_expose_classes():
m = get_compiled_module(democlass_helper2, use_boehm=not True, exports=[
- DemoClass, DemoSubclass, DemoNotAnnotated, setup_new_module])
+ DemoClass, DemoSubclass, DemoNotAnnotated, __init__])
obj = m.DemoClass(2, 3)
res = obj.demo()
assert res == DemoClass(2, 3).demo()
Modified: pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj
==============================================================================
--- pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj (original)
+++ pypy/dist/pypy/translator/c/winproj/extension/extension.vcproj Thu Apr 27 09:55:16 2006
@@ -208,7 +208,7 @@
</File>
</Filter>
<File
- RelativePath="..\..\..\..\..\..\..\Documents and Settings\ctismer\Local Settings\Temp\usession-2331\testing_1\testing_1.c">
+ RelativePath="..\..\..\..\..\..\..\Documents and Settings\ctismer\Local Settings\Temp\usession-2434\testing_1\testing_1.c">
</File>
</Files>
<Globals>
Modified: pypy/dist/pypy/translator/c/wrapper.py
==============================================================================
--- pypy/dist/pypy/translator/c/wrapper.py (original)
+++ pypy/dist/pypy/translator/c/wrapper.py Thu Apr 27 09:55:16 2006
@@ -13,7 +13,7 @@
ALWAYS_INLINE = False
-def gen_wrapper(func, translator, newname=None):
+def gen_wrapper(func, translator, newname=None, as_method=False):
"""generate a wrapper function for 'func' that can be put in a
PyCFunction object. The wrapper has signature
@@ -63,6 +63,9 @@
varguments = []
varnames = func.func_code.co_varnames
func_defaults = func.func_defaults or ()
+ if as_method:
+ nb_positional_args -= 1
+ varnames = varnames[1:]
for i in range(nb_positional_args):
# "argument_i = decode_arg(fname, i, name, vargs, vkwds)" or
# "argument_i = decode_arg_def(fname, i, name, vargs, vkwds, default)"
@@ -102,6 +105,8 @@
# use the rtyper to produce the conversions
inputargs = f._obj.graph.getargs()
+ if as_method:
+ varguments.insert(0, vself)
for i in range(len(varguments)):
if FUNCTYPE.ARGS[i] != PyObjPtr:
# "argument_i = type_conversion_operations(argument_i)"
More information about the Pypy-commit
mailing list