21
21
#include <stdio.h>
22
22
#include <inttypes.h>
23
23
24
+ #define DONE mrb_gc_arena_restore(mrb, ai);
24
25
25
26
static void
26
27
cfunc_type_destructor (mrb_state * mrb , void * p )
@@ -203,7 +204,18 @@ cfunc_type_addr(mrb_state *mrb, mrb_value self)
203
204
204
205
205
206
static
206
- mrb_int fixnum_value (mrb_state * mrb , mrb_value val )
207
+ mrb_value int64_to_mrb (int64_t val )
208
+ {
209
+ if (val < MRB_INT_MIN || val > MRB_INT_MAX ) {
210
+ return mrb_float_value (val );
211
+ }
212
+ else {
213
+ return mrb_fixnum_value (val );
214
+ }
215
+ }
216
+
217
+ static
218
+ int64_t mrb_to_int64 (mrb_state * mrb , mrb_value val )
207
219
{
208
220
switch (mrb_type (val )) {
209
221
case MRB_TT_FIXNUM :
@@ -292,10 +304,10 @@ cfunc_uint64_class_get(mrb_state *mrb, mrb_value klass)
292
304
struct mrb_ffi_type * mft = rclass_to_mrb_ffi_type (mrb , mrb_class_ptr (klass ));
293
305
uint64_t uint64 = * (uint64_t * )cfunc_pointer_ptr (pointer );
294
306
295
- if (uint64 > MRB_INT_MAX ) {
307
+ if (uint64 > UINT32_MAX ) {
296
308
mrb_raise (mrb , E_TYPE_ERROR , "too big. Use low, high" );
297
309
}
298
- return mrb_fixnum_value (uint64 );
310
+ return int64_to_mrb (uint64 );
299
311
}
300
312
301
313
@@ -307,19 +319,19 @@ cfunc_uint64_get_value(mrb_state *mrb, mrb_value self)
307
319
if (data -> refer ) {
308
320
uint64 = * (uint64_t * )data -> value ._pointer ;
309
321
}
310
- if (uint64 > MRB_INT_MAX ) {
322
+ if (uint64 > UINT32_MAX ) {
311
323
mrb_raise (mrb , E_TYPE_ERROR , "too big. Use low, high" );
312
324
}
313
325
314
- return mrb_fixnum_value (uint64 );
326
+ return int64_to_mrb (uint64 );
315
327
}
316
328
317
329
318
330
mrb_value
319
331
cfunc_uint64_get_low (mrb_state * mrb , mrb_value self )
320
332
{
321
333
struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
322
- return mrb_fixnum_value (data -> value ._uint64 & 0xffffffff );
334
+ return int64_to_mrb (data -> value ._uint64 & 0xffffffff );
323
335
}
324
336
325
337
@@ -330,7 +342,7 @@ cfunc_uint64_set_low(mrb_state *mrb, mrb_value self)
330
342
mrb_get_args (mrb , "o" , & val );
331
343
332
344
struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
333
- data -> value ._uint64 = (data -> value ._uint64 & 0xffffffff00000000 ) | (((uint64_t )fixnum_value (mrb , val )) & 0xffffffff );
345
+ data -> value ._uint64 = (data -> value ._uint64 & 0xffffffff00000000 ) | (((uint64_t )mrb_to_int64 (mrb , val )) & 0xffffffff );
334
346
return val ;
335
347
}
336
348
@@ -339,7 +351,7 @@ mrb_value
339
351
cfunc_uint64_get_high (mrb_state * mrb , mrb_value self )
340
352
{
341
353
struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
342
- return mrb_fixnum_value (data -> value ._uint64 >> 32 );
354
+ return int64_to_mrb (data -> value ._uint64 >> 32 );
343
355
}
344
356
345
357
@@ -350,7 +362,7 @@ cfunc_uint64_set_high(mrb_state *mrb, mrb_value self)
350
362
mrb_get_args (mrb , "o" , & val );
351
363
352
364
struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
353
- data -> value ._uint64 = (data -> value ._uint64 & 0x00000000ffffffff ) | (((uint64_t )fixnum_value (mrb , val )) << 32 );
365
+ data -> value ._uint64 = (data -> value ._uint64 & 0x00000000ffffffff ) | (((uint64_t )mrb_to_int64 (mrb , val )) << 32 );
354
366
355
367
return val ;
356
368
}
@@ -366,6 +378,50 @@ cfunc_uint64_to_s(mrb_state *mrb, mrb_value self)
366
378
}
367
379
368
380
381
+
382
+
383
+ // sint64 specific
384
+ mrb_value
385
+ cfunc_sint64_class_get (mrb_state * mrb , mrb_value klass )
386
+ {
387
+ mrb_value pointer ;
388
+ mrb_get_args (mrb , "o" , & pointer );
389
+
390
+ struct mrb_ffi_type * mft = rclass_to_mrb_ffi_type (mrb , mrb_class_ptr (klass ));
391
+ int64_t sint64 = * (int64_t * )cfunc_pointer_ptr (pointer );
392
+
393
+ if (sint64 > INT32_MAX || sint64 < INT32_MIN ) {
394
+ mrb_raise (mrb , E_TYPE_ERROR , "out of range. Use low, high" );
395
+ }
396
+ return int64_to_mrb (sint64 );
397
+ }
398
+
399
+
400
+ mrb_value
401
+ cfunc_sint64_get_value (mrb_state * mrb , mrb_value self )
402
+ {
403
+ struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
404
+ int64_t sint64 = data -> value ._sint64 ;
405
+ if (data -> refer ) {
406
+ sint64 = * (int64_t * )data -> value ._pointer ;
407
+ }
408
+ if (sint64 > INT32_MAX || sint64 < INT32_MIN ) {
409
+ mrb_raise (mrb , E_TYPE_ERROR , "out of range. Use low, high" );
410
+ }
411
+ return int64_to_mrb (sint64 );
412
+ }
413
+
414
+
415
+ mrb_value
416
+ cfunc_int64_to_s (mrb_state * mrb , mrb_value self )
417
+ {
418
+ struct cfunc_type_data * data = (struct cfunc_type_data * )DATA_PTR (self );
419
+ char str [65 ];
420
+ snprintf (str , sizeof (str ), "%" PRId64 , data -> value ._sint64 );
421
+ return mrb_str_new_cstr (mrb , str );
422
+ }
423
+
424
+
369
425
// nil specific
370
426
mrb_value
371
427
cfunc_nil_addr (mrb_state * mrb , mrb_value self )
@@ -475,17 +531,17 @@ cfunc_type_ffi_##name##_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_
475
531
.data_to_mrb = &cfunc_type_ffi_##type_##_data_to_mrb \
476
532
}
477
533
478
- define_cfunc_type (sint8 , & ffi_type_sint8 , int8_t , mrb_fixnum_value , fixnum_value );
479
- define_cfunc_type (uint8 , & ffi_type_uint8 , uint8_t , mrb_fixnum_value , fixnum_value );
534
+ define_cfunc_type (sint8 , & ffi_type_sint8 , int8_t , int64_to_mrb , mrb_to_int64 );
535
+ define_cfunc_type (uint8 , & ffi_type_uint8 , uint8_t , int64_to_mrb , mrb_to_int64 );
480
536
481
- define_cfunc_type (sint16 , & ffi_type_sint16 , int16_t , mrb_fixnum_value , fixnum_value );
482
- define_cfunc_type (uint16 , & ffi_type_uint16 , uint16_t , mrb_fixnum_value , fixnum_value );
537
+ define_cfunc_type (sint16 , & ffi_type_sint16 , int16_t , int64_to_mrb , mrb_to_int64 );
538
+ define_cfunc_type (uint16 , & ffi_type_uint16 , uint16_t , int64_to_mrb , mrb_to_int64 );
483
539
484
- define_cfunc_type (sint32 , & ffi_type_sint32 , int32_t , mrb_fixnum_value , fixnum_value );
485
- define_cfunc_type (uint32 , & ffi_type_uint32 , uint32_t , mrb_fixnum_value , fixnum_value );
540
+ define_cfunc_type (sint32 , & ffi_type_sint32 , int32_t , int64_to_mrb , mrb_to_int64 );
541
+ define_cfunc_type (uint32 , & ffi_type_uint32 , uint32_t , int64_to_mrb , mrb_to_int64 );
486
542
487
- define_cfunc_type (sint64 , & ffi_type_sint64 , int64_t , mrb_fixnum_value , fixnum_value );
488
- define_cfunc_type (uint64 , & ffi_type_uint64 , uint64_t , mrb_fixnum_value , fixnum_value );
543
+ define_cfunc_type (sint64 , & ffi_type_sint64 , int64_t , int64_to_mrb , mrb_to_int64 );
544
+ define_cfunc_type (uint64 , & ffi_type_uint64 , uint64_t , int64_to_mrb , mrb_to_int64 );
489
545
490
546
define_cfunc_type (float , & ffi_type_float , float , mrb_float_value , float_value );
491
547
define_cfunc_type (double , & ffi_type_double , double , mrb_float_value , float_value );
@@ -523,6 +579,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module)
523
579
state -> type_class = type_class ;
524
580
set_cfunc_state (mrb , (struct RObject * )type_class , state );
525
581
582
+ int ai = mrb_gc_arena_save (mrb );
526
583
mrb_define_class_method (mrb , type_class , "refer" , cfunc_type_class_refer , ARGS_REQ (1 ));
527
584
mrb_define_class_method (mrb , type_class , "size" , cfunc_type_size , ARGS_NONE ());
528
585
mrb_define_class_method (mrb , type_class , "align" , cfunc_type_align , ARGS_NONE ());
@@ -534,6 +591,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module)
534
591
mrb_define_method (mrb , type_class , "value=" , cfunc_type_set_value , ARGS_REQ (1 ));
535
592
mrb_define_method (mrb , type_class , "addr" , cfunc_type_addr , ARGS_NONE ());
536
593
mrb_define_method (mrb , type_class , "to_ffi_value" , cfunc_type_addr , ARGS_NONE ());
594
+ DONE ;
537
595
538
596
int map_size = sizeof (types ) / sizeof (struct mrb_ffi_type );
539
597
int i ;
@@ -542,6 +600,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module)
542
600
mrb_value ffi_type = mrb_obj_value (Data_Wrap_Struct (mrb , mrb -> object_class , & cfunc_class_ffi_data_type , & types [i ]));
543
601
mrb_obj_iv_set (mrb , (struct RObject * )new_class , mrb_intern (mrb , "@ffi_type" ), ffi_type );
544
602
}
603
+ DONE ;
545
604
546
605
mrb_value mod = mrb_obj_value (module );
547
606
state -> void_class = mrb_class_ptr (mrb_const_get (mrb , mod , mrb_intern (mrb , "Void" )));
@@ -555,11 +614,13 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module)
555
614
state -> sint64_class = mrb_class_ptr (mrb_const_get (mrb , mod , mrb_intern (mrb , "SInt64" )));
556
615
state -> float_class = mrb_class_ptr (mrb_const_get (mrb , mod , mrb_intern (mrb , "Float" )));
557
616
state -> double_class = mrb_class_ptr (mrb_const_get (mrb , mod , mrb_intern (mrb , "Double" )));
617
+ DONE ;
558
618
559
619
mrb_define_class_method (mrb , mrb -> nil_class , "size" , cfunc_nil_size , ARGS_NONE ());
560
620
mrb_define_class_method (mrb , mrb -> nil_class , "align" , cfunc_nil_align , ARGS_NONE ());
621
+ DONE ;
561
622
562
- // sint64 specific
623
+ // uint64 specific
563
624
struct RClass * uint64_class = state -> uint64_class ;
564
625
mrb_define_class_method (mrb , uint64_class , "get" , cfunc_uint64_class_get , ARGS_REQ (1 ));
565
626
mrb_define_method (mrb , uint64_class , "value" , cfunc_uint64_get_value , ARGS_NONE ());
@@ -568,4 +629,16 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module)
568
629
mrb_define_method (mrb , uint64_class , "high" , cfunc_uint64_get_high , ARGS_NONE ());
569
630
mrb_define_method (mrb , uint64_class , "high=" , cfunc_uint64_set_high , ARGS_REQ (1 ));
570
631
mrb_define_method (mrb , uint64_class , "to_s" , cfunc_uint64_to_s , ARGS_REQ (1 ));
632
+ DONE ;
633
+
634
+ // sint64 specific
635
+ struct RClass * sint64_class = state -> sint64_class ;
636
+ mrb_define_class_method (mrb , sint64_class , "get" , cfunc_sint64_class_get , ARGS_REQ (1 ));
637
+ mrb_define_method (mrb , sint64_class , "value" , cfunc_sint64_get_value , ARGS_NONE ());
638
+ mrb_define_method (mrb , sint64_class , "low" , cfunc_uint64_get_low , ARGS_NONE ());
639
+ mrb_define_method (mrb , sint64_class , "low=" , cfunc_uint64_set_low , ARGS_REQ (1 ));
640
+ mrb_define_method (mrb , sint64_class , "high" , cfunc_uint64_get_high , ARGS_NONE ());
641
+ mrb_define_method (mrb , sint64_class , "high=" , cfunc_uint64_set_high , ARGS_REQ (1 ));
642
+ mrb_define_method (mrb , sint64_class , "to_s" , cfunc_int64_to_s , ARGS_REQ (1 ));
643
+ DONE ;
571
644
}
0 commit comments