Author: Armin Rigo <[email protected]>
Branch: hpy
Changeset: r98118:387736249e65
Date: 2019-11-18 18:39 +0100
http://bitbucket.org/pypy/pypy/changeset/387736249e65/

Log:    merge heads

diff --git a/pypy/module/hpy_universal/_vendored/include/cpython/hpy.h 
b/pypy/module/hpy_universal/_vendored/include/cpython/hpy.h
--- a/pypy/module/hpy_universal/_vendored/include/cpython/hpy.h
+++ b/pypy/module/hpy_universal/_vendored/include/cpython/hpy.h
@@ -37,23 +37,30 @@
     HPy h_None;
     HPy h_True;
     HPy h_False;
+    HPy h_ValueError;
 } *HPyContext;
 
 /* XXX! should be defined only once, not once for every .c! */
-static struct _HPyContext_s _global_ctx = {
-    .h_None = _py2h(Py_None),
-    .h_True = _py2h(Py_True),
-    .h_False = _py2h(Py_False),
-};
+static struct _HPyContext_s _global_ctx;
+
+#define HPy_NULL ((HPy){NULL})
+#define HPy_IsNull(x) ((x)._o == NULL)
 
 HPyAPI_FUNC(HPyContext)
 _HPyGetContext(void) {
-    return &_global_ctx;
+    HPyContext ctx = &_global_ctx;
+    if (HPy_IsNull(ctx->h_None)) {
+        // XXX: we need to find a better way to check whether the ctx is
+        // initialized or not
+        ctx->h_None = _py2h(Py_None);
+        ctx->h_True = _py2h(Py_True);
+        ctx->h_False = _py2h(Py_False);
+        ctx->h_ValueError = _py2h(PyExc_ValueError);
+    }
+    return ctx;
 }
 
 
-#define HPy_NULL ((HPy){NULL})
-#define HPy_IsNull(x) ((x)._o == NULL)
 
 HPyAPI_FUNC(HPy)
 HPyNone_Get(HPyContext ctx)
@@ -197,5 +204,11 @@
     return result;
 }
 
+HPyAPI_FUNC(void)
+HPyErr_SetString(HPyContext ctx, HPy type, const char *message)
+{
+    PyErr_SetString(_h2py(type), message);
+}
+
 
 #endif /* !HPy_CPYTHON_H */
diff --git 
a/pypy/module/hpy_universal/_vendored/include/universal/autogen_ctx.h 
b/pypy/module/hpy_universal/_vendored/include/universal/autogen_ctx.h
--- a/pypy/module/hpy_universal/_vendored/include/universal/autogen_ctx.h
+++ b/pypy/module/hpy_universal/_vendored/include/universal/autogen_ctx.h
@@ -13,6 +13,7 @@
     HPy h_None;
     HPy h_True;
     HPy h_False;
+    HPy h_ValueError;
     HPy (*ctx_Module_Create)(HPyContext ctx, HPyModuleDef *def);
     HPy (*ctx_Dup)(HPyContext ctx, HPy h);
     void (*ctx_Close)(HPyContext ctx, HPy h);
@@ -21,6 +22,7 @@
     int (*ctx_Arg_Parse)(HPyContext ctx, HPy *args, HPy_ssize_t nargs, const 
char *fmt, va_list _vl);
     HPy (*ctx_Number_Add)(HPyContext ctx, HPy x, HPy y);
     HPy (*ctx_Unicode_FromString)(HPyContext ctx, const char *utf8);
+    void (*ctx_Err_SetString)(HPyContext ctx, HPy type, const char *message);
     HPy (*ctx_FromPyObject)(HPyContext ctx, struct _object *obj);
     struct _object *(*ctx_AsPyObject)(HPyContext ctx, HPy h);
     struct _object *(*ctx_CallRealFunctionFromTrampoline)(HPyContext ctx, 
struct _object *self, struct _object *args, void *func, int ml_flags);
diff --git 
a/pypy/module/hpy_universal/_vendored/include/universal/autogen_func.h 
b/pypy/module/hpy_universal/_vendored/include/universal/autogen_func.h
--- a/pypy/module/hpy_universal/_vendored/include/universal/autogen_func.h
+++ b/pypy/module/hpy_universal/_vendored/include/universal/autogen_func.h
@@ -40,6 +40,10 @@
      return ctx->ctx_Unicode_FromString ( ctx, utf8 ); 
 }
 
+static inline void HPyErr_SetString(HPyContext ctx, HPy type, const char 
*message) {
+     ctx->ctx_Err_SetString ( ctx, type, message ); 
+}
+
 static inline HPy HPy_FromPyObject(HPyContext ctx, struct _object *obj) {
      return ctx->ctx_FromPyObject ( ctx, obj ); 
 }
diff --git a/pypy/module/hpy_universal/_vendored/test/test_basic.py 
b/pypy/module/hpy_universal/_vendored/test/test_basic.py
--- a/pypy/module/hpy_universal/_vendored/test/test_basic.py
+++ b/pypy/module/hpy_universal/_vendored/test/test_basic.py
@@ -158,3 +158,26 @@
         """)
         assert mod.f(4) is False
         assert mod.f(6) is True
+
+    def test_exception(self):
+        import pytest
+        mod = self.make_module("""
+            HPy_METH_O(f)
+            static HPy f_impl(HPyContext ctx, HPy self, HPy arg)
+            {
+                long x = HPyLong_AsLong(ctx, arg);
+                if (x < 5) {
+                    return HPyLong_FromLong(ctx, -x);
+                }
+                else {
+                    HPyErr_SetString(ctx, ctx->h_ValueError, "hello world");
+                    return HPy_NULL;
+                }
+            }
+            @EXPORT f METH_O
+            @INIT
+        """)
+        assert mod.f(-10) == 10
+        with pytest.raises(ValueError) as exc:
+            mod.f(20)
+        assert str(exc.value) == 'hello world'
diff --git a/pypy/module/hpy_universal/handles.py 
b/pypy/module/hpy_universal/handles.py
--- a/pypy/module/hpy_universal/handles.py
+++ b/pypy/module/hpy_universal/handles.py
@@ -4,6 +4,7 @@
     ('None', lambda space: space.w_None),
     ('False', lambda space: space.w_False),
     ('True', lambda space: space.w_True),
+    ('ValueError', lambda space: space.w_ValueError),
     ]
 
 
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
@@ -7,6 +7,7 @@
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.error import raise_import_error
 from pypy.interpreter.module import Module
+from pypy.interpreter.error import OperationError
 
 from pypy.module.hpy_universal import llapi, handles, interp_extfunc
 from pypy.module.hpy_universal.state import State
@@ -80,13 +81,23 @@
 
 @apifunc([llapi.HPyContext, rffi.CCHARP], llapi.HPy, error=0)
 def HPyUnicode_FromString(space, ctx, utf8):
+    w_obj = _maybe_utf8_to_w(space, utf8)
+    return handles.new(space, w_obj)
+
+def _maybe_utf8_to_w(space, utf8):
+    # should this be a method of space?
     s = rffi.charp2str(utf8)
     try:
         length = rutf8.check_utf8(s, allow_surrogates=False)
     except rutf8.CheckError:
         raise   # XXX do something
-    w_obj = space.newtext(s, length)
-    return handles.new(space, w_obj)
+    return space.newtext(s, length)
+
+@apifunc([llapi.HPyContext, llapi.HPy, rffi.CCHARP], lltype.Void, error=None)
+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)
+   raise OperationError(w_exc_type, w_obj)
 
 
 def create_hpy_module(space, name, origin, lib, initfunc):
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
@@ -26,6 +26,7 @@
     ('h_None', HPy),
     ('h_True', HPy),
     ('h_False', HPy),
+    ('h_ValueError', HPy),
     ('ctx_Module_Create', rffi.VOIDP),
     ('ctx_Dup', rffi.VOIDP),
     ('ctx_Close', rffi.VOIDP),
@@ -34,6 +35,7 @@
     ('ctx_Arg_Parse', rffi.VOIDP),
     ('ctx_Number_Add', rffi.VOIDP),
     ('ctx_Unicode_FromString', rffi.VOIDP),
+    ('ctx_Err_SetString', rffi.VOIDP),
     ('ctx_FromPyObject', rffi.VOIDP),
     ('ctx_AsPyObject', rffi.VOIDP),
     ('ctx_CallRealFunctionFromTrampoline', rffi.VOIDP),
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
@@ -69,3 +69,6 @@
         #
         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)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to