Skip to content

Commit 028e735

Browse files
committed
[GR-20187] [GR-20189] [GR-21725] [GR-22572] Add support for HPy.
PullRequest: graalpython/760
2 parents 097d8b5 + 08b5a45 commit 028e735

Some content is hidden

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

63 files changed

+7980
-283
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Python3.g4.stamp
8080
/.*.csv*
8181
/graal_dumps
8282
*.jfr
83+
.DS_Store
8384

8485
graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/antlr/.antlr/
8586
graalpython/lib-python/3/test/data

THIRD_PARTY_LICENSE.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,3 +3151,31 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31513151
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31523152
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31533153
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3154+
3155+
================================================================================
3156+
3157+
HPy: a better API for Python
3158+
3159+
License
3160+
=======
3161+
MIT License
3162+
3163+
Copyright (c) 2019 pyhandle
3164+
3165+
Permission is hereby granted, free of charge, to any person obtaining a copy
3166+
of this software and associated documentation files (the "Software"), to deal
3167+
in the Software without restriction, including without limitation the rights
3168+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3169+
copies of the Software, and to permit persons to whom the Software is
3170+
furnished to do so, subject to the following conditions:
3171+
3172+
The above copyright notice and this permission notice shall be included in all
3173+
copies or substantial portions of the Software.
3174+
3175+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3176+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3177+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3178+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3179+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3180+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3181+
SOFTWARE.

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{ "overlay": "2feca4419570e36151cea7cda2a5bd5d57fd27e3" }
1+
{ "overlay": "7cf5c656b389584db3339485ccd8b9b4b40bf4d9" }
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
* Copyright (c) 2019, 2020, 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+
#include "hpy.h"
42+
#include <polyglot.h>
43+
#include <truffle.h>
44+
45+
#include <wchar.h>
46+
47+
#define SRC_CS "utf-8"
48+
49+
POLYGLOT_DECLARE_TYPE(HPy);
50+
POLYGLOT_DECLARE_STRUCT(_HPyContext_s);
51+
POLYGLOT_DECLARE_TYPE(HPyMethodDef);
52+
POLYGLOT_DECLARE_TYPE(HPyModuleDef);
53+
POLYGLOT_DECLARE_TYPE(wchar_t);
54+
55+
int graal_hpy_init(void *initObject) {
56+
// register the native type of HPy
57+
polyglot_invoke(initObject, "setHPyContextNativeType", polyglot__HPyContext_s_typeid());
58+
polyglot_invoke(initObject, "setHPyNativeType", polyglot_HPy_typeid());
59+
polyglot_invoke(initObject, "setHPyArrayNativeType", polyglot_array_typeid(polyglot_HPy_typeid(), 0));
60+
61+
// register null handle
62+
polyglot_invoke(initObject, "setHPyNullHandle", HPy_NULL);
63+
64+
// register size of wchar_t
65+
polyglot_invoke(initObject, "setWcharSize", sizeof(wchar_t));
66+
67+
return 0;
68+
}
69+
70+
71+
void* graal_hpy_from_HPy_array(void *arr, uint64_t len) {
72+
return polyglot_from_HPy_array(arr, len);
73+
}
74+
75+
void* graal_hpy_from_i8_array(void *arr, uint64_t len) {
76+
return polyglot_from_i8_array(arr, len);
77+
}
78+
79+
wchar_t* graal_hpy_from_wchar_array(wchar_t *arr, uint64_t len) {
80+
if (len == -1) {
81+
len = (uint64_t) wcslen(arr);
82+
}
83+
return polyglot_from_wchar_t_array(arr, len);
84+
}
85+
86+
void* graal_hpy_from_HPyMethodDef(void *ptr) {
87+
return polyglot_from_HPyMethodDef(ptr);
88+
}
89+
90+
void* graal_hpy_from_HPyModuleDef(void *ptr) {
91+
return polyglot_from_HPyModuleDef(ptr);
92+
}
93+
94+
void* graal_hpy_get_m_name(HPyModuleDef *moduleDef) {
95+
return polyglot_from_string(moduleDef->m_name, SRC_CS);
96+
}
97+
98+
void* graal_hpy_get_m_doc(HPyModuleDef *moduleDef) {
99+
const char *m_doc = moduleDef->m_doc;
100+
if (m_doc) {
101+
return polyglot_from_string(m_doc, SRC_CS);
102+
}
103+
return polyglot_from_string("", SRC_CS);
104+
}
105+
106+
void* graal_hpy_get_ml_name(HPyMethodDef *methodDef) {
107+
return polyglot_from_string(methodDef->ml_name, SRC_CS);
108+
}
109+
110+
void* graal_hpy_get_ml_doc(HPyMethodDef *methodDef) {
111+
return polyglot_from_string(methodDef->ml_doc, SRC_CS);
112+
}
113+
114+
void* graal_hpy_get_m_methods(HPyModuleDef *moduleDef) {
115+
uint64_t len=0;
116+
while ((moduleDef->m_methods[len]).ml_name != NULL) {
117+
len++;
118+
}
119+
return polyglot_from_HPyMethodDef_array(moduleDef->m_methods, len);
120+
}
121+
122+
void* graal_hpy_from_string(const char *ptr) {
123+
return polyglot_from_string(ptr, SRC_CS);
124+
}
125+
126+
/*
127+
* Casts a 'wchar_t*' array to an 'int8_t*' array and also associates the proper length.
128+
* The length is determined using 'wcslen' if 'len == -1'.
129+
*/
130+
int8_t* graal_hpy_i8_from_wchar_array(wchar_t *arr, uint64_t len) {
131+
if (len == -1) {
132+
len = (uint64_t) (wcslen(arr) * sizeof(wchar_t));
133+
}
134+
return polyglot_from_i8_array((int8_t *) arr, len);
135+
}
136+
137+
typedef void* VoidPtr;
138+
POLYGLOT_DECLARE_TYPE(VoidPtr);
139+
140+
typedef union {
141+
void *ptr;
142+
float f;
143+
double d;
144+
int64_t i64;
145+
int32_t i32;
146+
int16_t i16;
147+
int8_t i8;
148+
uint64_t u64;
149+
uint32_t u32;
150+
uint16_t u16;
151+
uint8_t u8;
152+
/* TODO(fa) this should be a Py_complex; is there any equivalent ? */
153+
uint64_t c;
154+
} OutVar;
155+
156+
POLYGLOT_DECLARE_TYPE(OutVar);
157+
typedef struct { OutVar *content; } OutVarPtr;
158+
POLYGLOT_DECLARE_TYPE(OutVarPtr);
159+
OutVarPtr* graal_hpy_allocate_outvar() {
160+
return polyglot_from_OutVarPtr(truffle_managed_malloc(sizeof(OutVarPtr)));
161+
}
162+
163+
/*
164+
* Transforms a Java handle array to native.
165+
* TODO(fa): This currently uses a workaround because Sulong does not fully
166+
* support passing structs via interop. Therefore, we pretend to have 'void *'
167+
* array and convert to handle using 'HPy_FromVoidP'.
168+
*/
169+
HPy* graal_hpy_array_to_native(VoidPtr *source, uint64_t len) {
170+
uint64_t i;
171+
HPy *dest = (HPy *)malloc(len*sizeof(HPy));
172+
for (i=0; i < len; i++) {
173+
dest[i] = HPy_FromVoidP(source[i]);
174+
}
175+
return dest;
176+
}
177+
178+
void get_next_vaarg(va_list *p_va, OutVarPtr *p_outvar) {
179+
p_outvar->content = (OutVar *)va_arg(*p_va, void *);
180+
}
181+
182+
void* graal_hpy_context_to_native(void* cobj) {
183+
return truffle_deref_handle_for_managed(cobj);
184+
}
185+
186+
#define PRIMITIVE_ARRAY_TO_NATIVE(__jtype__, __ctype__, __polyglot_type__, __element_cast__) \
187+
void* graal_hpy_##__jtype__##_array_to_native(const void* jarray, int64_t len) { \
188+
int64_t i; \
189+
int64_t size = len + 1; \
190+
__ctype__* carr = (__ctype__*) malloc(size * sizeof(__ctype__)); \
191+
carr[len] = (__ctype__)0; \
192+
for (i=0; i < len; i++) { \
193+
carr[i] = __element_cast__(polyglot_get_array_element(jarray, i)); \
194+
} \
195+
return polyglot_from_##__polyglot_type__##_array(carr, len); \
196+
} \
197+
198+
PRIMITIVE_ARRAY_TO_NATIVE(byte, int8_t, i8, polyglot_as_i8);
199+
PRIMITIVE_ARRAY_TO_NATIVE(int, int32_t, i32, polyglot_as_i32);
200+
PRIMITIVE_ARRAY_TO_NATIVE(long, int64_t, i64, polyglot_as_i64);
201+
PRIMITIVE_ARRAY_TO_NATIVE(double, double, double, polyglot_as_double);
202+
PRIMITIVE_ARRAY_TO_NATIVE(pointer, VoidPtr, VoidPtr, (VoidPtr));
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/* MIT License
2+
*
3+
* Copyright (c) 2020, Oracle and/or its affiliates.
4+
* Copyright (c) 2019 pyhandle
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
/*
26+
DO NOT EDIT THIS FILE!
27+
28+
This file is automatically generated by tools/autogen.py from tools/public_api.h.
29+
Run this to regenerate:
30+
make autogen
31+
32+
*/
33+
34+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromLong)(HPyContext ctx, long value)
35+
{
36+
return _py2h(PyLong_FromLong(value));
37+
}
38+
39+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromLongLong)(HPyContext ctx, long long v)
40+
{
41+
return _py2h(PyLong_FromLongLong(v));
42+
}
43+
44+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Long_FromUnsignedLongLong)(HPyContext ctx, unsigned long long v)
45+
{
46+
return _py2h(PyLong_FromUnsignedLongLong(v));
47+
}
48+
49+
HPyAPI_STORAGE long _HPy_IMPL_NAME(Long_AsLong)(HPyContext ctx, HPy h)
50+
{
51+
return PyLong_AsLong(_h2py(h));
52+
}
53+
54+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Float_FromDouble)(HPyContext ctx, double v)
55+
{
56+
return _py2h(PyFloat_FromDouble(v));
57+
}
58+
59+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Number_Add)(HPyContext ctx, HPy h1, HPy h2)
60+
{
61+
return _py2h(PyNumber_Add(_h2py(h1), _h2py(h2)));
62+
}
63+
64+
HPyAPI_STORAGE void _HPy_IMPL_NAME(Err_SetString)(HPyContext ctx, HPy h_type, const char *message)
65+
{
66+
return PyErr_SetString(_h2py(h_type), message);
67+
}
68+
69+
HPyAPI_STORAGE int _HPy_IMPL_NAME(Object_IsTrue)(HPyContext ctx, HPy h)
70+
{
71+
return PyObject_IsTrue(_h2py(h));
72+
}
73+
74+
HPyAPI_STORAGE int _HPy_IMPL_NAME(Bytes_Check)(HPyContext ctx, HPy h)
75+
{
76+
return PyBytes_Check(_h2py(h));
77+
}
78+
79+
HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Bytes_Size)(HPyContext ctx, HPy h)
80+
{
81+
return PyBytes_Size(_h2py(h));
82+
}
83+
84+
HPyAPI_STORAGE HPy_ssize_t _HPy_IMPL_NAME(Bytes_GET_SIZE)(HPyContext ctx, HPy h)
85+
{
86+
return PyBytes_GET_SIZE(_h2py(h));
87+
}
88+
89+
HPyAPI_STORAGE char *_HPy_IMPL_NAME(Bytes_AsString)(HPyContext ctx, HPy h)
90+
{
91+
return PyBytes_AsString(_h2py(h));
92+
}
93+
94+
HPyAPI_STORAGE char *_HPy_IMPL_NAME(Bytes_AS_STRING)(HPyContext ctx, HPy h)
95+
{
96+
return PyBytes_AS_STRING(_h2py(h));
97+
}
98+
99+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromString)(HPyContext ctx, const char *utf8)
100+
{
101+
return _py2h(PyUnicode_FromString(utf8));
102+
}
103+
104+
HPyAPI_STORAGE int _HPy_IMPL_NAME(Unicode_Check)(HPyContext ctx, HPy h)
105+
{
106+
return PyUnicode_Check(_h2py(h));
107+
}
108+
109+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_AsUTF8String)(HPyContext ctx, HPy h)
110+
{
111+
return _py2h(PyUnicode_AsUTF8String(_h2py(h)));
112+
}
113+
114+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Unicode_FromWideChar)(HPyContext ctx, const wchar_t *w, HPy_ssize_t size)
115+
{
116+
return _py2h(PyUnicode_FromWideChar(w, size));
117+
}
118+
119+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(List_New)(HPyContext ctx, HPy_ssize_t len)
120+
{
121+
return _py2h(PyList_New(len));
122+
}
123+
124+
HPyAPI_STORAGE int _HPy_IMPL_NAME(List_Append)(HPyContext ctx, HPy h_list, HPy h_item)
125+
{
126+
return PyList_Append(_h2py(h_list), _h2py(h_item));
127+
}
128+
129+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dict_New)(HPyContext ctx)
130+
{
131+
return _py2h(PyDict_New());
132+
}
133+
134+
HPyAPI_STORAGE int _HPy_IMPL_NAME(Dict_SetItem)(HPyContext ctx, HPy h_dict, HPy h_key, HPy h_val)
135+
{
136+
return PyDict_SetItem(_h2py(h_dict), _h2py(h_key), _h2py(h_val));
137+
}
138+
139+
HPyAPI_STORAGE HPy _HPy_IMPL_NAME(Dict_GetItem)(HPyContext ctx, HPy h_dict, HPy h_key)
140+
{
141+
return _py2h(PyDict_GetItem(_h2py(h_dict), _h2py(h_key)));
142+
}
143+

0 commit comments

Comments
 (0)