Author: Antonio Cuni <[email protected]>
Branch: hpy
Changeset: r98171:64a75c77d1cc
Date: 2019-11-28 11:52 +0100
http://bitbucket.org/pypy/pypy/changeset/64a75c77d1cc/

Log:    finally! Collect all the api functions automatically and stick them
        into the context. We need to make this RPython, though

diff --git a/pypy/module/hpy_universal/apiset.py 
b/pypy/module/hpy_universal/apiset.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/hpy_universal/apiset.py
@@ -0,0 +1,39 @@
+import re
+from rpython.rtyper.annlowlevel import llhelper
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rlib.objectmodel import specialize, llhelper_can_raise
+
+
+class APISet(object):
+
+    _PREFIX = re.compile(r'^_?HPy_?')
+
+    def __init__(self):
+        self.all_functions = []
+
+    def func(self, argtypes, restype):
+        def decorate(fn):
+            # attach various helpers to fn, so you can access things like
+            # HPyNumber_Add.get_llhelper(), HPyNumber_Add.basename, etc.
+
+            # get_llhelper
+            ll_functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
+            @specialize.memo()
+            def make_wrapper(space):
+                @llhelper_can_raise
+                def wrapper(*args):
+                    return fn(space, *args)
+                return wrapper
+            def get_llhelper(space):
+                return llhelper(ll_functype, make_wrapper(space))
+            fn.get_llhelper = get_llhelper
+
+            # basename
+            fn.basename = self._PREFIX.sub(r'', fn.__name__)
+
+            # record it into the API
+            self.all_functions.append(fn)
+            return fn
+        return decorate
+
+API = APISet()
diff --git a/pypy/module/hpy_universal/interp_hpy.py 
b/pypy/module/hpy_universal/interp_hpy.py
--- a/pypy/module/hpy_universal/interp_hpy.py
+++ b/pypy/module/hpy_universal/interp_hpy.py
@@ -1,7 +1,5 @@
-from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.rdynload import dlopen, dlsym, DLOpenError
-from rpython.rlib.objectmodel import specialize, llhelper_can_raise
 from rpython.rlib import rutf8
 
 from pypy.interpreter.gateway import unwrap_spec
@@ -11,26 +9,11 @@
 
 from pypy.module.hpy_universal import llapi, handles, interp_extfunc
 from pypy.module.hpy_universal.state import State
+from pypy.module.hpy_universal.apiset import API
 from pypy.module.cpyext.api import generic_cpy_call_dont_convert_result
 
 
-def apifunc(argtypes, restype):
-    def decorate(fn):
-        ll_functype = lltype.Ptr(lltype.FuncType(argtypes, restype))
-        @specialize.memo()
-        def make_wrapper(space):
-            @llhelper_can_raise
-            def wrapper(*args):
-                return fn(space, *args)
-            return wrapper
-        def get_llhelper(space):
-            return llhelper(ll_functype, make_wrapper(space))
-        fn.get_llhelper = get_llhelper
-        return fn
-    return decorate
-
-
-@apifunc([llapi.HPyContext, lltype.Ptr(llapi.HPyModuleDef)], llapi.HPy)
[email protected]([llapi.HPyContext, lltype.Ptr(llapi.HPyModuleDef)], llapi.HPy)
 def HPyModule_Create(space, ctx, hpydef):
     modname = rffi.constcharp2str(hpydef.c_m_name)
     w_mod = Module(space, space.newtext(modname))
@@ -51,20 +34,20 @@
     return handles.new(space, w_mod)
 
 
-@apifunc([llapi.HPyContext, llapi.HPy], llapi.HPy)
[email protected]([llapi.HPyContext, llapi.HPy], llapi.HPy)
 def HPy_Dup(space, ctx, h):
     return handles.dup(space, h)
 
-@apifunc([llapi.HPyContext, llapi.HPy], lltype.Void)
[email protected]([llapi.HPyContext, llapi.HPy], lltype.Void)
 def HPy_Close(space, ctx, h):
     handles.close(space, h)
 
-@apifunc([llapi.HPyContext, rffi.LONG], llapi.HPy)
[email protected]([llapi.HPyContext, rffi.LONG], llapi.HPy)
 def HPyLong_FromLong(space, ctx, value):
     w_obj = space.newint(rffi.cast(lltype.Signed, value))
     return handles.new(space, w_obj)
 
-@apifunc([llapi.HPyContext, llapi.HPy], rffi.LONG)
[email protected]([llapi.HPyContext, llapi.HPy], rffi.LONG)
 def HPyLong_AsLong(space, ctx, h):
     w_obj = handles.deref(space, h)
     #w_obj = space.int(w_obj)     --- XXX write a test for this
@@ -74,14 +57,14 @@
     #    ...
     return result
 
-@apifunc([llapi.HPyContext, llapi.HPy, llapi.HPy], llapi.HPy)
[email protected]([llapi.HPyContext, llapi.HPy, llapi.HPy], llapi.HPy)
 def HPyNumber_Add(space, ctx, h1, h2):
     w_obj1 = handles.deref(space, h1)
     w_obj2 = handles.deref(space, h2)
     w_result = space.add(w_obj1, w_obj2)
     return handles.new(space, w_result)
 
-@apifunc([llapi.HPyContext, rffi.CCHARP], llapi.HPy)
[email protected]([llapi.HPyContext, rffi.CCHARP], llapi.HPy)
 def HPyUnicode_FromString(space, ctx, utf8):
     w_obj = _maybe_utf8_to_w(space, utf8)
     return handles.new(space, w_obj)
@@ -95,7 +78,7 @@
         raise   # XXX do something
     return space.newtext(s, length)
 
-@apifunc([llapi.HPyContext, llapi.HPy, rffi.CCHARP], lltype.Void)
[email protected]([llapi.HPyContext, llapi.HPy, rffi.CCHARP], lltype.Void)
 def HPyErr_SetString(space, ctx, h_exc_type, utf8):
    w_obj = _maybe_utf8_to_w(space, utf8)
    w_exc_type = handles.deref(space, h_exc_type)
diff --git a/pypy/module/hpy_universal/state.py 
b/pypy/module/hpy_universal/state.py
--- a/pypy/module/hpy_universal/state.py
+++ b/pypy/module/hpy_universal/state.py
@@ -5,6 +5,7 @@
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.objectmodel import specialize
 from pypy.module.hpy_universal import llapi, handles
+from pypy.module.hpy_universal.apiset import API
 
 CONTEXT_FIELDS = unrolling_iterable(llapi.HPyContext.TO._names)
 CONSTANT_NAMES = unrolling_iterable([name for name, _ in handles.CONSTANTS])
@@ -50,31 +51,11 @@
                 h_struct.c__i = i
             i = i + 1
 
-        # XXX collect all these functions automatically
-        from pypy.module.hpy_universal import interp_hpy
-        
-        funcptr = interp_hpy.HPyModule_Create.get_llhelper(space)
-        self.ctx.c_ctx_Module_Create = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPy_Dup.get_llhelper(space)
-        self.ctx.c_ctx_Dup = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPy_Close.get_llhelper(space)
-        self.ctx.c_ctx_Close = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPyLong_FromLong.get_llhelper(space)
-        self.ctx.c_ctx_Long_FromLong = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPyLong_AsLong.get_llhelper(space)
-        self.ctx.c_ctx_Long_AsLong = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPyNumber_Add.get_llhelper(space)
-        self.ctx.c_ctx_Number_Add = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPyUnicode_FromString.get_llhelper(space)
-        self.ctx.c_ctx_Unicode_FromString = rffi.cast(rffi.VOIDP, funcptr)
-        #
-        funcptr = interp_hpy.HPyErr_SetString.get_llhelper(space)
-        self.ctx.c_ctx_Err_SetString = rffi.cast(rffi.VOIDP, funcptr)
-        #
+        # XXX this is not RPython, we need a way to turn this into an
+        # unrolling_iterable
+        for func in API.all_functions:
+            funcptr = rffi.cast(rffi.VOIDP, func.get_llhelper(space))
+            ctx_field = 'c_ctx_' + func.basename
+            setattr(self.ctx, ctx_field, funcptr)
+
         self.ctx.c_ctx_Arg_Parse = rffi.cast(rffi.VOIDP, 
llapi.DONT_CALL_ctx_Arg_Parse)
diff --git a/pypy/module/hpy_universal/test/test_apiset.py 
b/pypy/module/hpy_universal/test/test_apiset.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/hpy_universal/test/test_apiset.py
@@ -0,0 +1,36 @@
+from rpython.rtyper.lltypesystem import lltype
+from pypy.module.hpy_universal.api import APISet
+
+class TestAPISet(object):
+
+    def test_func(self):
+        api = APISet()
+        @api.func([lltype.Signed, lltype.Signed], lltype.Float)
+        def divide(space, a, b):
+            return float(a)/b
+        #
+        assert divide(None, 5, 2) == 2.5
+        assert api.all_functions == [divide]
+
+    def test_basename(self):
+        api = APISet()
+        @api.func([], lltype.Void)
+        def HPyFoo_Bar(space):
+            return None
+        @api.func([], lltype.Void)
+        def _HPyFoo_Internal(space):
+            return None
+
+        assert HPyFoo_Bar.basename == 'Foo_Bar'
+        assert _HPyFoo_Internal.basename == 'Foo_Internal'
+
+    def test_llhelper(self):
+        api = APISet()
+        @api.func([lltype.Signed, lltype.Signed], lltype.Float)
+        def divide(space, a, b):
+            assert space == 'MySpace'
+            return float(a)/b
+        #
+        space = 'MySpace'
+        lldivide = divide.get_llhelper(space)
+        assert lldivide(5, 2) == 2.5
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to