mrb_parser 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b96059708452f131c2ef1c44c20b13c163b687f9
4
+ data.tar.gz: 9df8a740b518b0b6cd628f9c026360213bd1c5a5
5
+ SHA512:
6
+ metadata.gz: fdc2cd80c1e26c8b5eee9191c628398d71f757512d2cf202c208ab571af24760609a25b5993b840a9662a262bea230bc8e7bdb7be5c5330782cdb834f51ece9c
7
+ data.tar.gz: fe9035d908042c98ebc57d00d37ddc84da200a96cb81524b40118cf5ef7056e53b8a8cb9242cb30b3235604401394a1dfb247084bda47815d809789f0ed98650
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *~
19
+ #*#
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mrb_parser.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Team Yamanekko
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # MrbParser: mrb file parser
2
+
3
+ MrbParer is a parser library and command to parse mrb format, binary code format
4
+ generated by mruby(mrbc).
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'mrb_parser'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install mrb_parser
19
+
20
+ ## Usage
21
+
22
+ MrbParser has a simple command: ``mrb_parser``.
23
+
24
+ $ mrb_parser sample.mrb
25
+
26
+ To show more information, with ``-d`` option:
27
+
28
+ $ mrb_parser -d sample.mrb
29
+
30
+ ## TODO
31
+
32
+ * support LINENO section (current implementation is broken)
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/mrb_parser ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'mrb_parser'
5
+
6
+ def usage
7
+ abort "usage: mrb_parser [-d] <mrb file>"
8
+ end
9
+
10
+ def main
11
+ if ARGV.size < 1 or ARGV.size > 2
12
+ usage
13
+ end
14
+
15
+ verbose = nil
16
+ filename = ARGV[0]
17
+ if filename == "-d"
18
+ filename = ARGV[1]
19
+ verbose = true
20
+ end
21
+
22
+ if !File.exist? filename
23
+ abort "#{filename}: file not found"
24
+ end
25
+
26
+ parser = MrbParser.new(filename)
27
+ parser.verbose = verbose
28
+ parser.parse
29
+ parser.dump
30
+ end
31
+
32
+ main
@@ -0,0 +1,390 @@
1
+ class MrbParser
2
+ class CodeDump
3
+
4
+ MAXARG_Bx = 0xffff
5
+ MAXARG_sBx = (MAXARG_Bx>>1) ## `sBx' is signed
6
+
7
+ OP_NOP = 0 # /* */
8
+ OP_MOVE = 1 # /* A B R(A) := R(B) */
9
+ OP_LOADL = 2 # /* A Bx R(A) := Lit(Bx) */
10
+ OP_LOADI = 3 # /* A sBx R(A) := sBx */
11
+ OP_LOADSYM = 4 # /* A Bx R(A) := Sym(Bx) */
12
+ OP_LOADNIL = 5 # /* A R(A) := nil */
13
+ OP_LOADSELF = 6 # /* A R(A) := self */
14
+ OP_LOADT = 7 # /* A R(A) := true */
15
+ OP_LOADF = 8 # /* A R(A) := false */
16
+
17
+ OP_GETGLOBAL = 9 # /* A Bx R(A) := getglobal(Sym(Bx)) */
18
+ OP_SETGLOBAL =10 # /* A Bx setglobal(Sym(Bx), R(A)) */
19
+ OP_GETSPECIAL=11 # /*A Bx R(A) := Special[Bx] */
20
+ OP_SETSPECIAL=12 # /*A Bx Special[Bx] := R(A) */
21
+ OP_GETIV = 13 # /* A Bx R(A) := ivget(Sym(Bx)) */
22
+ OP_SETIV = 14 # /* A Bx ivset(Sym(Bx),R(A)) */
23
+ OP_GETCV = 15 # /* A Bx R(A) := cvget(Sym(Bx)) */
24
+ OP_SETCV = 16 # /* A Bx cvset(Sym(Bx),R(A)) */
25
+ OP_GETCONST = 17 # /* A Bx R(A) := constget(Sym(Bx)) */
26
+ OP_SETCONST = 18 # /* A Bx constset(Sym(Bx),R(A)) */
27
+ OP_GETMCNST = 19 # /* A Bx R(A) := R(A)::Sym(B) */
28
+ OP_SETMCNST = 20 # /* A Bx R(A+1)::Sym(B) := R(A) */
29
+ OP_GETUPVAR = 21 # /* A B C R(A) := uvget(B,C) */
30
+ OP_SETUPVAR = 22 # /* A B C uvset(B,C,R(A)) */
31
+
32
+ OP_JMP = 23 # /* sBx pc+=sBx */
33
+ OP_JMPIF = 24 # /* A sBx if R(A) pc+=sBx */
34
+ OP_JMPNOT = 25 # /* A sBx if !R(A) pc+=sBx */
35
+ OP_ONERR = 26 # /* sBx rescue_push(pc+sBx) */
36
+ OP_RESCUE = 27 # /* A clear(exc); R(A) := exception (ignore when A=0) */
37
+ OP_POPERR = 28 # /* A A.times{rescue_pop()} */
38
+ OP_RAISE = 29 # /* A raise(R(A)) */
39
+ OP_EPUSH = 30 # /* Bx ensure_push(SEQ[Bx]) */
40
+ OP_EPOP = 31 # /* A A.times{ensure_pop().call} */
41
+
42
+ OP_SEND = 32 # /* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
43
+ OP_SENDB = 33 # /* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
44
+ OP_FSEND = 34 # /* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
45
+ OP_CALL = 35 # /* A B C R(A) := self.call(R(A),.., R(A+C)) */
46
+ OP_SUPER = 36 # /* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
47
+ OP_ARGARY = 37 # /* A Bx R(A) := argument array (16=6:1:5:4) */
48
+ OP_ENTER = 38 # /* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
49
+ OP_KARG = 39 # /* A B C R(A) := kdict[mSym(B)]; if C kdict.rm(mSym(B)) */
50
+ OP_KDICT = 40 # /* A C R(A) := kdict */
51
+
52
+ OP_RETURN = 41 # /* A B return R(A) (B=normal,in-block return/break) */
53
+ OP_TAILCALL = 42 # /* A B C return call(R(A),mSym(B),*R(C)) */
54
+ OP_BLKPUSH = 43 # /* A Bx R(A) := block (16=6:1:5:4) */
55
+
56
+ OP_ADD = 44 # /* A B C R(A) := R(A)+R(A+1) (mSyms[B]=:+,C=1) */
57
+ OP_ADDI = 45 # /* A B C R(A) := R(A)+C (mSyms[B]=:+) */
58
+ OP_SUB = 46 # /* A B C R(A) := R(A)-R(A+1) (mSyms[B]=:-,C=1) */
59
+ OP_SUBI = 47 # /* A B C R(A) := R(A)-C (mSyms[B]=:-) */
60
+ OP_MUL = 48 # /* A B C R(A) := R(A)*R(A+1) (mSyms[B]=:*,C=1) */
61
+ OP_DIV = 49 # /* A B C R(A) := R(A)/R(A+1) (mSyms[B]=:/,C=1) */
62
+ OP_EQ = 50 # /* A B C R(A) := R(A)==R(A+1) (mSyms[B]=:==,C=1) */
63
+ OP_LT = 51 # /* A B C R(A) := R(A)<R(A+1) (mSyms[B]=:<,C=1) */
64
+ OP_LE = 52 # /* A B C R(A) := R(A)<=R(A+1) (mSyms[B]=:<=,C=1) */
65
+ OP_GT = 53 # /* A B C R(A) := R(A)>R(A+1) (mSyms[B]=:>,C=1) */
66
+ OP_GE = 54 # /* A B C R(A) := R(A)>=R(A+1) (mSyms[B]=:>=,C=1) */
67
+
68
+ OP_ARRAY = 55 # /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
69
+ OP_ARYCAT = 56 # /* A B ary_cat(R(A),R(B)) */
70
+ OP_ARYPUSH = 57 # /* A B ary_push(R(A),R(B)) */
71
+ OP_AREF = 58 # /* A B C R(A) := R(B)[C] */
72
+ OP_ASET = 59 # /* A B C R(B)[C] := R(A) */
73
+ OP_APOST = 60 # /* A B C *R(A),R(A+1)..R(A+C) := R(A) */
74
+
75
+ OP_STRING = 61 # /* A Bx R(A) := str_dup(Lit(Bx)) */
76
+ OP_STRCAT = 62 # /* A B str_cat(R(A),R(B)) */
77
+
78
+ OP_HASH = 63 # /* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
79
+ OP_LAMBDA = 64 # /* A Bz Cz R(A) := lambda(SEQ[Bz],Cm) */
80
+ OP_RANGE = 65 # /* A B C R(A) := range_new(R(B),R(B+1),C) */
81
+
82
+ OP_OCLASS = 66 # /* A R(A) := ::Object */
83
+ OP_CLASS = 67 # /* A B R(A) := newclass(R(A),mSym(B),R(A+1)) */
84
+ OP_MODULE = 68 # /* A B R(A) := newmodule(R(A),mSym(B)) */
85
+ OP_EXEC = 69 # /* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */
86
+ OP_METHOD = 70 # /* A B R(A).newmethod(mSym(B),R(A+1)) */
87
+ OP_SCLASS = 71 # /* A B R(A) := R(B).singleton_class */
88
+ OP_TCLASS = 72 # /* A R(A) := target_class */
89
+
90
+ OP_DEBUG = 73 # /* A print R(A) */
91
+ OP_STOP = 74 # /* stop VM */
92
+ OP_ERR = 75 # /* Bx raise RuntimeError with message Lit(Bx) */
93
+
94
+ OP_RSVD1 = 76 # /* reserved instruction #1 */
95
+ OP_RSVD2 = 77 # /* reserved instruction #2 */
96
+ OP_RSVD3 = 78 # /* reserved instruction #3 */
97
+ OP_RSVD4 = 79 # /* reserved instruction #4 */
98
+ OP_RSVD5 = 80 # /* reserved instruction #5 */
99
+
100
+
101
+ OP_R_NORMAL = 0
102
+ OP_R_BREAK = 1
103
+ OP_R_RETURN = 2
104
+
105
+ # instructions: packed 32 bit
106
+ # -------------------------------
107
+ # A:B:C:OP = 9: 9: 7: 7
108
+ # A:Bx:OP = 9:16: 7
109
+ # Ax:OP = 25: 7
110
+ # A:Bz:Cz:OP = 9:14: 2: 7
111
+
112
+ def initialize(irep)
113
+ @irep = irep
114
+ end
115
+
116
+ def opcode(code)
117
+ code & 0x7F
118
+ end
119
+
120
+ def getarg_a(code)
121
+ (code >> 23) & 0x1ff
122
+ end
123
+
124
+ def getarg_b(code)
125
+ (code >> 14) & 0x1ff
126
+ end
127
+
128
+ def getarg_c(code)
129
+ (code >> 7) & 0x7f
130
+ end
131
+
132
+ def getarg_bx(code)
133
+ (code >> 7) & 0xffff
134
+ end
135
+
136
+ def getarg_sbx(code)
137
+ getarg_bx(code) - MAXARG_sBx
138
+ end
139
+
140
+ def getarg_ax(code)
141
+ (code >> 7) & 0x1ffffff
142
+ end
143
+
144
+ def getarg_unpack_b(code, n1, n2)
145
+ (code >> (7 + n2)) & ((1 << n1)-1)
146
+ end
147
+
148
+ def getarg_unpack_c(code, n1, n2)
149
+ (code >> 7) & ((1 << n2)-1)
150
+ end
151
+
152
+ def getarg_b2(code)
153
+ getarg_unpack_b(code, 14, 2)
154
+ end
155
+
156
+ def getarg_c2(code)
157
+ getarg_unpack_c(code, 14, 2)
158
+ end
159
+
160
+
161
+ def dump(c, i)
162
+ printf("%03d ", i)
163
+ op = opcode(c)
164
+ case op
165
+ when OP_NOP
166
+ printf("OP_NOP\n")
167
+ when OP_MOVE
168
+ printf("OP_MOVE\tR%d\tR%d\n", getarg_a(c), getarg_b(c))
169
+ when OP_LOADL
170
+ printf("OP_LOADL\tR%d\tL(%d)\n", getarg_a(c), getarg_bx(c))
171
+ when OP_LOADI
172
+ printf("OP_LOADI\tR%d\t%d\n", getarg_a(c), getarg_sbx(c))
173
+ when OP_LOADSYM
174
+ printf("OP_LOADSYM\tR%d\t:%s\n", getarg_a(c),
175
+ @irep.syms[getarg_bx(c)])
176
+ when OP_LOADNIL
177
+ printf("OP_LOADNIL\tR%d\n", getarg_a(c))
178
+ when OP_LOADSELF
179
+ printf("OP_LOADSELF\tR%d\n", getarg_a(c))
180
+ when OP_LOADT
181
+ printf("OP_LOADT\tR%d\n", getarg_a(c))
182
+ when OP_LOADF
183
+ printf("OP_LOADF\tR%d\n", getarg_a(c))
184
+ when OP_GETGLOBAL
185
+ printf("OP_GETGLOBAL\tR%d\t:%s\n", getarg_a(c),
186
+ @irep.syms[getarg_bx(c)])
187
+ when OP_SETGLOBAL
188
+ printf("OP_SETGLOBAL\t:%s\tR%d\n",
189
+ @irep.syms[getarg_bx(c)],
190
+ getarg_a(c))
191
+ when OP_GETCONST
192
+ printf("OP_GETCONST\tR%d\t:%s\n", getarg_a(c),
193
+ @irep.syms[getarg_bx(c)])
194
+ when OP_SETCONST
195
+ printf("OP_SETCONST\t:%s\tR%d\n",
196
+ @irep.syms[getarg_bx(c)],
197
+ getarg_a(c))
198
+ when OP_GETMCNST
199
+ printf("OP_GETMCNST\tR%d\tR%d::%s\n", getarg_a(c), getarg_a(c),
200
+ @irep.syms[getarg_bx(c)])
201
+ when OP_SETMCNST
202
+ printf("OP_SETMCNST\tR%d::%s\tR%d\n", getarg_a(c)+1,
203
+ @irep.syms[getarg_bx(c)],
204
+ getarg_a(c))
205
+ when OP_GETIV
206
+ printf("OP_GETIV\tR%d\t%s\n", getarg_a(c),
207
+ @irep.syms[getarg_bx(c)])
208
+ when OP_SETIV
209
+ printf("OP_SETIV\t%s\tR%d\n",
210
+ @irep.syms[getarg_bx(c)],
211
+ getarg_a(c))
212
+ when OP_GETUPVAR
213
+ printf("OP_GETUPVAR\tR%d\t%d\t%d\n",
214
+ getarg_a(c), getarg_b(c), getarg_c(c))
215
+ when OP_SETUPVAR
216
+ printf("OP_SETUPVAR\tR%d\t%d\t%d\n",
217
+ getarg_a(c), getarg_b(c), getarg_c(c))
218
+ when OP_GETCV
219
+ printf("OP_GETCV\tR%d\t%s\n", getarg_a(c),
220
+ @irep.syms[getarg_bx(c)])
221
+ when OP_SETCV
222
+ printf("OP_SETCV\t%s\tR%d\n",
223
+ @irep.syms[getarg_bx(c)],
224
+ getarg_a(c))
225
+ when OP_JMP
226
+ printf("OP_JMP\t\t%03d\n", i+getarg_sbx(c))
227
+ when OP_JMPIF
228
+ printf("OP_JMPIF\tR%d\t%03d\n", getarg_a(c), i+getarg_sbx(c))
229
+ when OP_JMPNOT
230
+ printf("OP_JMPNOT\tR%d\t%03d\n", getarg_a(c), i+getarg_sbx(c));
231
+ when OP_SEND
232
+ printf("OP_SEND\tR%d\t:%s\t%d\n", getarg_a(c),
233
+ @irep.syms[getarg_b(c)],
234
+ getarg_c(c))
235
+ when OP_SENDB
236
+ printf("OP_SENDB\tR%d\t:%s\t%d\n", getarg_a(c),
237
+ @irep.syms[getarg_b(c)],
238
+ getarg_c(c))
239
+ when OP_TAILCALL
240
+ printf("OP_TAILCALL\tR%d\t:%s\t%d\n", getarg_a(c),
241
+ @irep.syms[getarg_b(c)],
242
+ getarg_c(c))
243
+ when OP_SUPER
244
+ printf("OP_SUPER\tR%d\t%d\n", getarg_a(c),
245
+ getarg_c(c))
246
+ when OP_ARGARY
247
+ printf("OP_ARGARY\tR%d\t%d:%d:%d:%d\n", getarg_a(c),
248
+ (getarg_bx(c)>>10)&0x3f,
249
+ (getarg_bx(c)>>9)&0x1,
250
+ (getarg_bx(c)>>4)&0x1f,
251
+ (getarg_bx(c)>>0)&0xf)
252
+
253
+ when OP_ENTER
254
+ printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
255
+ (getarg_ax(c)>>18)&0x1f,
256
+ (getarg_ax(c)>>13)&0x1f,
257
+ (getarg_ax(c)>>12)&0x1,
258
+ (getarg_ax(c)>>7)&0x1f,
259
+ (getarg_ax(c)>>2)&0x1f,
260
+ (getarg_ax(c)>>1)&0x1,
261
+ getarg_ax(c) & 0x1)
262
+ when OP_RETURN
263
+ printf("OP_RETURN\tR%d", getarg_a(c))
264
+ case getarg_b(c)
265
+ when OP_R_NORMAL
266
+ printf("\n")
267
+ when OP_R_RETURN
268
+ printf("\treturn\n")
269
+ when OP_R_BREAK
270
+ printf("\tbreak\n")
271
+ else
272
+ printf("\tbroken\n")
273
+ end
274
+ when OP_BLKPUSH
275
+ printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d\n", getarg_a(c),
276
+ (getarg_bx(c)>>10)&0x3f,
277
+ (getarg_bx(c)>>9)&0x1,
278
+ (getarg_bx(c)>>4)&0x1f,
279
+ (getarg_bx(c)>>0)&0xf)
280
+
281
+ when OP_LAMBDA
282
+ printf("OP_LAMBDA\tR%d\tI(%+d)\t%d\n", getarg_a(c), getarg_b2(c), getarg_c2(c))
283
+ when OP_RANGE
284
+ printf("OP_RANGE\tR%d\tR%d\t%d\n", getarg_a(c), getarg_b(c), getarg_c(c))
285
+ when OP_METHOD
286
+ printf("OP_METHOD\tR%d\t:%s\n", getarg_a(c),
287
+ @irep.syms[getarg_b(c)])
288
+
289
+ when OP_ADD
290
+ printf("OP_ADD\tR%d\t:%s\t%d\n", getarg_a(c),
291
+ @irep.syms[getarg_b(c)],
292
+ getarg_c(c))
293
+ when OP_ADDI
294
+ printf("OP_ADDI\tR%d\t:%s\t%d\n", getarg_a(c),
295
+ @irep.syms[getarg_b(c)],
296
+ getarg_c(c))
297
+ when OP_SUB
298
+ printf("OP_SUB\tR%d\t:%s\t%d\n", getarg_a(c),
299
+ @irep.syms[getarg_b(c)],
300
+ getarg_c(c))
301
+ when OP_SUBI
302
+ printf("OP_SUBI\tR%d\t:%s\t%d\n", getarg_a(c),
303
+ @irep.syms[getarg_b(c)],
304
+ getarg_c(c))
305
+ when OP_MUL
306
+ printf("OP_MUL\tR%d\t:%s\t%d\n", getarg_a(c),
307
+ @irep.syms[getarg_b(c)],
308
+ getarg_c(c))
309
+ when OP_DIV
310
+ printf("OP_DIV\tR%d\t:%s\t%d\n", getarg_a(c),
311
+ @irep.syms[getarg_b(c)],
312
+ getarg_c(c))
313
+ when OP_LT
314
+ printf("OP_LT\tR%d\t:%s\t%d\n", getarg_a(c),
315
+ @irep.syms[getarg_b(c)],
316
+ getarg_c(c))
317
+ when OP_LE
318
+ printf("OP_LE\tR%d\t:%s\t%d\n", getarg_a(c),
319
+ @irep.syms[getarg_b(c)],
320
+ getarg_c(c))
321
+ when OP_GT
322
+ printf("OP_GT\tR%d\t:%s\t%d\n", getarg_a(c),
323
+ @irep.syms[getarg_b(c)],
324
+ getarg_c(c))
325
+ when OP_GE
326
+ printf("OP_GE\tR%d\t:%s\t%d\n", getarg_a(c),
327
+ @irep.syms[getarg_b(c)],
328
+ getarg_c(c))
329
+ when OP_EQ
330
+ printf("OP_EQ\tR%d\t:%s\t%d\n", getarg_a(c),
331
+ @irep.syms[getarg_b(c)],
332
+ getarg_c(c))
333
+
334
+ when OP_STOP
335
+ printf("OP_STOP\n")
336
+
337
+ when OP_ARRAY
338
+ printf("OP_ARRAY\tR%d\tR%d\t%d\n", getarg_a(c), getarg_b(c), getarg_c(c))
339
+ when OP_ARYCAT
340
+ printf("OP_ARYCAT\tR%d\tR%d\n", getarg_a(c), getarg_b(c))
341
+ when OP_ARYPUSH
342
+ printf("OP_ARYPUSH\tR%d\tR%d\n", getarg_a(c), getarg_b(c))
343
+ when OP_AREF
344
+ printf("OP_AREF\tR%d\tR%d\t%d\n", getarg_a(c), getarg_b(c), getarg_c(c))
345
+ when OP_APOST
346
+ printf("OP_APOST\tR%d\t%d\t%d\n", getarg_a(c), getarg_b(c), getarg_c(c))
347
+ when OP_STRING
348
+ s = @irep.pool[getarg_bx(c)]
349
+ printf("OP_STRING\tR%d\t%s\n", getarg_a(c), s)
350
+ when OP_STRCAT
351
+ printf("OP_STRCAT\tR%d\tR%d\n", getarg_a(c), getarg_b(c))
352
+ when OP_HASH
353
+ printf("OP_HASH\tR%d\tR%d\t%d\n", getarg_a(c), getarg_b(c), getarg_c(c))
354
+
355
+ when OP_OCLASS
356
+ printf("OP_OCLASS\tR%d\n", getarg_a(c))
357
+ when OP_CLASS
358
+ printf("OP_cLASS\tR%d\t:%s\n", getarg_a(c),
359
+ @irep.syms[getarg_b(c)])
360
+ when OP_MODULE
361
+ printf("OP_MODULE\tR%d\t:%s\n", getarg_a(c),
362
+ @irep.syms[getarg_b(c)])
363
+ when OP_EXEC
364
+ printf("OP_EXEC\tR%d\tI(%+d)\n", getarg_a(c), getarg_bx(c))
365
+ when OP_SCLASS
366
+ printf("OP_SCLASS\tR%d\tR%d\n", getarg_a(c), getarg_b(c))
367
+ when OP_TCLASS
368
+ printf("OP_TCLASS\tR%d\n", getarg_a(c))
369
+ when OP_ERR
370
+ printf("OP_ERR\tL(%d)\n", getarg_bx(c))
371
+ when OP_EPUSH
372
+ printf("OP_EPUSH\t:I(%+d)\n", getarg_bx(c))
373
+ when OP_ONERR
374
+ printf("OP_ONERR\t%03d\n", i+getarg_sbx(c))
375
+ when OP_RESCUE
376
+ printf("OP_RESCUE\tR%d\n", getarg_a(c))
377
+ when OP_RAISE
378
+ printf("OP_RAISE\tR%d\n", getarg_a(c))
379
+ when OP_POPERR
380
+ printf("OP_POPERR\t%d\n", getarg_a(c))
381
+ when OP_EPOP
382
+ printf("OP_EPOP\t%d\n", getarg_a(c))
383
+ else
384
+ printf("OP_unknown %d\t%d\t%d\t%d\n", opcode(c),
385
+ getarg_a(c), getarg_b(c), getarg_c(c))
386
+ end
387
+ end
388
+
389
+ end
390
+ end
@@ -0,0 +1,32 @@
1
+ class MrbParser
2
+
3
+ ##
4
+ # calculate CRC
5
+ #
6
+ # an Ruby port of src/crc.c in mruby
7
+ #
8
+ class CRC
9
+
10
+ CRC_16_CCITT = 0x11021 ## x^16+x^12+x^5+1
11
+ CRC_XOR_PATTERN = (CRC_16_CCITT << 8)
12
+ CRC_CARRY_BIT = 0x01000000
13
+ CHAR_BIT = 8
14
+
15
+ def self.calc_crc_16_ccitt(data0, nbytes, crc)
16
+ data = data0.unpack("C*")
17
+ crcwk = crc << 8
18
+ for ibyte in 0...nbytes
19
+ crcwk |= data[ibyte]
20
+ for ibit in 0...CHAR_BIT
21
+ crcwk <<= 1
22
+ carry = crcwk & CRC_CARRY_BIT
23
+ if carry.nonzero?
24
+ crcwk ^= CRC_XOR_PATTERN
25
+ end
26
+ end
27
+ end
28
+ return crcwk >> 8
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,76 @@
1
+ class MrbParser
2
+ class DebugInfo
3
+
4
+ MRB_DEBUG_LINE_ARY = 0
5
+ MRB_DEBUG_LINE_FLAT_MAP = 1
6
+
7
+ LINE_TYPE = ["ARY", "FLAT_MAP"]
8
+
9
+ attr_accessor :pc_count
10
+ attr_accessor :files
11
+ attr_accessor :debug_section
12
+ attr_accessor :irep_record
13
+ attr_reader :infos
14
+
15
+ def initialize(debug_section, irep_record)
16
+ @debug_section = debug_section
17
+ @irep_record = irep_record
18
+ irep_record.debug_info = self
19
+ @infos = []
20
+ end
21
+
22
+ def parse_record(parser)
23
+ @pc_count = parser.read_uint32
24
+ flen = parser.read_uint16
25
+ @files = []
26
+ flen.times do
27
+ file = DebugInfoFile.new
28
+ @files << file
29
+ file.start_pos = parser.read_uint32
30
+ filename_idx = parser.read_uint16
31
+ file.filename = @debug_section.filenames[filename_idx]
32
+
33
+ file.line_entry_count = parser.read_uint32
34
+ file.line_type = parser.read_uint8
35
+ case file.line_type
36
+ when MRB_DEBUG_LINE_ARY ## 0
37
+ file.line_ary = []
38
+ file.line_entry_count.times do
39
+ file.line_ary << parser.read_uint16
40
+ end
41
+ when MRB_DEBUG_LINE_FLAT_MAP ## 1
42
+ file.line_flat_map = []
43
+ file.line_entry_count.times do
44
+ start_pos = parser.read_uint32
45
+ line = parser.read_uint16
46
+ file.line_flat_map << {start_pos: start_pos, line: line}
47
+ end
48
+ else
49
+ raise
50
+ end
51
+ end
52
+ @irep_record.recs.each do |irep_record|
53
+ info = MrbParser::DebugInfo.new(@debug_section, irep_record)
54
+ @infos << info
55
+ info.parse_record(parser)
56
+ end
57
+ self
58
+ end
59
+
60
+ def printf_indent(n, *args)
61
+ print " "*n
62
+ printf *args
63
+ end
64
+
65
+ def dump(n = 2)
66
+ printf_indent n, "*** DEBUG INFO ***\n"
67
+ printf_indent n, "count: %d\n", @pc_count
68
+ printf_indent n, "files: %d\n", @files.size
69
+ @files.map{|file| file.dump(n+2)}
70
+ @infos.each do |debug_info|
71
+ debug_info.dump(n + 2)
72
+ end
73
+ printf_indent n, "*** ***\n"
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,40 @@
1
+ class MrbParser
2
+ class DebugInfoFile
3
+ attr_accessor :start_pos
4
+ attr_accessor :filename
5
+ attr_accessor :line_entry_count
6
+ attr_accessor :line_type
7
+
8
+ attr_accessor :line_flat_map
9
+ attr_accessor :line_ary
10
+
11
+ def initialize
12
+ end
13
+
14
+ def printf_indent(n, *args)
15
+ print " "*n
16
+ printf *args
17
+ end
18
+
19
+ def dump(n = 2)
20
+ printf_indent n, "*** DEBUG INFO FILE ***\n"
21
+ printf_indent n, "start: %d\n", @start_pos
22
+ printf_indent n, "fname: %s\n", @filename
23
+ printf_indent n, "line type: %d (%s)\n", @line_type,
24
+ MrbParser::DebugInfo::LINE_TYPE[@line_type]
25
+ printf_indent n, "lines: %d\n", @line_entry_count
26
+ case @line_type
27
+ when MrbParser::DebugInfo::MRB_DEBUG_LINE_ARY
28
+ @line_ary.each do |line|
29
+ printf_indent n, " line: %d\n", line
30
+ end
31
+ when MrbParser::DebugInfo::MRB_DEBUG_LINE_FLAT_MAP
32
+ @line_flat_map.each do |map|
33
+ printf_indent n, " line: %d, start_pos: %d\n", map[:line], map[:start_pos]
34
+ end
35
+ end
36
+
37
+ printf_indent n, "*** ***\n"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,43 @@
1
+ require 'mrb_parser/debug_info'
2
+ require 'mrb_parser/debug_info_file'
3
+
4
+ class MrbParser
5
+ class DebugSection < Section
6
+
7
+ attr_accessor :debug_info
8
+ attr_accessor :filenames
9
+
10
+ def initialize(*)
11
+ super
12
+ end
13
+
14
+ def parse_record(parser)
15
+ rec = parser.irep_section.rec
16
+ @debug_info = MrbParser::DebugInfo.new(self, rec)
17
+ @debug_info.parse_record(parser)
18
+ end
19
+
20
+ def parse_body(parser)
21
+ filenames_len = parser.read_uint16
22
+ @filenames = []
23
+ filenames_len.times do
24
+ @filenames << parser.read_n16string
25
+ end
26
+ parse_record(parser)
27
+ self
28
+ end
29
+
30
+ def dump
31
+ printf "*** DEBUG SECTION ***\n"
32
+ printf "secID: %s\n", @signature
33
+ printf "size : %s\n", @size
34
+ printf "files: %d\n", @filenames.size
35
+ @filenames.each do |fname|
36
+ printf " filename: %s\n", fname
37
+ end
38
+ @debug_info.dump
39
+ printf "*** ***\n"
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ class MrbParser
2
+ class EndSection < Section
3
+ def initialize(*)
4
+ super
5
+ end
6
+
7
+ def parse_body(parser)
8
+ end
9
+
10
+ def end?
11
+ true
12
+ end
13
+
14
+ def dump
15
+ printf "*** END SECTION ***\n"
16
+ printf "secID: %s\n", @signature
17
+ printf "size : %s\n", @size
18
+ printf "*** ***\n"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ class MrbParser
2
+ class Error < StandardError; end
3
+ end
@@ -0,0 +1,59 @@
1
+ require 'mrb_parser/crc'
2
+ class MrbParser
3
+ class Header
4
+
5
+ attr_reader :signature, :version, :crc, :size,
6
+ :compiler_name, :compiler_version
7
+
8
+ def self.parse(parser)
9
+ header = Header.new()
10
+ header.parse(parser)
11
+ end
12
+
13
+ def initialize
14
+ end
15
+
16
+ def parse(parser)
17
+ @signature = parser.read_chars(4)
18
+ @version = parser.read_chars(4)
19
+ @crc = parser.read_uint16
20
+ @crc_verified = check_crc(parser)
21
+ @size = parser.read_uint32
22
+ @compiler_name = parser.read_chars(4)
23
+ @compiler_version = parser.read_chars(4)
24
+
25
+ if parser.verbose
26
+ if !valid?
27
+ STDERR.print "** [WARN] This header seems to be invalid. **\n"
28
+ end
29
+ end
30
+
31
+ self
32
+ end
33
+
34
+ def check_crc(parser)
35
+ pos = parser.pos
36
+ rest_data = parser.read(nil)
37
+ parser.seek(pos)
38
+ checksum = MrbParser::CRC.calc_crc_16_ccitt(rest_data, rest_data.size, 0)
39
+ @crc == checksum
40
+ end
41
+
42
+
43
+ def valid?
44
+ @signature == "RITE" && @version == "0002" && @crc_verified
45
+ end
46
+
47
+ def dump
48
+ printf "*** BINARY HEADER ***\n"
49
+ printf "secID: %s\n", @signature
50
+ printf "ver : %s\n", @version
51
+ printf "crc : 0x%04x (%s)\n", @crc, @crc_verified
52
+ printf "size : 0x%08x\n", @size
53
+ printf "compiler:\n"
54
+ printf " name: %s\n", @compiler_name
55
+ printf " ver : %s\n", @compiler_version
56
+ printf "*** ***\n"
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,109 @@
1
+ require 'mrb_parser/code_dump'
2
+
3
+ class MrbParser
4
+ class IrepRecord
5
+
6
+ IREP_TT_STRING = 0
7
+ IREP_TT_FIXNUM = 1
8
+ IREP_TT_FLOAT = 2
9
+
10
+ MRB_DUMP_NULL_SYM_LEN = 0xFFFF
11
+
12
+ attr_accessor :debug_info
13
+ attr_reader :recs
14
+ attr_reader :syms
15
+ attr_reader :pool
16
+
17
+ def initialize
18
+ end
19
+
20
+ def parse_record(parser)
21
+ @section_size = parser.read_uint32
22
+ @nlocals = parser.read_uint16
23
+ @nregs = parser.read_uint16
24
+ rlen = parser.read_uint16
25
+ parse_iseq(parser)
26
+ parse_pool(parser)
27
+ parse_symbol(parser)
28
+ @recs = []
29
+ rlen.times do |i|
30
+ rec = IrepRecord.new()
31
+ @recs[i] = rec.parse_record(parser)
32
+ end
33
+ self
34
+ end
35
+
36
+ def parse_iseq(parser)
37
+ ilen = parser.read_uint32
38
+ @iseq = []
39
+ ilen.times do |i|
40
+ @iseq << parser.read_uint32
41
+ end
42
+ end
43
+
44
+ def parse_pool(parser)
45
+ plen = parser.read_uint32
46
+ @pool = []
47
+ plen.times do |i|
48
+ type = parser.read_uint8
49
+ str = parser.read_n16string
50
+ case type
51
+ when IREP_TT_FIXNUM
52
+ @pool[i] = Integer(str)
53
+ when IREP_TT_FLOAT
54
+ @pool[i] = Float(str)
55
+ when IREP_TT_STRING
56
+ @pool[i] = str
57
+ else
58
+ @pool[i] = nil
59
+ end
60
+ end
61
+ end
62
+
63
+ def parse_symbol(parser)
64
+ slen = parser.read_uint32
65
+ @syms = []
66
+ slen.times do |i|
67
+ len = parser.read_uint16
68
+ if len == MRB_DUMP_NULL_SYM_LEN
69
+ @syms[i] = nil
70
+ next
71
+ end
72
+ @syms[i] = parser.read_chars(len)
73
+ terminater = parser.read_uint8 ## skip NULL byte
74
+ end
75
+ end
76
+
77
+ def printf_indent(n, *args)
78
+ print " "*n
79
+ printf *args
80
+ end
81
+
82
+ def dump(n = 2)
83
+ code_dump = MrbParser::CodeDump.new(self)
84
+ printf_indent n, "*** IREP RECORD ***\n"
85
+ printf_indent n, "locals: %d\n", @nlocals
86
+ printf_indent n, "regs : %d\n", @nregs
87
+ printf_indent n, "iseqs : %d\n", @iseq.size
88
+ @iseq.each_with_index do |code, i|
89
+ printf_indent n, " code: %08x\n", code
90
+ printf_indent n, " "
91
+ code_dump.dump(code, i)
92
+ end
93
+ printf_indent n, "pools : %d\n", @pool.size
94
+ @pool.each do |pool|
95
+ printf_indent n, " pool: %s\n", pool.inspect
96
+ end
97
+ printf_indent n, "syms : %d\n", @syms.size
98
+ @syms.each do |item|
99
+ printf_indent n, " sym: %s\n", item.inspect
100
+ end
101
+ printf_indent n, "ireps : %d\n", @recs.size
102
+ @recs.each do |rec|
103
+ rec.dump(n+2)
104
+ end
105
+ printf_indent n, "*** ***\n"
106
+ end
107
+ end
108
+ end
109
+
@@ -0,0 +1,34 @@
1
+ require 'mrb_parser/irep_record'
2
+ class MrbParser
3
+ class IrepSection < Section
4
+
5
+ attr_reader :rec
6
+
7
+ def initialize(*)
8
+ super
9
+ end
10
+
11
+ def parse_body(parser)
12
+ @vm_version = parser.read_chars(4)
13
+ @rec = parse_record(parser)
14
+ parser.irep_section = self
15
+ self
16
+ end
17
+
18
+ def parse_record(parser)
19
+ rec = MrbParser::IrepRecord.new
20
+ rec.parse_record(parser)
21
+ rec
22
+ end
23
+
24
+ def dump
25
+ printf "*** IREP SECTION ***\n"
26
+ printf "secID : %s\n", @signature
27
+ printf "size : %s\n", @size
28
+ printf "vm ver: %s\n", @vm_version
29
+ @rec.dump
30
+ printf "*** ***\n"
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ class MrbParser
2
+ class LinenoSection < Section
3
+ def initialize(*)
4
+ super
5
+ end
6
+
7
+ def parse_body(parser, irep_record = nil)
8
+ record_size = parser.read_uint32
9
+ @filename = parser.read_n16string
10
+ @niseq = parser.read_uint32
11
+ @lines = []
12
+ @niseq.times do |i|
13
+ line = parser.read_uint16
14
+ @lines << line
15
+ end
16
+
17
+ unless irep_record
18
+ irep_record = parser.irep_section.rec
19
+ end
20
+ irep_record.debug_info = self
21
+
22
+ irep_record.recs.each do |rec|
23
+ parse_body(parser, rec)
24
+ end
25
+ end
26
+
27
+ def dump
28
+ printf "*** LINENO SECTION ***\n"
29
+ printf "secID : %s\n", @signature
30
+ printf "size : %s\n", @size
31
+ printf "*** ***\n"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ class MrbParser
2
+ class Section
3
+
4
+ require 'mrb_parser/irep_section'
5
+ require 'mrb_parser/lineno_section'
6
+ require 'mrb_parser/debug_section'
7
+ require 'mrb_parser/end_section'
8
+
9
+ BINARY_EOF = "END\0"
10
+ IREP_IDENTIFIER = "IREP"
11
+ LINENO_IDENTIFIER = "LINE"
12
+ DEBUG_IDENTIFIER = "DBG\0"
13
+
14
+ attr_reader :signature, :size
15
+
16
+ def initialize(signature = nil, size = nil)
17
+ @signature = signature
18
+ @size = size
19
+ end
20
+
21
+ def self.parse(parser)
22
+ section = MrbParser::Section.new
23
+ section.parse(parser)
24
+ end
25
+
26
+ def parse(parser)
27
+ signature = parser.read_chars(4)
28
+ size = parser.read_uint32
29
+ case signature
30
+ when IREP_IDENTIFIER
31
+ section = MrbParser::IrepSection
32
+ when LINENO_IDENTIFIER
33
+ section = MrbParser::LinenoSection
34
+ when DEBUG_IDENTIFIER
35
+ section = MrbParser::DebugSection
36
+ when BINARY_EOF
37
+ section = MrbParser::EndSection
38
+ else
39
+ raise MrbParser::Error, "cannot parse; invalid section signature: '#{signature}'"
40
+ end
41
+ sec = section.new(signature, size)
42
+ sec.parse_body(parser)
43
+ sec
44
+ end
45
+
46
+ def end?
47
+ false
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,45 @@
1
+ class MrbParser
2
+ module Utils
3
+ def read(n)
4
+ @data.read(n)
5
+ end
6
+
7
+ def pos
8
+ @data.pos
9
+ end
10
+
11
+ def seek(n)
12
+ @data.seek(n)
13
+ end
14
+
15
+ def read_format(pat, n)
16
+ byteseq = @data.read(n)
17
+ val = byteseq.unpack(pat)[0]
18
+ if @verbose
19
+ p [@data, n, val]
20
+ end
21
+ val
22
+ end
23
+
24
+ def read_uint8
25
+ read_format("C1", 1)
26
+ end
27
+
28
+ def read_uint16
29
+ read_format("n1", 2)
30
+ end
31
+
32
+ def read_uint32
33
+ read_format("N1", 4)
34
+ end
35
+
36
+ def read_chars(n)
37
+ read_format("a#{n}", n)
38
+ end
39
+
40
+ def read_n16string
41
+ len = read_uint16
42
+ read_format("a#{len}", len)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ class MrbParser
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mrb_parser.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'mrb_parser/header'
2
+ require 'mrb_parser/section'
3
+ require 'mrb_parser/error'
4
+ require "mrb_parser/version"
5
+ require "mrb_parser/utils"
6
+
7
+ class MrbParser
8
+ include MrbParser::Utils
9
+
10
+ attr_accessor :verbose
11
+ attr_accessor :irep_section
12
+ attr_reader :header, :sections
13
+
14
+ def self.parse(filename)
15
+ parser = MrbParser.new(filename)
16
+ parser.parse
17
+ end
18
+
19
+ def initialize(filename)
20
+ @filename = filename
21
+ @data = nil
22
+ @irep_section = nil
23
+ @sections = []
24
+ end
25
+
26
+ def parse
27
+ @data = File.open(@filename)
28
+ @header = MrbParser::Header.parse(self)
29
+
30
+ while true
31
+ section = MrbParser::Section.parse(self)
32
+ @sections << section
33
+ break if section.end?
34
+ end
35
+ end
36
+
37
+ def dump
38
+ @header.dump
39
+ @sections.each do |section|
40
+ section.dump
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mrb_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mrb_parser"
8
+ spec.version = MrbParser::VERSION
9
+ spec.authors = ["yamanekko"]
10
+ spec.email = ["yamanekko@tatsu-zine.com"]
11
+ spec.description = %q{simple library to parse mrb file, mruby bytecode file.}
12
+ spec.summary = %q{mrb (mruby bytecode) parser}
13
+ spec.homepage = "https://github.com/yamanekko/mrb_parser"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1 @@
1
+ require_relative '../lib/mrb_parser'
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mrb_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - yamanekko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: simple library to parse mrb file, mruby bytecode file.
56
+ email:
57
+ - yamanekko@tatsu-zine.com
58
+ executables:
59
+ - mrb_parser
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/mrb_parser
69
+ - lib/mrb_parser.rb
70
+ - lib/mrb_parser/code_dump.rb
71
+ - lib/mrb_parser/crc.rb
72
+ - lib/mrb_parser/debug_info.rb
73
+ - lib/mrb_parser/debug_info_file.rb
74
+ - lib/mrb_parser/debug_section.rb
75
+ - lib/mrb_parser/end_section.rb
76
+ - lib/mrb_parser/error.rb
77
+ - lib/mrb_parser/header.rb
78
+ - lib/mrb_parser/irep_record.rb
79
+ - lib/mrb_parser/irep_section.rb
80
+ - lib/mrb_parser/lineno_section.rb
81
+ - lib/mrb_parser/section.rb
82
+ - lib/mrb_parser/utils.rb
83
+ - lib/mrb_parser/version.rb
84
+ - mrb_parser.gemspec
85
+ - spec/spec_helper.rb
86
+ homepage: https://github.com/yamanekko/mrb_parser
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.2.0.rc.1
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: mrb (mruby bytecode) parser
110
+ test_files:
111
+ - spec/spec_helper.rb