Author: Armin Rigo <[email protected]>
Branch: hpy
Changeset: r98081:3612658138c2
Date: 2019-11-16 21:16 +0100
http://bitbucket.org/pypy/pypy/changeset/3612658138c2/
Log: (antocuni, ronan, arigo)
Progress towards, but not yet, reaching test_noop_function
diff --git a/pypy/module/hpy_universal/interp_extfunc.py
b/pypy/module/hpy_universal/interp_extfunc.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/hpy_universal/interp_extfunc.py
@@ -0,0 +1,79 @@
+from rpython.rtyper.lltypesystem import lltype, rffi
+from pypy.interpreter.error import oefmt
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.typedef import TypeDef, interp2app
+
+from pypy.module.hpy_universal import llapi, handles
+from pypy.module.hpy_universal.state import State
+from pypy.module.cpyext.api import generic_cpy_call_dont_convert_result
+
+
+class W_ExtensionFunction(W_Root):
+ _immutable_fields_ = ["flags", "name"]
+
+ def __init__(self, ml):
+ self.ml = ml
+ self.name = rffi.charp2str(self.ml.c_ml_name)
+ self.flags = rffi.cast(lltype.Signed, self.ml.c_ml_flags)
+ # fetch the real HPy function pointer, by calling ml_meth, which
+ # is a function that returns it and also the CPython-only trampoline
+ with lltype.scoped_alloc(
+ rffi.CArray(llapi._HPyCFunctionPtr), 1) as funcptr:
+ with lltype.scoped_alloc(
+ rffi.CArray(llapi._HPy_CPyCFunctionPtr), 1) \
+ as ignored_trampoline:
+ ml.c_ml_meth(funcptr, ignored_trampoline)
+ self.cfuncptr = funcptr[0]
+
+ def call_keywords(self, space, __args__):
+ raise NotImplementedError("later")
+
+ def call_noargs(self, space):
+ state = space.fromcache(State)
+ h_result = generic_cpy_call_dont_convert_result(space, self.cfuncptr,
+ state.ctx, 0, 0)
+ # XXX check for exceptions
+ return handles.consume(h_result)
+
+ def call_o(self, space, w_arg):
+ raise NotImplementedError("later")
+
+ def call_varargs(self, space, arguments_w):
+ raise NotImplementedError("later")
+
+ def descr_call(self, space, __args__):
+ flags = self.flags
+ length = len(__args__.arguments_w)
+
+ if flags & llapi.METH_KEYWORDS:
+ return self.call_keywords(space, __args__)
+
+ if __args__.keywords:
+ raise oefmt(space.w_TypeError,
+ "%s() takes no keyword arguments", self.name)
+
+ if flags & llapi.METH_NOARGS:
+ if length == 0:
+ return self.call_noargs(space)
+ raise oefmt(space.w_TypeError,
+ "%s() takes no arguments", self.name)
+
+ if flags & llapi.METH_O:
+ if length != 1:
+ raise oefmt(space.w_TypeError,
+ "%s() takes exactly one argument (%d given)",
+ self.name, length)
+ return self.call_o(space, __args__.arguments_w[0])
+
+ if flags & llapi.METH_VARARGS:
+ return self.call_varargs(space, __args__.arguments_w)
+ else: # shouldn't happen!
+ raise oefmt(space.w_RuntimeError, "unknown calling convention")
+
+
+
+W_ExtensionFunction.typedef = TypeDef(
+ 'extension_function',
+ __call__ = interp2app(W_ExtensionFunction.descr_call),
+ )
+W_ExtensionFunction.typedef.acceptable_as_base_class = False
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
@@ -5,31 +5,27 @@
from pypy.interpreter.error import raise_import_error
from pypy.interpreter.module import Module
-from pypy.module.hpy_universal import llapi, handles
+from pypy.module.hpy_universal import llapi, handles, interp_extfunc
+from pypy.module.hpy_universal.state import State
from pypy.module.cpyext.api import generic_cpy_call_dont_convert_result
from pypy.module.cpyext.api import slot_function
-class State:
- def __init__(self, space):
- "NOT_RPYTHON"
- self.space = space
- self.ctx = lltype.nullptr(rffi.VOIDP.TO)
-
- def setup(self):
- if not self.ctx:
- space = self.space
- funcptr = HPyModule_Create.api_func.get_llhelper(space)
- llapi._HPy_FillFunction(rffi.cast(rffi.INT_real, 0),
- rffi.cast(rffi.VOIDP, funcptr))
- self.ctx = llapi._HPy_GetGlobalCtx()
-
-
@slot_function([llapi.HPyContext, lltype.Ptr(llapi.HPyModuleDef)],
llapi.HPy, error=0)
def HPyModule_Create(space, ctx, hpydef):
modname = rffi.charp2str(hpydef.c_m_name)
w_mod = Module(space, space.newtext(modname))
+ #
+ # add all the functions defined in hpydef.c_m_methods
+ if hpydef.c_m_methods:
+ p = hpydef.c_m_methods
+ i = 0
+ while p[i].c_ml_name:
+ w_extfunc = interp_extfunc.W_ExtensionFunction(p[i])
+ space.setattr(w_mod, space.newtext(w_extfunc.name), w_extfunc)
+ i += 1
+ #
return handles.new(space, w_mod)
diff --git a/pypy/module/hpy_universal/llapi.py
b/pypy/module/hpy_universal/llapi.py
--- a/pypy/module/hpy_universal/llapi.py
+++ b/pypy/module/hpy_universal/llapi.py
@@ -4,7 +4,21 @@
HPy = lltype.Signed
-HPyContext = rffi.VOIDP
+HPyContextS = lltype.Struct('dummy_HPyContext_s',
+ ('ctx_version', rffi.INT_real),
+ ('ctx_Module_Create', rffi.VOIDP),
+ ('ctx_None_Get', rffi.VOIDP),
+ ('ctx_Dup', rffi.VOIDP),
+ ('ctx_Close', rffi.VOIDP),
+ ('ctx_Long_FromLong', rffi.VOIDP),
+ ('ctx_Arg_ParseTuple', rffi.VOIDP),
+ ('ctx_Number_Add', rffi.VOIDP),
+ ('ctx_Unicode_FromString', rffi.VOIDP),
+ ('ctx_FromPyObject', rffi.VOIDP),
+ ('ctx_AsPyObject', rffi.VOIDP),
+ ('ctx_CallRealFunctionFromTrampoline', rffi.VOIDP),
+)
+HPyContext = lltype.Ptr(HPyContextS)
HPyInitFuncPtr = lltype.Ptr(lltype.FuncType([HPyContext], HPy))
@@ -31,6 +45,11 @@
('m_methods', rffi.CArrayPtr(HPyMethodDef)),
)
+METH_VARARGS = 0x0001
+METH_KEYWORDS = 0x0002
+METH_NOARGS = 0x0004
+METH_O = 0x0008
+
# ----------------------------------------------------------------
@@ -47,26 +66,7 @@
"""],
separate_module_sources=["""
-struct _HPyRawContext_s {
- int ctx_version;
- void *ctx_raw_functions[1];
-};
-
-union _HPyContext_s_union {
- struct _HPyContext_s ctx;
- struct _HPyRawContext_s rawctx;
-};
-
-union _HPyContext_s_union hpy_global_ctx = {
- {
- .ctx_version = 1,
- }
-};
-
-void _HPy_FillFunction(int index, void *function)
-{
- hpy_global_ctx.rawctx.ctx_raw_functions[index] = function;
-}
+struct _HPyContext_s hpy_global_ctx;
void *_HPy_GetGlobalCtx(void)
{
@@ -75,11 +75,5 @@
"""])
-
-_HPy_FillFunction = rffi.llexternal('_HPy_FillFunction',
- [rffi.INT_real, rffi.VOIDP],
- lltype.Void,
- compilation_info=eci, _nowrapper=True)
-
_HPy_GetGlobalCtx = rffi.llexternal('_HPy_GetGlobalCtx', [], HPyContext,
compilation_info=eci, _nowrapper=True)
diff --git a/pypy/module/hpy_universal/state.py
b/pypy/module/hpy_universal/state.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/hpy_universal/state.py
@@ -0,0 +1,33 @@
+import os
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.annlowlevel import llhelper
+from pypy.module.hpy_universal import llapi
+
+
+class State:
+ def __init__(self, space):
+ "NOT_RPYTHON"
+ self.space = space
+ self.ctx = lltype.nullptr(rffi.VOIDP.TO)
+
+ def setup(self):
+ if self.ctx:
+ return
+
+ self.ctx = llapi._HPy_GetGlobalCtx()
+
+ DUMMY_FUNC = lltype.FuncType([], lltype.Void)
+ for name in llapi.HPyContext.TO._names:
+ if name != 'ctx_version':
+ def missing_function(name=name):
+ print ("oops! calling the slot %r, which is not
implemented"
+ % (name,))
+ os._exit(1)
+ funcptr = llhelper(lltype.Ptr(DUMMY_FUNC), missing_function)
+ setattr(self.ctx, name, rffi.cast(rffi.VOIDP, funcptr))
+
+ # XXX collect all these functions automatically
+ from pypy.module.hpy_universal import interp_hpy
+ space = self.space
+ funcptr = interp_hpy.HPyModule_Create.api_func.get_llhelper(space)
+ self.ctx.ctx_Module_Create = rffi.cast(rffi.VOIDP, funcptr)
diff --git a/pypy/module/hpy_universal/test/support.py
b/pypy/module/hpy_universal/test/support.py
--- a/pypy/module/hpy_universal/test/support.py
+++ b/pypy/module/hpy_universal/test/support.py
@@ -41,7 +41,8 @@
filename.write(source)
#
ext = _support.get_extension(str(filename), name,
include_dirs=[INCLUDE_DIR],
- extra_compile_args=['-Wfatal-errors'])
+ extra_compile_args=['-Wfatal-errors', '-g',
'-Og'],
+ extra_link_args=['-g'])
so_filename = _support.c_compile(str(tmpdir), ext,
compiler_verbose=False,
universal_mode=True)
#
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit