evoasm 0.0.2.pre7 → 0.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.gdbinit +41 -0
  3. data/.gitignore +1 -2
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +660 -0
  8. data/Makefile +1 -1
  9. data/README.md +17 -9
  10. data/Rakefile +39 -107
  11. data/bin/gdb +1 -1
  12. data/bin/gdb_loop +4 -0
  13. data/docs/FindingInstructions.md +17 -0
  14. data/docs/JIT.md +14 -0
  15. data/docs/SymbolicRegression.md +102 -0
  16. data/docs/Visualization.md +29 -0
  17. data/docs/examples/bit_insts.rb +44 -0
  18. data/docs/examples/jit.rb +26 -0
  19. data/docs/examples/loss.gif +0 -0
  20. data/docs/examples/program.png +0 -0
  21. data/docs/examples/sym_reg.rb +64 -0
  22. data/docs/examples/vis.rb +38 -0
  23. data/evoasm.gemspec +21 -15
  24. data/ext/evoasm_ext/Rakefile +3 -0
  25. data/ext/evoasm_ext/compile.rake +35 -0
  26. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
  27. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
  28. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
  29. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
  30. data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
  31. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
  32. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
  33. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
  34. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
  35. data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
  36. data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
  37. data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
  38. data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
  39. data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
  40. data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
  41. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
  42. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
  43. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
  44. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
  45. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
  46. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
  47. data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
  48. data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
  49. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
  50. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
  51. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
  52. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
  53. data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
  54. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
  55. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
  56. data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
  57. data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
  58. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
  59. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
  60. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
  61. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
  62. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
  63. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
  64. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
  65. data/lib/evoasm.rb +28 -11
  66. data/lib/evoasm/buffer.rb +105 -0
  67. data/lib/evoasm/capstone.rb +100 -0
  68. data/lib/evoasm/domain.rb +116 -0
  69. data/lib/evoasm/error.rb +37 -16
  70. data/lib/evoasm/exception_error.rb +19 -0
  71. data/lib/evoasm/ffi_ext.rb +53 -0
  72. data/lib/evoasm/libevoasm.rb +286 -0
  73. data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
  74. data/lib/evoasm/parameter.rb +20 -0
  75. data/lib/evoasm/population.rb +145 -0
  76. data/lib/evoasm/population/parameters.rb +227 -0
  77. data/lib/evoasm/population/plotter.rb +89 -0
  78. data/lib/evoasm/prng.rb +64 -0
  79. data/lib/evoasm/program.rb +195 -12
  80. data/lib/evoasm/program/io.rb +144 -0
  81. data/lib/evoasm/test.rb +8 -0
  82. data/lib/evoasm/version.rb +1 -1
  83. data/lib/evoasm/x64.rb +115 -0
  84. data/lib/evoasm/x64/cpu_state.rb +95 -0
  85. data/lib/evoasm/x64/instruction.rb +109 -0
  86. data/lib/evoasm/x64/operand.rb +156 -0
  87. data/lib/evoasm/x64/parameters.rb +211 -0
  88. data/test/helpers/population_helper.rb +128 -0
  89. data/test/helpers/test_helper.rb +1 -0
  90. data/test/helpers/x64_helper.rb +24 -0
  91. data/test/integration/bitwise_reverse_test.rb +41 -0
  92. data/test/integration/gcd_test.rb +52 -0
  93. data/test/integration/popcnt_test.rb +46 -0
  94. data/test/integration/sym_reg_test.rb +68 -0
  95. data/test/unit/evoasm/buffer_test.rb +48 -0
  96. data/test/unit/evoasm/capstone_test.rb +18 -0
  97. data/test/unit/evoasm/domain_test.rb +55 -0
  98. data/test/unit/evoasm/population/parameters_test.rb +106 -0
  99. data/test/unit/evoasm/population_test.rb +96 -0
  100. data/test/unit/evoasm/prng_test.rb +47 -0
  101. data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
  102. data/test/unit/evoasm/x64/encoding_test.rb +320 -0
  103. data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
  104. data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
  105. data/test/unit/evoasm/x64/instruction_test.rb +62 -0
  106. data/test/unit/evoasm/x64/parameters_test.rb +65 -0
  107. data/test/unit/evoasm/x64_test.rb +52 -0
  108. metadata +195 -89
  109. data/Gemfile.rake +0 -8
  110. data/Gemfile.rake.lock +0 -51
  111. data/LICENSE.txt +0 -373
  112. data/data/tables/README.md +0 -19
  113. data/data/tables/x64.csv +0 -1684
  114. data/data/templates/evoasm-x64.c.erb +0 -319
  115. data/data/templates/evoasm-x64.h.erb +0 -126
  116. data/examples/abs.yml +0 -20
  117. data/examples/popcnt.yml +0 -17
  118. data/examples/sym_reg.yml +0 -26
  119. data/exe/evoasm-search +0 -13
  120. data/ext/evoasm_ext/evoasm-alloc.c +0 -145
  121. data/ext/evoasm_ext/evoasm-alloc.h +0 -59
  122. data/ext/evoasm_ext/evoasm-arch.c +0 -44
  123. data/ext/evoasm_ext/evoasm-arch.h +0 -161
  124. data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
  125. data/ext/evoasm_ext/evoasm-buf.c +0 -130
  126. data/ext/evoasm_ext/evoasm-buf.h +0 -47
  127. data/ext/evoasm_ext/evoasm-error.c +0 -31
  128. data/ext/evoasm_ext/evoasm-error.h +0 -75
  129. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
  130. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
  131. data/ext/evoasm_ext/evoasm-log.h +0 -69
  132. data/ext/evoasm_ext/evoasm-misc.c +0 -23
  133. data/ext/evoasm_ext/evoasm-misc.h +0 -282
  134. data/ext/evoasm_ext/evoasm-param.h +0 -37
  135. data/ext/evoasm_ext/evoasm-search.c +0 -2145
  136. data/ext/evoasm_ext/evoasm-search.h +0 -214
  137. data/ext/evoasm_ext/evoasm-util.h +0 -40
  138. data/ext/evoasm_ext/evoasm-x64.c +0 -275624
  139. data/ext/evoasm_ext/evoasm-x64.h +0 -5436
  140. data/ext/evoasm_ext/evoasm.c +0 -7
  141. data/ext/evoasm_ext/evoasm.h +0 -23
  142. data/ext/evoasm_ext/evoasm_ext.c +0 -1757
  143. data/ext/evoasm_ext/extconf.rb +0 -31
  144. data/lib/evoasm/cli.rb +0 -6
  145. data/lib/evoasm/cli/search.rb +0 -127
  146. data/lib/evoasm/core_ext.rb +0 -1
  147. data/lib/evoasm/core_ext/array.rb +0 -9
  148. data/lib/evoasm/core_ext/integer.rb +0 -10
  149. data/lib/evoasm/core_ext/kwstruct.rb +0 -13
  150. data/lib/evoasm/core_ext/range.rb +0 -5
  151. data/lib/evoasm/examples.rb +0 -27
  152. data/lib/evoasm/gen.rb +0 -8
  153. data/lib/evoasm/gen/enum.rb +0 -169
  154. data/lib/evoasm/gen/name_util.rb +0 -80
  155. data/lib/evoasm/gen/state.rb +0 -176
  156. data/lib/evoasm/gen/state_dsl.rb +0 -152
  157. data/lib/evoasm/gen/strio.rb +0 -27
  158. data/lib/evoasm/gen/translator.rb +0 -1102
  159. data/lib/evoasm/gen/version.rb +0 -5
  160. data/lib/evoasm/gen/x64.rb +0 -237
  161. data/lib/evoasm/gen/x64/funcs.rb +0 -495
  162. data/lib/evoasm/gen/x64/inst.rb +0 -781
  163. data/lib/evoasm/search.rb +0 -40
  164. data/lib/evoasm/tasks/gen_task.rb +0 -86
  165. data/lib/evoasm/tasks/template_task.rb +0 -52
  166. data/test/test_helper.rb +0 -1
  167. data/test/x64/test_helper.rb +0 -19
  168. data/test/x64/x64_test.rb +0 -87
@@ -1,7 +0,0 @@
1
- #include "evoasm.h"
2
- #include "evoasm-log.h"
3
-
4
- void
5
- evoasm_init(int argc, const char **argv, FILE *log_file) {
6
- evoasm_log_file = log_file;
7
- }
@@ -1,23 +0,0 @@
1
- /* vim: set filetype=c: */
2
-
3
- #pragma once
4
-
5
- #include <stdint.h>
6
- #include <stdlib.h>
7
- #include <stdbool.h>
8
- #include <limits.h>
9
- #include <assert.h>
10
- #include <math.h>
11
- #include <string.h>
12
- #include <inttypes.h>
13
-
14
- #include "evoasm-util.h"
15
- #include "evoasm-log.h"
16
- #include "evoasm-buf.h"
17
- #include "evoasm-alloc.h"
18
- #include "evoasm-arch.h"
19
- #include "evoasm-error.h"
20
-
21
- void
22
- evoasm_init(int argc, const char **argv, FILE *log_file);
23
-
@@ -1,1757 +0,0 @@
1
- #include <ruby.h>
2
-
3
- static VALUE mEvoasm;
4
- static VALUE cX64;
5
- VALUE evoasm_cX64Instruction;
6
- static VALUE cInstruction;
7
- static VALUE cParameters;
8
- static VALUE cX64Parameters;
9
- static VALUE cParameter;
10
- static VALUE cRegister;
11
- static VALUE cX64Register;
12
- static VALUE cOperand;
13
- static VALUE cX64Operand;
14
- static VALUE cArchitecture;
15
- static VALUE cBuffer;
16
- static VALUE cSearch;
17
- static VALUE cProgram;
18
- static VALUE cKernel;
19
- static VALUE eError;
20
- static VALUE eArchitectureError;
21
-
22
- static VALUE domains_cache;
23
- static VALUE instructions_cache;
24
-
25
- static ID rb_id_brute_force;
26
- static ID rb_id_genetic;
27
- static ID rb_id_id;
28
-
29
- #include "evoasm-x64.h"
30
- #include "evoasm-buf.h"
31
- #include "evoasm-search.h"
32
-
33
- void evoasm_raise_last_error();
34
-
35
- static void
36
- buf_free(void *p) {
37
- evoasm_buf *buf = (evoasm_buf *)p;
38
- EVOASM_TRY(raise, evoasm_buf_destroy, buf);
39
- xfree(p);
40
- return;
41
-
42
- raise:
43
- xfree(p);
44
- evoasm_raise_last_error();
45
- }
46
-
47
- static const rb_data_type_t rb_buf_type = {
48
- "Evoasm::Buffer",
49
- {NULL, buf_free, NULL,},
50
- NULL, NULL,
51
- RUBY_TYPED_FREE_IMMEDIATELY,
52
- };
53
-
54
- static void
55
- x64_free(void *p) {
56
- evoasm_x64 *x64 = (evoasm_x64 *) p;
57
- evoasm_x64_destroy(x64);
58
- xfree(p);
59
- }
60
-
61
- static void
62
- x64_mark(void *p) {
63
- evoasm_x64 *x64 = (evoasm_x64 *) p;
64
- (void) x64;
65
- }
66
-
67
- static const rb_data_type_t rb_arch_type = {
68
- "Evoasm::Architecture",
69
- {NULL, NULL, NULL,},
70
- NULL, NULL,
71
- RUBY_TYPED_FREE_IMMEDIATELY,
72
- };
73
-
74
- static const rb_data_type_t rb_x64_type = {
75
- "Evoasm::X64",
76
- {x64_mark, x64_free, NULL,},
77
- &rb_arch_type, NULL,
78
- RUBY_TYPED_FREE_IMMEDIATELY,
79
- };
80
-
81
- static VALUE
82
- rb_buffer_alloc(VALUE klass) {
83
- evoasm_buf *buf = ALLOC(evoasm_buf);
84
-
85
- return TypedData_Wrap_Struct(klass, &rb_buf_type, buf);
86
- }
87
-
88
- static VALUE
89
- rb_buffer_initialize(int argc, VALUE *argv, VALUE self) {
90
- evoasm_buf *buf;
91
- VALUE rb_size;
92
- VALUE rb_malloc = Qtrue;
93
-
94
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
95
-
96
- rb_scan_args(argc, argv, "11", &rb_size, &rb_malloc);
97
-
98
- EVOASM_TRY(failed, evoasm_buf_init, buf,
99
- RTEST(rb_malloc) ? EVOASM_BUF_TYPE_MALLOC : EVOASM_BUF_TYPE_MMAP, NUM2SIZET(rb_size));
100
-
101
- return self;
102
-
103
- failed:
104
- return Qnil;
105
- }
106
-
107
- #ifdef HAVE_CAPSTONE_CAPSTONE_H
108
- #include <capstone/capstone.h>
109
-
110
- static VALUE
111
- x64_disassemble(unsigned char *data, size_t len, bool addr) {
112
- csh handle;
113
- cs_insn *insn;
114
- size_t count;
115
- VALUE rb_result;
116
-
117
- /* FIXME: check arch */
118
- if(cs_open(CS_ARCH_X86, CS_MODE_64, &handle) != CS_ERR_OK) {
119
- return Qnil;
120
- }
121
-
122
- count = cs_disasm(handle, data, len, (uintptr_t) data, 0, &insn);
123
- rb_result = rb_ary_new2((long) count);
124
- if(count > 0) {
125
- size_t j;
126
-
127
- for(j = 0; j < count; j++) {
128
- VALUE line;
129
- if(addr) {
130
- line = rb_sprintf("0x%"PRIx64": %s %s", insn[j].address, insn[j].mnemonic, insn[j].op_str);
131
- } else {
132
- line = rb_sprintf("%s %s", insn[j].mnemonic, insn[j].op_str);
133
- }
134
- rb_ary_push(rb_result, line);
135
- }
136
- cs_free(insn, count);
137
- }
138
-
139
- cs_close(&handle);
140
- return rb_result;
141
- }
142
-
143
- static VALUE
144
- rb_buffer_disassemble(VALUE self) {
145
- evoasm_buf *buf;
146
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
147
-
148
- return x64_disassemble(buf->data, buf->pos, true);
149
- }
150
-
151
- static VALUE
152
- rb_x64_s_disassemble(VALUE self, VALUE as_str) {
153
- unsigned char *data = (unsigned char *) RSTRING_PTR(as_str);
154
- size_t len = (size_t)RSTRING_LEN(as_str);
155
-
156
- return x64_disassemble(data, len, false);
157
- }
158
- #endif
159
-
160
- static VALUE
161
- rb_buffer_size(VALUE self) {
162
- evoasm_buf *buf;
163
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
164
-
165
- return SIZET2NUM(buf->capa);
166
- }
167
-
168
- static VALUE
169
- rb_buffer_reset(VALUE self) {
170
- evoasm_buf *buf;
171
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
172
-
173
- evoasm_buf_reset(buf);
174
-
175
- return Qnil;
176
- }
177
-
178
- static VALUE
179
- rb_buffer_to_s(VALUE self) {
180
- evoasm_buf *buf;
181
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
182
-
183
- return rb_usascii_str_new((char *)buf->data, (long) buf->pos);
184
- }
185
-
186
- #if 0
187
- static VALUE
188
- rb_buffer_protect(VALUE self, evoasm_buf_prot mode) {
189
- evoasm_buf *buf;
190
-
191
- TypedData_Get_Struct(self, evoasm_buf, &rb_buf_type, buf);
192
- return evoasm_buf_protect(buf, mode) ? Qtrue : Qfalse;
193
- }
194
-
195
- static VALUE
196
- rb_buffer_rx(VALUE self) {
197
- return rb_buffer_protect(self, EVOASM_BUF_PROT_RX);
198
- }
199
-
200
- static VALUE
201
- rb_buffer_rw(VALUE self) {
202
- return rb_buffer_protect(self, EVOASM_BUF_PROT_RW);
203
- }
204
- #endif
205
-
206
-
207
- //evoasm_inst *evoasm_population_inst_seed_random(uint32_t sol_idx, uint32_t inst_idx, void *insts, uint16_t, void *) {
208
- // return NULL
209
- //}
210
-
211
- static void
212
- search_free(void *p) {
213
- evoasm_search *search = (evoasm_search *)p;
214
- evoasm_search_destroy(search);
215
- xfree(p);
216
- }
217
-
218
- static void
219
- search_mark(void *p) {
220
- //evoasm_search *search = (evoasm_search *)p;
221
- }
222
-
223
- static const rb_data_type_t rb_search_type = {
224
- "Evoasm::Search",
225
- {search_mark, search_free, NULL,},
226
- NULL, NULL,
227
- RUBY_TYPED_FREE_IMMEDIATELY,
228
- };
229
-
230
- static VALUE
231
- rb_search_alloc(VALUE klass) {
232
- evoasm_search *search = ZALLOC(evoasm_search);
233
- return TypedData_Wrap_Struct(klass, &rb_search_type, search);
234
- }
235
-
236
- typedef struct {
237
- evoasm_kernel kernel;
238
- VALUE params;
239
- VALUE insts;
240
- VALUE program;
241
- } rb_evoasm_kernel;
242
-
243
- typedef struct {
244
- evoasm_program program;
245
- //VALUE params;
246
- VALUE buffer;
247
- VALUE body_buffer;
248
- VALUE insts;
249
- VALUE arch;
250
- VALUE kernels;
251
- } rb_evoasm_program;
252
-
253
- static void
254
- kernel_free(void *p) {
255
- rb_evoasm_kernel *kernel = (rb_evoasm_kernel *)p;
256
- xfree(kernel->kernel.params);
257
- xfree(p);
258
- }
259
-
260
- static void
261
- program_free(void *p) {
262
- rb_evoasm_program *program = (rb_evoasm_program *)p;
263
- xfree(program->program.params);
264
- xfree(p);
265
- }
266
-
267
-
268
- static void
269
- kernel_mark(void *p) {
270
- rb_evoasm_kernel *kernel = (rb_evoasm_kernel *)p;
271
- rb_gc_mark(kernel->params);
272
- rb_gc_mark(kernel->insts);
273
- rb_gc_mark(kernel->program);
274
- }
275
-
276
- static void
277
- program_mark(void *p) {
278
- rb_evoasm_program *program = (rb_evoasm_program *)p;
279
- rb_gc_mark(program->buffer);
280
- rb_gc_mark(program->body_buffer);
281
- rb_gc_mark(program->buffer);
282
- rb_gc_mark(program->kernels);
283
- }
284
-
285
- static const rb_data_type_t rb_program_type = {
286
- "Evoasm::Program",
287
- {program_mark, program_free, NULL,},
288
- NULL, NULL,
289
- RUBY_TYPED_FREE_IMMEDIATELY,
290
- };
291
-
292
- static const rb_data_type_t rb_kernel_type = {
293
- "Evoasm::Kernel",
294
- {kernel_mark, kernel_free, NULL,},
295
- NULL, NULL,
296
- RUBY_TYPED_FREE_IMMEDIATELY,
297
- };
298
-
299
- static const rb_data_type_t rb_inst_type = {
300
- "Evoasm::Instruction",
301
- {NULL, NULL, NULL,},
302
- NULL, NULL,
303
- RUBY_TYPED_FREE_IMMEDIATELY,
304
- };
305
-
306
- typedef struct {
307
- evoasm_inst *inst;
308
- VALUE arch;
309
- } rb_evoasm_inst;
310
-
311
- typedef struct {
312
- evoasm_x64_inst *inst;
313
- VALUE arch;
314
- } rb_evoasm_x64_inst;
315
-
316
- static void
317
- x64_inst_free(void *p) {
318
- //rb_evoasm_x64_inst *inst = (rb_evoasm_x64_inst *)p;
319
- xfree(p);
320
- }
321
-
322
- static void
323
- x64_inst_mark(void *p) {
324
- rb_evoasm_x64_inst *inst = (rb_evoasm_x64_inst *)p;
325
- rb_gc_mark(inst->arch);
326
- }
327
-
328
- static const rb_data_type_t rb_x64_inst_type = {
329
- "Evoasm::X64::Instruction",
330
- {x64_inst_mark, x64_inst_free, NULL,},
331
- &rb_inst_type, NULL,
332
- RUBY_TYPED_FREE_IMMEDIATELY,
333
- };
334
-
335
- static VALUE
336
- rb_program_buffer(int argc, VALUE *argv, VALUE self) {
337
- rb_evoasm_program *program;
338
- VALUE buffer;
339
- VALUE rb_sandbox = Qfalse;
340
-
341
- rb_scan_args(argc, argv, "01", &rb_sandbox);
342
-
343
- TypedData_Get_Struct(self, rb_evoasm_program, &rb_program_type, program);
344
-
345
- if(RTEST(rb_sandbox)) {
346
- buffer = program->buffer;
347
- } else {
348
- buffer = program->body_buffer;
349
- }
350
-
351
- return buffer;
352
- }
353
-
354
- static VALUE
355
- rb_program_kernels(VALUE self) {
356
- rb_evoasm_program *program;
357
- TypedData_Get_Struct(self, rb_evoasm_program, &rb_program_type, program);
358
-
359
- return program->kernels;
360
- }
361
-
362
- static void
363
- rb_examples_to_c(VALUE rb_examples, VALUE rb_arity, evoasm_program_io *examples) {
364
- unsigned i;
365
- long examples_len;
366
-
367
- Check_Type(rb_examples, T_ARRAY);
368
-
369
- examples_len = RARRAY_LEN(rb_examples);
370
- if(examples_len == 0) {
371
- rb_raise(rb_eArgError, "examples must not be empty");
372
- return;
373
- }
374
-
375
- examples->vals = evoasm_calloc((size_t) examples_len, sizeof(evoasm_example_val));
376
- examples->len = (uint16_t) examples_len;
377
- examples->arity = (uint8_t) NUM2CHR(rb_arity);
378
-
379
- for(i = 0; i < EVOASM_PROGRAM_IO_MAX_ARITY; i++) {
380
- examples->types[i] = EVOASM_EXAMPLE_TYPE_I64;
381
- }
382
-
383
- for(i = 0; i < examples->len; i++) {
384
- VALUE elem = RARRAY_AREF(rb_examples, i);
385
- if(RB_FLOAT_TYPE_P(elem)) {
386
- examples->types[i % examples->arity] = EVOASM_EXAMPLE_TYPE_F64;
387
- }
388
- }
389
-
390
- for(i = 0; i < examples->len; i++) {
391
- VALUE elem = RARRAY_AREF(rb_examples, i);
392
- switch(examples->types[i % examples->arity]) {
393
- case EVOASM_EXAMPLE_TYPE_F64:
394
- examples->vals[i].f64 = NUM2DBL(elem);
395
- break;
396
- case EVOASM_EXAMPLE_TYPE_I64:
397
- examples->vals[i].i64 = NUM2LL(elem);
398
- break;
399
- default:
400
- evoasm_assert_not_reached();
401
- }
402
- }
403
- }
404
-
405
- static VALUE
406
- example_val_to_rb(evoasm_example_val val, evoasm_example_type type) {
407
- switch(type) {
408
- case EVOASM_EXAMPLE_TYPE_U64: return ULL2NUM(val.u64);
409
- case EVOASM_EXAMPLE_TYPE_I64: return LL2NUM(val.i64);
410
- case EVOASM_EXAMPLE_TYPE_F64: return rb_float_new((double) val.f64);
411
- default:
412
- evoasm_assert_not_reached();
413
- return Qnil;
414
- }
415
- }
416
-
417
- static VALUE
418
- rb_program_eliminate_introns_bang(VALUE self) {
419
- rb_evoasm_program *program;
420
-
421
- TypedData_Get_Struct(self, rb_evoasm_program, &rb_program_type, program);
422
-
423
- EVOASM_TRY(raise, evoasm_program_eliminate_introns, &program->program);
424
-
425
- return self;
426
- raise:
427
- evoasm_raise_last_error();
428
- return Qnil;
429
- }
430
-
431
- static VALUE
432
- rb_program_output_registers(VALUE self) {
433
- rb_evoasm_program *program;
434
- VALUE ary = rb_ary_new();
435
- size_t i;
436
-
437
- TypedData_Get_Struct(self, rb_evoasm_program, &rb_program_type, program);
438
-
439
- for(i = 0; i < program->program._output.arity; i++) {
440
- switch(program->program.arch->cls->id) {
441
- case EVOASM_ARCH_X64:
442
- rb_ary_push(ary, ID2SYM(rb_x64_reg_ids[program->program.output_regs[i]]));
443
- break;
444
- default: evoasm_assert_not_reached();
445
- }
446
- }
447
- return ary;
448
- }
449
-
450
- static VALUE
451
- rb_program_run(VALUE self, VALUE rb_input, VALUE rb_arity) {
452
- rb_evoasm_program *program;
453
- unsigned i, j;
454
- VALUE rb_ary;
455
- evoasm_program_input input;
456
- evoasm_program_output output = {0};
457
-
458
- TypedData_Get_Struct(self, rb_evoasm_program, &rb_program_type, program);
459
-
460
- rb_examples_to_c(rb_input, rb_arity, &input);
461
-
462
- if(!evoasm_program_run(&program->program,
463
- &input,
464
- &output)) {
465
- return Qnil;
466
- }
467
-
468
- rb_ary = rb_ary_new2(EVOASM_PROGRAM_OUTPUT_N(&output));
469
-
470
- for(i = 0; i < EVOASM_PROGRAM_OUTPUT_N(&output); i++) {
471
- VALUE rb_output = rb_ary_new2(output.arity);
472
- for(j = 0; j < output.arity; j++) {
473
- VALUE val = example_val_to_rb(output.vals[i * output.arity + j],
474
- output.types[j]);
475
- rb_ary_push(rb_output, val);
476
- }
477
- rb_ary_push(rb_ary, rb_output);
478
- }
479
- // rb_ary_push(rb_ary, example_val_to_rb(vals[i], examples.types[i]));
480
- //}
481
-
482
- evoasm_program_output_destroy((evoasm_program_io *) &output);
483
-
484
- return rb_ary;
485
- }
486
-
487
- static void
488
- params_free(void *p) {
489
- xfree(p);
490
- }
491
-
492
- static const rb_data_type_t rb_params_type = {
493
- "Evoasm::Parameters",
494
- {NULL, NULL, NULL,},
495
- NULL, NULL,
496
- RUBY_TYPED_FREE_IMMEDIATELY,
497
- };
498
-
499
- static const rb_data_type_t rb_x64_params_type = {
500
- "Evoasm::X64::Parameters",
501
- {NULL, params_free, NULL,},
502
- &rb_params_type, NULL,
503
- RUBY_TYPED_FREE_IMMEDIATELY,
504
- };
505
-
506
- static VALUE
507
- rb_x64_parameters_alloc(VALUE klass) {
508
- evoasm_x64_params *x64_params = ZALLOC(evoasm_x64_params);
509
- return TypedData_Wrap_Struct(klass, &rb_x64_params_type, x64_params);
510
- }
511
-
512
- static VALUE
513
- rb_kernel_parameters(VALUE self) {
514
- rb_evoasm_kernel *kernel;
515
- rb_evoasm_program *program;
516
-
517
- TypedData_Get_Struct(self, rb_evoasm_kernel, &rb_kernel_type, kernel);
518
- TypedData_Get_Struct(kernel->program, rb_evoasm_program, &rb_program_type, program);
519
-
520
- if(kernel->params != Qnil) return kernel->params;
521
-
522
- {
523
- unsigned i;
524
- kernel->params = rb_ary_new2(kernel->kernel.params->size);
525
- for(i = 0; i < kernel->kernel.params->size; i++) {
526
- VALUE rb_params;
527
-
528
- switch(program->program.arch->cls->id) {
529
- case EVOASM_ARCH_X64: {
530
- evoasm_x64_params *params;
531
- rb_params = rb_x64_parameters_alloc(cX64Parameters);
532
- TypedData_Get_Struct(rb_params, evoasm_x64_params, &rb_x64_params_type, params);
533
- MEMCPY(params->vals, kernel->kernel.params->params[i].param_vals, evoasm_arch_param_val, EVOASM_X64_N_PARAMS);
534
- params->set = kernel->kernel.params->params[i].set_params;
535
- break;
536
- }
537
- default: evoasm_assert_not_reached();
538
- }
539
- rb_ary_push(kernel->params, rb_params);
540
- }
541
- }
542
-
543
- return kernel->params;
544
- }
545
-
546
- static VALUE
547
- rb_kernel_instructions(VALUE self) {
548
- rb_evoasm_kernel *kernel;
549
- rb_evoasm_program *program;
550
-
551
- TypedData_Get_Struct(self, rb_evoasm_kernel, &rb_kernel_type, kernel);
552
- TypedData_Get_Struct(kernel->program, rb_evoasm_program, &rb_program_type, program);
553
-
554
- if(kernel->insts != Qnil) return kernel->insts;
555
-
556
- {
557
- unsigned i;
558
- kernel->insts = rb_ary_new2(kernel->kernel.params->size);
559
- for(i = 0; i < kernel->kernel.params->size; i++) {
560
- VALUE rb_inst;
561
-
562
- switch(program->program.arch->cls->id) {
563
- case EVOASM_ARCH_X64: {
564
- rb_evoasm_x64_inst *inst = ALLOC(rb_evoasm_x64_inst);
565
- inst->arch = program->arch;
566
- inst->inst = (evoasm_x64_inst *) kernel->kernel.params->params[i].inst;
567
- rb_inst = TypedData_Wrap_Struct(evoasm_cX64Instruction, &rb_x64_inst_type, inst);
568
- break;
569
- }
570
- default: evoasm_assert_not_reached();
571
- }
572
- rb_ary_push(kernel->insts, rb_inst);
573
- }
574
- }
575
-
576
- return kernel->insts;
577
- }
578
-
579
- static VALUE
580
- rb_program_alloc(VALUE klass) {
581
- rb_evoasm_program *program = ALLOC(rb_evoasm_program);
582
- //program->params = Qnil;
583
- program->buffer = Qnil;
584
- program->kernels = Qnil;
585
- return TypedData_Wrap_Struct(klass, &rb_program_type, program);
586
- }
587
-
588
- static VALUE
589
- rb_kernel_alloc(VALUE klass) {
590
- rb_evoasm_kernel *kernel = ALLOC(rb_evoasm_kernel);
591
- kernel->params = Qnil;
592
- kernel->program = Qnil;
593
- return TypedData_Wrap_Struct(klass, &rb_kernel_type, kernel);
594
- }
595
-
596
-
597
- static evoasm_arch_param_id
598
- x64_param_sym_to_id(VALUE sym) {
599
- int i;
600
- ID id = SYM2ID(sym);
601
- for(i = 0; i < EVOASM_X64_N_PARAMS; i++) {
602
- if(rb_x64_param_ids[i] == id) {
603
- return (evoasm_x64_param_id) i;
604
- }
605
- }
606
- evoasm_assert_not_reached();
607
- }
608
-
609
- struct arch_with_params {
610
- evoasm_arch *arch;
611
- evoasm_search_params *params;
612
- };
613
-
614
- static evoasm_arch_param_id
615
- param_sym_to_c(VALUE rb_key, unsigned n_params) {
616
- unsigned i;
617
- ID id = SYM2ID(rb_key);
618
-
619
- for(i = 0; i < n_params; i++) {
620
- if(rb_x64_param_ids[i] == id) {
621
- return (evoasm_arch_param_id) i;
622
- }
623
- }
624
-
625
- rb_raise(rb_eKeyError, "invalid key");
626
- return 0;
627
- }
628
-
629
- static evoasm_arch_param_val
630
- param_val_to_c(VALUE rb_value) {
631
- switch(TYPE(rb_value)) {
632
- case T_SYMBOL: {
633
- unsigned i;
634
- ID id = SYM2ID(rb_value);
635
- for(i = 0; i < EVOASM_X64_N_REGS; i++) {
636
- if(rb_x64_reg_ids[i] == id) {
637
- return (evoasm_arch_param_val) i;
638
- }
639
- }
640
- rb_raise(rb_eArgError, "invalid value");
641
- break;
642
- }
643
- case T_FIXNUM:
644
- case T_BIGNUM:
645
- return NUM2LL(rb_value);
646
- case T_OBJECT:
647
- return NUM2LL(rb_funcall(rb_value, rb_id_id, 0, NULL));
648
- case T_TRUE:
649
- case T_FALSE:
650
- return (rb_value == Qtrue ? 1 : 0);
651
- default:
652
- rb_raise(rb_eArgError, "invalid key type");
653
- return 0;
654
- }
655
- }
656
-
657
- static evoasm_domain *
658
- rb_domain_to_c(VALUE rb_domain) {
659
- if(rb_obj_is_kind_of(rb_domain, rb_cRange)) {
660
- VALUE rb_beg;
661
- VALUE rb_end;
662
- int exclp;
663
-
664
- evoasm_interval *interval = ALLOC(evoasm_interval);
665
- interval->type = EVOASM_DOMAIN_TYPE_INTERVAL;
666
-
667
- if(rb_range_values(rb_domain, &rb_beg, &rb_end, &exclp) == Qtrue) {
668
- interval->min = NUM2LL(rb_beg);
669
- interval->max = NUM2LL(rb_end);
670
- if(exclp) interval->max--;
671
- }
672
- else {
673
- evoasm_assert_not_reached();
674
- }
675
- return (evoasm_domain *) interval;
676
- } else {
677
- Check_Type(rb_domain, T_ARRAY);
678
-
679
- {
680
- unsigned i;
681
- long len = RARRAY_LEN(rb_domain);
682
- evoasm_enum *enm;
683
-
684
- if(len > EVOASM_ENUM_MAX_LEN) {
685
- rb_raise(rb_eArgError, "array exceeds maximum length of %d", EVOASM_ENUM_MAX_LEN);
686
- return NULL;
687
- }
688
-
689
- enm = xmalloc(EVOASM_ENUM_SIZE(RARRAY_LEN(rb_domain)));
690
- enm->type = EVOASM_DOMAIN_TYPE_ENUM;
691
- enm->len = (uint16_t) len;
692
-
693
- for(i = 0; i < RARRAY_LEN(rb_domain); i++) {
694
- enm->vals[i] = param_val_to_c(RARRAY_AREF(rb_domain, i));
695
- }
696
- return (evoasm_domain *) enm;
697
- }
698
- }
699
- }
700
-
701
- static int
702
- set_domain(VALUE key, VALUE val, VALUE user_data) {
703
- struct arch_with_params *arch_with_params = (struct arch_with_params *) user_data;
704
- evoasm_search_params *search_params = arch_with_params->params;
705
- evoasm_arch_param_id param_id = param_sym_to_c(key, arch_with_params->arch->cls->n_params);
706
- search_params->domains[param_id] = rb_domain_to_c(val);
707
- return ST_CONTINUE;
708
- }
709
-
710
- static void
711
- set_size_param(VALUE rb_size, evoasm_search_params *params, int id) {
712
- unsigned min_size, max_size;
713
-
714
- if(FIXNUM_P(rb_size)) {
715
- min_size = (evoasm_program_size) FIX2UINT(rb_size);
716
- max_size = min_size;
717
- } else {
718
- VALUE rb_beg;
719
- VALUE rb_end;
720
- int exclp;
721
- if(rb_range_values(rb_size, &rb_beg, &rb_end, &exclp) == Qtrue) {
722
- min_size = FIX2UINT(rb_beg);
723
- max_size = FIX2UINT(rb_end);
724
- if(exclp) max_size--;
725
- } else {
726
- rb_raise(rb_eArgError, "invalid program size");
727
- }
728
- }
729
-
730
- if(id == 0) {
731
- params->min_kernel_size = (evoasm_kernel_size) min_size;
732
- params->max_kernel_size = (evoasm_kernel_size) max_size;
733
- } else if(id == 1) {
734
- params->min_program_size = (evoasm_program_size) min_size;
735
- params->max_program_size = (evoasm_program_size) max_size;
736
- } else {
737
- evoasm_assert_not_reached();
738
- }
739
- }
740
-
741
- static VALUE
742
- rb_search_initialize(int argc, VALUE* argv, VALUE self) {
743
- VALUE rb_arch, rb_pop_size, rb_kernel_size, rb_program_size, rb_insts, rb_input, rb_output;
744
- VALUE rb_input_arity, rb_output_arity, rb_params, rb_mutation_rate;
745
- VALUE rb_seed, rb_domains, rb_recur_limit;
746
-
747
- evoasm_search *search;
748
- evoasm_arch *arch;
749
- evoasm_search_params search_params;
750
- evoasm_arch_param_id *params;
751
- evoasm_inst **insts;
752
- unsigned i;
753
- long insts_len;
754
- long params_len;
755
- uint32_t pop_size;
756
- uint32_t mutation_rate;
757
- uint32_t recur_limit;
758
-
759
- evoasm_program_input input;
760
- evoasm_program_input output;
761
-
762
- VALUE *args[] = {
763
- &rb_input,
764
- &rb_input_arity,
765
- &rb_output,
766
- &rb_output_arity,
767
- &rb_arch,
768
- &rb_pop_size,
769
- &rb_kernel_size,
770
- &rb_program_size,
771
- &rb_insts,
772
- &rb_params,
773
- &rb_mutation_rate,
774
- &rb_seed,
775
- &rb_domains,
776
- &rb_recur_limit
777
- };
778
-
779
- if(argc != EVOASM_ARY_LEN(args)) {
780
- rb_error_arity(argc, EVOASM_ARY_LEN(args), EVOASM_ARY_LEN(args));
781
- return Qnil;
782
- }
783
-
784
- for(i = 0; i < (unsigned) argc; i++) {
785
- *args[i] = argv[i];
786
- }
787
-
788
- Check_Type(rb_insts, T_ARRAY);
789
- Check_Type(rb_params, T_ARRAY);
790
- Check_Type(rb_seed, T_ARRAY);
791
- Check_Type(rb_domains, T_HASH);
792
-
793
- TypedData_Get_Struct(self, evoasm_search, &rb_search_type, search);
794
- TypedData_Get_Struct(rb_arch, evoasm_arch, &rb_arch_type, arch);
795
-
796
- insts_len = RARRAY_LEN(rb_insts);
797
- params_len = RARRAY_LEN(rb_params);
798
- pop_size = (uint32_t) FIX2UINT(rb_pop_size);
799
- mutation_rate = (uint32_t)(UINT32_MAX * NUM2DBL(rb_mutation_rate));
800
- recur_limit = (uint32_t)(FIX2UINT(rb_recur_limit));
801
-
802
-
803
- if(RARRAY_LEN(rb_seed) < 64) {
804
- rb_raise(rb_eArgError, "seed must be an array of size at least 64");
805
- }
806
-
807
- if(pop_size % 2) {
808
- rb_raise(rb_eArgError, "poulation size must be even");
809
- return Qnil;
810
- }
811
-
812
- if(insts_len == 0) {
813
- rb_raise(rb_eArgError, "instructions must not be empty");
814
- return Qnil;
815
- }
816
-
817
- if(params_len == 0) {
818
- rb_raise(rb_eArgError, "parameters must not be empty");
819
- return Qnil;
820
- }
821
-
822
- rb_examples_to_c(rb_input, rb_input_arity, &input);
823
- rb_examples_to_c(rb_output, rb_output_arity, &output);
824
-
825
- insts = ZALLOC_N(evoasm_inst *, (size_t) insts_len);
826
- for(i = 0; i < insts_len; i++) {
827
- VALUE elem = RARRAY_AREF(rb_insts, i);
828
- rb_evoasm_inst *inst;
829
- TypedData_Get_Struct(elem, rb_evoasm_inst, &rb_inst_type, inst);
830
- insts[i] = inst->inst;
831
- }
832
-
833
- params = ZALLOC_N(evoasm_arch_param_id, (size_t) params_len);
834
- for(i = 0; i < params_len; i++) {
835
- switch(arch->cls->id) {
836
- case EVOASM_ARCH_X64:
837
- params[i] = (evoasm_arch_param_id) x64_param_sym_to_id(RARRAY_AREF(rb_params, i));
838
- break;
839
- default: evoasm_assert_not_reached();
840
- }
841
- }
842
-
843
- search_params = (evoasm_search_params) {
844
- .pop_size = pop_size,
845
- .insts = insts,
846
- .program_input = input,
847
- .program_output = output,
848
- .insts_len = (uint16_t) insts_len,
849
- .params = params,
850
- .params_len = (uint8_t) params_len,
851
- .mutation_rate = mutation_rate,
852
- .recur_limit = recur_limit
853
- };
854
-
855
- for(i = 0; i < EVOASM_ARY_LEN(search_params.seed32.data); i++) {
856
- search_params.seed32.data[i] = (uint32_t) FIX2UINT(RARRAY_AREF(rb_seed, i));
857
- }
858
-
859
- for(i = 0; i < EVOASM_ARY_LEN(search_params.seed64.data); i++) {
860
- search_params.seed64.data[i] = (uint64_t) NUM2ULL(RARRAY_AREF(rb_seed, i));
861
- }
862
-
863
- set_size_param(rb_kernel_size, &search_params, 0);
864
- set_size_param(rb_program_size, &search_params, 1);
865
-
866
- {
867
- struct arch_with_params user_data = {arch, &search_params};
868
- rb_hash_foreach(rb_domains, set_domain, (VALUE) &user_data);
869
- }
870
-
871
- EVOASM_TRY(raise, evoasm_search_init, search, arch, &search_params);
872
-
873
- return self;
874
-
875
- raise:
876
- evoasm_raise_last_error();
877
- return Qnil;
878
- }
879
-
880
- static const rb_data_type_t rb_op_type = {
881
- "Evoasm::Operand",
882
- {NULL, NULL, NULL,},
883
- NULL, NULL,
884
- RUBY_TYPED_FREE_IMMEDIATELY,
885
- };
886
-
887
- static const rb_data_type_t rb_x64_op_type = {
888
- "Evoasm::X64::Operand",
889
- {NULL, NULL, NULL,},
890
- &rb_op_type, NULL,
891
- RUBY_TYPED_FREE_IMMEDIATELY,
892
- };
893
-
894
- static const rb_data_type_t rb_param_type = {
895
- "Evoasm::Parameter",
896
- {NULL, NULL, NULL,},
897
- NULL, NULL,
898
- RUBY_TYPED_FREE_IMMEDIATELY,
899
- };
900
-
901
- static const rb_data_type_t rb_reg_type = {
902
- "Evoasm::Register",
903
- {NULL, NULL, NULL,},
904
- NULL, NULL,
905
- RUBY_TYPED_FREE_IMMEDIATELY,
906
- };
907
-
908
- static const rb_data_type_t rb_x64_reg_type = {
909
- "Evoasm::::X64::Register",
910
- {NULL, NULL, NULL,},
911
- &rb_reg_type, NULL,
912
- RUBY_TYPED_FREE_IMMEDIATELY,
913
- };
914
-
915
- static void
916
- x64_parameters_aset(evoasm_x64_params *params, VALUE rb_key, VALUE rb_value) {
917
- evoasm_arch_param_id key;
918
- evoasm_arch_param_val param_val = 0;
919
-
920
- key = param_sym_to_c(rb_key, EVOASM_X64_N_PARAMS);
921
- param_val = param_val_to_c(rb_value);
922
-
923
- evoasm_arch_params_set(params->vals, (evoasm_bitmap *) &params->set, key, param_val);
924
- return;
925
- }
926
-
927
- static VALUE
928
- rb_x64_parameters_aset(VALUE self, VALUE rb_key, VALUE rb_value) {
929
- evoasm_x64_params *params;
930
- TypedData_Get_Struct(self, evoasm_x64_params, &rb_x64_params_type, params);
931
-
932
- x64_parameters_aset(params, rb_key, rb_value);
933
- return Qnil;
934
- }
935
-
936
- static VALUE
937
- rb_x64_parameters_aref(VALUE self, VALUE rb_key) {
938
- evoasm_x64_params *params;
939
- evoasm_arch_param_id key = (evoasm_arch_param_id) FIX2UINT(rb_key);
940
- TypedData_Get_Struct(self, evoasm_x64_params, &rb_x64_params_type, params);
941
-
942
- if((unsigned)key >= (unsigned)EVOASM_X64_N_PARAMS) {
943
- rb_raise(rb_eKeyError, "invalid key");
944
- return Qnil;
945
- }
946
-
947
- if(!evoasm_bitmap_get((evoasm_bitmap *) &params->set, key)) {
948
- return Qnil;
949
- } else {
950
- return LL2NUM(params->vals[key]);
951
- }
952
- }
953
-
954
- static int
955
- x64_params_set_kv(VALUE key, VALUE val, VALUE params) {
956
- x64_parameters_aset((evoasm_x64_params *) params, key, val);
957
- return ST_CONTINUE;
958
- }
959
-
960
- static void
961
- x64_params_set_from_hash(evoasm_x64_params *params, VALUE hash) {
962
- rb_hash_foreach(hash, x64_params_set_kv, (VALUE) params);
963
- }
964
-
965
- static VALUE
966
- rb_x64_parameters_initialize(int argc, VALUE *argv, VALUE self) {
967
- evoasm_x64_params *params;
968
- VALUE rb_params;
969
-
970
- TypedData_Get_Struct(self, evoasm_x64_params, &rb_x64_params_type, params);
971
- rb_scan_args(argc, argv, "01", &rb_params);
972
-
973
- if(!NIL_P(rb_params)) {
974
- x64_params_set_from_hash(params, rb_params);
975
- }
976
-
977
- return self;
978
- }
979
-
980
- static void
981
- error_free(void *p) {
982
- evoasm_error *error = (evoasm_error *)p;
983
- (void) error;
984
- xfree(p);
985
- }
986
-
987
- void *realloc_func(void *ptr, size_t size) {
988
- return ruby_xrealloc(ptr, size);
989
- }
990
-
991
-
992
- static ID error_code_unknown;
993
- static ID error_code_not_encodable;
994
- static ID error_code_missing_param;
995
- static ID error_code_invalid_access;
996
- static ID error_code_missing_feature;
997
-
998
- struct result_func_data {
999
- evoasm_program *program;
1000
- evoasm_loss loss;
1001
- evoasm_search *search;
1002
- int tag;
1003
- VALUE block;
1004
- };
1005
-
1006
- static VALUE
1007
- result_func(VALUE user_data) {
1008
-
1009
- struct result_func_data *data = (struct result_func_data *) user_data;
1010
-
1011
- evoasm_loss loss = data->loss;
1012
- evoasm_program tmp_program = *data->program;
1013
-
1014
- /*VALUE proc = (VALUE) user_data;*/
1015
- VALUE rb_program = rb_program_alloc(cProgram);
1016
- VALUE rb_buffer = rb_buffer_alloc(cBuffer);
1017
- VALUE rb_body_buffer = rb_buffer_alloc(cBuffer);
1018
- VALUE rb_kernels = rb_ary_new2(tmp_program.params->size);
1019
-
1020
- assert(data->program->body_buf->pos > 0);
1021
-
1022
- {
1023
- evoasm_buf *buf;
1024
- TypedData_Get_Struct(rb_buffer, evoasm_buf, &rb_buf_type, buf);
1025
- EVOASM_TRY(raise, evoasm_buf_clone, data->program->buf, buf);
1026
- tmp_program.buf = buf;
1027
- }
1028
-
1029
- {
1030
- evoasm_buf *buf;
1031
- TypedData_Get_Struct(rb_body_buffer, evoasm_buf, &rb_buf_type, buf);
1032
- EVOASM_TRY(raise, evoasm_buf_clone, data->program->body_buf, buf);
1033
- tmp_program.body_buf = buf;
1034
- }
1035
-
1036
- {
1037
- unsigned i;
1038
- for(i = 0; i < data->program->params->size; i++) {
1039
- evoasm_kernel *orig_kernel = &data->program->kernels[i];
1040
- rb_evoasm_kernel *kernel;
1041
- size_t params_size;
1042
-
1043
- VALUE rb_kernel = rb_kernel_alloc(cKernel);
1044
- TypedData_Get_Struct(rb_kernel, rb_evoasm_kernel, &rb_kernel_type, kernel);
1045
-
1046
- params_size = sizeof(evoasm_kernel_params) + orig_kernel->params->size * sizeof(evoasm_kernel_param);
1047
- kernel->kernel.params = xmalloc(params_size);
1048
- kernel->params = Qnil;
1049
- kernel->insts = Qnil;
1050
- kernel->program = rb_program;
1051
- memcpy(kernel->kernel.params, data->program->params, params_size);
1052
-
1053
- rb_ary_push(rb_kernels, rb_kernel);
1054
- }
1055
- }
1056
-
1057
- {
1058
- size_t params_size = sizeof(evoasm_program_params);
1059
-
1060
- tmp_program.index = 0;
1061
- tmp_program._signal_ctx = NULL;
1062
- tmp_program.reset_rflags = false;
1063
- tmp_program._input.vals = NULL;
1064
- tmp_program._output.vals = NULL;
1065
- tmp_program.output_vals = NULL;
1066
-
1067
- tmp_program.params = xmalloc(params_size);
1068
- memcpy(tmp_program.params, data->program->params, params_size);
1069
- }
1070
-
1071
- {
1072
- rb_evoasm_program *program;
1073
- TypedData_Get_Struct(rb_program, rb_evoasm_program, &rb_program_type, program);
1074
-
1075
- program->kernels = rb_kernels;
1076
- program->buffer = rb_buffer;
1077
- program->body_buffer = rb_body_buffer;
1078
- program->arch = (VALUE) data->program->arch->user_data;
1079
- program->program = tmp_program;
1080
-
1081
- assert(program->program.body_buf->pos > 0);
1082
- }
1083
-
1084
- {
1085
- VALUE yield_vals[] = {rb_program, rb_float_new(loss)};
1086
- return rb_proc_call(data->block, rb_ary_new_from_values(2, yield_vals));
1087
- }
1088
-
1089
- raise:
1090
- evoasm_raise_last_error();
1091
- return Qnil;
1092
- }
1093
-
1094
-
1095
- static bool
1096
- _result_func(evoasm_program *program, evoasm_loss loss, void *user_data) {
1097
- struct result_func_data *result_data = (struct result_func_data *) user_data;
1098
- VALUE retval;
1099
-
1100
- result_data->loss = loss;
1101
- result_data->program = program;
1102
- result_data->tag = 0;
1103
-
1104
- retval = rb_protect(result_func, (VALUE) result_data, &result_data->tag);
1105
-
1106
- if(result_data->tag != 0 || retval == Qfalse) {
1107
- return false;
1108
- }
1109
-
1110
- return true;
1111
- }
1112
-
1113
-
1114
- static VALUE
1115
- rb_search_start(VALUE self, VALUE rb_max_loss) {
1116
- evoasm_search *search;
1117
- VALUE block;
1118
- struct result_func_data result_data;
1119
- rb_need_block();
1120
-
1121
- TypedData_Get_Struct(self, evoasm_search, &rb_search_type, search);
1122
-
1123
- block = rb_block_proc();
1124
- result_data.block = block;
1125
- result_data.search = search;
1126
-
1127
- evoasm_search_start(search, (evoasm_loss) NUM2DBL(rb_max_loss), _result_func, &result_data);
1128
- if(result_data.tag) {
1129
- rb_jump_tag(result_data.tag);
1130
- }
1131
- return Qnil;
1132
- }
1133
-
1134
-
1135
- static const rb_data_type_t rb_error_type = {
1136
- "Evoasm::Error",
1137
- {NULL, error_free, NULL,},
1138
- NULL, NULL,
1139
- RUBY_TYPED_FREE_IMMEDIATELY,
1140
- };
1141
-
1142
- static const rb_data_type_t rb_arch_error_type = {
1143
- "Evoasm::Architecture::Error",
1144
- {NULL, error_free, NULL,},
1145
- &rb_error_type, NULL,
1146
- RUBY_TYPED_FREE_IMMEDIATELY,
1147
- };
1148
-
1149
-
1150
- void
1151
- evoasm_raise_last_error() {
1152
- VALUE exc;
1153
-
1154
- evoasm_error *error = &evoasm_last_error;
1155
-
1156
- switch(error->type) {
1157
- case EVOASM_ERROR_TYPE_ARCH: {
1158
- evoasm_arch_error *arch_error = ALLOC(evoasm_arch_error);
1159
- *arch_error = *((evoasm_arch_error *)error);
1160
- exc = TypedData_Wrap_Struct(eArchitectureError, &rb_arch_error_type, arch_error);
1161
- break;
1162
- }
1163
- default: {
1164
- evoasm_error *_error = ALLOC(evoasm_error);
1165
- *_error = *error;
1166
- exc = TypedData_Wrap_Struct(eError, &rb_error_type, _error);
1167
- break;
1168
- }
1169
- }
1170
- rb_obj_call_init(exc, 0, NULL);
1171
- rb_exc_raise(exc);
1172
- }
1173
-
1174
-
1175
- static VALUE
1176
- rb_error_code(VALUE self) {
1177
- evoasm_error *error;
1178
- TypedData_Get_Struct(self, evoasm_error, &rb_error_type, error);
1179
-
1180
- switch(error->code) {
1181
- case EVOASM_ERROR_CODE_NONE: return ID2SYM(error_code_unknown);
1182
- default: return Qnil;
1183
- }
1184
- }
1185
-
1186
-
1187
- static VALUE
1188
- rb_error_message(VALUE self) {
1189
- evoasm_error *error;
1190
- size_t len;
1191
- TypedData_Get_Struct(self, evoasm_error, &rb_error_type, error);
1192
-
1193
- if(error->msg[0] == '\0') {
1194
- return Qnil;
1195
- }
1196
-
1197
- len = strnlen(error->msg, EVOASM_ERROR_MAX_MSG_LEN);
1198
- return rb_str_new(error->msg, (long) len);
1199
- }
1200
-
1201
- static VALUE
1202
- rb_architecture_error_code(VALUE self) {
1203
- evoasm_arch_error *error;
1204
- TypedData_Get_Struct(self, evoasm_arch_error, &rb_arch_error_type, error);
1205
-
1206
- switch(error->code) {
1207
- case EVOASM_ARCH_ERROR_CODE_NOT_ENCODABLE: return ID2SYM(error_code_not_encodable);
1208
- case EVOASM_ARCH_ERROR_CODE_MISSING_PARAM: return ID2SYM(error_code_missing_param);
1209
- case EVOASM_ARCH_ERROR_CODE_INVALID_ACCESS: return ID2SYM(error_code_invalid_access);
1210
- case EVOASM_ARCH_ERROR_CODE_MISSING_FEATURE: return ID2SYM(error_code_missing_feature);
1211
- default: return rb_error_code(self);
1212
- }
1213
- }
1214
-
1215
- static VALUE
1216
- rb_architecture_error_parameter(VALUE self) {
1217
- evoasm_arch_error *error;
1218
- TypedData_Get_Struct(self, evoasm_arch_error, &rb_arch_error_type, error);
1219
-
1220
- if(error->code == EVOASM_ARCH_ERROR_CODE_MISSING_PARAM) {
1221
- switch(error->data.arch->cls->id) {
1222
- case EVOASM_ARCH_X64: return ID2SYM(rb_x64_param_ids[error->data.param]);
1223
- default: evoasm_assert_not_reached();
1224
- }
1225
- }
1226
- else {
1227
- return Qnil;
1228
- }
1229
- }
1230
-
1231
- static VALUE
1232
- rb_architecture_error_register(VALUE self) {
1233
- evoasm_arch_error *error;
1234
- TypedData_Get_Struct(self, evoasm_arch_error, &rb_arch_error_type, error);
1235
-
1236
- if(error->code == EVOASM_ARCH_ERROR_CODE_INVALID_ACCESS) {
1237
- switch(error->data.arch->cls->id) {
1238
- case EVOASM_ARCH_X64: return ID2SYM(rb_x64_reg_ids[error->data.reg]);
1239
- default: evoasm_assert_not_reached();
1240
- }
1241
- }
1242
- else {
1243
- return Qnil;
1244
- }
1245
- }
1246
-
1247
- static VALUE
1248
- rb_architecture_error_instruction(VALUE self) {
1249
- evoasm_arch_error *error;
1250
- TypedData_Get_Struct(self, evoasm_arch_error, &rb_arch_error_type, error);
1251
-
1252
- if(error->code == EVOASM_ARCH_ERROR_CODE_INVALID_ACCESS) {
1253
- switch(error->data.arch->cls->id) {
1254
- case EVOASM_ARCH_X64: return ID2SYM(rb_x64_inst_ids[error->data.inst]);
1255
- default: evoasm_assert_not_reached();
1256
- }
1257
- }
1258
- else {
1259
- return Qnil;
1260
- }
1261
- }
1262
-
1263
- static VALUE
1264
- rb_architecture_error_architecture(VALUE self) {
1265
- evoasm_arch_error *error;
1266
- TypedData_Get_Struct(self, evoasm_arch_error, &rb_arch_error_type, error);
1267
-
1268
- if(error->data.arch->user_data != NULL) {
1269
- return (VALUE) error->data.arch->user_data;
1270
- }
1271
- else {
1272
- evoasm_assert_not_reached();
1273
- }
1274
- }
1275
-
1276
- static VALUE
1277
- rb_x64_alloc(VALUE klass) {
1278
- evoasm_x64 *x64 = xmalloc(sizeof(evoasm_x64));
1279
-
1280
- return TypedData_Wrap_Struct(klass, &rb_x64_type, x64);
1281
- }
1282
-
1283
- static VALUE
1284
- rb_x64_initialize(VALUE self) {
1285
- evoasm_x64 *x64;
1286
- TypedData_Get_Struct(self, evoasm_x64, &rb_x64_type, x64);
1287
-
1288
- EVOASM_TRY(raise, evoasm_x64_init, x64);
1289
- ((evoasm_arch *)x64)->user_data = (void *) self;
1290
-
1291
- return self;
1292
-
1293
- raise:
1294
- evoasm_raise_last_error();
1295
- return Qnil;
1296
- }
1297
-
1298
- static VALUE
1299
- x64_instruction_encode(evoasm_x64_inst *inst, evoasm_x64 *x64, VALUE rb_params) {
1300
- evoasm_x64_params *params;
1301
- evoasm_x64_params _params = {0};
1302
- evoasm_arch *arch = (evoasm_arch *) x64;
1303
- VALUE rb_str;
1304
-
1305
- switch(TYPE(rb_params)) {
1306
- case T_DATA:
1307
- TypedData_Get_Struct(rb_params, evoasm_x64_params, &rb_x64_params_type, params);
1308
- break;
1309
- case T_HASH:
1310
- x64_params_set_from_hash(&_params, rb_params);
1311
- params = &_params;
1312
- break;
1313
- default:
1314
- rb_raise(rb_eArgError, "parameters must be hash or Evoasm::X64::Parameters");
1315
- return Qnil;
1316
- }
1317
-
1318
- EVOASM_TRY(raise, evoasm_inst_encode, (evoasm_inst *)inst, arch, params->vals, (evoasm_bitmap *) &params->set);
1319
-
1320
- rb_str = rb_usascii_str_new((char *)(arch->buf + arch->buf_start),
1321
- (long) (arch->buf_end - arch->buf_start));
1322
- evoasm_arch_reset(arch);
1323
- return rb_str;
1324
-
1325
- raise:
1326
- evoasm_raise_last_error();
1327
- return Qnil;
1328
-
1329
- }
1330
-
1331
- static VALUE
1332
- rb_x64_encode(int argc, VALUE *argv, VALUE self) {
1333
- evoasm_x64 *x64;
1334
- unsigned i;
1335
- ID id;
1336
- VALUE rb_params;
1337
- VALUE rb_inst_name;
1338
- evoasm_x64_inst *inst = NULL;
1339
-
1340
- rb_scan_args(argc, argv, "2", &rb_inst_name, &rb_params);
1341
-
1342
- Check_Type(rb_inst_name, T_SYMBOL);
1343
- Check_Type(rb_params, T_HASH);
1344
- id = SYM2ID(rb_inst_name);
1345
-
1346
- TypedData_Get_Struct(self, evoasm_x64, &rb_x64_type, x64);
1347
-
1348
- for(i = 0; i < EVOASM_X64_N_INSTS; i++) {
1349
- if(rb_x64_inst_ids[i] == id) {
1350
- inst = (evoasm_x64_inst *) evoasm_x64_get_inst(x64, i, true);
1351
- break;
1352
- }
1353
- }
1354
-
1355
- if(inst == NULL) {
1356
- rb_raise(rb_eArgError, "unknown instruction");
1357
- return Qnil;
1358
- }
1359
-
1360
- return x64_instruction_encode(inst, x64, rb_params);
1361
- }
1362
-
1363
- static VALUE
1364
- rb_x64_register_id(VALUE self) {
1365
- evoasm_x64_operand *op;
1366
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_reg_type, op);
1367
- return UINT2NUM(op->reg_id);
1368
- }
1369
-
1370
- static VALUE
1371
- rb_x64_register_name(VALUE self) {
1372
- evoasm_x64_operand *op;
1373
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_reg_type, op);
1374
- if(op->reg_id < EVOASM_X64_N_REGS) {
1375
- return ID2SYM(rb_x64_reg_ids[op->reg_id]);
1376
- }
1377
- else {
1378
- return Qnil;
1379
- }
1380
- }
1381
-
1382
- static VALUE
1383
- rb_x64_register_type(VALUE self) {
1384
- evoasm_x64_operand *op;
1385
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_reg_type, op);
1386
- return ID2SYM(rb_x64_reg_type_ids[op->reg_type]);
1387
- }
1388
-
1389
- static VALUE
1390
- rb_x64_operand_type(VALUE self) {
1391
- evoasm_x64_operand *op;
1392
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_op_type, op);
1393
-
1394
- return ID2SYM(rb_x64_operand_type_ids[op->type]);
1395
- }
1396
-
1397
- static VALUE
1398
- rb_x64_operand_written_p(VALUE self) {
1399
- evoasm_x64_operand *op;
1400
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_op_type, op);
1401
-
1402
- return op->acc_w ? Qtrue : Qfalse;
1403
- }
1404
-
1405
- static VALUE
1406
- rb_x64_operand_read_p(VALUE self) {
1407
- evoasm_x64_operand *op;
1408
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_op_type, op);
1409
-
1410
- return op->acc_r ? Qtrue : Qfalse;
1411
- }
1412
-
1413
- static VALUE
1414
- rb_x64_operand_register(VALUE self) {
1415
- evoasm_x64_operand *op;
1416
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_op_type, op);
1417
-
1418
- if(op->type == EVOASM_X64_OPERAND_TYPE_REG ||
1419
- op->type == EVOASM_X64_OPERAND_TYPE_RM) {
1420
- VALUE rb_reg = TypedData_Wrap_Struct(cX64Register, &rb_x64_reg_type, op);
1421
- return rb_reg;
1422
- }
1423
-
1424
- return Qnil;
1425
- }
1426
-
1427
- static VALUE
1428
- rb_x64_operand_size(VALUE self) {
1429
- evoasm_x64_operand *op;
1430
- TypedData_Get_Struct(self, evoasm_x64_operand, &rb_x64_op_type, op);
1431
-
1432
- switch(op->size) {
1433
- case EVOASM_OPERAND_SIZE_1: return INT2FIX(1);
1434
- case EVOASM_OPERAND_SIZE_8: return INT2FIX(8);
1435
- case EVOASM_OPERAND_SIZE_16: return INT2FIX(16);
1436
- case EVOASM_OPERAND_SIZE_32: return INT2FIX(32);
1437
- case EVOASM_OPERAND_SIZE_64: return INT2FIX(64);
1438
- case EVOASM_OPERAND_SIZE_128: return INT2FIX(128);
1439
- case EVOASM_OPERAND_SIZE_256: return INT2FIX(256);
1440
- case EVOASM_OPERAND_SIZE_512: return INT2FIX(512);
1441
- default: return Qnil;
1442
- }
1443
- return Qnil;
1444
- }
1445
-
1446
- static VALUE
1447
- rb_parameter_name(VALUE self) {
1448
- evoasm_arch_param *param;
1449
- TypedData_Get_Struct(self, evoasm_arch_param, &rb_param_type, param);
1450
- return ID2SYM(rb_x64_param_ids[param->id]);
1451
- }
1452
-
1453
- static VALUE
1454
- rb_parameter_id(VALUE self) {
1455
- evoasm_arch_param *param;
1456
- TypedData_Get_Struct(self, evoasm_arch_param, &rb_param_type, param);
1457
- return UINT2NUM(param->id);
1458
- }
1459
-
1460
- static VALUE
1461
- rb_domain_to_rb(evoasm_domain *domain) {
1462
- VALUE rb_domain;
1463
-
1464
- switch(domain->type) {
1465
- case EVOASM_DOMAIN_TYPE_INTERVAL: {
1466
- evoasm_interval *interval = (evoasm_interval *) domain;
1467
- rb_domain = rb_range_new(LL2NUM(interval->min), LL2NUM(interval->max), false);
1468
- break;
1469
- }
1470
- case EVOASM_DOMAIN_TYPE_ENUM: {
1471
- evoasm_enum *enm = (evoasm_enum *) domain;
1472
- uint16_t j;
1473
- VALUE *enm_vals = ALLOCA_N(VALUE, enm->len);
1474
- for(j = 0; j < enm->len; j++) {
1475
- enm_vals[j] = LL2NUM(enm->vals[j]);
1476
- }
1477
- rb_domain = rb_ary_new_from_values(enm->len, enm_vals);
1478
- break;
1479
- }
1480
- default: evoasm_assert_not_reached();
1481
- }
1482
-
1483
- return rb_domain;
1484
- }
1485
-
1486
- static VALUE
1487
- rb_parameter_domain(VALUE self) {
1488
- evoasm_arch_param *param;
1489
- evoasm_domain *domain;
1490
- VALUE rb_domain;
1491
-
1492
- TypedData_Get_Struct(self, evoasm_arch_param, &rb_param_type, param);
1493
-
1494
- domain = param->domain;
1495
- rb_domain = RARRAY_AREF(domains_cache, domain->index);
1496
-
1497
- if(NIL_P(rb_domain)) {
1498
- rb_domain = rb_domain_to_rb(domain);
1499
- rb_obj_freeze(rb_domain);
1500
- }
1501
- RARRAY_ASET(domains_cache, domain->index, rb_domain);
1502
- return rb_domain;
1503
- }
1504
-
1505
-
1506
- static VALUE
1507
- rb_architecture_instructions(VALUE self) {
1508
- evoasm_arch *arch;
1509
- evoasm_inst **insts;
1510
- uint16_t len, i;
1511
- VALUE *vals;
1512
-
1513
- TypedData_Get_Struct(self, evoasm_arch, &rb_arch_type, arch);
1514
- insts = ALLOCA_N(evoasm_inst *, arch->cls->n_insts);
1515
- len = evoasm_arch_insts(arch, (const evoasm_inst **) insts);
1516
- if(len == 0) return Qnil;
1517
-
1518
- vals = ALLOCA_N(VALUE, len);
1519
-
1520
- for(i = 0; i < len; i++) {
1521
- switch(arch->cls->id) {
1522
- case EVOASM_ARCH_X64: {
1523
- rb_evoasm_x64_inst *inst = ALLOC(rb_evoasm_x64_inst);
1524
- inst->arch = self;
1525
- inst->inst = (evoasm_x64_inst *) insts[i];
1526
- vals[i] = TypedData_Wrap_Struct(evoasm_cX64Instruction, &rb_x64_inst_type, inst);
1527
- break;
1528
- }
1529
- default: evoasm_assert_not_reached();
1530
- }
1531
- }
1532
-
1533
- return rb_ary_new_from_values(len, vals);
1534
- }
1535
-
1536
- static VALUE
1537
- rb_instruction_id(VALUE self) {
1538
- rb_evoasm_inst *inst;
1539
- TypedData_Get_Struct(self, rb_evoasm_inst, &rb_inst_type, inst);
1540
-
1541
- return UINT2NUM(inst->inst->id);
1542
- }
1543
-
1544
- static VALUE
1545
- rb_x64_instruction_flags(VALUE self) {
1546
- rb_evoasm_x64_inst *inst;
1547
- TypedData_Get_Struct(self, rb_evoasm_x64_inst, &rb_x64_inst_type, inst);
1548
-
1549
- return ULL2NUM(inst->inst->flags);
1550
- }
1551
-
1552
-
1553
- static VALUE
1554
- rb_x64_instruction_operands(VALUE self) {
1555
- rb_evoasm_x64_inst *inst;
1556
- unsigned i;
1557
- VALUE *vals;
1558
-
1559
- TypedData_Get_Struct(self, rb_evoasm_x64_inst, &rb_x64_inst_type, inst);
1560
-
1561
- if(inst->inst->n_operands == 0) {
1562
- return rb_ary_new();
1563
- }
1564
-
1565
- vals = ALLOC_N(VALUE, inst->inst->n_operands);
1566
-
1567
- for(i = 0; i < inst->inst->n_operands; i++) {
1568
- vals[i] = TypedData_Wrap_Struct(cX64Operand, &rb_x64_op_type, (void *)&inst->inst->operands[i]);
1569
- }
1570
- return rb_ary_new_from_values(inst->inst->n_operands, vals);
1571
- }
1572
-
1573
- static VALUE
1574
- rb_x64_instruction_features(VALUE self) {
1575
- rb_evoasm_x64_inst *inst;
1576
- TypedData_Get_Struct(self, rb_evoasm_x64_inst, &rb_x64_inst_type, inst);
1577
-
1578
- return ULL2NUM(inst->inst->features);
1579
- }
1580
-
1581
- static VALUE
1582
- rb_x64_instruction_name(VALUE self) {
1583
- rb_evoasm_x64_inst *inst;
1584
- TypedData_Get_Struct(self, rb_evoasm_x64_inst, &rb_inst_type, inst);
1585
-
1586
- return ID2SYM(rb_x64_inst_ids[((evoasm_inst *)inst->inst)->id]);
1587
- }
1588
-
1589
- static VALUE
1590
- rb_x64_instruction_encode(VALUE self, VALUE rb_params) {
1591
- rb_evoasm_x64_inst *inst;
1592
- evoasm_x64 *x64;
1593
-
1594
- TypedData_Get_Struct(self, rb_evoasm_x64_inst, &rb_x64_inst_type, inst);
1595
- TypedData_Get_Struct(inst->arch, evoasm_x64, &rb_x64_type, x64);
1596
-
1597
- return x64_instruction_encode(inst->inst, x64, rb_params);
1598
- }
1599
-
1600
- static VALUE
1601
- rb_instruction_parameters(VALUE self) {
1602
- rb_evoasm_inst *inst;
1603
- uint16_t i;
1604
- VALUE *vals;
1605
-
1606
- TypedData_Get_Struct(self, rb_evoasm_inst, &rb_inst_type, inst);
1607
-
1608
- if(inst->inst->params_len == 0) {
1609
- return rb_ary_new();
1610
- }
1611
-
1612
- vals = ALLOC_N(VALUE, inst->inst->params_len);
1613
-
1614
- for(i = 0; i < inst->inst->params_len; i++) {
1615
- vals[i] = TypedData_Wrap_Struct(cParameter, &rb_param_type, (void *)&inst->inst->params[i]);
1616
- }
1617
- return rb_ary_new_from_values(inst->inst->params_len, vals);
1618
- }
1619
-
1620
- VALUE rb_evoasm_log_level;
1621
-
1622
- static VALUE
1623
- rb_evoasm_log_level_set(VALUE self, VALUE level) {
1624
- evoasm_log_level prev_level = evoasm_min_log_level;
1625
- evoasm_min_log_level = (evoasm_log_level)
1626
- EVOASM_CLAMP(FIX2INT(level),
1627
- EVOASM_MIN_LOG_LEVEL, EVOASM_N_LOG_LEVELS - 1);
1628
-
1629
- fprintf(stderr, "%d\n", evoasm_min_log_level);
1630
- return INT2FIX(prev_level);
1631
- }
1632
-
1633
- extern const uint16_t evoasm_n_domains;
1634
-
1635
- void Init_evoasm_ext() {
1636
- mEvoasm = rb_define_module("Evoasm");
1637
-
1638
- cArchitecture = rb_define_class_under(mEvoasm, "Architecture", rb_cData);
1639
- cX64 = rb_define_class_under(mEvoasm, "X64", cArchitecture);
1640
- cParameter = rb_define_class_under(mEvoasm, "Parameter", rb_cData);
1641
- cRegister = rb_define_class_under(mEvoasm, "Register", rb_cData);
1642
- cX64Register = rb_define_class_under(cX64, "Register", cRegister);
1643
- cOperand = rb_define_class_under(mEvoasm, "Operand", rb_cData);
1644
- cX64Operand = rb_define_class_under(cX64, "Operand", cOperand);
1645
- cBuffer = rb_define_class_under(mEvoasm, "Buffer", rb_cData);
1646
- cSearch = rb_define_class_under(mEvoasm, "Search", rb_cData);
1647
- cProgram = rb_define_class_under(mEvoasm, "Program", rb_cData);
1648
- cKernel = rb_define_class_under(mEvoasm, "Kernel", rb_cData);
1649
- cParameters = rb_define_class_under(mEvoasm, "Parameters", rb_cData);
1650
- cX64Parameters = rb_define_class_under(cX64, "Parameters", cParameters);
1651
- cInstruction = rb_define_class_under(mEvoasm, "Instruction", rb_cData);
1652
- evoasm_cX64Instruction = rb_define_class_under(cX64, "Instruction", cInstruction);
1653
-
1654
- rb_define_singleton_method(mEvoasm, "log_level=", rb_evoasm_log_level_set, 1);
1655
-
1656
- eError = rb_define_class_under(mEvoasm, "Error", rb_eStandardError);
1657
- eArchitectureError = rb_define_class_under(cArchitecture, "Error", eError);
1658
- rb_define_method(eError, "code", RUBY_METHOD_FUNC(rb_error_code), 0);
1659
- rb_define_method(eError, "__message", RUBY_METHOD_FUNC(rb_error_message), 0);
1660
- rb_define_method(eArchitectureError, "code", RUBY_METHOD_FUNC(rb_architecture_error_code), 0);
1661
- rb_define_method(eArchitectureError, "parameter", RUBY_METHOD_FUNC(rb_architecture_error_parameter), 0);
1662
- rb_define_method(eArchitectureError, "register", RUBY_METHOD_FUNC(rb_architecture_error_register), 0);
1663
- rb_define_method(eArchitectureError, "instruction", RUBY_METHOD_FUNC(rb_architecture_error_instruction), 0);
1664
- rb_define_method(eArchitectureError, "architecture", RUBY_METHOD_FUNC(rb_architecture_error_architecture), 0);
1665
-
1666
- evoasm_x64_ruby_define_consts();
1667
-
1668
- error_code_unknown = rb_intern("unknown");
1669
- error_code_not_encodable = rb_intern("not_encodable");
1670
- error_code_missing_param = rb_intern("missing_param");
1671
- error_code_invalid_access = rb_intern("invalid_access");
1672
- error_code_missing_feature = rb_intern("missing_feature");
1673
-
1674
- rb_define_alloc_func(cBuffer, rb_buffer_alloc);
1675
- rb_define_method(cBuffer, "initialize", rb_buffer_initialize, -1);
1676
- rb_define_method(cBuffer, "size", RUBY_METHOD_FUNC(rb_buffer_size), 0);
1677
- rb_define_method(cBuffer, "reset!", RUBY_METHOD_FUNC(rb_buffer_reset), 0);
1678
- rb_define_method(cBuffer, "to_s", RUBY_METHOD_FUNC(rb_buffer_to_s), 0);
1679
- #ifdef HAVE_CAPSTONE_CAPSTONE_H
1680
- rb_define_method(cBuffer, "disassemble", rb_buffer_disassemble, 0);
1681
- #endif
1682
-
1683
- rb_define_alloc_func(cSearch, rb_search_alloc);
1684
- rb_define_private_method(cSearch, "__initialize__", rb_search_initialize, -1);
1685
- rb_define_method(cSearch, "start!", rb_search_start, 1);
1686
-
1687
- #if 0
1688
- rb_define_method(cX64, "rw!", RUBY_METHOD_FUNC(rb_buffer_rw), 0);
1689
- rb_define_method(cX64, "rx!", RUBY_METHOD_FUNC(rb_buffer_rx), 0);
1690
- #endif
1691
-
1692
- rb_define_alloc_func(cProgram, rb_program_alloc);
1693
- rb_define_method(cProgram, "buffer", rb_program_buffer, -1);
1694
- rb_define_method(cProgram, "kernels", rb_program_kernels, 0);
1695
- rb_define_private_method(cProgram, "__run__", rb_program_run, 2);
1696
- rb_define_method(cProgram, "eliminate_introns!", rb_program_eliminate_introns_bang, 0);
1697
- rb_define_method(cProgram, "output_registers", rb_program_output_registers, 0);
1698
-
1699
- rb_define_alloc_func(cKernel, rb_kernel_alloc);
1700
- rb_define_method(cKernel, "parameters", rb_kernel_parameters, 0);
1701
- rb_define_method(cKernel, "instructions", rb_kernel_instructions, 0);
1702
-
1703
- rb_define_method(cParameter, "domain", rb_parameter_domain, 0);
1704
- rb_define_method(cParameter, "name", rb_parameter_name, 0);
1705
- rb_define_method(cParameter, "id", rb_parameter_id, 0);
1706
-
1707
- rb_define_method(cX64Register, "id", rb_x64_register_id, 0);
1708
- rb_define_method(cX64Register, "name", rb_x64_register_name, 0);
1709
- rb_define_method(cX64Register, "type", rb_x64_register_type, 0);
1710
-
1711
- rb_define_method(cX64Operand, "type", rb_x64_operand_type, 0);
1712
- rb_define_method(cX64Operand, "written?", rb_x64_operand_written_p, 0);
1713
- rb_define_method(cX64Operand, "read?", rb_x64_operand_read_p, 0);
1714
- rb_define_method(cX64Operand, "register", rb_x64_operand_register, 0);
1715
- rb_define_method(cX64Operand, "size", rb_x64_operand_size, 0);
1716
-
1717
- rb_define_method(cInstruction, "id", rb_instruction_id, 0);
1718
- rb_define_method(cInstruction, "parameters", rb_instruction_parameters, 0);
1719
-
1720
- rb_define_method(evoasm_cX64Instruction, "encode", rb_x64_instruction_encode, 0);
1721
- rb_define_method(evoasm_cX64Instruction, "name", rb_x64_instruction_name, 0);
1722
- rb_define_method(evoasm_cX64Instruction, "flags", rb_x64_instruction_flags, 0);
1723
- rb_define_method(evoasm_cX64Instruction, "features", rb_x64_instruction_features, 0);
1724
- rb_define_method(evoasm_cX64Instruction, "operands", rb_x64_instruction_operands, 0);
1725
-
1726
- rb_define_alloc_func(cX64, rb_x64_alloc);
1727
- rb_define_method(cX64, "initialize", rb_x64_initialize, 0);
1728
- rb_define_method(cX64, "encode", rb_x64_encode, -1);
1729
- #ifdef HAVE_CAPSTONE_CAPSTONE_H
1730
- rb_define_singleton_method(cX64, "disassemble", rb_x64_s_disassemble, 1);
1731
- #endif
1732
-
1733
- rb_define_method(cArchitecture, "instructions", RUBY_METHOD_FUNC(rb_architecture_instructions), 0);
1734
-
1735
- rb_define_alloc_func(cX64Parameters, rb_x64_parameters_alloc);
1736
- rb_define_method(cX64Parameters, "initialize", rb_x64_parameters_initialize, -1);
1737
-
1738
- rb_define_method(cX64Parameters, "[]=", RUBY_METHOD_FUNC(rb_x64_parameters_aset), 2);
1739
- rb_define_method(cX64Parameters, "[]", RUBY_METHOD_FUNC(rb_x64_parameters_aref), 1);
1740
-
1741
- rb_define_const(mEvoasm,
1742
- "ARCH_X64", UINT2NUM(EVOASM_ARCH_X64));
1743
-
1744
- domains_cache = rb_ary_new2(evoasm_n_domains);
1745
- rb_ary_resize(domains_cache, evoasm_n_domains);
1746
- rb_gc_register_address(&domains_cache);
1747
-
1748
- instructions_cache = rb_ary_new2(EVOASM_X64_N_INSTS);
1749
- rb_ary_resize(instructions_cache, EVOASM_X64_N_INSTS);
1750
- rb_gc_register_address(&instructions_cache);
1751
-
1752
- rb_id_brute_force = rb_intern("brute_force");
1753
- rb_id_genetic = rb_intern("genetic");
1754
- rb_id_id = rb_intern("id");
1755
-
1756
- evoasm_init(0, NULL, stderr);
1757
- }