@@ -87,6 +87,8 @@ static JNIEnv* jniEnv;
8787 UPCALL(ListCheck, SIG_HPY, SIG_INT) \
8888 UPCALL(UnicodeFromWideChar, SIG_PTR SIG_SIZE_T, SIG_HPY) \
8989 UPCALL(UnicodeFromJCharArray, SIG_JCHARARRAY, SIG_HPY) \
90+ UPCALL(SetItems, SIG_HPY SIG_STRING SIG_HPY, SIG_INT) \
91+ UPCALL(GetItems, SIG_HPY SIG_STRING, SIG_HPY) \
9092 UPCALL(DictNew, , SIG_HPY) \
9193 UPCALL(ListNew, SIG_SIZE_T, SIG_HPY) \
9294 UPCALL(TupleFromArray, SIG_JLONGARRAY SIG_BOOL, SIG_HPY) \
@@ -218,6 +220,42 @@ static void ctx_Field_Store_jni(HPyContext *ctx, HPy owner, HPyField *field, HPy
218220 field -> _i = DO_UPCALL_SIZE_T (CONTEXT_INSTANCE (ctx ), FieldStore , HPY_UP (owner ), field -> _i , HPY_UP (value ));
219221}
220222
223+ static const char * getBoxedPrimitiveName (uint64_t bits ) {
224+ assert (!isBoxedHandle (bits ));
225+ if (isBoxedInt (bits )) {
226+ return "int" ;
227+ }
228+ assert (isBoxedDouble (bits ));
229+ return "float" ;
230+ }
231+
232+ int ctx_SetItem_s_jni (HPyContext * ctx , HPy target , const char * name , HPy value ) {
233+ uint64_t bits = toBits (target );
234+ if (!isBoxedHandle (bits )) {
235+ const size_t buffer_size = 128 ;
236+ char message [buffer_size ];
237+ snprintf (message , buffer_size ,
238+ "'%s' object does not support item assignment" , getBoxedPrimitiveName (bits ));
239+ HPyErr_SetString (ctx , ctx -> h_TypeError , message );
240+ return -1 ;
241+ }
242+ jstring jname = (* jniEnv )-> NewStringUTF (jniEnv , name );
243+ return DO_UPCALL_INT (CONTEXT_INSTANCE (ctx ), SetItems , target , jname , value );
244+ }
245+
246+ HPy ctx_GetItem_s_jni (HPyContext * ctx , HPy target , const char * name ) {
247+ uint64_t bits = toBits (target );
248+ if (!isBoxedHandle (bits )) {
249+ const size_t buffer_size = 128 ;
250+ char message [buffer_size ];
251+ snprintf (message , buffer_size ,
252+ "'%s' object is not subscriptable" , getBoxedPrimitiveName (bits ));
253+ return HPyErr_SetString (ctx , ctx -> h_TypeError , message );
254+ }
255+ jstring jname = (* jniEnv )-> NewStringUTF (jniEnv , name );
256+ return DO_UPCALL_HPY (CONTEXT_INSTANCE (ctx ), GetItems , target , jname );
257+ }
258+
221259//*************************
222260// BOXING
223261
@@ -258,14 +296,29 @@ static HPy (*original_Global_Load)(HPyContext *ctx, HPyGlobal global);
258296static void (* original_Field_Store )(HPyContext * ctx , HPy target_object , HPyField * target_field , HPy h );
259297static HPy (* original_Field_Load )(HPyContext * ctx , HPy source_object , HPyField source_field );
260298static int (* original_Is )(HPyContext * ctx , HPy a , HPy b );
299+ static HPy (* original_Type )(HPyContext * , HPy );
261300
262301static int augment_Is (HPyContext * ctx , HPy a , HPy b ) {
263302 long bitsA = toBits (a );
264303 long bitsB = toBits (b );
265304 if (bitsA == bitsB ) {
266305 return 1 ;
267306 } else if (isBoxedHandle (bitsA ) && isBoxedHandle (bitsB )) {
268- return original_Is (ctx , a , b );
307+ // This code assumes that objects pointed by a handle <= SINGLETON_HANDLES_MAX
308+ // always get that same handle
309+ long unboxedA = unboxHandle (bitsA );
310+ long unboxedB = unboxHandle (bitsB );
311+ if (unboxedA <= SINGLETON_HANDLES_MAX ) {
312+ return 0 ;
313+ } else if (unboxedB <= SINGLETON_HANDLES_MAX ) {
314+ return 0 ;
315+ }
316+ // This code assumes that space[x] != NULL <=> objects pointed by x has native struct
317+ void * * space = (void * * )ctx -> _private ;
318+ if (space [unboxedA ] == NULL && space [unboxedB ] == NULL ) {
319+ return original_Is (ctx , a , b );
320+ }
321+ return space [unboxedA ] == space [unboxedB ];
269322 } else {
270323 return 0 ;
271324 }
@@ -504,7 +557,7 @@ _HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems
504557}
505558
506559HPy augment_Global_Load (HPyContext * ctx , HPyGlobal global ) {
507- long bits = toBits (global );
560+ uint64_t bits = toBits (global );
508561 if (bits && isBoxedHandle (bits )) {
509562 return original_Global_Load (ctx , global );
510563 } else {
@@ -513,7 +566,7 @@ HPy augment_Global_Load(HPyContext *ctx, HPyGlobal global) {
513566}
514567
515568void augment_Global_Store (HPyContext * ctx , HPyGlobal * global , HPy h ) {
516- long bits = toBits (h );
569+ uint64_t bits = toBits (h );
517570 if (bits && isBoxedHandle (bits )) {
518571 original_Global_Store (ctx , global , h );
519572 } else {
@@ -522,7 +575,7 @@ void augment_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h) {
522575}
523576
524577HPy augment_Field_Load (HPyContext * ctx , HPy source_object , HPyField source_field ) {
525- long bits = toBits (source_field );
578+ uint64_t bits = toBits (source_field );
526579 if (bits && isBoxedHandle (bits )) {
527580 return original_Field_Load (ctx , source_object , source_field );
528581 } else {
@@ -531,14 +584,25 @@ HPy augment_Field_Load(HPyContext *ctx, HPy source_object, HPyField source_field
531584}
532585
533586void augment_Field_Store (HPyContext * ctx , HPy target_object , HPyField * target_field , HPy h ) {
534- long bits = toBits (h );
587+ uint64_t bits = toBits (h );
535588 if (bits && isBoxedHandle (bits )) {
536589 original_Field_Store (ctx , target_object , target_field , h );
537590 } else {
538591 target_field -> _i = h ._i ;
539592 }
540593}
541594
595+ HPy augment_Type (HPyContext * ctx , HPy h ) {
596+ uint64_t bits = toBits (h );
597+ if (isBoxedInt (bits )) {
598+ return ctx -> h_LongType ;
599+ } else if (isBoxedDouble (bits )) {
600+ return ctx -> h_FloatType ;
601+ } else {
602+ return original_Type (ctx , h );
603+ }
604+ }
605+
542606void initDirectFastPaths (HPyContext * context ) {
543607 LOG ("%p" , context );
544608 context -> name = "HPy Universal ABI (GraalVM backend, JNI)" ;
@@ -595,6 +659,8 @@ void initDirectFastPaths(HPyContext *context) {
595659
596660 AUGMENT (Is );
597661
662+ AUGMENT (Type );
663+
598664#undef AUGMENT
599665}
600666
@@ -656,6 +722,9 @@ JNIEXPORT jint JNICALL Java_com_oracle_graal_python_builtins_objects_cext_hpy_Gr
656722 context -> ctx_Field_Load = ctx_Field_Load_jni ;
657723 context -> ctx_Field_Store = ctx_Field_Store_jni ;
658724
725+ context -> ctx_SetItem_s = ctx_SetItem_s_jni ;
726+ context -> ctx_GetItem_s = ctx_GetItem_s_jni ;
727+
659728 graal_hpy_context_get_native_context (context )-> jni_context = (void * ) (* env )-> NewGlobalRef (env , ctx );
660729 assert (clazz != NULL );
661730
@@ -672,6 +741,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_graal_python_builtins_objects_cext_hpy_Gr
672741#define SIG_TRACKER "J"
673742#define SIG_JCHARARRAY "[C"
674743#define SIG_JLONGARRAY "[J"
744+ #define SIG_STRING "Ljava/lang/String;"
675745
676746#define UPCALL (name , jniSigArgs , jniSigRet ) \
677747 jniMethod_ ## name = (*env)->GetMethodID(env, clazz, "ctx" #name, "(" jniSigArgs ")" jniSigRet); \
0 commit comments