ruby-libjit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/jit.c ADDED
@@ -0,0 +1,1521 @@
1
+ #ifndef RUBY_DEFINES_GNU_SOURCE
2
+ #define _GNU_SOURCE
3
+ #endif
4
+
5
+ #include <ruby.h>
6
+
7
+ #include <stdio.h>
8
+
9
+ #include <jit/jit.h>
10
+ #include <jit/jit-dump.h>
11
+
12
+ #include "rubyjit.h"
13
+ #include "method_data.h"
14
+
15
+ #ifdef NEED_MINIMAL_NODE
16
+ #include "minimal_node.h"
17
+ #endif
18
+
19
+ static VALUE rb_mJIT;
20
+ static VALUE rb_cContext;
21
+ static VALUE rb_cFunction;
22
+ static VALUE rb_cType;
23
+ static VALUE rb_mABI;
24
+ static VALUE rb_cValue;
25
+ static VALUE rb_cLabel;
26
+ static VALUE rb_mCall;
27
+ static VALUE rb_cClosure;
28
+
29
+ jit_type_t jit_type_VALUE;
30
+ jit_type_t jit_type_ID;
31
+ jit_type_t jit_type_Function_Ptr;
32
+
33
+ static jit_type_t ruby_vararg_signature;
34
+
35
+ typedef void (*Void_Function_Ptr)();
36
+
37
+ struct Closure
38
+ {
39
+ VALUE function;
40
+ Void_Function_Ptr function_ptr;
41
+ };
42
+
43
+ #ifdef VALUE_IS_PTR
44
+ /* Rubinius */
45
+ typedef jit_ptr jit_VALUE;
46
+ #define jit_underlying_type_VALUE jit_type_void_ptr
47
+ #define SET_CONSTANT_VALUE(c, v) (c.un.ptr_value = v)
48
+
49
+ #elif SIZEOF_VALUE == 4
50
+ /* 32-bit */
51
+ typedef jit_uint jit_VALUE;
52
+ #define jit_underlying_type_VALUE jit_type_uint
53
+ #define SET_CONSTANT_VALUE(c, v) (c.un.uint_value = v)
54
+
55
+ #elif SIZEOF_VALUE == 8
56
+ /* 64-bit */
57
+ typedef jit_ulong jit_VALUE;
58
+ #define jit_underlying_type_VALUE jit_type_ulong
59
+ #define SET_CONSTANT_VALUE(c, v) (c.un.ulong_value = v)
60
+
61
+ #else
62
+ #error "Unsupported size for VALUE"
63
+ #endif
64
+
65
+ #if SIZEOF_ID == 4
66
+ /* 32-bit */
67
+ typedef jit_uint jit_ID;
68
+ #define jit_underlying_type_ID jit_type_uint
69
+ #define SET_CONSTANT_ID(c, v) (c.un.uint_value = v)
70
+ #elif SIZEOF_ID == 8
71
+ /* 64-bit */
72
+ typedef jit_ulong jit_ID;
73
+ #define jit_underlying_type_ID jit_type_ulong
74
+ #define SET_CONSTANT_ID(c, v) (c.un.ulong_value = v)
75
+ #else
76
+ #error "Unsupported size for ID"
77
+ #endif
78
+
79
+ typedef jit_ptr jit_Function_Ptr;
80
+ #define jit_underlying_type_void_ptr jit_type_void_ptr
81
+ #define SET_FUNCTION_POINTER_VALUE(c, v) (c.un.ptr_value = v)
82
+
83
+ #ifdef HAVE_RB_ERRINFO
84
+ #define ruby_errinfo rb_errinfo()
85
+ #endif
86
+
87
+ /* ---------------------------------------------------------------------------
88
+ * Utility functions
89
+ * ---------------------------------------------------------------------------
90
+ */
91
+
92
+ static void check_type(char const * param_name, VALUE expected_klass, VALUE val)
93
+ {
94
+ if(!rb_obj_is_kind_of(val, expected_klass))
95
+ {
96
+ rb_raise(
97
+ rb_eTypeError,
98
+ "Wrong type for %s; expected %s but got %s",
99
+ param_name,
100
+ rb_class2name(expected_klass),
101
+ rb_class2name(CLASS_OF(val)));
102
+ }
103
+ }
104
+
105
+ void raise_memory_error_if_zero(void * v)
106
+ {
107
+ if(!v)
108
+ {
109
+ rb_raise(rb_eNoMemError, "Out of memory");
110
+ }
111
+ }
112
+
113
+ /* ---------------------------------------------------------------------------
114
+ * Context
115
+ * ---------------------------------------------------------------------------
116
+ */
117
+
118
+ static void context_mark(jit_context_t context)
119
+ {
120
+ VALUE functions = (VALUE)jit_context_get_meta(context, RJT_FUNCTIONS);
121
+ rb_gc_mark(functions);
122
+ }
123
+
124
+ /*
125
+ * call-seq:
126
+ * context = Context.new
127
+ *
128
+ * Create a new context.
129
+ */
130
+ static VALUE context_s_new(VALUE klass)
131
+ {
132
+ jit_context_t context = jit_context_create();
133
+ jit_context_set_meta(context, RJT_FUNCTIONS, (void*)rb_ary_new(), 0);
134
+ return Data_Wrap_Struct(rb_cContext, context_mark, jit_context_destroy, context);
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * context.build { ... }
140
+ *
141
+ * Acquire a lock on the context so it can be used to build a function.
142
+ */
143
+ static VALUE context_build(VALUE self)
144
+ {
145
+ jit_context_t context;
146
+ Data_Get_Struct(self, struct _jit_context, context);
147
+ jit_context_build_start(context);
148
+ #ifdef HAVE_RB_ENSURE
149
+ return rb_ensure(
150
+ rb_yield,
151
+ self,
152
+ RUBY_METHOD_FUNC(jit_context_build_end),
153
+ (VALUE)context);
154
+ #else
155
+ /* Rubinius does not yet have rb_ensure */
156
+ rb_yield(self);
157
+ jit_context_build_end(context);
158
+ #endif
159
+ }
160
+
161
+ /*
162
+ * call-seq:
163
+ * Context.build { |context| ... }
164
+ *
165
+ * Create a context and acquire a lock on it, then yield the context to
166
+ * the block.
167
+ */
168
+ static VALUE context_s_build(VALUE klass)
169
+ {
170
+ return context_build(context_s_new(klass));
171
+ }
172
+
173
+ /* ---------------------------------------------------------------------------
174
+ * Closure
175
+ * ---------------------------------------------------------------------------
176
+ */
177
+
178
+ static void mark_closure(struct Closure * closure)
179
+ {
180
+ rb_gc_mark(closure->function);
181
+ }
182
+
183
+ VALUE closure_to_int(VALUE self)
184
+ {
185
+ struct Closure * closure;
186
+ Data_Get_Struct(self, struct Closure, closure);
187
+ VALUE v = ULONG2NUM((unsigned long)closure->function_ptr);
188
+ return v;
189
+ }
190
+
191
+ VALUE closure_to_s(VALUE self)
192
+ {
193
+ struct Closure * closure;
194
+ VALUE args[4];
195
+ Data_Get_Struct(self, struct Closure, closure);
196
+ args[0] = rb_str_new2("#<JIT::Closure:0x%x function=%s function_ptr=0x%x>");
197
+ args[1] = ULONG2NUM((unsigned long)self);
198
+ args[2] = rb_any_to_s(closure->function);
199
+ args[3] = ULONG2NUM((unsigned long)closure->function_ptr);
200
+ return rb_f_sprintf(sizeof(args)/sizeof(args[0]), args);
201
+ }
202
+
203
+ VALUE closure_inspect(VALUE self)
204
+ {
205
+ return closure_to_s(self);
206
+ }
207
+
208
+ /* ---------------------------------------------------------------------------
209
+ * Function
210
+ * ---------------------------------------------------------------------------
211
+ */
212
+
213
+ static void mark_function(jit_function_t function)
214
+ {
215
+ rb_gc_mark((VALUE)jit_function_get_meta(function, RJT_VALUE_OBJECTS));
216
+ rb_gc_mark((VALUE)jit_function_get_meta(function, RJT_CONTEXT));
217
+ }
218
+
219
+ static VALUE create_function(int argc, VALUE * argv, VALUE klass)
220
+ {
221
+ VALUE context_v;
222
+ VALUE signature_v;
223
+ VALUE parent_function_v;
224
+
225
+ jit_function_t function;
226
+ jit_function_t parent_function;
227
+ jit_context_t context;
228
+ jit_type_t signature;
229
+ jit_type_t untagged_signature;
230
+
231
+ VALUE function_v;
232
+ VALUE functions;
233
+
234
+ int signature_tag;
235
+
236
+ rb_scan_args(argc, argv, "21", &context_v, &signature_v, &parent_function_v);
237
+
238
+ Data_Get_Struct(context_v, struct _jit_context, context);
239
+ Data_Get_Struct(signature_v, struct _jit_type, signature);
240
+
241
+ signature_tag = jit_type_get_kind(signature);
242
+
243
+ /* If this signature was tagged, get the untagged type */
244
+ if((untagged_signature = jit_type_get_tagged_type(signature)))
245
+ {
246
+ signature = untagged_signature;
247
+ }
248
+
249
+ if(RTEST(parent_function_v))
250
+ {
251
+ /* If this function has a parent, then it is a nested function */
252
+ Data_Get_Struct(parent_function_v, struct _jit_function, parent_function);
253
+ function = jit_function_create_nested(context, signature, parent_function);
254
+ }
255
+ else
256
+ {
257
+ /* Otherwise, it's a standalone function */
258
+ function = jit_function_create(context, signature);
259
+ }
260
+
261
+ /* Make sure the function is around as long as the context is */
262
+ if(!jit_function_set_meta(function, RJT_VALUE_OBJECTS, (void *)rb_ary_new(), 0, 0))
263
+ {
264
+ rb_raise(rb_eNoMemError, "Out of memory");
265
+ }
266
+
267
+ /* Remember the signature's tag for later */
268
+ if(!jit_function_set_meta(function, RJT_TAG_FOR_SIGNATURE, (void *)signature_tag, 0, 0))
269
+ {
270
+ rb_raise(rb_eNoMemError, "Out of memory");
271
+ }
272
+
273
+ /* And remember the function's context for later */
274
+ if(!jit_function_set_meta(function, RJT_CONTEXT, (void *)context_v, 0, 0))
275
+ {
276
+ rb_raise(rb_eNoMemError, "Out of memory");
277
+ }
278
+
279
+ function_v = Data_Wrap_Struct(rb_cFunction, mark_function, 0, function);
280
+
281
+ /* Add this function to the context's list of functions */
282
+ functions = (VALUE)jit_context_get_meta(context, RJT_FUNCTIONS);
283
+ rb_ary_push(functions, function_v);
284
+
285
+ return function_v;
286
+ }
287
+
288
+ /*
289
+ * call-seq:
290
+ * function.compile()
291
+ *
292
+ * Begin compiling a function.
293
+ */
294
+ static VALUE function_compile(VALUE self)
295
+ {
296
+ jit_function_t function;
297
+ Data_Get_Struct(self, struct _jit_function, function);
298
+ if(!jit_function_compile(function))
299
+ {
300
+ rb_raise(rb_eRuntimeError, "Unable to compile function");
301
+ }
302
+ return self;
303
+ }
304
+
305
+ /*
306
+ * call-seq:
307
+ * function = Function.new(context, signature, [parent])
308
+ *
309
+ * Create a new function.
310
+ */
311
+ static VALUE function_s_new(int argc, VALUE * argv, VALUE klass)
312
+ {
313
+ if(rb_block_given_p())
314
+ {
315
+ rb_raise(rb_eArgError, "Function.new does not take a block");
316
+ }
317
+
318
+ return create_function(argc, argv, klass);
319
+ }
320
+
321
+ static VALUE function_abandon_if_exception(VALUE function_v)
322
+ {
323
+ if(ruby_errinfo)
324
+ {
325
+ jit_function_t function;
326
+ Data_Get_Struct(function_v, struct _jit_function, function);
327
+ jit_function_abandon(function);
328
+ }
329
+ return Qnil;
330
+ }
331
+
332
+ /*
333
+ * call-seq:
334
+ * function = Function.new(context, signature, [parent]) { |function| ... }
335
+ *
336
+ * Create a new function, begin compiling it, and pass the function to
337
+ * the block.
338
+ */
339
+ static VALUE function_s_compile(int argc, VALUE * argv, VALUE klass)
340
+ {
341
+ VALUE function = create_function(argc, argv, klass);
342
+ rb_yield(function);
343
+ function_compile(function);
344
+ #ifdef HAVE_RB_ENSURE
345
+ rb_ensure(
346
+ function_compile,
347
+ function,
348
+ function_abandon_if_exception,
349
+ function);
350
+ #else
351
+ /* Rubinius does not yet have rb_ensure */
352
+ function_compile(function);
353
+ function_abandon_if_exception(function);
354
+ #endif
355
+ return function;
356
+ }
357
+
358
+ /*
359
+ * Get the value that corresponds to a specified function parameter.
360
+ *
361
+ * call-seq:
362
+ * value = function.get_param(index)
363
+ */
364
+ static VALUE function_get_param(VALUE self, VALUE idx)
365
+ {
366
+ jit_function_t function;
367
+ jit_value_t value;
368
+ Data_Get_Struct(self, struct _jit_function, function);
369
+ value = jit_value_get_param(function, NUM2INT(idx));
370
+ raise_memory_error_if_zero(value);
371
+ return Data_Wrap_Struct(rb_cValue, 0, 0, value);
372
+ }
373
+
374
+ #include "insns.inc"
375
+
376
+ static VALUE function_value_klass(VALUE self, VALUE type_v, VALUE klass)
377
+ {
378
+ jit_function_t function;
379
+ jit_type_t type;
380
+ jit_value_t value;
381
+
382
+ Data_Get_Struct(self, struct _jit_function, function);
383
+
384
+ check_type("type", rb_cType, type_v);
385
+ Data_Get_Struct(type_v, struct _jit_type, type);
386
+
387
+ /* TODO: When we wrap a value, we should inject a reference to the
388
+ * function in the object, so the function stays around as long as the
389
+ * value does */
390
+ value = jit_value_create(function, type);
391
+ return Data_Wrap_Struct(klass, 0, 0, value);
392
+ }
393
+
394
+ static VALUE coerce_to_jit(VALUE function, VALUE type_v, VALUE value_v);
395
+
396
+ /*
397
+ * call-seq:
398
+ * value = function.value(type)
399
+ * value = function.value(type, initial_value)
400
+ *
401
+ * Create a value (placeholder/variable) with the given type.
402
+ */
403
+ static VALUE function_value(int argc, VALUE * argv, VALUE self)
404
+ {
405
+ VALUE type_v = Qnil;
406
+ VALUE initial_value_v = Qnil;
407
+
408
+ VALUE new_value = Qnil;
409
+
410
+ rb_scan_args(argc, argv, "11", &type_v, &initial_value_v);
411
+
412
+ new_value = function_value_klass(self, type_v, rb_cValue);
413
+
414
+ if(argc > 1)
415
+ {
416
+ function_insn_store(
417
+ self,
418
+ new_value,
419
+ coerce_to_jit(self, type_v, initial_value_v));
420
+ }
421
+
422
+ return new_value;
423
+ }
424
+
425
+ static jit_value_t create_const(jit_function_t function, jit_type_t type, VALUE constant)
426
+ {
427
+ jit_constant_t c;
428
+ int kind = jit_type_get_kind(type);
429
+
430
+ switch(kind)
431
+ {
432
+ case JIT_TYPE_INT:
433
+ {
434
+ c.type = type;
435
+ c.un.int_value = NUM2INT(constant);
436
+ break;
437
+ }
438
+
439
+ case JIT_TYPE_UINT:
440
+ {
441
+ c.type = type;
442
+ c.un.int_value = NUM2UINT(constant);
443
+ break;
444
+ }
445
+
446
+ case JIT_TYPE_FLOAT32:
447
+ {
448
+ c.type = type;
449
+ c.un.float32_value = NUM2DBL(constant);
450
+ break;
451
+ }
452
+
453
+ case JIT_TYPE_FLOAT64:
454
+ {
455
+ c.type = type;
456
+ c.un.float64_value = NUM2DBL(constant);
457
+ break;
458
+ }
459
+
460
+ case JIT_TYPE_PTR:
461
+ {
462
+ c.type = type;
463
+ c.un.ptr_value = (void *)NUM2ULONG(constant);
464
+ break;
465
+ }
466
+
467
+ case JIT_TYPE_FIRST_TAGGED + RJT_OBJECT:
468
+ {
469
+ VALUE value_objects = (VALUE)jit_function_get_meta(function, RJT_VALUE_OBJECTS);
470
+
471
+ c.type = type;
472
+ SET_CONSTANT_VALUE(c, constant);
473
+
474
+ /* Make sure the object gets marked as long as the function is
475
+ * around */
476
+ rb_ary_push(value_objects, constant);
477
+ break;
478
+ }
479
+
480
+ case JIT_TYPE_FIRST_TAGGED + RJT_ID:
481
+ {
482
+ c.type = type;
483
+ SET_CONSTANT_ID(c, SYM2ID(constant));
484
+ break;
485
+ }
486
+
487
+ case JIT_TYPE_FIRST_TAGGED + RJT_FUNCTION_PTR:
488
+ {
489
+ c.type = type;
490
+ SET_FUNCTION_POINTER_VALUE(
491
+ c,
492
+ (Void_Function_Ptr)NUM2ULONG(rb_to_int(constant)));
493
+ break;
494
+ }
495
+
496
+ default:
497
+ rb_raise(rb_eTypeError, "Unsupported type");
498
+ }
499
+
500
+ return jit_value_create_constant(function, &c);
501
+ }
502
+
503
+ /*
504
+ * call-seq:
505
+ * value = function.const(type, constant_value)
506
+ *
507
+ * Create a constant value with the given type.
508
+ */
509
+ static VALUE function_const(VALUE self, VALUE type_v, VALUE constant)
510
+ {
511
+ jit_function_t function;
512
+ jit_type_t type;
513
+ jit_value_t value;
514
+
515
+ Data_Get_Struct(self, struct _jit_function, function);
516
+
517
+ check_type("type", rb_cType, type_v);
518
+ Data_Get_Struct(type_v, struct _jit_type, type);
519
+
520
+ value = create_const(function, type, constant);
521
+ return Data_Wrap_Struct(rb_cValue, 0, 0, value);
522
+ }
523
+
524
+ static VALUE coerce_to_jit(VALUE function, VALUE type_v, VALUE value_v)
525
+ {
526
+ if(rb_obj_is_kind_of(value_v, rb_cValue))
527
+ {
528
+ return value_v;
529
+ }
530
+ else
531
+ {
532
+ return function_const(function, type_v, value_v);
533
+ }
534
+ }
535
+
536
+ static void convert_call_args(jit_function_t function, jit_value_t * args, VALUE args_v, jit_type_t signature)
537
+ {
538
+ int j;
539
+
540
+ for(j = 0; j < RARRAY(args_v)->len; ++j)
541
+ {
542
+ VALUE value = RARRAY(args_v)->ptr[j];
543
+ jit_value_t arg;
544
+
545
+ jit_type_t type = jit_type_get_param(signature, j);
546
+ if(!type)
547
+ {
548
+ rb_raise(rb_eArgError, "Type missing for param %d", j);
549
+ }
550
+
551
+ if(rb_obj_is_kind_of(value, rb_cValue))
552
+ {
553
+ Data_Get_Struct(value, struct _jit_value, arg);
554
+ if(!arg)
555
+ {
556
+ rb_raise(rb_eArgError, "Argument %d is invalid", j);
557
+ }
558
+ args[j] = arg;
559
+ }
560
+ else
561
+ {
562
+ args[j] = create_const(function, type, value);
563
+ }
564
+ }
565
+ }
566
+
567
+ /*
568
+ * call-seq:
569
+ * value = function.call(name, called_function, flags, [arg1 [, ... ]])
570
+ *
571
+ * Generate an instruction to call the specified function.
572
+ */
573
+ static VALUE function_insn_call(int argc, VALUE * argv, VALUE self)
574
+ {
575
+ jit_function_t function;
576
+
577
+ VALUE name_v;
578
+ VALUE called_function_v;
579
+ VALUE args_v;
580
+ VALUE flags_v = Qnil;
581
+
582
+ char const * name;
583
+ jit_function_t called_function;
584
+ jit_type_t signature;
585
+ jit_value_t * args;
586
+ jit_value_t retval;
587
+ int flags;
588
+ size_t num_args;
589
+
590
+ rb_scan_args(argc, argv, "3*", &name_v, &called_function_v, &flags_v, &args_v);
591
+
592
+ Data_Get_Struct(self, struct _jit_function, function);
593
+
594
+ name = STR2CSTR(name_v);
595
+
596
+ check_type("called function", rb_cFunction, called_function_v);
597
+ Data_Get_Struct(called_function_v, struct _jit_function, called_function);
598
+
599
+ num_args = RARRAY(args_v)->len;
600
+ args = ALLOCA_N(jit_value_t, num_args);
601
+
602
+ signature = jit_function_get_signature(function);
603
+ convert_call_args(function, args, args_v, signature);
604
+
605
+ flags = NUM2INT(flags_v);
606
+
607
+ retval = jit_insn_call(
608
+ function, name, called_function, 0, args, num_args, flags);
609
+ return Data_Wrap_Struct(rb_cValue, 0, 0, retval);
610
+ }
611
+
612
+ /*
613
+ * call-seq:
614
+ * value = function.call(name, flags, [arg1 [, ... ]])
615
+ *
616
+ * Generate an instruction to call a native function.
617
+ */
618
+ static VALUE function_insn_call_native(int argc, VALUE * argv, VALUE self)
619
+ {
620
+ jit_function_t function;
621
+
622
+ VALUE name_v;
623
+ VALUE args_v;
624
+ VALUE function_ptr_v;
625
+ VALUE signature_v;
626
+ VALUE flags_v;
627
+
628
+ char const * name;
629
+ jit_value_t * args;
630
+ jit_value_t retval;
631
+ void * function_ptr;
632
+ jit_type_t signature;
633
+ int flags;
634
+ size_t num_args;
635
+
636
+ rb_scan_args(argc, argv, "4*", &name_v, &function_ptr_v, &signature_v, &flags_v, &args_v);
637
+
638
+ Data_Get_Struct(self, struct _jit_function, function);
639
+
640
+ if(SYMBOL_P(name_v))
641
+ {
642
+ name = rb_id2name(SYM2ID(name_v));
643
+ }
644
+ else
645
+ {
646
+ name = StringValuePtr(name_v);
647
+ }
648
+
649
+ function_ptr = (void *)NUM2ULONG(function_ptr_v);
650
+
651
+ Data_Get_Struct(signature_v, struct _jit_type, signature);
652
+
653
+ num_args = RARRAY(args_v)->len;
654
+ args = ALLOCA_N(jit_value_t, num_args);
655
+
656
+ if(num_args != jit_type_num_params(signature))
657
+ {
658
+ rb_raise(
659
+ rb_eArgError,
660
+ "Wrong number of arguments passed for %s (expecting %d but got %d)",
661
+ name,
662
+ jit_type_num_params(signature),
663
+ num_args);
664
+ }
665
+
666
+ convert_call_args(function, args, args_v, signature);
667
+
668
+ flags = NUM2INT(flags_v);
669
+
670
+ retval = jit_insn_call_native(
671
+ function, name, function_ptr, signature, args, num_args, flags);
672
+ return Data_Wrap_Struct(rb_cValue, 0, 0, retval);
673
+ }
674
+
675
+ /*
676
+ * call-seq:
677
+ * function.insn_return()
678
+ * function.insn_return(value)
679
+ *
680
+ * Emit an instruction to return from the function. If value is
681
+ * specified, return the given value, otherwise return void.
682
+ */
683
+ static VALUE function_insn_return(int argc, VALUE * argv, VALUE self)
684
+ {
685
+ jit_function_t function;
686
+ jit_value_t value = 0;
687
+ VALUE value_v = Qnil;
688
+
689
+ rb_scan_args(argc, argv, "01", &value_v);
690
+
691
+ if(value_v != Qnil)
692
+ {
693
+ Data_Get_Struct(value_v, struct _jit_value, value);
694
+ }
695
+
696
+ Data_Get_Struct(self, struct _jit_function, function);
697
+ jit_insn_return(function, value);
698
+
699
+ return Qnil;
700
+ }
701
+
702
+ /*
703
+ * call-seq:
704
+ * function.apply(arg1 [, arg2 [, ... ]])
705
+ *
706
+ * Call a compiled function. Each argument passed in will be converted
707
+ * to the type specified by the function's signature.
708
+ *
709
+ * If the function's signature is Type::RUBY_VARARG_SIGNATURE, then the
710
+ * arguments will be passed in with the first parameter the count of the
711
+ * number of arguments, the second parameter a pointer to an array
712
+ * containing the second through the last argument, and the third
713
+ * parameter the explicit self (that is, the first argument passed to
714
+ * apply).
715
+ */
716
+ static VALUE function_apply(int argc, VALUE * argv, VALUE self)
717
+ {
718
+ jit_function_t function;
719
+ jit_type_t signature;
720
+ int j, n;
721
+ void * * args;
722
+ char * arg_data;
723
+ int signature_tag;
724
+
725
+ Data_Get_Struct(self, struct _jit_function, function);
726
+ signature = jit_function_get_signature(function);
727
+ n = jit_type_num_params(signature);
728
+
729
+ /* void pointers to each of the arguments */
730
+ args = ALLOCA_N(void *, n);
731
+
732
+ /* the actual data */
733
+ /* TODO: we need to allocate the proper size (but 8 bytes per arg
734
+ * should be sufficient for now) */
735
+ arg_data = (char *)ALLOCA_N(char, 8 * n);
736
+
737
+ signature_tag = (int)jit_function_get_meta(function, RJT_TAG_FOR_SIGNATURE);
738
+ if(signature_tag == JIT_TYPE_FIRST_TAGGED + RJT_RUBY_VARARG_SIGNATURE)
739
+ {
740
+ jit_VALUE result;
741
+ int f_argc = argc - 1;
742
+ VALUE f_self = *(VALUE *)argv;
743
+ VALUE * f_argv = ((VALUE *)argv) + 1;
744
+ void * f_args[3];
745
+ f_args[0] = &f_argc;
746
+ f_args[1] = &f_argv;
747
+ f_args[2] = &f_self;
748
+ jit_function_apply(function, f_args, &result);
749
+ return result;
750
+ }
751
+
752
+ if(argc != n)
753
+ {
754
+ rb_raise(
755
+ rb_eArgError,
756
+ "Wrong number of arguments (expected %d but got %d)",
757
+ n,
758
+ argc);
759
+ }
760
+
761
+ for(j = 0; j < n; ++j)
762
+ {
763
+ jit_type_t arg_type = jit_type_get_param(signature, j);
764
+ int kind = jit_type_get_kind(arg_type);
765
+ switch(kind)
766
+ {
767
+ case JIT_TYPE_INT:
768
+ {
769
+ *(int *)arg_data = NUM2INT(argv[j]);
770
+ args[j] = (int *)arg_data;
771
+ arg_data += sizeof(int);
772
+ break;
773
+ }
774
+
775
+ case JIT_TYPE_UINT:
776
+ {
777
+ *(int *)arg_data = NUM2UINT(argv[j]);
778
+ args[j] = (int *)arg_data;
779
+ arg_data += sizeof(int);
780
+ break;
781
+ }
782
+
783
+ case JIT_TYPE_FIRST_TAGGED + RJT_OBJECT:
784
+ {
785
+ *(VALUE *)arg_data = argv[j];
786
+ args[j] = (VALUE *)arg_data;
787
+ arg_data += sizeof(VALUE);
788
+ break;
789
+ }
790
+
791
+ case JIT_TYPE_FIRST_TAGGED + RJT_ID:
792
+ {
793
+ *(ID *)arg_data = SYM2ID(argv[j]);
794
+ args[j] = (ID *)arg_data;
795
+ arg_data += sizeof(ID);
796
+ break;
797
+ }
798
+
799
+ case JIT_TYPE_FIRST_TAGGED + RJT_FUNCTION_PTR:
800
+ {
801
+ *(Void_Function_Ptr *)arg_data =
802
+ (Void_Function_Ptr)NUM2ULONG(rb_to_int(argv[j]));
803
+ args[j] = (Void_Function_Ptr *)(arg_data);
804
+ arg_data += sizeof(Void_Function_Ptr);
805
+ break;
806
+ }
807
+
808
+ default:
809
+ rb_raise(rb_eTypeError, "Unsupported type %d", kind);
810
+ }
811
+ }
812
+
813
+ {
814
+ jit_type_t return_type = jit_type_get_return(signature);
815
+ int return_kind = jit_type_get_kind(return_type);
816
+ switch(return_kind)
817
+ {
818
+ case JIT_TYPE_INT:
819
+ {
820
+ jit_int result;
821
+ jit_function_apply(function, args, &result);
822
+ return INT2NUM(result);
823
+ }
824
+
825
+ case JIT_TYPE_FLOAT32:
826
+ {
827
+ jit_float32 result;
828
+ jit_function_apply(function, args, &result);
829
+ return rb_float_new(result);
830
+ }
831
+
832
+ case JIT_TYPE_FLOAT64:
833
+ {
834
+ jit_float64 result;
835
+ jit_function_apply(function, args, &result);
836
+ return rb_float_new(result);
837
+ }
838
+
839
+ case JIT_TYPE_FIRST_TAGGED + RJT_OBJECT:
840
+ {
841
+ jit_VALUE result;
842
+ jit_function_apply(function, args, &result);
843
+ return result;
844
+ }
845
+
846
+ case JIT_TYPE_FIRST_TAGGED + RJT_ID:
847
+ {
848
+ jit_ID result;
849
+ jit_function_apply(function, args, &result);
850
+ return ID2SYM(result);
851
+ }
852
+
853
+ default:
854
+ rb_raise(rb_eTypeError, "Unsupported return type %d", return_kind);
855
+ }
856
+ }
857
+ }
858
+
859
+ /*
860
+ * call-seq:
861
+ * level = function.optimization_level()
862
+ *
863
+ * Get the optimization level for a function.
864
+ */
865
+ static VALUE function_optimization_level(VALUE self)
866
+ {
867
+ jit_function_t function;
868
+ Data_Get_Struct(self, struct _jit_function, function);
869
+ return INT2NUM(jit_function_get_optimization_level(function));
870
+ }
871
+
872
+ /*
873
+ * call-seq:
874
+ * function.optimization_level = level
875
+ *
876
+ * Set the optimization level for a function.
877
+ */
878
+ static VALUE function_set_optimization_level(VALUE self, VALUE level)
879
+ {
880
+ jit_function_t function;
881
+ Data_Get_Struct(self, struct _jit_function, function);
882
+ jit_function_set_optimization_level(function, NUM2INT(level));
883
+ return level;
884
+ }
885
+
886
+ /*
887
+ * call-seq:
888
+ * level = function.max_optimization_level()
889
+ *
890
+ * Get the maximum optimization level (which should be the same for any
891
+ * function).
892
+ */
893
+ static VALUE function_max_optimization_level(VALUE klass)
894
+ {
895
+ return INT2NUM(jit_function_get_max_optimization_level());
896
+ }
897
+
898
+ /*
899
+ * call-seq:
900
+ * str = function.dump()
901
+ *
902
+ * Dump the instructions in a function to a string.
903
+ */
904
+ static VALUE function_dump(VALUE self)
905
+ {
906
+ #ifdef HAVE_FMEMOPEN
907
+ jit_function_t function;
908
+ char buf[16*1024]; /* TODO: big enough? */
909
+ FILE * fp = fmemopen(buf, sizeof(buf), "w");
910
+ Data_Get_Struct(self, struct _jit_function, function);
911
+ jit_dump_function(fp, function, 0);
912
+ fclose(fp);
913
+ return rb_str_new2(buf);
914
+ #else
915
+ rb_raise(rb_eNotImpError, "Not implemented: missing fmemopen");
916
+ #endif
917
+ }
918
+
919
+ /*
920
+ * call-seq:
921
+ * ptr = function.to_closure()
922
+ *
923
+ * Return a pointer to a closure for a function. This pointer can be
924
+ * passed into other functions as a function pointer.
925
+ */
926
+ static VALUE function_to_closure(VALUE self)
927
+ {
928
+ jit_function_t function;
929
+ struct Closure * closure;
930
+ VALUE closure_v = Data_Make_Struct(
931
+ rb_cClosure, struct Closure, mark_closure, free, closure);
932
+ Data_Get_Struct(self, struct _jit_function, function);
933
+ closure->function = self;
934
+ closure->function_ptr =
935
+ (Void_Function_Ptr)jit_function_to_closure(function);
936
+ return closure_v;
937
+ }
938
+
939
+ /*
940
+ * call-seq:
941
+ * context = function.context()
942
+ *
943
+ * Get a function's context.
944
+ */
945
+ static VALUE function_get_context(VALUE self)
946
+ {
947
+ jit_function_t function;
948
+ Data_Get_Struct(self, struct _jit_function, function);
949
+ return (VALUE)jit_function_get_meta(function, RJT_CONTEXT);
950
+ }
951
+
952
+ /*
953
+ * call-seq:
954
+ * is_compiled = function.compiled?
955
+ *
956
+ * Determine whether a function is compiled.
957
+ */
958
+ static VALUE function_is_compiled(VALUE self)
959
+ {
960
+ jit_function_t function;
961
+ Data_Get_Struct(self, struct _jit_function, function);
962
+ return jit_function_is_compiled(function) ? Qtrue : Qfalse;
963
+ }
964
+
965
+ /* ---------------------------------------------------------------------------
966
+ * Type
967
+ * ---------------------------------------------------------------------------
968
+ */
969
+
970
+ /* This function does not increment the reference count. It is assumed
971
+ * that the caller will increment the reference count and that the newly
972
+ * wrapped object will take ownership. */
973
+ static VALUE wrap_type_with_klass(jit_type_t type, VALUE klass)
974
+ {
975
+ return Data_Wrap_Struct(klass, 0, jit_type_free, type);
976
+ }
977
+
978
+ static VALUE wrap_type(jit_type_t type)
979
+ {
980
+ return wrap_type_with_klass(type, rb_cType);
981
+ }
982
+
983
+ /*
984
+ * call-seq:
985
+ * type = Type.create_signature(abi, return_type, array_of_param_types)
986
+ *
987
+ * Create a new signature.
988
+ */
989
+ static VALUE type_s_create_signature(
990
+ VALUE klass, VALUE abi_v, VALUE return_type_v, VALUE params_v)
991
+ {
992
+ jit_abi_t abi = NUM2INT(abi_v);
993
+ jit_type_t return_type;
994
+ jit_type_t * params;
995
+ jit_type_t signature;
996
+ int j;
997
+ int len;
998
+
999
+ check_type("return type", rb_cType, return_type_v);
1000
+
1001
+ Data_Get_Struct(return_type_v, struct _jit_type, return_type);
1002
+
1003
+ Check_Type(params_v, T_ARRAY);
1004
+ len = RARRAY(params_v)->len;
1005
+ params = ALLOCA_N(jit_type_t, len);
1006
+ for(j = 0; j < len; ++j)
1007
+ {
1008
+ VALUE param = RARRAY(params_v)->ptr[j];
1009
+ check_type("param", rb_cType, param);
1010
+ Data_Get_Struct(param, struct _jit_type, params[j]);
1011
+ }
1012
+
1013
+ signature = jit_type_create_signature(abi, return_type, params, len, 1);
1014
+ return wrap_type(signature);
1015
+ }
1016
+
1017
+ /*
1018
+ * call-seq:
1019
+ * type = Type.create_struct(array_of_field_types)
1020
+ *
1021
+ * Create a new struct type.
1022
+ */
1023
+ static VALUE type_s_create_struct(
1024
+ VALUE klass, VALUE fields_v)
1025
+ {
1026
+ jit_type_t * fields;
1027
+ jit_type_t struct_type;
1028
+ int len;
1029
+ int j;
1030
+
1031
+ Check_Type(fields_v, T_ARRAY);
1032
+ len = RARRAY(fields_v)->len;
1033
+ fields = ALLOCA_N(jit_type_t, len);
1034
+ for(j = 0; j < len; ++j)
1035
+ {
1036
+ VALUE field = RARRAY(fields_v)->ptr[j];
1037
+ check_type("field", rb_cType, field);
1038
+ Data_Get_Struct(field, struct _jit_type, fields[j]);
1039
+ }
1040
+
1041
+ struct_type = jit_type_create_struct(fields, RARRAY(fields_v)->len, 1);
1042
+ return wrap_type_with_klass(struct_type, klass);
1043
+ }
1044
+
1045
+ /*
1046
+ * call-seq:
1047
+ * type = Type.create_pointer(pointed_to_type)
1048
+ *
1049
+ * Create a new pointer type, pointing to the given type.
1050
+ */
1051
+ static VALUE type_s_create_pointer(
1052
+ VALUE klass, VALUE type_v)
1053
+ {
1054
+ jit_type_t type;
1055
+ jit_type_t pointer_type;
1056
+ Data_Get_Struct(type_v, struct _jit_type, type);
1057
+ pointer_type = jit_type_create_pointer(type, 1);
1058
+ return wrap_type_with_klass(pointer_type, klass);
1059
+ }
1060
+
1061
+ /*
1062
+ * call-seq:
1063
+ * offset = struct_type.get_offset(index)
1064
+ *
1065
+ * Get the offset of the nth field in a struct.
1066
+ */
1067
+ static VALUE type_get_offset(VALUE self, VALUE field_index_v)
1068
+ {
1069
+ int field_index = NUM2INT(field_index_v);
1070
+ jit_type_t type;
1071
+ Data_Get_Struct(self, struct _jit_type, type);
1072
+ return INT2NUM(jit_type_get_offset(type, field_index));
1073
+ }
1074
+
1075
+ /*
1076
+ * call-seq:
1077
+ * offset = struct_type.set_offset(index, offset)
1078
+ *
1079
+ * Set the offset of the nth field in a struct.
1080
+ */
1081
+ static VALUE type_set_offset(VALUE self, VALUE field_index_v, VALUE offset_v)
1082
+ {
1083
+ int field_index = NUM2INT(field_index_v);
1084
+ int offset = NUM2UINT(offset_v);
1085
+ jit_type_t type;
1086
+ Data_Get_Struct(self, struct _jit_type, type);
1087
+ jit_type_set_offset(type, field_index, offset);
1088
+ return Qnil;
1089
+ }
1090
+
1091
+ /*
1092
+ * call-seq:
1093
+ * offset = struct_type.size
1094
+ *
1095
+ * Get the size of a struct or union type.
1096
+ */
1097
+ static VALUE type_size(VALUE self)
1098
+ {
1099
+ jit_type_t type;
1100
+ Data_Get_Struct(self, struct _jit_type, type);
1101
+ return INT2NUM(jit_type_get_size(type));
1102
+ }
1103
+
1104
+ /* ---------------------------------------------------------------------------
1105
+ * Value
1106
+ * ---------------------------------------------------------------------------
1107
+ */
1108
+
1109
+ static VALUE value_s_new_value(VALUE klass, VALUE function, VALUE type)
1110
+ {
1111
+ return function_value_klass(function, type, klass);
1112
+ }
1113
+
1114
+ /*
1115
+ * call-seq:
1116
+ * str = value.to_s
1117
+ *
1118
+ * Return a string representation of the value.
1119
+ */
1120
+ static VALUE value_to_s(VALUE self)
1121
+ {
1122
+ #ifdef HAVE_FMEMOPEN
1123
+ char buf[1024];
1124
+ FILE * fp = fmemopen(buf, sizeof(buf), "w");
1125
+ jit_value_t value;
1126
+ jit_function_t function;
1127
+ Data_Get_Struct(self, struct _jit_value, value);
1128
+ function = jit_value_get_function(value);
1129
+ jit_dump_value(fp, function, value, 0);
1130
+ fclose(fp);
1131
+ return rb_str_new2(buf);
1132
+ #else
1133
+ rb_raise(rb_eNotImpError, "Not implemented: missing fmemopen");
1134
+ #endif
1135
+ }
1136
+
1137
+ /*
1138
+ * call-seq:
1139
+ * str = value.inspect
1140
+ *
1141
+ * Return a string representation of a value with additional
1142
+ * information about the value.
1143
+ */
1144
+ static VALUE value_inspect(VALUE self)
1145
+ {
1146
+ jit_value_t value;
1147
+ jit_type_t type;
1148
+ char const * cname = rb_obj_classname(self);
1149
+ VALUE args[6];
1150
+ Data_Get_Struct(self, struct _jit_value, value);
1151
+ type = jit_value_get_type(value);
1152
+ args[0] = rb_str_new2("#<%s:0x%x %s ptr=0x%x type=0x%x>");
1153
+ args[1] = rb_str_new2(cname);
1154
+ args[2] = ULONG2NUM((unsigned long)self);
1155
+ args[3] = value_to_s(self);
1156
+ args[4] = ULONG2NUM((unsigned long)value);
1157
+ args[5] = ULONG2NUM((unsigned long)type);
1158
+ return rb_f_sprintf(sizeof(args)/sizeof(args[0]), args);
1159
+ }
1160
+
1161
+ /*
1162
+ * call-seq:
1163
+ * is_valid = value.valid?
1164
+ *
1165
+ * Determine if a value is valid (non-zero).
1166
+ */
1167
+ static VALUE value_is_valid(VALUE self)
1168
+ {
1169
+ jit_value_t value;
1170
+ Data_Get_Struct(self, struct _jit_value, value);
1171
+ return (value != 0) ? Qtrue : Qfalse;
1172
+ }
1173
+
1174
+ /*
1175
+ * call-seq:
1176
+ * is_temporary = value.temporary?
1177
+ *
1178
+ * Determine if a value represents a temporary.
1179
+ */
1180
+ static VALUE value_is_temporary(VALUE self)
1181
+ {
1182
+ jit_value_t value;
1183
+ Data_Get_Struct(self, struct _jit_value, value);
1184
+ return jit_value_is_temporary(value) ? Qtrue : Qfalse;
1185
+ }
1186
+
1187
+ /*
1188
+ * call-seq:
1189
+ * is_local = value.local?
1190
+ *
1191
+ * Determine if a value represents a local.
1192
+ */
1193
+ static VALUE value_is_local(VALUE self)
1194
+ {
1195
+ jit_value_t value;
1196
+ Data_Get_Struct(self, struct _jit_value, value);
1197
+ return jit_value_is_local(value) ? Qtrue : Qfalse;
1198
+ }
1199
+
1200
+ /*
1201
+ * call-seq:
1202
+ * is_local = value.constant?
1203
+ *
1204
+ * Determine if a value represents a constant.
1205
+ */
1206
+ static VALUE value_is_constant(VALUE self)
1207
+ {
1208
+ jit_value_t value;
1209
+ Data_Get_Struct(self, struct _jit_value, value);
1210
+ return jit_value_is_constant(value) ? Qtrue : Qfalse;
1211
+ }
1212
+
1213
+ /*
1214
+ * call-seq:
1215
+ * is_volatile = value.volatile?
1216
+ *
1217
+ * Determine if a value is volatile (that is, the contents must be
1218
+ * reloaded from memory each time it is used).
1219
+ */
1220
+ static VALUE value_is_volatile(VALUE self)
1221
+ {
1222
+ jit_value_t value;
1223
+ Data_Get_Struct(self, struct _jit_value, value);
1224
+ return jit_value_is_volatile(value) ? Qtrue : Qfalse;
1225
+ }
1226
+
1227
+ /*
1228
+ * call-seq:
1229
+ * value.volatile = is_volatile
1230
+ *
1231
+ * Make a value volatile (that is, ensure that its contents are reloaded
1232
+ * from memory each time it is used).
1233
+ */
1234
+ static VALUE value_set_volatile(VALUE self)
1235
+ {
1236
+ jit_value_t value;
1237
+ Data_Get_Struct(self, struct _jit_value, value);
1238
+ jit_value_set_volatile(value);
1239
+ return Qnil;
1240
+ }
1241
+
1242
+ /*
1243
+ * call-seq:
1244
+ * is_addressable = value.addressable?
1245
+ *
1246
+ * Determine if a value is addressable.
1247
+ */
1248
+ static VALUE value_is_addressable(VALUE self)
1249
+ {
1250
+ jit_value_t value;
1251
+ Data_Get_Struct(self, struct _jit_value, value);
1252
+ return jit_value_is_addressable(value) ? Qtrue : Qfalse;
1253
+ }
1254
+
1255
+ /*
1256
+ * call-seq:
1257
+ * value.addressable = is_addressable
1258
+ *
1259
+ * Make a value addressable.
1260
+ */
1261
+ static VALUE value_set_addressable(VALUE self)
1262
+ {
1263
+ jit_value_t value;
1264
+ Data_Get_Struct(self, struct _jit_value, value);
1265
+ jit_value_set_addressable(value);
1266
+ return Qnil;
1267
+ }
1268
+
1269
+ /*
1270
+ * call-seq:
1271
+ * function = value.function()
1272
+ *
1273
+ * Get a value's function.
1274
+ */
1275
+ static VALUE value_function(VALUE self)
1276
+ {
1277
+ jit_value_t value;
1278
+ jit_function_t function;
1279
+ Data_Get_Struct(self, struct _jit_value, value);
1280
+ function = jit_value_get_function(value);
1281
+ return Data_Wrap_Struct(rb_cFunction, mark_function, 0, function);
1282
+ }
1283
+
1284
+ /*
1285
+ * call-seq:
1286
+ * function = value.type()
1287
+ *
1288
+ * Get a value's type.
1289
+ */
1290
+ static VALUE value_type(VALUE self)
1291
+ {
1292
+ jit_value_t value;
1293
+ jit_type_t type;
1294
+ Data_Get_Struct(self, struct _jit_value, value);
1295
+ type = jit_value_get_type(value);
1296
+ return wrap_type(type);
1297
+ }
1298
+
1299
+ /*
1300
+ * call-seq:
1301
+ * value1, value2 = value1.coerce(value2)
1302
+ *
1303
+ * If the given value is a JIT::Value, return an +[ self, value ]+,
1304
+ * otherwise coerce the value to the same type as self and return
1305
+ * +[ self, coerced_value ]+.
1306
+ */
1307
+ static VALUE value_coerce(VALUE self, VALUE value)
1308
+ {
1309
+ return rb_assoc_new(
1310
+ self,
1311
+ coerce_to_jit(
1312
+ value_function(self),
1313
+ value_type(self),
1314
+ value));
1315
+ }
1316
+
1317
+ /* ---------------------------------------------------------------------------
1318
+ * Label
1319
+ * ---------------------------------------------------------------------------
1320
+ */
1321
+
1322
+ /*
1323
+ * call-seq:
1324
+ * label = Label.new
1325
+ *
1326
+ * Create a new label.
1327
+ */
1328
+ static VALUE label_s_new(VALUE klass)
1329
+ {
1330
+ jit_label_t * label;
1331
+ VALUE labelval = Data_Make_Struct(rb_cLabel, jit_label_t, 0, xfree, label);
1332
+ *label = jit_label_undefined;
1333
+ return labelval;
1334
+ }
1335
+
1336
+ /* ---------------------------------------------------------------------------
1337
+ * Module
1338
+ * ---------------------------------------------------------------------------
1339
+ */
1340
+
1341
+ /*
1342
+ * call-seq:
1343
+ * module.define_jit_method(name, function)
1344
+ *
1345
+ * Use a Function to define an instance method on a module. The
1346
+ * function should have one of two signatures:
1347
+ *
1348
+ * * The first parameter to the function should be an OBJECT that
1349
+ * represents the self parameter and the rest of the parameters, or
1350
+ *
1351
+ * * The function's signature should be Type::RUBY_VARARG_SIGNATURE.
1352
+ */
1353
+ static VALUE module_define_jit_method(VALUE klass, VALUE name_v, VALUE function_v)
1354
+ {
1355
+ char const * name;
1356
+ jit_function_t function;
1357
+ jit_type_t signature;
1358
+ int signature_tag;
1359
+ int arity;
1360
+ VALUE closure_v;
1361
+ struct Closure * closure;
1362
+
1363
+ if(SYMBOL_P(name_v))
1364
+ {
1365
+ name = rb_id2name(SYM2ID(name_v));
1366
+ }
1367
+ else
1368
+ {
1369
+ name = STR2CSTR(name_v);
1370
+ }
1371
+
1372
+ Data_Get_Struct(function_v, struct _jit_function, function);
1373
+
1374
+ signature = jit_function_get_signature(function);
1375
+ signature_tag = (int)jit_function_get_meta(function, RJT_TAG_FOR_SIGNATURE);
1376
+ if(signature_tag == JIT_TYPE_FIRST_TAGGED + RJT_RUBY_VARARG_SIGNATURE)
1377
+ {
1378
+ arity = -1;
1379
+ }
1380
+ else
1381
+ {
1382
+ /* TODO: check the types to make sure they are OBJECT */
1383
+ arity = jit_type_num_params(signature) - 1;
1384
+ }
1385
+
1386
+ closure_v = function_to_closure(function_v);
1387
+ Data_Get_Struct(closure_v, struct Closure, closure);
1388
+ define_method_with_data(
1389
+ klass, rb_intern(name), RUBY_METHOD_FUNC(closure->function_ptr),
1390
+ arity, closure_v);
1391
+ return Qnil;
1392
+ }
1393
+
1394
+ /* ---------------------------------------------------------------------------
1395
+ * Init
1396
+ * ---------------------------------------------------------------------------
1397
+ */
1398
+
1399
+ void Init_jit()
1400
+ {
1401
+ jit_init();
1402
+
1403
+ rb_mJIT = rb_define_module("JIT");
1404
+
1405
+ rb_cContext = rb_define_class_under(rb_mJIT, "Context", rb_cObject);
1406
+ rb_define_singleton_method(rb_cContext, "new", context_s_new, 0);
1407
+ rb_define_method(rb_cContext, "build", context_build, 0);
1408
+ rb_define_singleton_method(rb_cContext, "build", context_s_build, 0);
1409
+
1410
+ rb_cClosure = rb_define_class_under(rb_mJIT, "Closure", rb_cObject);
1411
+ rb_define_method(rb_cClosure, "to_int", closure_to_int, 0);
1412
+ rb_define_method(rb_cClosure, "to_s", closure_to_s, 0);
1413
+ rb_define_method(rb_cClosure, "inspect", closure_inspect, 0);
1414
+
1415
+ rb_cFunction = rb_define_class_under(rb_mJIT, "Function", rb_cObject);
1416
+ rb_define_singleton_method(rb_cFunction, "new", function_s_new, -1);
1417
+ rb_define_method(rb_cFunction, "compile", function_compile, 0);
1418
+ rb_define_singleton_method(rb_cFunction, "compile", function_s_compile, -1);
1419
+ rb_define_method(rb_cFunction, "get_param", function_get_param, 1);
1420
+ init_insns();
1421
+ rb_define_method(rb_cFunction, "insn_call", function_insn_call, -1);
1422
+ rb_define_method(rb_cFunction, "insn_call_native", function_insn_call_native, -1);
1423
+ rb_define_method(rb_cFunction, "insn_return", function_insn_return, -1);
1424
+ rb_define_method(rb_cFunction, "apply", function_apply, -1);
1425
+ rb_define_alias(rb_cFunction, "call", "apply");
1426
+ rb_define_method(rb_cFunction, "value", function_value, -1);
1427
+ rb_define_method(rb_cFunction, "const", function_const, 2);
1428
+ rb_define_method(rb_cFunction, "optimization_level", function_optimization_level, 0);
1429
+ rb_define_method(rb_cFunction, "optimization_level=", function_set_optimization_level, 1);
1430
+ rb_define_singleton_method(rb_cFunction, "max_optimization_level", function_max_optimization_level, 0);
1431
+ rb_define_method(rb_cFunction, "dump", function_dump, 0);
1432
+ rb_define_method(rb_cFunction, "to_closure", function_to_closure, 0);
1433
+ rb_define_method(rb_cFunction, "context", function_get_context, 0);
1434
+ rb_define_method(rb_cFunction, "compiled?", function_is_compiled, 0);
1435
+
1436
+ rb_cType = rb_define_class_under(rb_mJIT, "Type", rb_cObject);
1437
+ rb_define_singleton_method(rb_cType, "create_signature", type_s_create_signature, 3);
1438
+ rb_define_singleton_method(rb_cType, "create_struct", type_s_create_struct, 1);
1439
+ rb_define_singleton_method(rb_cType, "create_pointer", type_s_create_pointer, 1);
1440
+ rb_define_method(rb_cType, "get_offset", type_get_offset, 1);
1441
+ rb_define_method(rb_cType, "set_offset", type_set_offset, 2);
1442
+ rb_define_method(rb_cType, "size", type_size, 0);
1443
+ rb_define_const(rb_cType, "VOID", wrap_type(jit_type_void));
1444
+ rb_define_const(rb_cType, "SBYTE", wrap_type(jit_type_sbyte));
1445
+ rb_define_const(rb_cType, "UBYTE", wrap_type(jit_type_ubyte));
1446
+ rb_define_const(rb_cType, "SHORT", wrap_type(jit_type_short));
1447
+ rb_define_const(rb_cType, "USHORT", wrap_type(jit_type_ushort));
1448
+ rb_define_const(rb_cType, "INT", wrap_type(jit_type_int));
1449
+ rb_define_const(rb_cType, "UINT", wrap_type(jit_type_uint));
1450
+ rb_define_const(rb_cType, "NINT", wrap_type(jit_type_nint));
1451
+ rb_define_const(rb_cType, "NUINT", wrap_type(jit_type_nuint));
1452
+ rb_define_const(rb_cType, "LONG", wrap_type(jit_type_long));
1453
+ rb_define_const(rb_cType, "ULONG", wrap_type(jit_type_ulong));
1454
+ rb_define_const(rb_cType, "FLOAT32", wrap_type(jit_type_float32));
1455
+ rb_define_const(rb_cType, "FLOAT64", wrap_type(jit_type_float64));
1456
+ rb_define_const(rb_cType, "NFLOAT", wrap_type(jit_type_nfloat));
1457
+ rb_define_const(rb_cType, "VOID_PTR", wrap_type(jit_type_void_ptr));
1458
+
1459
+ jit_type_VALUE = jit_type_create_tagged(jit_underlying_type_VALUE, RJT_OBJECT, 0, 0, 1);
1460
+ rb_define_const(rb_cType, "OBJECT", wrap_type(jit_type_VALUE));
1461
+
1462
+ jit_type_ID = jit_type_create_tagged(jit_underlying_type_ID, RJT_ID, 0, 0, 1);
1463
+ rb_define_const(rb_cType, "ID", wrap_type(jit_type_ID));
1464
+
1465
+ jit_type_Function_Ptr = jit_type_create_tagged(jit_underlying_type_ID, RJT_FUNCTION_PTR, 0, 0, 1);
1466
+ rb_define_const(rb_cType, "FUNCTION_PTR", wrap_type(jit_type_Function_Ptr));
1467
+
1468
+ {
1469
+ jit_type_t ruby_vararg_param_types[3];
1470
+ jit_type_t ruby_vararg_signature_untagged;
1471
+ ruby_vararg_param_types[0] = jit_type_int;
1472
+ ruby_vararg_param_types[1] = jit_type_void_ptr;
1473
+ ruby_vararg_param_types[2] = jit_type_VALUE;
1474
+ ruby_vararg_signature_untagged = jit_type_create_signature(
1475
+ jit_abi_cdecl,
1476
+ jit_type_VALUE,
1477
+ ruby_vararg_param_types,
1478
+ 3,
1479
+ 1);
1480
+ ruby_vararg_signature = jit_type_create_tagged(ruby_vararg_signature_untagged, RJT_RUBY_VARARG_SIGNATURE, 0, 0, 1);
1481
+ }
1482
+ rb_define_const(rb_cType, "RUBY_VARARG_SIGNATURE", wrap_type(ruby_vararg_signature));
1483
+
1484
+ rb_mABI = rb_define_module_under(rb_mJIT, "ABI");
1485
+ rb_define_const(rb_mABI, "CDECL", INT2NUM(jit_abi_cdecl));
1486
+ rb_define_const(rb_mABI, "VARARG", INT2NUM(jit_abi_vararg));
1487
+ rb_define_const(rb_mABI, "STDCALL", INT2NUM(jit_abi_stdcall));
1488
+ rb_define_const(rb_mABI, "FASTCALL", INT2NUM(jit_abi_fastcall));
1489
+
1490
+ rb_cValue = rb_define_class_under(rb_mJIT, "Value", rb_cObject);
1491
+ rb_define_singleton_method(rb_cValue, "new_value", value_s_new_value, 2);
1492
+ rb_define_method(rb_cValue, "to_s", value_to_s, 0);
1493
+ rb_define_method(rb_cValue, "inspect", value_inspect, 0);
1494
+ rb_define_method(rb_cValue, "valid?", value_is_valid, 0);
1495
+ rb_define_method(rb_cValue, "temporary?", value_is_temporary, 0);
1496
+ rb_define_method(rb_cValue, "local?", value_is_local, 0);
1497
+ rb_define_method(rb_cValue, "constant?", value_is_constant, 0);
1498
+ rb_define_method(rb_cValue, "volatile?", value_is_volatile, 0);
1499
+ rb_define_method(rb_cValue, "set_volatile", value_set_volatile, 0);
1500
+ rb_define_method(rb_cValue, "addressable?", value_is_addressable, 0);
1501
+ rb_define_method(rb_cValue, "addressable=", value_set_addressable, 0);
1502
+ rb_define_method(rb_cValue, "function", value_function, 0);
1503
+ rb_define_method(rb_cValue, "type", value_type, 0);
1504
+ rb_define_method(rb_cValue, "coerce", value_coerce, 1);
1505
+
1506
+ rb_cLabel = rb_define_class_under(rb_mJIT, "Label", rb_cObject);
1507
+ rb_define_singleton_method(rb_cLabel, "new", label_s_new, 0);
1508
+
1509
+ rb_mCall = rb_define_module_under(rb_mJIT, "Call");
1510
+ rb_define_const(rb_mCall, "NOTHROW", INT2NUM(JIT_CALL_NOTHROW));
1511
+ rb_define_const(rb_mCall, "NORETURN", INT2NUM(JIT_CALL_NORETURN));
1512
+ rb_define_const(rb_mCall, "TAIL", INT2NUM(JIT_CALL_TAIL));
1513
+
1514
+ /* VALUE rb_cModule = rb_define_module(); */
1515
+ rb_define_method(rb_cModule, "define_jit_method", module_define_jit_method, 2);
1516
+
1517
+ #ifdef NEED_MINIMAL_NODE
1518
+ Init_minimal_node();
1519
+ #endif
1520
+ }
1521
+