ytljit 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +29 -0
- data/Rakefile +22 -0
- data/ext/code_alloc.c +266 -0
- data/ext/extconf.rb +3 -0
- data/ext/ytljit.c +527 -0
- data/ext/ytljit.h +285 -0
- data/lib/ytljit/asm.rb +205 -0
- data/lib/ytljit/asmext.rb +199 -0
- data/lib/ytljit/asmext_x64.rb +212 -0
- data/lib/ytljit/asmext_x86.rb +128 -0
- data/lib/ytljit/asmutil.rb +182 -0
- data/lib/ytljit/codespace.rb +92 -0
- data/lib/ytljit/error.rb +7 -0
- data/lib/ytljit/instruction.rb +138 -0
- data/lib/ytljit/instruction_ia.rb +1298 -0
- data/lib/ytljit/instruction_x64.rb +41 -0
- data/lib/ytljit/instruction_x86.rb +11 -0
- data/lib/ytljit/marshal.rb +133 -0
- data/lib/ytljit/matcher.rb +235 -0
- data/lib/ytljit/rubyvm.rb +63 -0
- data/lib/ytljit/struct.rb +125 -0
- data/lib/ytljit/type.rb +112 -0
- data/lib/ytljit/util.rb +63 -0
- data/lib/ytljit/vm.rb +1649 -0
- data/lib/ytljit/vm_codegen.rb +491 -0
- data/lib/ytljit/vm_inline_method.rb +85 -0
- data/lib/ytljit/vm_inspect.rb +74 -0
- data/lib/ytljit/vm_sendnode.rb +561 -0
- data/lib/ytljit/vm_trans.rb +508 -0
- data/lib/ytljit/vm_type.rb +299 -0
- data/lib/ytljit/vm_type_gen.rb +158 -0
- data/lib/ytljit/vm_typeinf.rb +98 -0
- data/lib/ytljit.rb +46 -0
- data/test/asmsample.rb +117 -0
- data/test/cstest.rb +61 -0
- data/test/marshaltest.rb +27 -0
- data/test/test_assemble.rb +148 -0
- data/test/test_assemble2.rb +286 -0
- data/test/test_codespace.rb +102 -0
- data/test/test_typeinf.rb +21 -0
- data/test/tivmtest.rb +54 -0
- data/test/vmtest.rb +59 -0
- data/test/vmtest2.rb +41 -0
- data/test/vmtest3.rb +22 -0
- data/test/vmtest_compile_only.rb +41 -0
- data/test/vmtest_execute_only.rb +22 -0
- metadata +121 -0
data/ext/ytljit.c
ADDED
@@ -0,0 +1,527 @@
|
|
1
|
+
#include <setjmp.h>
|
2
|
+
#include <dlfcn.h>
|
3
|
+
#include <unistd.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
#include "ytljit.h"
|
8
|
+
|
9
|
+
VALUE ytl_mYTLJit;
|
10
|
+
VALUE ytl_cCodeSpace;
|
11
|
+
VALUE ytl_cValueSpace;
|
12
|
+
VALUE ytl_cStepHandler;
|
13
|
+
VALUE ytl_eStepHandler;
|
14
|
+
static ID ytl_v_step_handler_id;
|
15
|
+
|
16
|
+
static void *dl_handles[MAX_DL_HANDLES];
|
17
|
+
static int used_dl_handles = 0;
|
18
|
+
|
19
|
+
VALUE
|
20
|
+
ytl_address_of(VALUE self, VALUE symstr)
|
21
|
+
{
|
22
|
+
int i;
|
23
|
+
char *sym;
|
24
|
+
void *add;
|
25
|
+
|
26
|
+
sym = StringValuePtr(symstr);
|
27
|
+
for (i = 0; i < used_dl_handles; i++) {
|
28
|
+
if ((add = dlsym(dl_handles[i], sym)) != NULL) {
|
29
|
+
return ULONG2NUM((uintptr_t)add);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
return Qnil;
|
34
|
+
}
|
35
|
+
|
36
|
+
VALUE
|
37
|
+
ytl_method_address_of(VALUE klass, VALUE mname)
|
38
|
+
{
|
39
|
+
rb_method_entry_t *me;
|
40
|
+
ID mid = SYM2ID(mname);
|
41
|
+
|
42
|
+
me = rb_method_entry(klass, mid);
|
43
|
+
|
44
|
+
if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC) {
|
45
|
+
return ULONG2NUM((uintptr_t)me->def->body.cfunc.func);
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
return Qnil;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE
|
53
|
+
ytl_instance_var_address_of(VALUE slf, VALUE ivname)
|
54
|
+
{
|
55
|
+
ID ivid = SYM2ID(ivname);
|
56
|
+
struct st_table *iv_index_tbl;
|
57
|
+
VALUE *valadd, *ptr;
|
58
|
+
long len;
|
59
|
+
st_data_t index;
|
60
|
+
|
61
|
+
len = ROBJECT_NUMIV(slf);
|
62
|
+
ptr = ROBJECT_IVPTR(slf);
|
63
|
+
iv_index_tbl = ROBJECT_IV_INDEX_TBL(slf);
|
64
|
+
if (!iv_index_tbl) return Qnil;
|
65
|
+
if (!st_lookup(iv_index_tbl, (st_data_t)ivid, &index)) return Qnil;
|
66
|
+
if (len <= (long)index) return Qnil;
|
67
|
+
valadd = &ptr[index];
|
68
|
+
return ULONG2NUM((uintptr_t)valadd);
|
69
|
+
}
|
70
|
+
|
71
|
+
void *
|
72
|
+
ytl_method_address_of_raw(VALUE klass, VALUE mname)
|
73
|
+
{
|
74
|
+
rb_method_entry_t *me;
|
75
|
+
ID mid = SYM2ID(mname);
|
76
|
+
|
77
|
+
me = rb_method_entry(klass, mid);
|
78
|
+
|
79
|
+
if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC) {
|
80
|
+
return (void *)me->def->body.cfunc.func;
|
81
|
+
}
|
82
|
+
else {
|
83
|
+
return NULL;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
VALUE
|
88
|
+
ytl_binding_to_a(VALUE self)
|
89
|
+
{
|
90
|
+
rb_proc_t *proc;
|
91
|
+
rb_binding_t *bptr;
|
92
|
+
rb_env_t *env;
|
93
|
+
VALUE resary;
|
94
|
+
VALUE eleary;
|
95
|
+
VALUE tmpenv;
|
96
|
+
int i;
|
97
|
+
|
98
|
+
GetBindingPtr(self, bptr);
|
99
|
+
|
100
|
+
resary = rb_ary_new();
|
101
|
+
|
102
|
+
tmpenv = bptr->env;
|
103
|
+
while (tmpenv) {
|
104
|
+
GetEnvPtr(tmpenv, env);
|
105
|
+
eleary = rb_ary_new();
|
106
|
+
rb_ary_push(eleary, env->block.self);
|
107
|
+
|
108
|
+
for (i = 0; i <= env->local_size; i++) {
|
109
|
+
rb_ary_push(eleary, env->env[i]);
|
110
|
+
}
|
111
|
+
rb_ary_push(resary, eleary);
|
112
|
+
|
113
|
+
tmpenv = env->prev_envval;
|
114
|
+
}
|
115
|
+
|
116
|
+
return resary;
|
117
|
+
}
|
118
|
+
|
119
|
+
VALUE
|
120
|
+
ytl_binding_variables(VALUE self)
|
121
|
+
{
|
122
|
+
rb_binding_t *bptr;
|
123
|
+
rb_env_t *env;
|
124
|
+
rb_iseq_t *iseq;
|
125
|
+
VALUE resary;
|
126
|
+
VALUE eleary;
|
127
|
+
VALUE tmpenv;
|
128
|
+
int i;
|
129
|
+
|
130
|
+
GetBindingPtr(self, bptr);
|
131
|
+
|
132
|
+
resary = rb_ary_new();
|
133
|
+
|
134
|
+
tmpenv = bptr->env;
|
135
|
+
while (tmpenv) {
|
136
|
+
GetEnvPtr(tmpenv, env);
|
137
|
+
eleary = rb_ary_new();
|
138
|
+
iseq = env->block.iseq;
|
139
|
+
if (iseq) {
|
140
|
+
for (i = 0; i < iseq->local_table_size; i++) {
|
141
|
+
ID lid = iseq->local_table[i];
|
142
|
+
if (rb_is_local_id(lid)) {
|
143
|
+
rb_ary_push(eleary, ID2SYM(lid));
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
rb_ary_push(resary, eleary);
|
149
|
+
tmpenv = env->prev_envval;
|
150
|
+
}
|
151
|
+
|
152
|
+
return resary;
|
153
|
+
}
|
154
|
+
|
155
|
+
|
156
|
+
VALUE
|
157
|
+
ytl_proc_to_iseq(VALUE self)
|
158
|
+
{
|
159
|
+
rb_proc_t *proc;
|
160
|
+
rb_iseq_t *iseq;
|
161
|
+
|
162
|
+
GetProcPtr(self, proc);
|
163
|
+
iseq = proc->block.iseq;
|
164
|
+
if (proc->is_from_method) {
|
165
|
+
NODE *node = (NODE *)iseq;
|
166
|
+
/* method(:foo).to_proc */
|
167
|
+
iseq = rb_method_get_iseq(node->u2.value);
|
168
|
+
}
|
169
|
+
if (iseq) {
|
170
|
+
return iseq->self;
|
171
|
+
}
|
172
|
+
else {
|
173
|
+
return Qnil;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
VALUE
|
178
|
+
ytl_proc_copy(VALUE self, VALUE procval)
|
179
|
+
{
|
180
|
+
rb_proc_t *src, *dst;
|
181
|
+
GetProcPtr(procval, src);
|
182
|
+
GetProcPtr(self, dst);
|
183
|
+
|
184
|
+
dst->block = src->block;
|
185
|
+
dst->block.proc = procval;
|
186
|
+
dst->blockprocval = src->blockprocval;
|
187
|
+
dst->envval = src->envval;
|
188
|
+
dst->safe_level = src->safe_level;
|
189
|
+
dst->is_lambda = src->is_lambda;
|
190
|
+
|
191
|
+
return self;
|
192
|
+
}
|
193
|
+
|
194
|
+
VALUE
|
195
|
+
ytl_memref(VALUE self, VALUE addr)
|
196
|
+
{
|
197
|
+
return UINT2NUM(*((char *)NUM2LONG(addr)));
|
198
|
+
}
|
199
|
+
|
200
|
+
VALUE
|
201
|
+
ytl_code_space_allocate(VALUE klass)
|
202
|
+
{
|
203
|
+
struct CodeSpace *obj;
|
204
|
+
|
205
|
+
obj = csalloc(INIT_CODE_SPACE_SIZE);
|
206
|
+
obj->size = INIT_CODE_SPACE_SIZE - sizeof(struct CodeSpace);
|
207
|
+
obj->used = 0;
|
208
|
+
return Data_Wrap_Struct(klass, NULL, csfree, (void *)obj);
|
209
|
+
}
|
210
|
+
|
211
|
+
VALUE
|
212
|
+
ytl_value_space_allocate(VALUE klass)
|
213
|
+
{
|
214
|
+
struct CodeSpace *obj;
|
215
|
+
|
216
|
+
obj = csalloc(VALUE_SPACE_SIZE);
|
217
|
+
obj->size = VALUE_SPACE_SIZE - sizeof(struct CodeSpace);
|
218
|
+
obj->used = 0;
|
219
|
+
return Data_Wrap_Struct(klass, NULL, csfree, (void *)obj);
|
220
|
+
}
|
221
|
+
|
222
|
+
VALUE
|
223
|
+
ytl_code_space_emit(VALUE self, VALUE offset, VALUE src)
|
224
|
+
{
|
225
|
+
struct CodeSpace *raw_cs;
|
226
|
+
char *src_ptr;
|
227
|
+
size_t src_len;
|
228
|
+
int raw_offset;
|
229
|
+
size_t cooked_offset;
|
230
|
+
struct RData *data_cs;
|
231
|
+
|
232
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
233
|
+
src_ptr = RSTRING_PTR(src);
|
234
|
+
src_len = RSTRING_LEN(src);
|
235
|
+
raw_offset = FIX2INT(offset);
|
236
|
+
cooked_offset = raw_offset;
|
237
|
+
if (raw_offset < 0) {
|
238
|
+
cooked_offset = raw_cs->used - raw_offset + 1;
|
239
|
+
}
|
240
|
+
|
241
|
+
while (raw_cs->size <= src_len + cooked_offset + 4) {
|
242
|
+
size_t newsize = (raw_cs->size + sizeof(struct CodeSpace)) * 2;
|
243
|
+
void *new_cs = csalloc(newsize);
|
244
|
+
|
245
|
+
//*(struct CodeSpace *)new_cs = *(struct CodeSpace *)raw_cs;
|
246
|
+
memcpy(new_cs, raw_cs, newsize / 2);
|
247
|
+
csfree(raw_cs);
|
248
|
+
raw_cs = new_cs;
|
249
|
+
raw_cs->size = newsize - sizeof(struct CodeSpace);
|
250
|
+
}
|
251
|
+
|
252
|
+
memcpy(raw_cs->body + cooked_offset, src_ptr, src_len);
|
253
|
+
if (raw_cs->used < cooked_offset + src_len) {
|
254
|
+
raw_cs->used = cooked_offset + src_len;
|
255
|
+
}
|
256
|
+
data_cs = (struct RData *)self;
|
257
|
+
data_cs->data = raw_cs;
|
258
|
+
|
259
|
+
return src;
|
260
|
+
}
|
261
|
+
|
262
|
+
VALUE
|
263
|
+
ytl_code_space_ref(VALUE self, VALUE offset)
|
264
|
+
{
|
265
|
+
struct CodeSpace *raw_cs;
|
266
|
+
|
267
|
+
int raw_offset;
|
268
|
+
size_t cooked_offset;
|
269
|
+
|
270
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
271
|
+
raw_offset = FIX2INT(offset);
|
272
|
+
cooked_offset = raw_offset;
|
273
|
+
if (raw_offset < 0) {
|
274
|
+
size_t rev_offset = -raw_offset;
|
275
|
+
cooked_offset = raw_cs->used + rev_offset + 1;
|
276
|
+
}
|
277
|
+
|
278
|
+
return INT2FIX(raw_cs->body[cooked_offset]);
|
279
|
+
}
|
280
|
+
|
281
|
+
VALUE
|
282
|
+
ytl_code_current_pos(VALUE self)
|
283
|
+
{
|
284
|
+
struct CodeSpace *raw_cs;
|
285
|
+
|
286
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
287
|
+
return INT2NUM(raw_cs->used);
|
288
|
+
}
|
289
|
+
|
290
|
+
VALUE
|
291
|
+
ytl_code_set_current_pos(VALUE self, VALUE val)
|
292
|
+
{
|
293
|
+
struct CodeSpace *raw_cs;
|
294
|
+
|
295
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
296
|
+
raw_cs->used = NUM2INT(val);
|
297
|
+
return val;
|
298
|
+
}
|
299
|
+
|
300
|
+
VALUE
|
301
|
+
ytl_code_base_address(VALUE self)
|
302
|
+
{
|
303
|
+
struct CodeSpace *raw_cs;
|
304
|
+
|
305
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
306
|
+
return ULONG2NUM((unsigned long)raw_cs->body);
|
307
|
+
}
|
308
|
+
|
309
|
+
VALUE
|
310
|
+
ytl_code_call(int argc, VALUE *argv, VALUE self)
|
311
|
+
{
|
312
|
+
VALUE addr;
|
313
|
+
VALUE args;
|
314
|
+
VALUE rc;
|
315
|
+
void *raddr;
|
316
|
+
|
317
|
+
rb_scan_args(argc, argv, "11", &addr, &args);
|
318
|
+
raddr = (void *)NUM2ULONG(addr);
|
319
|
+
|
320
|
+
#ifdef __x86_64__
|
321
|
+
asm("mov %1, %%rax;"
|
322
|
+
"call *%2;"
|
323
|
+
"mov %%rax, %0;"
|
324
|
+
: "=r"(rc)
|
325
|
+
: "r"(args), "r"(raddr)
|
326
|
+
: "%rax", "%rbx");
|
327
|
+
#elif __CYGWIN__
|
328
|
+
asm("mov %1, %%eax;"
|
329
|
+
"call *%2;"
|
330
|
+
"mov %%eax, %0;"
|
331
|
+
: "=r"(rc)
|
332
|
+
: "r"(args), "r"(raddr)
|
333
|
+
: "%eax", "%ebx");
|
334
|
+
#elif __i386__
|
335
|
+
/* push %ebx ? */
|
336
|
+
asm("mov %1, %%eax;"
|
337
|
+
"call *%2;"
|
338
|
+
"mov %%eax, %0;"
|
339
|
+
: "=r"(rc)
|
340
|
+
: "r"(args), "r"(raddr)
|
341
|
+
: "%eax");
|
342
|
+
/* pop %ebx ? */
|
343
|
+
#else
|
344
|
+
#error "only i386 or x86-64 is supported"
|
345
|
+
#endif
|
346
|
+
|
347
|
+
return rc;
|
348
|
+
}
|
349
|
+
|
350
|
+
VALUE
|
351
|
+
ytl_code_space_code(VALUE self)
|
352
|
+
{
|
353
|
+
struct CodeSpace *raw_cs;
|
354
|
+
|
355
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
356
|
+
|
357
|
+
return rb_str_new(raw_cs->body, raw_cs->used);
|
358
|
+
}
|
359
|
+
|
360
|
+
VALUE
|
361
|
+
ytl_code_space_to_s(VALUE self)
|
362
|
+
{
|
363
|
+
struct CodeSpace *raw_cs;
|
364
|
+
|
365
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
366
|
+
|
367
|
+
return rb_sprintf("#<codeSpace %p base=%p:...>", (void *)self, (void *)raw_cs->body);
|
368
|
+
}
|
369
|
+
|
370
|
+
VALUE
|
371
|
+
ytl_value_space_to_s(VALUE self)
|
372
|
+
{
|
373
|
+
struct CodeSpace *raw_cs;
|
374
|
+
|
375
|
+
raw_cs = (struct CodeSpace *)DATA_PTR(self);
|
376
|
+
|
377
|
+
return rb_sprintf("#<valueSpace %p base=%p:...>", (void *)self, (void *)raw_cs->body);
|
378
|
+
}
|
379
|
+
|
380
|
+
static VALUE *
|
381
|
+
get_registers(unsigned long *regs, VALUE *argv)
|
382
|
+
{
|
383
|
+
argv[0] = ULONG2NUM((unsigned long)__builtin_return_address(1));
|
384
|
+
|
385
|
+
/* regs[0] old bp
|
386
|
+
regs[-1] old ebx (maybe gcc depend)
|
387
|
+
regs[-2] return address
|
388
|
+
regs[-3] pusha starts
|
389
|
+
*/
|
390
|
+
argv[1] = ULONG2NUM(regs[-3]); /* eax */
|
391
|
+
argv[2] = ULONG2NUM(regs[-4]); /* ecx */
|
392
|
+
argv[3] = ULONG2NUM(regs[-5]); /* edx */
|
393
|
+
argv[4] = ULONG2NUM(regs[-6]); /* ebx */
|
394
|
+
argv[5] = ULONG2NUM(regs[-7]); /* ebp */
|
395
|
+
argv[6] = ULONG2NUM(regs[-8]); /* esi */
|
396
|
+
argv[7] = ULONG2NUM(regs[-9]); /* edi */
|
397
|
+
|
398
|
+
return argv;
|
399
|
+
}
|
400
|
+
|
401
|
+
static void
|
402
|
+
body(void)
|
403
|
+
{
|
404
|
+
VALUE *argv;
|
405
|
+
unsigned long *regs;
|
406
|
+
|
407
|
+
#if defined(__i386__) || defined(__i386)
|
408
|
+
asm("mov (%%ebp), %0"
|
409
|
+
: "=r" (regs) : : "%eax");
|
410
|
+
#elif defined(__x86_64__) || defined(__x86_64)
|
411
|
+
asm("mov (%%rbp), %0"
|
412
|
+
: "=r" (regs) : : "%rax");
|
413
|
+
#else
|
414
|
+
#error "only i386 or x86-64 is supported"
|
415
|
+
#endif
|
416
|
+
argv = ALLOCA_N(VALUE, 8);
|
417
|
+
argv = get_registers(regs, argv);
|
418
|
+
|
419
|
+
rb_funcall2(ytl_eStepHandler, ytl_v_step_handler_id, 8, argv);
|
420
|
+
}
|
421
|
+
|
422
|
+
static void
|
423
|
+
pushall(void)
|
424
|
+
{
|
425
|
+
#ifdef __x86_64__
|
426
|
+
asm("push %rax");
|
427
|
+
asm("push %rcx");
|
428
|
+
asm("push %rdx");
|
429
|
+
asm("push %rbx");
|
430
|
+
asm("push %rbp");
|
431
|
+
asm("push %rsi");
|
432
|
+
asm("push %rdi");
|
433
|
+
#elif __i386__
|
434
|
+
asm("pushal");
|
435
|
+
#else
|
436
|
+
#error "only i386 or x86-64 is supported"
|
437
|
+
#endif
|
438
|
+
}
|
439
|
+
|
440
|
+
static void
|
441
|
+
popall(void)
|
442
|
+
{
|
443
|
+
#ifdef __x86_64__
|
444
|
+
asm("pop %rdi");
|
445
|
+
asm("pop %rsi");
|
446
|
+
asm("pop %rbp");
|
447
|
+
asm("pop %rbx");
|
448
|
+
asm("pop %rdx");
|
449
|
+
asm("pop %rcx");
|
450
|
+
asm("pop %rax");
|
451
|
+
#elif __i386__
|
452
|
+
asm("popal");
|
453
|
+
#else
|
454
|
+
#error "only i386 or x86-64 is supported"
|
455
|
+
#endif
|
456
|
+
}
|
457
|
+
|
458
|
+
void
|
459
|
+
ytl_step_handler()
|
460
|
+
{
|
461
|
+
|
462
|
+
/* Don't add local variables. Maybe break consistency of stack */
|
463
|
+
|
464
|
+
pushall();
|
465
|
+
body();
|
466
|
+
popall();
|
467
|
+
}
|
468
|
+
|
469
|
+
void
|
470
|
+
Init_ytljit_ext()
|
471
|
+
{
|
472
|
+
VALUE *argv;
|
473
|
+
|
474
|
+
init_csarena();
|
475
|
+
|
476
|
+
ytl_mYTLJit = rb_define_module("YTLJit");
|
477
|
+
|
478
|
+
rb_define_module_function(ytl_mYTLJit, "address_of", ytl_address_of, 1);
|
479
|
+
rb_define_module_function(rb_cObject, "method_address_of",
|
480
|
+
ytl_method_address_of, 1);
|
481
|
+
rb_define_method(rb_cObject, "instance_var_address_of",
|
482
|
+
ytl_instance_var_address_of, 1);
|
483
|
+
rb_define_module_function(ytl_mYTLJit, "memref", ytl_memref, 1);
|
484
|
+
|
485
|
+
rb_define_method(rb_cBinding, "to_a", ytl_binding_to_a, 0);
|
486
|
+
rb_define_method(rb_cBinding, "variables", ytl_binding_variables, 0);
|
487
|
+
|
488
|
+
rb_define_method(rb_cProc, "to_iseq", ytl_proc_to_iseq, 0);
|
489
|
+
rb_define_method(rb_cProc, "copy", ytl_proc_copy, 1);
|
490
|
+
|
491
|
+
ytl_v_step_handler_id = rb_intern("step_handler");
|
492
|
+
|
493
|
+
ytl_cStepHandler = rb_define_class_under(ytl_mYTLJit, "StepHandler", rb_cObject);
|
494
|
+
argv = ALLOCA_N(VALUE, 1);
|
495
|
+
ytl_eStepHandler = rb_class_new_instance(0, argv, ytl_cStepHandler);
|
496
|
+
rb_global_variable(&ytl_eStepHandler);
|
497
|
+
|
498
|
+
ytl_cCodeSpace = rb_define_class_under(ytl_mYTLJit, "CodeSpace", rb_cObject);
|
499
|
+
rb_define_alloc_func(ytl_cCodeSpace, ytl_code_space_allocate);
|
500
|
+
rb_define_method(ytl_cCodeSpace, "[]=", ytl_code_space_emit, 2);
|
501
|
+
rb_define_method(ytl_cCodeSpace, "[]", ytl_code_space_ref, 1);
|
502
|
+
rb_define_method(ytl_cCodeSpace, "current_pos", ytl_code_current_pos, 0);
|
503
|
+
rb_define_method(ytl_cCodeSpace, "current_pos=", ytl_code_set_current_pos, 1);
|
504
|
+
rb_define_method(ytl_cCodeSpace, "base_address", ytl_code_base_address, 0);
|
505
|
+
rb_define_method(ytl_cCodeSpace, "call", ytl_code_call, -1);
|
506
|
+
rb_define_method(ytl_cCodeSpace, "code", ytl_code_space_code, 0);
|
507
|
+
rb_define_method(ytl_cCodeSpace, "to_s", ytl_code_space_to_s, 0);
|
508
|
+
|
509
|
+
ytl_cValueSpace =
|
510
|
+
rb_define_class_under(ytl_mYTLJit, "ValueSpace", ytl_cCodeSpace);
|
511
|
+
rb_define_alloc_func(ytl_cValueSpace, ytl_value_space_allocate);
|
512
|
+
rb_define_method(ytl_cValueSpace, "to_s", ytl_value_space_to_s, 0);
|
513
|
+
|
514
|
+
/* Open Handles */
|
515
|
+
#ifdef __CYGWIN__
|
516
|
+
OPEN_CHECK(dl_handles[used_dl_handles] = dlopen("cygwin1.dll", RTLD_LAZY));
|
517
|
+
used_dl_handles++;
|
518
|
+
OPEN_CHECK(dl_handles[used_dl_handles] = dlopen("cygruby191.dll", RTLD_LAZY));
|
519
|
+
used_dl_handles++;
|
520
|
+
OPEN_CHECK(dl_handles[used_dl_handles] = dlopen("ytljit.so", RTLD_LAZY));
|
521
|
+
used_dl_handles++;
|
522
|
+
#else
|
523
|
+
OPEN_CHECK(dl_handles[used_dl_handles] = dlopen(NULL, RTLD_LAZY));
|
524
|
+
used_dl_handles++;
|
525
|
+
#endif
|
526
|
+
}
|
527
|
+
|