mrb_parser 0.0.1

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
+ 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