Skip to content

Commit ecfeb2b

Browse files
committed
Merge branch 'master' into feature/GR-12099
2 parents 00a903c + f55f64b commit ecfeb2b

File tree

63 files changed

+3459
-447
lines changed

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

+3459
-447
lines changed

ci.jsonnet

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"git": ">=1.8.3",
7171
"mercurial": ">=3.2.4",
7272
"gcc": "==4.9.1",
73-
"llvm": ">=4.0",
73+
"llvm": "==4.0.1",
7474
"python": "==3.4.1",
7575
"libffi": ">=3.2.1",
7676
"bzip2": ">=1.0.6",

doc/INTEROP.md

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,12 @@ Returns true for None only.
145145

146146
###### HAS_SIZE
147147
According to the Truffle interop contract answering `true` to `HAS_SIZE` implies
148-
that indexed element access is available. Thus, we answer `true` here only for
149-
(sub-)instances of `tuple`, `list`, `array.array`, `bytearray`, `bytes`, `str`,
150-
and `range`.
148+
that indexed element access is available. However, we cannot fully guarantee
149+
this. We may answer `true` here when the object has both a `__len__` field and a
150+
`__getitem__` field. If the object's length is reported >0, we also try to read
151+
the item `0` and if that fails, we answer `false`. If the object reports it's
152+
empty, we cannot know if a read with an index will actually work, but we'll
153+
report `true`.
151154

152155
###### GET_SIZE
153156
Calls `__len__`. Just because `GET_SIZE` returns something positive does not
@@ -159,27 +162,35 @@ knowing what the `__getitem__` method does with an integer argument. Use
159162
Returns true for those values that can be unboxed using the `UNBOX` message.
160163

161164
###### KEY_INFO
162-
This will lookup the key using `READ`, assume it is readable and writable, and
163-
check `IS_EXECUTABLE`.
165+
This will lookup the key using the Python MRO. It will check if it's readable
166+
and writable, and also check if it has side-effects based on wether it is an
167+
inherited descriptor (i.e., an object with `__get__`, `__set__`, and/or
168+
`__delete__`). If the owner of the key is mutable (the owner being the class the
169+
key is inherited from or the object itself) then `REMOVABLE` and `MODIFABLE` are
170+
true. If the object itself is mutable, `INSERTABLE` will also be true. Finally,
171+
if the attribute is a function or it is *not* a descriptor and has a `__call__`,
172+
we declare it `INOCABLE`. We don't do this for descriptors, because we would
173+
have to run the `__get__` method and this message should not have side-effects.
164174

165175
###### HAS_KEYS
166-
Returns true for any boxed Python object, so small integers, booleans, or floats
167-
usually don't return true.
176+
Always returns true.
168177

169178
###### KEYS
170-
This returns the direct attributes of the receiver object, which would usually
171-
be available through `__getattribute__`.
172-
173-
The `KEYS` message requires the returned object to have only `java.lang.String`
174-
items. If the object responds to `keys`, `values`, `items`, and `__getitem__`,
175-
we assume it is Mapping, and we present the result of the `keys` method in
176-
combination with the attributes if, and only if, all keys are strings. This is
177-
roughly parallel to how `READ` and `WRITE` would be handled for string keys.
179+
This returns the all attributes of the receiver object that would usually be
180+
available through `__getattribute__`, i.e., both inherited and direct
181+
attributes.
182+
183+
If the object responds to `keys`, `values`, `items`, and `__getitem__`, we
184+
assume it is Mapping, and we present the String result of the `keys` method in
185+
combination with the attributes, prefixed with `[` if, and only if, the request
186+
asked for _internal_ keys also. The `KEYS` message requires the returned object
187+
to have only `java.lang.String` items, so inlo String keys are added to the
188+
result set. The `[` prefix ensures that in our handling of `READ` and `WRITE`
189+
messages we also treat them as mapping entries, not attributes.
178190

179191
It's still possible that none of the keys can be `READ`: the `READ` message uses
180192
Python semantics for lookup, which means that an inherited descriptor with a
181-
`__get__` method may still come before the object's keys and do anything
182-
(including raising an `AttributeError`).
193+
`__get__` method or the `__getitem__` method may still intercept actual access.
183194

184195
###### IS_POINTER
185196
Returns true if the object is a Python function defined in a Python C extension

graalpython/com.oracle.graal.python.cext/include/truffle.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ void *truffle_assign_managed(void *dst, void *managed);
5454
void *truffle_deref_handle_for_managed(void *managed);
5555
bool truffle_cannot_be_handle(void *nativeHandle);
5656

57+
// wrapping functions
58+
void *truffle_decorate_function(void *function, void *wrapper);
59+
5760
/*
5861
* All function below here are deprecated and will be removed in a future release.
5962
* Use the equivalent functions from <polyglot.h> instead.

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,8 @@ PyObject* WriteULongMember(PyObject* object, Py_ssize_t offset, PyObject* value)
461461
return value;
462462
}
463463

464-
UPCALL_ID(__bool__);
465464
PyObject* WriteBoolMember(PyObject* object, Py_ssize_t offset, PyObject* value) {
466-
WriteMember(object, offset, UPCALL_O(native_to_java(value), _jls___bool__) == Py_True ? (char)1 : (char)0, char);
465+
WriteMember(object, offset, UPCALL_O(native_to_java(value), polyglot_from_string("__bool__", SRC_CS)) == Py_True ? (char)1 : (char)0, char);
467466
return value;
468467
}
469468

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,13 @@ typedef struct {
7575
PyAPI_DATA(PyTypeObject) PyBuffer_Type;
7676
PyAPI_DATA(PyTypeObject) _PyExc_BaseException;
7777

78+
typedef void (*init_upcall)();
79+
7880
extern void *PY_TRUFFLE_CEXT;
7981
extern void *PY_BUILTIN;
8082
extern void *Py_NoValue;
83+
extern init_upcall upcalls[];
84+
extern unsigned init_upcall_n;
8185

8286
/* upcall functions for calling into Python */
8387
extern PyObject*(*PY_TRUFFLE_LANDING)(void *rcv, void* name, ...);
@@ -89,13 +93,6 @@ extern uint64_t (*PY_TRUFFLE_CEXT_LANDING_L)(void* name, ...);
8993
extern double (*PY_TRUFFLE_CEXT_LANDING_D)(void* name, ...);
9094
extern void* (*PY_TRUFFLE_CEXT_LANDING_PTR)(void* name, ...);
9195

92-
#define UPCALL_ID(name) \
93-
static void* _jls_ ## name; \
94-
__attribute__((constructor)) \
95-
static void init_jls_ ## name(void) { \
96-
_jls_ ## name = polyglot_from_string(#name, SRC_CS); \
97-
}
98-
9996
/* Call function with return type 'PyObject *'; does polyglot cast and error handling */
10097
#define UPCALL_O(__recv__, __name__, ...) PY_TRUFFLE_LANDING((__recv__), __name__, ##__VA_ARGS__)
10198

@@ -138,6 +135,13 @@ extern void* (*PY_TRUFFLE_CEXT_LANDING_PTR)(void* name, ...);
138135
/* Call function of 'python_cext' module with return type 'double'; no polyglot cast but error handling */
139136
#define UPCALL_CEXT_D(__name__, ...) (PY_TRUFFLE_CEXT_LANDING_D(__name__, ##__VA_ARGS__))
140137

138+
#define UPCALL_ID(name) \
139+
static void* _jls_ ## name; \
140+
__attribute__((constructor)) \
141+
static void init_upcall_ ## name(void) { \
142+
_jls_ ## name = polyglot_get_member(PY_TRUFFLE_CEXT, polyglot_from_string(#name, SRC_CS)); \
143+
}
144+
141145
#define as_char_pointer(obj) ((const char*)UPCALL_CEXT_PTR(polyglot_from_string("to_char_pointer", "ascii"), native_to_java(obj)))
142146
#define as_long(obj) ((long)polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "to_long", to_java(obj))))
143147
#define as_long_long(obj) ((long long)polyglot_as_i64(polyglot_invoke(PY_TRUFFLE_CEXT, "PyLong_AsPrimitive", to_java(obj), 1, sizeof(long long), polyglot_from_string("long long", "utf-8"))))

graalpython/com.oracle.graal.python.cext/src/dictobject.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,8 @@ int PyDict_DelItemString(PyObject *d, const char *key) {
114114
return UPCALL_CEXT_I(_jls_PyDict_DelItem, native_to_java(d), polyglot_from_string(key, SRC_CS));
115115
}
116116

117-
UPCALL_ID(update);
118117
int PyDict_Update(PyObject *a, PyObject *b) {
119-
PyObject* result = UPCALL_O(native_to_java(a), _jls_update, native_to_java(b));
118+
PyObject* result = UPCALL_O(native_to_java(a), polyglot_from_string("update", SRC_CS), native_to_java(b));
120119
if (PyErr_Occurred()) {
121120
return -1;
122121
} else {

graalpython/com.oracle.graal.python.cext/src/errors.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ void _PyErr_BadInternalCall(const char *filename, int lineno) {
4545
UPCALL_CEXT_VOID(_jls__PyErr_BadInternalCall, polyglot_from_string(filename, SRC_CS), lineno, native_to_java(NULL));
4646
}
4747

48+
UPCALL_ID(PyErr_CreateAndSetException);
4849
#undef PyErr_BadInternalCall
49-
UPCALL_ID(PyTruffle_Err_Format);
5050
void PyErr_BadInternalCall(void) {
5151
assert(0 && "bad argument to internal function");
52-
UPCALL_CEXT_VOID(_jls_PyTruffle_Err_Format, native_to_java(PyExc_SystemError), polyglot_from_string("bad argument to internal function", SRC_CS));
52+
UPCALL_CEXT_VOID(_jls_PyErr_CreateAndSetException, native_to_java(PyExc_SystemError), polyglot_from_string("bad argument to internal function", SRC_CS));
5353
}
5454
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
5555

@@ -64,7 +64,6 @@ void PyErr_SetString(PyObject *exception, const char *string) {
6464
PyErr_SetObject(exception, value);
6565
}
6666

67-
UPCALL_ID(PyErr_CreateAndSetException);
6867
void PyErr_SetObject(PyObject *exception, PyObject *value) {
6968
UPCALL_CEXT_VOID(_jls_PyErr_CreateAndSetException, native_to_java(exception), native_to_java(value));
7069
}

graalpython/com.oracle.graal.python.cext/src/exceptions.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,8 @@ void initialize_exceptions() {
121121
}
122122

123123

124-
UPCALL_ID(with_traceback);
125124
int PyException_SetTraceback(PyObject *self, PyObject *tb) {
126-
PyObject* result = UPCALL_O(native_to_java(self), _jls_with_traceback, native_to_java(tb));
125+
PyObject* result = UPCALL_O(native_to_java(self), polyglot_from_string("with_traceback", SRC_CS), native_to_java(tb));
127126
if (result == NULL) {
128127
return -1;
129128
} else {

graalpython/com.oracle.graal.python.cext/src/functionobject.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
PyTypeObject PyFunction_Type = PY_TRUFFLE_TYPE("function", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyFunctionObject));
4444

45-
UPCALL_ID(classmethod);
4645
PyObject* PyClassMethod_New(PyObject* method) {
47-
return UPCALL_O(PY_BUILTIN, _jls_classmethod, native_to_java(method));
46+
return UPCALL_O(PY_BUILTIN, polyglot_from_string("classmethod", SRC_CS), native_to_java(method));
4847
}

graalpython/com.oracle.graal.python.cext/src/import.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ PyObject* PyImport_Import(PyObject *name) {
4949
return UPCALL_CEXT_O(_jls_PyImport_ImportModule, native_to_java(name));
5050
}
5151

52-
UPCALL_ID(__import__);
5352
PyObject* PyImport_ImportModuleLevelObject(PyObject* name, PyObject* globals, PyObject* locals,
5453
PyObject* fromlist, int level) {
55-
return UPCALL_O(PY_BUILTIN, _jls___import__, native_to_java(name), native_to_java(globals),
54+
return UPCALL_O(PY_BUILTIN, polyglot_from_string("__import__", SRC_CS), native_to_java(name), native_to_java(globals),
5655
native_to_java(locals), native_to_java(fromlist), level);
5756
}
5857

0 commit comments

Comments
 (0)