fisk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 51dd7fb660158423e9c8acde6889de5304d01c7ffc305c3e0cfbf7fff0039acf
4
+ data.tar.gz: fd1a616b882af138d6016f30018937b7359f9c06e46243fdf55f6c3d5ace618d
5
+ SHA512:
6
+ metadata.gz: 922a53a72a875ec8e225b97e51c55f905944f0bb927496691471dc395536bbe2072bea424862814a08d22fd955d5c3dab820faa5c61e50d8f5ca57dd61cfcf12
7
+ data.tar.gz: 46336f3830380629188494a3784a01217d69a3e9fab48d41dff73300ca10fb3298d814cb20a6e0b62442fc2749036e5c4780f3789e16134fb0a0364b822aef8b
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "minitest"
4
+ gem "crabstone"
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2021 Aaron Patterson
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Fisk - A Pure Ruby Assembler
2
+
3
+ This is a pure Ruby assembler (I guess). I'm not 100% sure if it counts as
4
+ pure Ruby because it just reads an XML file and metaprograms most of it.
5
+ Anyway, you can use it to write assembly in Ruby, then have it assembled.
6
+
7
+ I named it after Wilson Fisk mainly because it reminds me of [this
8
+ project](https://github.com/seattlerb/wilson) and because I've been playing
9
+ lots of Spider-Man.
10
+
11
+ ## Usage
12
+
13
+ Here is an example of assembling something:
14
+
15
+ ```ruby
16
+ fisk = Fisk.new
17
+
18
+ binary = fisk.asm do
19
+ push rbp
20
+ mov rbp, rsp
21
+ int lit(3)
22
+ pop rbp
23
+ ret
24
+ end
25
+ ```
26
+
27
+ Though, it's not very fun to assemble something unless you can execute it. So
28
+ here is an example of how to execute the above assembly. This assembly code
29
+ will send an interrupt and tell the debugger to stop. So let's write the
30
+ machine code to some executable memory, and call it from a Ruby program that we
31
+ will start in lldb.
32
+
33
+ ```ruby
34
+ require "fisk"
35
+ require "fisk/helpers"
36
+
37
+ module Break
38
+ fisk = Fisk.new
39
+
40
+ jitbuf = Fisk::Helpers.jitbuffer 4096
41
+
42
+ fisk.asm(jitbuf) do
43
+ push rbp
44
+ mov rbp, rsp
45
+ int lit(3)
46
+ pop rbp
47
+ ret
48
+ end
49
+
50
+ define_singleton_method :dance!, &jitbuf.to_function([], Fiddle::TYPE_VOID)
51
+ end
52
+
53
+ def deep i = 2
54
+ if i == 0
55
+ Break.dance!
56
+ else
57
+ deep(i - 1)
58
+ end
59
+ end
60
+
61
+ deep
62
+ ```
63
+
64
+ If we launch this script under lldb, the debugger will halt the process when we call the `dance!` method:
65
+
66
+ ```
67
+ [aaron@tc-lan-adapter ~/g/fisk (master)]$ lldb ~/git/ruby/ruby -- -I lib fun.rb
68
+ error: module importing failed: invalid pathname
69
+ (lldb) target create "/Users/aaron/git/ruby/ruby"
70
+ procCurrent executable set to '/Users/aaron/git/ruby/ruby' (x86_64).
71
+ (lldb) settings set -- target.run-args "-I" "lib" "fun.rb"
72
+ (lldb) process launch
73
+ Process 33042 launched: '/Users/aaron/git/ruby/ruby' (x86_64)
74
+ Process 33042 stopped
75
+ * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
76
+ frame #0: 0x00000001007f4005
77
+ -> 0x1007f4005: popq %rbp
78
+ 0x1007f4006: retq
79
+ 0x1007f4007: addb %al, (%rax)
80
+ 0x1007f4009: addb %al, (%rax)
81
+ Target 0: (ruby) stopped.
82
+ (lldb) bt
83
+ * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
84
+ * frame #0: 0x00000001007f4005
85
+ frame #1: 0x00007fff2db538e5 libffi.dylib`ffi_call_unix64 + 85
86
+ frame #2: 0x00007fff2db5322a libffi.dylib`ffi_call_int + 692
87
+ frame #3: 0x0000000107458e3d fiddle.bundle`nogvl_ffi_call(ptr=0x00007ffeefbf9bb0) at function.c:204:5
88
+ frame #4: 0x00000001002e704f ruby`rb_nogvl(func=(fiddle.bundle`nogvl_ffi_call at function.c:201), data1=0x00007ffeefbf9bb0, ubf=0x0000000000000000, data2=0x0000000000000000, flags=0) at thread.c:1671:5
89
+ frame #5: 0x00000001002e7570 ruby`rb_thread_call_without_gvl(func=(fiddle.bundle`nogvl_ffi_call at function.c:201), data1=0x00007ffeefbf9bb0, ubf=0x0000000000000000, data2=0x0000000000000000) at thread.c:1787:12
90
+ frame #6: 0x00000001074585a6 fiddle.bundle`function_call(argc=0, argv=0x00000001080280c8, self=0x0000000128f85fd8) at function.c:375:15
91
+ frame #7: 0x0000000100383ca7 ruby`call_cfunc_m1(recv=0x0000000128f85fd8, argc=0, argv=0x00000001080280c8, func=(fiddle.bundle`function_call at function.c:211)) at vm_insnhelper.c:2594:12
92
+ frame #8: 0x000000010037ef99 ruby`vm_call_cfunc_with_frame(ec=0x0000000100b069b0, reg_cfp=0x0000000108127eb0, calling=0x00007ffeefbfa030) at vm_insnhelper.c:2924:11
93
+ frame #9: 0x0000000100377603 ruby`vm_call_cfunc(ec=0x0000000100b069b0, reg_cfp=0x0000000108127eb0, calling=0x00007ffeefbfa030) at vm_insnhelper.c:2945:12
94
+ frame #10: 0x0000000100376f2b ruby`vm_call_method_each_type(ec=0x0000000100b069b0, cfp=0x0000000108127eb0, calling=0x00007ffeefbfa030) at vm_insnhelper.c:3414:16
95
+ frame #11: 0x00000001003769e9 ruby`vm_call_method(ec=0x0000000100b069b0, cfp=0x0000000108127eb0, calling=0x00007ffeefbfa030) at vm_insnhelper.c:3507:20
96
+ frame #12: 0x00000001003578f5 ruby`vm_call_general(ec=0x0000000100b069b0, reg_cfp=0x0000000108127eb0, calling=0x00007ffeefbfa030) at vm_insnhelper.c:3550:12
97
+ frame #13: 0x000000010036d688 ruby`vm_sendish(ec=0x0000000100b069b0, reg_cfp=0x0000000108127eb0, cd=0x0000000100e2be30, block_handler=0x0000000000000000, method_explorer=mexp_search_method) at vm_insnhelper.c:4525:15
98
+ frame #14: 0x000000010033f3de ruby`vm_exec_core(ec=0x0000000100b069b0, initial=0x0000000000000000) at insns.def:789:11
99
+ frame #15: 0x0000000100361d6e ruby`rb_vm_exec(ec=0x0000000100b069b0, mjit_enable_p=true) at vm.c:2162:22
100
+ frame #16: 0x00000001003884c5 ruby`invoke_bmethod(ec=0x0000000100b069b0, iseq=0x000000010781d168, self=0x0000000128f7d180, captured=0x00000001294ef620, me=0x0000000128f85f10, type=0x0000000022220101, opt_pc=0) at vm.c:1292:11
101
+ frame #17: 0x0000000100360321 ruby`rb_vm_invoke_bmethod [inlined] invoke_iseq_block_from_c(ec=0x0000000100b069b0, captured=0x00000001294ef620, self=0x0000000128f7d180, argc=0, argv=0x00007ffeefbfcab0, kw_splat=0, passed_block_handler=0x0000000000000000, cref=0x0000000000000000, is_lambda=1, me=0x0000000128f85f10) at vm.c:1337:9
102
+ frame #18: 0x000000010036017d ruby`rb_vm_invoke_bmethod [inlined] invoke_block_from_c_proc(ec=0x0000000100b069b0, proc=0x00000001294ef620, self=0x0000000128f7d180, argc=0, argv=0x00007ffeefbfcab0, kw_splat=0, passed_block_handler=0x0000000000000000, is_lambda=1, me=0x0000000128f85f10) at vm.c:1434
103
+ frame #19: 0x00000001003600cf ruby`rb_vm_invoke_bmethod(ec=0x0000000100b069b0, proc=0x00000001294ef620, self=0x0000000128f7d180, argc=0, argv=0x00007ffeefbfcab0, kw_splat=0, block_handler=0x0000000000000000, me=0x0000000128f85f10) at vm.c:1470
104
+ frame #20: 0x000000010037f3e7 ruby`vm_call_bmethod_body(ec=0x0000000100b069b0, calling=0x00007ffeefbfcd20, argv=0x00007ffeefbfcab0) at vm_insnhelper.c:2983:11
105
+ frame #21: 0x0000000100377e8f ruby`vm_call_bmethod(ec=0x0000000100b069b0, cfp=0x0000000108127ee8, calling=0x00007ffeefbfcd20) at vm_insnhelper.c:3003:12
106
+ frame #22: 0x00000001003770c9 ruby`vm_call_method_each_type(ec=0x0000000100b069b0, cfp=0x0000000108127ee8, calling=0x00007ffeefbfcd20) at vm_insnhelper.c:3440:16
107
+ frame #23: 0x00000001003769e9 ruby`vm_call_method(ec=0x0000000100b069b0, cfp=0x0000000108127ee8, calling=0x00007ffeefbfcd20) at vm_insnhelper.c:3507:20
108
+ frame #24: 0x00000001003578f5 ruby`vm_call_general(ec=0x0000000100b069b0, reg_cfp=0x0000000108127ee8, calling=0x00007ffeefbfcd20) at vm_insnhelper.c:3550:12
109
+ frame #25: 0x000000010036d688 ruby`vm_sendish(ec=0x0000000100b069b0, reg_cfp=0x0000000108127ee8, cd=0x0000000100e2bcb0, block_handler=0x0000000000000000, method_explorer=mexp_search_method) at vm_insnhelper.c:4525:15
110
+ frame #26: 0x000000010033f3de ruby`vm_exec_core(ec=0x0000000100b069b0, initial=0x0000000000000000) at insns.def:789:11
111
+ frame #27: 0x0000000100361de7 ruby`rb_vm_exec(ec=0x0000000100b069b0, mjit_enable_p=true) at vm.c:2171:22
112
+ frame #28: 0x0000000100363070 ruby`rb_iseq_eval_main(iseq=0x000000010781da28) at vm.c:2419:11
113
+ frame #29: 0x00000001000dbefb ruby`rb_ec_exec_node(ec=0x0000000100b069b0, n=0x000000010781da28) at eval.c:317:2
114
+ frame #30: 0x00000001000dbd83 ruby`ruby_run_node(n=0x000000010781da28) at eval.c:375:30
115
+ frame #31: 0x00000001000036fc ruby`main(argc=4, argv=0x00007ffeefbff5f8) at main.c:47:9
116
+ frame #32: 0x00007fff20530621 libdyld.dylib`start + 1
117
+ frame #33: 0x00007fff20530621 libdyld.dylib`start + 1
118
+ ```
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require "rake/testtask"
2
+ require "rake/clean"
3
+
4
+ ENV["MT_NO_PLUGINS"] = "1"
5
+
6
+ XML_FILE = "tmp/Opcodes/opcodes/x86_64.xml"
7
+ LICENCE_FILE = "tmp/Opcodes/license.rst"
8
+ LIB_FILE = "lib/fisk/machine/generated.rb"
9
+
10
+ file XML_FILE do
11
+ Dir.mkdir 'tmp' unless File.directory?("tmp")
12
+ cd "tmp"
13
+ sh "git clone https://github.com/Maratyszcza/Opcodes.git"
14
+ end
15
+
16
+ file LIB_FILE => XML_FILE do
17
+ ruby "bin/build-machine.rb #{XML_FILE} #{LICENCE_FILE} > #{LIB_FILE}"
18
+ end
19
+
20
+ CLEAN.include LIB_FILE
21
+
22
+ Rake::TestTask.new do |t|
23
+ t.libs << "test"
24
+ t.test_files = FileList['test/test*.rb']
25
+ t.verbose = true
26
+ t.warning = true
27
+ end
28
+
29
+ task :test => LIB_FILE
@@ -0,0 +1,11 @@
1
+ require "nokogiri"
2
+ require "stringio"
3
+ require "erb"
4
+
5
+ doc = Nokogiri::XML(File.binread(ARGV[0]))
6
+ unique_operands = doc.css("Operand").map { |node|
7
+ %w{ type input output }.map { |x| node[x] }
8
+ }.uniq
9
+ license = File.readlines(ARGV[1])
10
+ erb = ERB.new File.read("bin/machine.rb.erb"), trim_mode: "-"
11
+ puts erb.result(binding)
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ <%= license.map { |x| "# #{x.chomp} " }.join "\n" %>
4
+
5
+ class Fisk
6
+ class Machine
7
+ OPERANDS = [
8
+ <%- unique_operands.each do |u_op| -%>
9
+ Fisk::Machine::Operand.new(<%= u_op[0].dump %>, <%= u_op[1] || "nil" %>, <%= u_op[2] || "nil" %>),
10
+ <% end %>
11
+ ]
12
+ <%-
13
+ doc.root.children.each do |instruction|
14
+ next unless instruction.name == "Instruction"
15
+ name = instruction["name"]
16
+ -%>
17
+ # Instruction <%= name %>
18
+ forms = []
19
+ <%-
20
+ instruction.children.each do |form|
21
+ next unless form.name == "InstructionForm"
22
+ -%>
23
+ operands = []
24
+ encodings = []
25
+ <%-
26
+ form.children.each do |child|
27
+ next if child.text?
28
+ case child.name
29
+ -%>
30
+ <%- when "Operand" -%>
31
+ operands << OPERANDS[<%= unique_operands.index(%w{ type input output }.map { |n| child[n] }) %>]
32
+ <%-
33
+ when "Encoding"
34
+ size = 0
35
+ -%>
36
+ encodings << Class.new(Fisk::Machine::Encoding) {
37
+ def encode buffer, operands
38
+ <%-
39
+ child.children.each do |encoding|
40
+ next if encoding.text?
41
+ case encoding.name
42
+ when "Opcode"
43
+ size += 1
44
+ -%>
45
+ add_opcode buffer, operands, 0x<%= sprintf("%02X", encoding["byte"].to_i(16)) %>, <%= encoding["addend"].inspect %>
46
+ <%-
47
+ when "Immediate"
48
+ size += encoding["size"].to_i
49
+ -%>
50
+ add_immediate buffer, operands, <%= encoding["value"].dump %>, <%= encoding["size"].to_i %>
51
+ <%-
52
+ when "CodeOffset"
53
+ size += encoding["size"].to_i
54
+ -%>
55
+ add_code_offset buffer, operands, <%= encoding["value"].dump %>, <%= encoding["size"].to_i %>
56
+ <%-
57
+ when "REX"
58
+ size += 1 unless encoding["mandatory"] == "false"
59
+ -%>
60
+ add_rex(buffer, operands,
61
+ <%= !(encoding["mandatory"] == "false") %>,
62
+ <%= encoding["W"].inspect %>,
63
+ <%= encoding["R"].inspect %>,
64
+ <%= encoding["X"].inspect %>,
65
+ <%= encoding["B"].inspect %>)
66
+ <%-
67
+ when "ModRM"
68
+ size += 1
69
+ -%>
70
+ add_modrm(buffer, operands,
71
+ <%= encoding["mode"].to_i(2) %>,
72
+ <%= encoding["reg"].inspect %>,
73
+ <%= encoding["rm"].inspect %>)
74
+ <%- when "Prefix" -%>
75
+ add_prefix buffer, operands, 0x<%= sprintf("%02X", encoding["byte"].to_i(16)) %>, <%= encoding["mandatory"] %>
76
+ <%- when "DataOffset" -%>
77
+ add_data_offset buffer, operands, <%= encoding["value"].dump %>, <%= encoding["size"].to_i %>
78
+ <%- else -%>
79
+ add_<%= encoding.name %> buffer, operands
80
+ <%- end -%>
81
+ <%- end -%>
82
+ end
83
+
84
+ def bytesize; <%= size %>; end
85
+ }.new
86
+ <%- when "ISA" -%>
87
+ <%- when "ImplicitOperand" -%>
88
+ <%-
89
+ else
90
+ raise NotImplementedError, child.name
91
+ -%>
92
+ <%- end -%>
93
+ <%- end -%>
94
+ forms << Fisk::Machine::Form.new(operands, encodings)
95
+ <%- end -%>
96
+ Fisk::Machine::Instructions[<%= name.dump %>] = Fisk::Machine::Instruction.new(<%= name.dump %>, forms)
97
+
98
+ <%- end -%>
99
+ end
100
+ end