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