Skip to content

Commit 412c22c

Browse files
committed
[GR-10357] [GR-11082] Introduce native sequence storage.
PullRequest: graalpython/158
2 parents a786437 + b2bde6e commit 412c22c

File tree

89 files changed

+4959
-2811
lines changed

Some content is hidden

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

89 files changed

+4959
-2811
lines changed

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

Lines changed: 228 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ polyglot_typeid polyglot_array_typeid(polyglot_typeid base, uint64_t len);
539539
/**
540540
* Converts a polyglot value to a dynamic struct or array pointer.
541541
*
542+
* The typeid passed to this function must refer to a struct or array type.
543+
* Passing a primitive typeid is not valid.
544+
*
542545
* @see polyglot_as_MyStruct
543546
* @see polyglot_as_MyStruct_array
544547
*
@@ -551,6 +554,9 @@ void *polyglot_as_typed(void *value, polyglot_typeid typeId);
551554
/**
552555
* Create a polyglot value from a native pointer to a struct or array.
553556
*
557+
* The typeid passed to this function must refer to a struct or array type.
558+
* Passing a primitive typeid is not valid.
559+
*
554560
* @see polyglot_from_MyStruct
555561
* @see polyglot_from_MyStruct_array
556562
*
@@ -564,31 +570,55 @@ void *polyglot_from_typed(void *ptr, polyglot_typeid typeId);
564570
* Internal function. Do not use directly.
565571
*
566572
* @see POLYGLOT_DECLARE_STRUCT
573+
* @see POLYGLOT_DECLARE_TYPE
567574
*/
568575
polyglot_typeid __polyglot_as_typeid(void *ptr);
569576

570-
#define POLYGLOT_DECLARE_GENERIC_TYPE(typedecl, typename) \
571-
__attribute__((always_inline)) static void *polyglot_##typename##_typeid() { \
577+
/**
578+
* Internal macro. Do not use directly.
579+
*
580+
* @see POLYGLOT_DECLARE_STRUCT
581+
* @see POLYGLOT_DECLARE_TYPE
582+
*/
583+
#define __POLYGLOT_DECLARE_GENERIC_ARRAY(typedecl, typename) \
584+
__attribute__((always_inline)) static inline polyglot_typeid polyglot_##typename##_typeid() { \
572585
static typedecl __polyglot_typeid_##typename[0]; \
573586
return __polyglot_as_typeid(__polyglot_typeid_##typename); \
574587
} \
575588
\
576-
__attribute__((always_inline)) static inline typedecl *polyglot_as_##typename(void *p) { \
577-
void *ret = polyglot_as_typed(p, polyglot_##typename##_typeid()); \
578-
return (typedecl *)ret; \
579-
} \
580-
\
581589
__attribute__((always_inline)) static inline typedecl *polyglot_as_##typename##_array(void *p) { \
582590
void *ret = polyglot_as_typed(p, polyglot_array_typeid(polyglot_##typename##_typeid(), 0)); \
583591
return (typedecl *)ret; \
584592
} \
585593
\
586-
__attribute__((always_inline)) static void *polyglot_from_##typename(typedecl * s) { \
587-
return polyglot_from_typed(s, polyglot_##typename##_typeid()); \
594+
__attribute__((always_inline)) static inline void *polyglot_from_##typename##_array(typedecl *arr, uint64_t len) { \
595+
return polyglot_from_typed(arr, polyglot_array_typeid(polyglot_##typename##_typeid(), len)); \
596+
}
597+
598+
__POLYGLOT_DECLARE_GENERIC_ARRAY(bool, boolean)
599+
__POLYGLOT_DECLARE_GENERIC_ARRAY(int8_t, i8)
600+
__POLYGLOT_DECLARE_GENERIC_ARRAY(int16_t, i16)
601+
__POLYGLOT_DECLARE_GENERIC_ARRAY(int32_t, i32)
602+
__POLYGLOT_DECLARE_GENERIC_ARRAY(int64_t, i64)
603+
__POLYGLOT_DECLARE_GENERIC_ARRAY(float, float)
604+
__POLYGLOT_DECLARE_GENERIC_ARRAY(double, double)
605+
606+
/**
607+
* Internal macro. Do not use directly.
608+
*
609+
* @see POLYGLOT_DECLARE_STRUCT
610+
* @see POLYGLOT_DECLARE_TYPE
611+
*/
612+
#define __POLYGLOT_DECLARE_GENERIC_TYPE(typedecl, typename) \
613+
__POLYGLOT_DECLARE_GENERIC_ARRAY(typedecl, typename) \
614+
\
615+
__attribute__((always_inline)) static inline typedecl *polyglot_as_##typename(void *p) { \
616+
void *ret = polyglot_as_typed(p, polyglot_##typename##_typeid()); \
617+
return (typedecl *)ret; \
588618
} \
589619
\
590-
__attribute__((always_inline)) static void *polyglot_from_##typename##_array(typedecl *arr, uint64_t len) { \
591-
return polyglot_from_typed(arr, polyglot_array_typeid(polyglot_##typename##_typeid(), len)); \
620+
__attribute__((always_inline)) static inline void *polyglot_from_##typename(typedecl * s) { \
621+
return polyglot_from_typed(s, polyglot_##typename##_typeid()); \
592622
}
593623

594624
/**
@@ -614,7 +644,7 @@ polyglot_typeid __polyglot_as_typeid(void *ptr);
614644
* void *polyglot_from_MyStruct_array(struct MyStruct *arr, uint64_t len);
615645
* \endcode
616646
*/
617-
#define POLYGLOT_DECLARE_STRUCT(type) POLYGLOT_DECLARE_GENERIC_TYPE(struct type, type)
647+
#define POLYGLOT_DECLARE_STRUCT(type) __POLYGLOT_DECLARE_GENERIC_TYPE(struct type, type)
618648

619649
/**
620650
* Declare polyglot conversion functions for a user-defined anonymous struct type.
@@ -639,9 +669,194 @@ polyglot_typeid __polyglot_as_typeid(void *ptr);
639669
* void *polyglot_from_MyType_array(MyType *arr, uint64_t len);
640670
* \endcode
641671
*/
642-
#define POLYGLOT_DECLARE_TYPE(type) POLYGLOT_DECLARE_GENERIC_TYPE(type, type)
672+
#define POLYGLOT_DECLARE_TYPE(type) __POLYGLOT_DECLARE_GENERIC_TYPE(type, type)
643673

644674
#ifdef DOXYGEN // documentation only
675+
676+
/**
677+
* Get a polyglot typeid for the primitive bool type.
678+
*/
679+
static void *polyglot_boolean_typeid();
680+
681+
/**
682+
* Get a polyglot typeid for the primitive int8_t type.
683+
*/
684+
static void *polyglot_int8_typeid();
685+
686+
/**
687+
* Get a polyglot typeid for the primitive int16_t type.
688+
*/
689+
static void *polyglot_int16_typeid();
690+
691+
/**
692+
* Get a polyglot typeid for the primitive int32_t type.
693+
*/
694+
static void *polyglot_int32_typeid();
695+
696+
/**
697+
* Get a polyglot typeid for the primitive int64_t type.
698+
*/
699+
static void *polyglot_int64_typeid();
700+
701+
/**
702+
* Get a polyglot typeid for the primitive float type.
703+
*/
704+
static void *polyglot_float_typeid();
705+
706+
/**
707+
* Get a polyglot typeid for the primitive double type.
708+
*/
709+
static void *polyglot_double_typeid();
710+
711+
/**
712+
* Converts a polyglot value to an integer array.
713+
*
714+
* For example, this code snippet:
715+
*
716+
* \code
717+
* int32_t *arr = polyglot_as_i32_array(arrayValue);
718+
* for (int i = 0; i < polyglot_get_array_size(arr); i++) {
719+
* sum += arr[i];
720+
* }
721+
* \endcode
722+
*
723+
* is equivalent to
724+
*
725+
* \code
726+
* for (int i = 0; i < polyglot_get_array_size(arrayValue); i++) {
727+
* void *elem = polyglot_get_array_element(arrayValue, i);
728+
* sum += polyglot_as_i32(elem);
729+
* }
730+
* \endcode
731+
*
732+
* The returned pointer is a view of the original value, and does not need to be
733+
* freed separately.
734+
*
735+
* \param value a polyglot array value
736+
* \return array view of the polyglot value
737+
*/
738+
static int32_t *polyglot_as_i32_array(void *value);
739+
740+
/**
741+
* Create a polyglot value from a native pointer to a primitive integer array.
742+
* The resulting polyglot value can be passed to other languages and accessed
743+
* from there.
744+
*
745+
* For example, given this code snippet:
746+
*
747+
* \code
748+
* int32_t *s = calloc(len, sizeof(*s));
749+
* s[idx] = ...;
750+
* void *value = polyglot_from_i32_array(s, len);
751+
* someJSFunction(value);
752+
* \endcode
753+
*
754+
* The following JavaScript code can access the native pointer as if it were a
755+
* JavaScript array:
756+
*
757+
* \code
758+
* function someJSFunction(value) {
759+
* ...
760+
* result = value[idx];
761+
* ...
762+
* }
763+
* \endcode
764+
*
765+
* The array access will be bounds checked with the given array length.
766+
*
767+
* The returned pointer will be semantically equal to the original pointer. In
768+
* particular, if one of them is freed, the other will become invalid.
769+
*
770+
* \param arr a pointer to a primitive integer array
771+
* \param len the length of the array
772+
* \return a polyglot value representing arr
773+
*/
774+
static void *polyglot_from_i32_array(int32_t *arr, uint64_t len);
775+
776+
/**
777+
* Converts a polyglot value to a bool array.
778+
*
779+
* \see polyglot_as_i32_array
780+
*/
781+
static bool *polyglot_as_boolean_array(void *value);
782+
783+
/**
784+
* Converts a polyglot value to an integer array.
785+
*
786+
* \see polyglot_as_i32_array
787+
*/
788+
static int8_t *polyglot_as_i8_array(void *value);
789+
790+
/**
791+
* Converts a polyglot value to an integer array.
792+
*
793+
* \see polyglot_as_i32_array
794+
*/
795+
static int16_t *polyglot_as_i16_array(void *value);
796+
797+
/**
798+
* Converts a polyglot value to an integer array.
799+
*
800+
* \see polyglot_as_i32_array
801+
*/
802+
static int64_t *polyglot_as_i64_array(void *value);
803+
804+
/**
805+
* Converts a polyglot value to a float array.
806+
*
807+
* \see polyglot_as_i32_array
808+
*/
809+
static float *polyglot_as_float_array(void *value);
810+
811+
/**
812+
* Converts a polyglot value to a double array.
813+
*
814+
* \see polyglot_as_i32_array
815+
*/
816+
static double *polyglot_as_double_array(void *value);
817+
818+
/**
819+
* Create a polyglot value from a native pointer to a primitive bool array.
820+
*
821+
* \see polyglot_from_i32_array
822+
*/
823+
static void *polyglot_from_boolean_array(bool *arr, uint64_t len);
824+
825+
/**
826+
* Create a polyglot value from a native pointer to a primitive integer array.
827+
*
828+
* \see polyglot_from_i32_array
829+
*/
830+
static void *polyglot_from_i8_array(int8_t *arr, uint64_t len);
831+
832+
/**
833+
* Create a polyglot value from a native pointer to a primitive integer array.
834+
*
835+
* \see polyglot_from_i32_array
836+
*/
837+
static void *polyglot_from_i16_array(int16_t *arr, uint64_t len);
838+
839+
/**
840+
* Create a polyglot value from a native pointer to a primitive integer array.
841+
*
842+
* \see polyglot_from_i32_array
843+
*/
844+
static void *polyglot_from_i64_array(int64_t *arr, uint64_t len);
845+
846+
/**
847+
* Create a polyglot value from a native pointer to a primitive float array.
848+
*
849+
* \see polyglot_from_i32_array
850+
*/
851+
static void *polyglot_from_float_array(float *arr, uint64_t len);
852+
853+
/**
854+
* Create a polyglot value from a native pointer to a primitive double array.
855+
*
856+
* \see polyglot_from_i32_array
857+
*/
858+
static void *polyglot_from_double_array(double *arr, uint64_t len);
859+
645860
struct MyStruct;
646861

647862
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ PyObject* PyBytes_FromStringAndSize(const char* str, Py_ssize_t sz) {
5252
setlocale(LC_ALL, NULL);
5353
const char* encoding = nl_langinfo(CODESET);
5454
void *jstr = str != NULL ? polyglot_from_string_n(str, sz, SRC_CS) : to_java(NULL);
55-
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", jstr, polyglot_from_string(encoding, SRC_CS));
55+
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", jstr, sz, polyglot_from_string(encoding, SRC_CS));
5656
}
5757

5858
PyObject * PyBytes_FromString(const char *str) {
5959
setlocale(LC_ALL, NULL);
6060
const char* encoding = nl_langinfo(CODESET);
61-
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", polyglot_from_string(str, SRC_CS), polyglot_from_string(encoding, SRC_CS));
61+
return UPCALL_CEXT_O("PyBytes_FromStringAndSize", polyglot_from_string(str, SRC_CS), 0, polyglot_from_string(encoding, SRC_CS));
6262
}
6363

6464
char* PyBytes_AsString(PyObject *obj) {

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

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,8 @@ initialize_type(_PyNotImplemented_Type, NotImplementedType, _object);
119119
initialize_type(PyDictProxy_Type, mappingproxy, _object);
120120
initialize_type(PyEllipsis_Type, ellipsis, _object);
121121

122-
typedef uint8_t ByteArray[0];
123-
POLYGLOT_DECLARE_TYPE(ByteArray);
124-
125-
typedef PyObject* PtrArray[0];
126-
POLYGLOT_DECLARE_TYPE(PtrArray);
122+
typedef PyObject* PyObjectPtr;
123+
POLYGLOT_DECLARE_TYPE(PyObjectPtr);
127124

128125
static void initialize_globals() {
129126
// None
@@ -210,12 +207,12 @@ void* get_ob_type(PyObject* obj) {
210207

211208
/** to be used from Java code only; returns the type ID for a byte array */
212209
polyglot_typeid get_byte_array_typeid(uint64_t len) {
213-
return polyglot_ByteArray_typeid();
210+
return polyglot_array_typeid(polyglot_i8_typeid(), len);
214211
}
215212

216213
/** to be used from Java code only; returns the type ID for a 'PyObject*' array */
217214
polyglot_typeid get_ptr_array_typeid(uint64_t len) {
218-
return polyglot_PtrArray_typeid();
215+
return polyglot_array_typeid(polyglot_PyObjectPtr_typeid(), len);
219216
}
220217

221218
typedef struct PyObjectHandle {
@@ -264,16 +261,23 @@ const char* PyTruffle_StringToCstr(void* o, int32_t strLen) {
264261
return str;
265262
}
266263

267-
const char* PyTruffle_ByteArrayToNative(const void* jbyteArray, int len) {
268-
int i;
269-
int size = len != 0 ? len : 1;
270-
char* barr = (const char*) malloc(size * sizeof(char));
271-
barr[0] = '\0';
272-
for(i=0; i < len; i++) {
273-
barr[i] = (char) polyglot_get_array_element(jbyteArray, i);
274-
}
275-
return (const char*) barr;
276-
}
264+
#define PRIMITIVE_ARRAY_TO_NATIVE(__jtype__, __ctype__, __polyglot_type__, __element_cast__) \
265+
void* PyTruffle_##__jtype__##ArrayToNative(const void* jarray, int64_t len) { \
266+
int64_t i; \
267+
int64_t size = len + 1; \
268+
__ctype__* carr = (__ctype__*) malloc(size * sizeof(__ctype__)); \
269+
carr[len] = (__ctype__)0; \
270+
for (i=0; i < len; i++) { \
271+
carr[i] = __element_cast__(polyglot_get_array_element(jarray, i)); \
272+
} \
273+
return polyglot_from_##__polyglot_type__##_array(carr, len); \
274+
} \
275+
276+
PRIMITIVE_ARRAY_TO_NATIVE(Byte, int8_t, i8, polyglot_as_i8);
277+
PRIMITIVE_ARRAY_TO_NATIVE(Int, int32_t, i32, polyglot_as_i32);
278+
PRIMITIVE_ARRAY_TO_NATIVE(Long, int64_t, i64, polyglot_as_i64);
279+
PRIMITIVE_ARRAY_TO_NATIVE(Double, double, double, polyglot_as_double);
280+
PRIMITIVE_ARRAY_TO_NATIVE(Object, PyObjectPtr, PyObjectPtr, (PyObjectPtr));
277281

278282
#define ReadMember(object, offset, T) ((T*)(((char*)object) + PyLong_AsSsize_t(offset)))[0]
279283

0 commit comments

Comments
 (0)