@@ -87,6 +87,8 @@ static JNIEnv* jniEnv;
87
87
UPCALL(ListCheck, SIG_HPY, SIG_INT) \
88
88
UPCALL(UnicodeFromWideChar, SIG_PTR SIG_SIZE_T, SIG_HPY) \
89
89
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) \
90
92
UPCALL(DictNew, , SIG_HPY) \
91
93
UPCALL(ListNew, SIG_SIZE_T, SIG_HPY) \
92
94
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
218
220
field -> _i = DO_UPCALL_SIZE_T (CONTEXT_INSTANCE (ctx ), FieldStore , HPY_UP (owner ), field -> _i , HPY_UP (value ));
219
221
}
220
222
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
+
221
259
//*************************
222
260
// BOXING
223
261
@@ -258,14 +296,29 @@ static HPy (*original_Global_Load)(HPyContext *ctx, HPyGlobal global);
258
296
static void (* original_Field_Store )(HPyContext * ctx , HPy target_object , HPyField * target_field , HPy h );
259
297
static HPy (* original_Field_Load )(HPyContext * ctx , HPy source_object , HPyField source_field );
260
298
static int (* original_Is )(HPyContext * ctx , HPy a , HPy b );
299
+ static HPy (* original_Type )(HPyContext * , HPy );
261
300
262
301
static int augment_Is (HPyContext * ctx , HPy a , HPy b ) {
263
302
long bitsA = toBits (a );
264
303
long bitsB = toBits (b );
265
304
if (bitsA == bitsB ) {
266
305
return 1 ;
267
306
} 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 ];
269
322
} else {
270
323
return 0 ;
271
324
}
@@ -504,7 +557,7 @@ _HPy_HIDDEN void upcallBulkClose(HPyContext *ctx, HPy *items, HPy_ssize_t nitems
504
557
}
505
558
506
559
HPy augment_Global_Load (HPyContext * ctx , HPyGlobal global ) {
507
- long bits = toBits (global );
560
+ uint64_t bits = toBits (global );
508
561
if (bits && isBoxedHandle (bits )) {
509
562
return original_Global_Load (ctx , global );
510
563
} else {
@@ -513,7 +566,7 @@ HPy augment_Global_Load(HPyContext *ctx, HPyGlobal global) {
513
566
}
514
567
515
568
void augment_Global_Store (HPyContext * ctx , HPyGlobal * global , HPy h ) {
516
- long bits = toBits (h );
569
+ uint64_t bits = toBits (h );
517
570
if (bits && isBoxedHandle (bits )) {
518
571
original_Global_Store (ctx , global , h );
519
572
} else {
@@ -522,7 +575,7 @@ void augment_Global_Store(HPyContext *ctx, HPyGlobal *global, HPy h) {
522
575
}
523
576
524
577
HPy augment_Field_Load (HPyContext * ctx , HPy source_object , HPyField source_field ) {
525
- long bits = toBits (source_field );
578
+ uint64_t bits = toBits (source_field );
526
579
if (bits && isBoxedHandle (bits )) {
527
580
return original_Field_Load (ctx , source_object , source_field );
528
581
} else {
@@ -531,14 +584,25 @@ HPy augment_Field_Load(HPyContext *ctx, HPy source_object, HPyField source_field
531
584
}
532
585
533
586
void augment_Field_Store (HPyContext * ctx , HPy target_object , HPyField * target_field , HPy h ) {
534
- long bits = toBits (h );
587
+ uint64_t bits = toBits (h );
535
588
if (bits && isBoxedHandle (bits )) {
536
589
original_Field_Store (ctx , target_object , target_field , h );
537
590
} else {
538
591
target_field -> _i = h ._i ;
539
592
}
540
593
}
541
594
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
+
542
606
void initDirectFastPaths (HPyContext * context ) {
543
607
LOG ("%p" , context );
544
608
context -> name = "HPy Universal ABI (GraalVM backend, JNI)" ;
@@ -595,6 +659,8 @@ void initDirectFastPaths(HPyContext *context) {
595
659
596
660
AUGMENT (Is );
597
661
662
+ AUGMENT (Type );
663
+
598
664
#undef AUGMENT
599
665
}
600
666
@@ -656,6 +722,9 @@ JNIEXPORT jint JNICALL Java_com_oracle_graal_python_builtins_objects_cext_hpy_Gr
656
722
context -> ctx_Field_Load = ctx_Field_Load_jni ;
657
723
context -> ctx_Field_Store = ctx_Field_Store_jni ;
658
724
725
+ context -> ctx_SetItem_s = ctx_SetItem_s_jni ;
726
+ context -> ctx_GetItem_s = ctx_GetItem_s_jni ;
727
+
659
728
graal_hpy_context_get_native_context (context )-> jni_context = (void * ) (* env )-> NewGlobalRef (env , ctx );
660
729
assert (clazz != NULL );
661
730
@@ -672,6 +741,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_graal_python_builtins_objects_cext_hpy_Gr
672
741
#define SIG_TRACKER "J"
673
742
#define SIG_JCHARARRAY "[C"
674
743
#define SIG_JLONGARRAY "[J"
744
+ #define SIG_STRING "Ljava/lang/String;"
675
745
676
746
#define UPCALL (name , jniSigArgs , jniSigRet ) \
677
747
jniMethod_ ## name = (*env)->GetMethodID(env, clazz, "ctx" #name, "(" jniSigArgs ")" jniSigRet); \
0 commit comments