ytljit 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|