Skip to content

Commit c191a11

Browse files
committed
[GR-33139] Implement HPy JNI backend.
PullRequest: graalpython/1907
2 parents a9fab60 + 1727a5a commit c191a11

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3656
-950
lines changed

graalpython/com.oracle.graal.python.cext/hpy/hpy.c

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ int graal_hpy_init(HPyContext context, void *initObject) {
8484
polyglot_invoke(initObject, "setHPyNativeType", polyglot_HPy_typeid());
8585
polyglot_invoke(initObject, "setHPyArrayNativeType", polyglot_array_typeid(polyglot_HPy_typeid(), 0));
8686

87-
// register null handle
88-
polyglot_invoke(initObject, "setHPyNullHandle", HPy_NULL);
89-
9087
// register size of wchar_t
9188
polyglot_invoke(initObject, "setWcharSize", sizeof(wchar_t));
9289

@@ -587,19 +584,19 @@ void graal_hpy_write_ptr(void* object, HPy_ssize_t offset, void* value) {
587584

588585
typedef void (*destroyfunc)(void *);
589586
/* to be used from Java code only */
590-
int graal_hpy_bulk_free(void* ptrArray[], int64_t len) {
587+
int graal_hpy_bulk_free(uint64_t ptrArray[], int64_t len) {
591588
int64_t i;
592-
void* obj;
589+
uint64_t obj;
593590
destroyfunc func;
594591

595592
for (i=0; i < len; i+=2) {
596593
obj = ptrArray[i];
597-
func = ptrArray[i+1];
598-
if (obj != NULL) {
594+
func = (destroyfunc) ptrArray[i+1];
595+
if (obj) {
599596
if (func != NULL) {
600-
func(obj);
597+
func((void *) obj);
601598
}
602-
free(obj);
599+
free((void *) obj);
603600
}
604601
}
605602
return 0;
@@ -1250,9 +1247,13 @@ HPyAPI_STORAGE void _HPy_IMPL_NAME(Dump)(HPyContext ctx, HPy h) {
12501247
#undef _HPy_IMPL_NAME_NOPREFIX
12511248
#undef _HPy_IMPL_NAME
12521249

1250+
#include "hpynative.h"
1251+
12531252
/* Allocate a native HPy context structure and fill it. */
1254-
HPyContext graal_hpy_context_to_native(HPyContext managed_context) {
1255-
HPyContext native_context = (HPyContext) malloc(sizeof(struct _HPyContext_s));
1253+
HPyContext graal_hpy_context_to_native(HPyContext managed_context, HPyContext overrides) {
1254+
GraalHPyContext *full_native_context = (GraalHPyContext *) malloc(sizeof(GraalHPyContext));
1255+
1256+
HPyContext native_context = graal_native_context_get_hpy_context(full_native_context);
12561257

12571258
#define COPY(__member) native_context->__member = managed_context->__member
12581259
COPY(name);
@@ -1334,7 +1335,7 @@ HPyContext graal_hpy_context_to_native(HPyContext managed_context) {
13341335
COPY(h_ListType);
13351336
#undef COPY
13361337

1337-
#define HPY_CTX_UPCALL(__fun) native_context->__fun = __fun;
1338+
#define HPY_CTX_UPCALL(__fun) { void* v = overrides->__fun; if (v != NULL) native_context->__fun = v; else native_context->__fun = __fun; }
13381339
HPY_CTX_UPCALL(ctx_Module_Create);
13391340
HPY_CTX_UPCALL(ctx_Dup);
13401341
HPY_CTX_UPCALL(ctx_Close);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
42+
#ifndef HPY_HPYNATIVE_H_
43+
#define HPY_HPYNATIVE_H_
44+
45+
#include <stddef.h>
46+
47+
#include "hpy.h"
48+
49+
typedef struct {
50+
void *jni_context;
51+
52+
/* embed HPy context */
53+
struct _HPyContext_s hpy_context;
54+
} GraalHPyContext;
55+
56+
#define MUST_INLINE __attribute__((always_inline)) static inline
57+
58+
MUST_INLINE HPyContext graal_native_context_get_hpy_context(GraalHPyContext *native_context) {
59+
return &(native_context->hpy_context);
60+
}
61+
62+
MUST_INLINE GraalHPyContext *graal_hpy_context_get_native_context(HPyContext hpy_context) {
63+
return (GraalHPyContext *)(((void *)hpy_context) - offsetof(GraalHPyContext, hpy_context));
64+
}
65+
66+
#endif /* HPY_HPYNATIVE_H_ */

graalpython/com.oracle.graal.python.cext/include/universal/autogen_ctx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@
3737
typedef HPy* _HPyPtr;
3838
typedef HPy _HPyConst;
3939

40+
#ifdef GRAALVM_PYTHON_LLVM
4041
#define HPy void*
4142
#define HPyListBuilder void*
4243
#define HPyTupleBuilder void*
4344
#define HPyTracker void*
45+
#endif
4446

4547

4648
struct _HPyContext_s {
@@ -249,7 +251,9 @@ struct _HPyContext_s {
249251
void (*ctx_Dump)(HPyContext ctx, HPy h);
250252
};
251253

254+
#ifdef GRAALVM_PYTHON_LLVM
252255
#undef HPy
253256
#undef HPyListBuilder
254257
#undef HPyTupleBuilder
255258
#undef HPyTracker
259+
#endif

graalpython/com.oracle.graal.python.cext/include/universal/autogen_trampolines.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
3535
*/
3636

37+
#ifdef GRAALVM_PYTHON_LLVM
3738
#define UNWRAP(_h) ((_h)._i)
3839
#define WRAP(_ptr) ((HPy){(_ptr)})
3940
#define UNWRAP_TUPLE_BUILDER(_h) ((_h)._tup)
@@ -42,6 +43,16 @@
4243
#define WRAP_LIST_BUILDER(_ptr) ((HPyListBuilder){(_ptr)})
4344
#define UNWRAP_TRACKER(_h) ((_h)._i)
4445
#define WRAP_TRACKER(_ptr) ((HPyTracker){(_ptr)})
46+
#else
47+
#define UNWRAP(_h) _h
48+
#define WRAP(_ptr) _ptr
49+
#define UNWRAP_TUPLE_BUILDER(_h) _h
50+
#define WRAP_TUPLE_BUILDER(_ptr) _ptr
51+
#define UNWRAP_LIST_BUILDER(_h) _h
52+
#define WRAP_LIST_BUILDER(_ptr) _ptr
53+
#define UNWRAP_TRACKER(_h) _h
54+
#define WRAP_TRACKER(_ptr) _ptr
55+
#endif
4556

4657
static inline HPy HPyModule_Create(HPyContext ctx, HPyModuleDef *def) {
4758
return WRAP(ctx->ctx_Module_Create ( ctx, def ));

graalpython/com.oracle.graal.python.cext/include/universal/hpy.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,17 @@ typedef intptr_t HPy_hash_t;
5656
are each just a pointer-sized integer. What this integer (or pointer)
5757
means is up to the implementation. For example, on both CPython and PyPy,
5858
the HPy structure contains an index in a global array. */
59+
#ifndef GRAALVM_PYTHON_LLVM
60+
typedef struct _HPy_s { HPy_ssize_t _i; } HPy;
61+
typedef struct { HPy_ssize_t _lst; } HPyListBuilder;
62+
typedef struct { HPy_ssize_t _tup; } HPyTupleBuilder;
63+
typedef struct { HPy_ssize_t _i; } HPyTracker;
64+
#else
5965
typedef struct _HPy_s { void* _i; } HPy;
6066
typedef struct { void* _lst; } HPyListBuilder;
6167
typedef struct { void* _tup; } HPyTupleBuilder;
6268
typedef struct { void* _i; } HPyTracker;
69+
#endif
6370

6471
typedef struct _HPyContext_s *HPyContext;
6572

@@ -68,14 +75,24 @@ typedef struct _HPyContext_s *HPyContext;
6875

6976

7077
/* misc stuff, which should probably go in its own header */
78+
#ifndef GRAALVM_PYTHON_LLVM
79+
#define HPy_NULL ((HPy){0})
80+
#define HPy_IsNull(x) ((x)._i == 0)
81+
#else
7182
#define HPy_NULL ((HPy){NULL})
7283
#define HPy_IsNull(x) ((x)._i == NULL)
84+
#endif
7385

7486
// XXX: we need to decide whether these are part of the official API or not,
7587
// and maybe introduce a better naming convetion. For now, they are needed for
7688
// ujson
89+
#ifndef GRAALVM_PYTHON_LLVM
90+
static inline HPy HPy_FromVoidP(void *p) { return (HPy){(HPy_ssize_t)p}; }
91+
static inline void* HPy_AsVoidP(HPy h) { return (void*)h._i; }
92+
#else
7793
static inline HPy HPy_FromVoidP(void *p) { return (HPy){p}; }
7894
static inline void* HPy_AsVoidP(HPy h) { return h._i; }
95+
#endif
7996

8097
// include runtime functions
8198
#include "common/macros.h"
@@ -91,6 +108,14 @@ static inline void* HPy_AsVoidP(HPy h) { return h._i; }
91108

92109
/* manual trampolines */
93110

111+
#ifdef GRAALVM_PYTHON_LLVM
112+
#define UNWRAP(_h) ((_h)._i)
113+
#define WRAP(_ptr) ((HPy){(_ptr)})
114+
#else
115+
#define UNWRAP(_h) _h
116+
#define WRAP(_ptr) _ptr
117+
#endif
118+
94119
static inline HPy _HPy_New(HPyContext ctx, HPy h_type, void **data) {
95120
/* Performance hack: the autogenerated version of this trampoline would
96121
simply forward data to ctx_New.
@@ -108,7 +133,7 @@ static inline HPy _HPy_New(HPyContext ctx, HPy h_type, void **data) {
108133
See https://github.com/pyhandle/hpy/pull/22#pullrequestreview-413365845
109134
*/
110135
void *data_result;
111-
HPy h = HPy_FromVoidP(ctx->ctx_New(ctx, HPy_AsVoidP(h_type), &data_result));
136+
HPy h = WRAP(ctx->ctx_New(ctx, UNWRAP(h_type), &data_result));
112137
*data = data_result;
113138
return h;
114139
}

graalpython/com.oracle.graal.python.cext/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ def build_libhpy(capi_home):
426426
files = [os.path.abspath(os.path.join(src_dir, f)) for f in os.listdir(src_dir) if f.endswith(".c")]
427427
module = Extension(libhpy_name,
428428
sources=files,
429-
define_macros=[("HPY_UNIVERSAL_ABI", None)],
429+
define_macros=[("HPY_UNIVERSAL_ABI", 1)],
430430
extra_compile_args=cflags_warnings,
431431
)
432432
args = [verbosity, 'build', 'install_lib', '-f', '--install-dir=%s' % capi_home, "clean"]

0 commit comments

Comments
 (0)