rubinius-compiler 2.3.1 → 3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rubinius/code/compiler.rb +10 -0
  3. data/lib/rubinius/{compiler → code/compiler}/compiled_file.rb +0 -0
  4. data/lib/rubinius/{compiler → code/compiler}/compiler.rb +0 -0
  5. data/lib/rubinius/{compiler → code/compiler}/evaluator.rb +0 -0
  6. data/lib/rubinius/{compiler → code/compiler}/generator.rb +0 -0
  7. data/lib/rubinius/{compiler → code/compiler}/generator_methods.rb +0 -0
  8. data/lib/rubinius/{compiler → code/compiler}/iseq.rb +0 -0
  9. data/lib/rubinius/{compiler → code/compiler}/locals.rb +0 -0
  10. data/lib/rubinius/{compiler → code/compiler}/opcodes.rb +0 -0
  11. data/lib/rubinius/{compiler → code/compiler}/printers.rb +0 -0
  12. data/lib/rubinius/{compiler → code/compiler}/stages.rb +0 -0
  13. data/lib/rubinius/{compiler → code/compiler}/version.rb +1 -1
  14. metadata +23 -271
  15. data/.gitignore +0 -17
  16. data/.travis.yml +0 -8
  17. data/Gemfile +0 -4
  18. data/LICENSE +0 -25
  19. data/README.md +0 -29
  20. data/Rakefile +0 -1
  21. data/lib/rubinius/compiler.rb +0 -10
  22. data/rubinius-compiler.gemspec +0 -28
  23. data/spec/alias_spec.rb +0 -39
  24. data/spec/and_spec.rb +0 -44
  25. data/spec/array_spec.rb +0 -110
  26. data/spec/attrasgn_spec.rb +0 -186
  27. data/spec/back_ref_spec.rb +0 -11
  28. data/spec/call_spec.rb +0 -580
  29. data/spec/case_spec.rb +0 -576
  30. data/spec/cdecl_spec.rb +0 -70
  31. data/spec/class_spec.rb +0 -120
  32. data/spec/colon2_spec.rb +0 -8
  33. data/spec/colon3_spec.rb +0 -8
  34. data/spec/const_spec.rb +0 -7
  35. data/spec/custom/guards/profiler.rb +0 -18
  36. data/spec/custom/helpers/generator.rb +0 -828
  37. data/spec/custom/matchers/compile_as.rb +0 -46
  38. data/spec/custom/mspec.rb +0 -15
  39. data/spec/custom/runner/actions/debug.rb +0 -10
  40. data/spec/custom/runner/actions/gcstats.rb +0 -17
  41. data/spec/custom/runner/actions/memory.rb +0 -11
  42. data/spec/custom/runner/actions/parser.rb +0 -14
  43. data/spec/custom/runner/actions/profiler.rb +0 -19
  44. data/spec/custom/runner/relates.rb +0 -86
  45. data/spec/custom/utils/options.rb +0 -40
  46. data/spec/custom/utils/script.rb +0 -50
  47. data/spec/cvar_spec.rb +0 -39
  48. data/spec/cvasgn_spec.rb +0 -33
  49. data/spec/cvdecl_spec.rb +0 -17
  50. data/spec/defined_spec.rb +0 -616
  51. data/spec/defn_spec.rb +0 -732
  52. data/spec/defs_spec.rb +0 -113
  53. data/spec/dot2_spec.rb +0 -16
  54. data/spec/dot3_spec.rb +0 -17
  55. data/spec/dregx_spec.rb +0 -160
  56. data/spec/dstr_spec.rb +0 -424
  57. data/spec/dsym_spec.rb +0 -18
  58. data/spec/dxstr_spec.rb +0 -24
  59. data/spec/ensure_spec.rb +0 -196
  60. data/spec/false_spec.rb +0 -7
  61. data/spec/flip2_spec.rb +0 -21
  62. data/spec/flip3_spec.rb +0 -12
  63. data/spec/for_spec.rb +0 -228
  64. data/spec/gasgn_spec.rb +0 -15
  65. data/spec/generator/encode_spec.rb +0 -34
  66. data/spec/gvar_spec.rb +0 -37
  67. data/spec/hash_spec.rb +0 -108
  68. data/spec/iasgn_spec.rb +0 -26
  69. data/spec/if_spec.rb +0 -415
  70. data/spec/iter_spec.rb +0 -1011
  71. data/spec/lasgn_spec.rb +0 -561
  72. data/spec/lit_spec.rb +0 -61
  73. data/spec/masgn_spec.rb +0 -1558
  74. data/spec/match2_spec.rb +0 -42
  75. data/spec/match3_spec.rb +0 -54
  76. data/spec/match_spec.rb +0 -29
  77. data/spec/module_spec.rb +0 -73
  78. data/spec/nil_spec.rb +0 -7
  79. data/spec/not_spec.rb +0 -47
  80. data/spec/nth_ref_spec.rb +0 -7
  81. data/spec/op_asgn_spec.rb +0 -563
  82. data/spec/or_spec.rb +0 -126
  83. data/spec/postexe_spec.rb +0 -11
  84. data/spec/preexe_spec.rb +0 -21
  85. data/spec/regex_spec.rb +0 -54
  86. data/spec/rescue_spec.rb +0 -763
  87. data/spec/return_spec.rb +0 -152
  88. data/spec/sclass_spec.rb +0 -138
  89. data/spec/spec_helper.rb +0 -12
  90. data/spec/str_spec.rb +0 -118
  91. data/spec/super_spec.rb +0 -170
  92. data/spec/transforms/assembly_spec.rb +0 -195
  93. data/spec/transforms/block_given_spec.rb +0 -75
  94. data/spec/transforms/fast_coerce_spec.rb +0 -112
  95. data/spec/transforms/fast_new_spec.rb +0 -255
  96. data/spec/transforms/invoke_primitive_spec.rb +0 -14
  97. data/spec/transforms/kernel_methods_spec.rb +0 -29
  98. data/spec/transforms/primitive_spec.rb +0 -33
  99. data/spec/transforms/privately_spec.rb +0 -24
  100. data/spec/true_spec.rb +0 -7
  101. data/spec/undef_spec.rb +0 -133
  102. data/spec/until_spec.rb +0 -254
  103. data/spec/valias_spec.rb +0 -11
  104. data/spec/while_spec.rb +0 -494
  105. data/spec/xstr_spec.rb +0 -10
  106. data/spec/yield_spec.rb +0 -92
  107. data/spec/zsuper_spec.rb +0 -63
data/spec/cdecl_spec.rb DELETED
@@ -1,70 +0,0 @@
1
- describe "A Cdecl node" do
2
- relates "X = 42" do
3
- compile do |g|
4
- g.push_scope
5
- g.push_literal :X
6
- g.push 42
7
- g.send :const_set, 2
8
- end
9
- end
10
-
11
- relates "::X = 1" do
12
- compile do |g|
13
- g.push_cpath_top
14
- g.push_literal :X
15
- g.push 1
16
- g.send :const_set, 2
17
- end
18
- end
19
-
20
- relates "X::Y = 1" do
21
- compile do |g|
22
- g.push 1
23
- g.push_literal :Y
24
- g.push_const :X
25
- g.rotate 3
26
- g.send :const_set, 2
27
- end
28
- end
29
-
30
- relates "X::Y::Z = a" do
31
- compile do |g|
32
- g.push :self
33
- g.send :a, 0, true
34
- g.push_literal :Z
35
- g.push_const :X
36
- g.find_const :Y
37
- g.rotate 3
38
- g.send :const_set, 2
39
- end
40
- end
41
-
42
- relates "a::A = 1" do
43
- compile do |g|
44
- g.push 1
45
- g.push_literal :A
46
- g.push :self
47
- g.send :a, 0, true
48
- g.rotate 3
49
- g.send :const_set, 2
50
- end
51
- end
52
-
53
- relates <<-ruby do
54
- a = Object
55
- a::B = b
56
- ruby
57
-
58
- compile do |g|
59
- g.push_const :Object
60
- g.set_local 0
61
- g.pop
62
- g.push :self
63
- g.send :b, 0, true
64
- g.push_literal :B
65
- g.push_local 0
66
- g.rotate 3
67
- g.send :const_set, 2
68
- end
69
- end
70
- end
data/spec/class_spec.rb DELETED
@@ -1,120 +0,0 @@
1
- describe "A Class node" do
2
- relates <<-ruby do
3
- class X
4
- puts((1 + 1))
5
- def blah
6
- puts("hello")
7
- end
8
- end
9
- ruby
10
-
11
- compile do |g|
12
- in_class :X do |d|
13
- d.push :self
14
- d.push 1
15
- d.push 1
16
- d.send :+, 1, false
17
- d.send :puts, 1, true
18
- d.pop
19
-
20
- d.in_method :blah do |d2|
21
- d2.push :self
22
- d2.push_literal "hello"
23
- d2.string_dup
24
- d2.send :puts, 1, true
25
- end
26
- end
27
- end
28
- end
29
-
30
- relates <<-ruby do
31
- class ::Y
32
- c
33
- end
34
- ruby
35
-
36
- compile do |g|
37
- g.push_rubinius
38
- g.push_literal :Y
39
- g.push :nil
40
- g.push_cpath_top
41
- g.send :open_class_under, 3
42
- d = new_generator(g, :Y)
43
- g.create_block d
44
- d.push_self
45
- d.add_scope
46
- d.push :self
47
- d.send :c, 0, true
48
- d.ret
49
-
50
- g.swap
51
- g.push_scope
52
- g.push_true
53
- g.send :call_under, 3
54
- end
55
- end
56
-
57
- relates <<-ruby do
58
- class X::Y
59
- c
60
- end
61
- ruby
62
-
63
- compile do |g|
64
- in_class "X::Y" do |d|
65
- d.push :self
66
- d.send :c, 0, true
67
- end
68
- end
69
- end
70
-
71
- relates <<-ruby do
72
- class X < Array
73
- end
74
- ruby
75
-
76
- compile do |g|
77
- g.push_rubinius
78
- g.push_literal :X
79
- g.push_const :Array
80
- g.push_scope
81
- g.send :open_class, 3
82
- g.pop
83
- g.push :nil
84
- end
85
- end
86
-
87
- relates <<-ruby do
88
- class X < expr
89
- end
90
- ruby
91
-
92
- compile do |g|
93
- g.push_rubinius
94
- g.push_literal :X
95
- g.push :self
96
- g.send :expr, 0, true
97
- g.push_scope
98
- g.send :open_class, 3
99
-
100
- g.pop
101
- g.push :nil
102
- end
103
- end
104
-
105
- relates <<-ruby do
106
- class X < Object
107
- end
108
- ruby
109
-
110
- compile do |g|
111
- g.push_rubinius
112
- g.push_literal :X
113
- g.push_const :Object
114
- g.push_scope
115
- g.send :open_class, 3
116
- g.pop
117
- g.push :nil
118
- end
119
- end
120
- end
data/spec/colon2_spec.rb DELETED
@@ -1,8 +0,0 @@
1
- describe "A Colon2 node" do
2
- relates "X::Y" do
3
- compile do |g|
4
- g.push_const :X
5
- g.find_const :Y
6
- end
7
- end
8
- end
data/spec/colon3_spec.rb DELETED
@@ -1,8 +0,0 @@
1
- describe "A Colon3 node" do
2
- relates "::X" do
3
- compile do |g|
4
- g.push_cpath_top
5
- g.find_const :X
6
- end
7
- end
8
- end
data/spec/const_spec.rb DELETED
@@ -1,7 +0,0 @@
1
- describe "A Const node" do
2
- relates "X" do
3
- compile do |g|
4
- g.push_const :X
5
- end
6
- end
7
- end
@@ -1,18 +0,0 @@
1
- require 'tooling/profiler/profiler'
2
-
3
- class ProfilerGuard < SpecGuard
4
- def match?
5
- Rubinius::Profiler::Instrumenter.available? and
6
- not Rubinius::Profiler::Instrumenter.active?
7
- end
8
- end
9
-
10
- class Object
11
- def with_profiler
12
- g = ProfilerGuard.new
13
- g.name = :with_profiler
14
- yield if g.yield?
15
- ensure
16
- g.unregister
17
- end
18
- end
@@ -1,828 +0,0 @@
1
- # TODO: document TestGenerator
2
- module Rubinius
3
- class TestGenerator
4
- class Label
5
- attr_reader :ip
6
-
7
- def initialize(gen)
8
- @generator = gen
9
- @ip = nil
10
- @used = false
11
- end
12
-
13
- attr_reader :used
14
- alias_method :used?, :used
15
-
16
- def used!
17
- @used = true
18
- end
19
-
20
- def inspect
21
- self.to_sym.inspect
22
- end
23
-
24
- def to_sym
25
- return :UNSET_LABEL unless @ip
26
- # raise "Unset label!" unless @ip
27
- :"label_#{@ip}"
28
- end
29
-
30
- def set!
31
- @ip = @generator.new_label_id
32
- @generator.set_label self.to_sym
33
- end
34
-
35
- def ==(lbl)
36
- raise "Unset label!" unless @ip
37
- return self.to_sym == lbl if Symbol === lbl
38
- @ip == lbl.ip
39
- end
40
- end
41
-
42
- # TestGenerator methods
43
-
44
- def self.define_opcode_method(name)
45
- class_eval <<-CODE
46
- def #{name}(*args)
47
- add :#{name}, *args
48
- end
49
- CODE
50
- end
51
-
52
- excluded_opcodes = [:class, :goto, :set_label, :cast_array, :setup_unwind]
53
-
54
- Rubinius::InstructionSet.opcodes.each do |opcode|
55
- next if excluded_opcodes.include? opcode.name
56
- define_opcode_method opcode.name
57
- end
58
-
59
- [:add_literal,
60
- :pop_modifiers,
61
- :push,
62
- :push_literal_at,
63
- :push_modifiers,
64
- :invoke_primitive,
65
- :last_match,
66
- :send,
67
- :send_super,
68
- :send_with_block,
69
- :send_with_splat,
70
- :swap].each do |name|
71
- define_opcode_method name
72
- end
73
-
74
- def git(lbl)
75
- lbl.used!
76
- add :goto_if_true, lbl
77
- end
78
-
79
- def gif(lbl)
80
- lbl.used!
81
- add :goto_if_false, lbl
82
- end
83
-
84
- def send_vcall(meth)
85
- send meth, 0, true
86
- end
87
-
88
- # The :g accessor is provided to make the code in the
89
- # utility methods below clearer
90
- attr_reader :g
91
- attr_accessor :stream, :ip, :redo, :break, :next, :retry,
92
- :name, :file, :line, :primitive, :for_block, :for_module_body,
93
- :required_args, :post_args, :total_args, :splat_index,
94
- :local_count, :local_names, :block_index
95
-
96
-
97
- def initialize
98
- @stream = []
99
- @ip = 0
100
- @lbl = 0
101
- @slot = 0
102
- @g = self
103
- @state = []
104
- @stack_locals = 0
105
- end
106
-
107
- def new_stack_local
108
- idx = @stack_locals
109
- @stack_locals += 1
110
- return idx
111
- end
112
-
113
- def state
114
- @state.last
115
- end
116
-
117
- # TODO: put TestGenerator under Rubinius
118
- def push_state(scope)
119
- @state << Rubinius::ToolSets::Spec::AST::State.new(scope)
120
- end
121
-
122
- def pop_state
123
- @state.pop
124
- end
125
- def run(node)
126
- node.bytecode(self)
127
- end
128
-
129
- def convert_to_ary(ary)
130
- ary.map do |item|
131
- if item.respond_to? :to_ary
132
- convert_to_ary item.to_ary
133
- elsif item.kind_of? TestGenerator
134
- item.to_a
135
- else
136
- item
137
- end
138
- end
139
- end
140
-
141
- def to_a
142
- convert_to_ary [:test_generator, @stream]
143
- end
144
-
145
- def pretty_inspect
146
- to_a.pretty_inspect
147
- end
148
-
149
- def inspect
150
- to_a.inspect
151
- end
152
-
153
- def add(*args)
154
- @last = args
155
- @stream << args
156
- @ip += 1
157
- end
158
-
159
- def new_slot
160
- @ip
161
- end
162
-
163
- def new_label
164
- Label.new self
165
- end
166
-
167
- def new_label_id
168
- @lbl += 1
169
- @lbl
170
- end
171
-
172
- def dup
173
- add :dup
174
- end
175
-
176
- def definition_line(line)
177
- # nothing
178
- end
179
-
180
- def set_line(line)
181
- @line = line
182
- end
183
-
184
- def set_label(lbl)
185
- @stream << [:set_label, lbl.to_sym]
186
- end
187
-
188
- def close
189
- end
190
-
191
- def ==(tg)
192
- tg.class == self.class && tg.stream == @stream
193
- end
194
-
195
- # Hack to provide expected semantics
196
- def ===(other)
197
- equal? other
198
- end
199
-
200
- def find_literal(lit)
201
- lit
202
- end
203
-
204
- def goto(x)
205
- raise "Bad goto: #{x.inspect} on #{caller.first}" unless Label === x
206
- x.used!
207
- add :goto, x
208
- end
209
-
210
- def setup_unwind(label, *)
211
- add :setup_unwind, label
212
- end
213
-
214
- def send_primitive(name)
215
- @primitive = name
216
- end
217
-
218
- def push_unique_literal(lit)
219
- push_literal lit
220
- end
221
-
222
- def push_generator(desc)
223
- push_literal desc
224
- end
225
-
226
- def new_block_generator(g)
227
- blk = g.class.new
228
- blk.name == :__block__
229
-
230
- blk
231
- end
232
-
233
- def new_generator(g, name=nil)
234
- meth = g.class.new
235
- meth.name = name
236
-
237
- meth
238
- end
239
-
240
- def splatted_array(n=1)
241
- bottom = g.new_label
242
-
243
- if block_given?
244
- yield
245
- else
246
- g.push 1
247
- end
248
- g.make_array n
249
-
250
- g.cast_array
251
- g.dup
252
- g.send :size, 0
253
- g.push 1
254
- g.send :>, 1
255
- g.git bottom
256
-
257
- g.push 0
258
- g.send :at, 1
259
-
260
- bottom.set!
261
- end
262
-
263
- def in_block_send(name, type, required=nil, call_count=0, vis=true)
264
- d = new_block_generator(g)
265
-
266
- # Arguments for blocks are handled differently in 1.9
267
- ruby_version_is ""..."1.9" do
268
- count = nil
269
-
270
- case type
271
- when :none
272
- required = -1
273
- when :empty
274
- required = 0
275
- when :blank
276
- required = -1
277
- d.cast_for_splat_block_arg
278
- when :single
279
- required = 1
280
- d.cast_for_single_block_arg
281
- d.set_local 0
282
- when :splat
283
- required = -1
284
- d.cast_for_splat_block_arg
285
- d.set_local 0
286
- when :rest
287
- count = required.abs - 1
288
- when :multi
289
- count = required.abs
290
- end
291
-
292
- if count
293
- d.cast_for_multi_block_arg
294
-
295
- (0...count).each do |n|
296
- d.shift_array
297
- d.set_local n
298
- d.pop
299
- end
300
- end
301
-
302
- if type == :rest
303
- d.set_local count
304
- end
305
-
306
- if type != :none and type != :empty and type != 0
307
- d.pop
308
- end
309
- end
310
-
311
- d.push_modifiers
312
- d.new_label.set!
313
-
314
- yield d
315
-
316
- d.pop_modifiers
317
- d.ret
318
-
319
- g.create_block(d)
320
-
321
- g.send_with_block name, call_count, vis
322
- end
323
-
324
- def in_class(name)
325
- case name
326
- when Symbol
327
- g.push_rubinius
328
- g.push_literal name
329
- g.push :nil
330
-
331
- g.push_scope
332
- g.send :open_class, 3
333
- when String
334
- g.push_rubinius
335
-
336
- levels = name.split(/::/).map { |s| s.to_sym }
337
- klass = levels.pop
338
-
339
- g.push_literal klass
340
- g.push :nil
341
-
342
- levels.each do |level|
343
- g.push_const level
344
- end
345
-
346
- g.send :open_class_under, 3
347
- end
348
-
349
- return unless block_given?
350
-
351
- d = new_generator(g, :Y)
352
-
353
- g.create_block d
354
-
355
- d.push_self
356
- d.add_scope
357
-
358
- yield d
359
-
360
- d.ret
361
-
362
- g.swap
363
- g.push_scope
364
- g.push_true
365
- g.send :call_under, 3
366
- end
367
-
368
- def in_singleton_method(name, sing)
369
- g.push_rubinius
370
-
371
- g.push_literal name
372
-
373
- d = new_generator(g, name)
374
-
375
- yield d
376
- d.ret
377
-
378
- g.push_literal(d)
379
-
380
- g.push_scope
381
-
382
- if sing.kind_of? Array
383
- g.add *sing
384
- else
385
- g.add sing
386
- end
387
-
388
- g.send :attach_method, 4
389
- end
390
-
391
- def in_method(name, singleton=false)
392
- if singleton
393
- raise "use in_singleton_method"
394
- end
395
-
396
- g.push_rubinius
397
-
398
- g.push_literal name
399
-
400
- d = new_generator(g, name)
401
-
402
- yield d
403
- d.ret
404
-
405
- g.push_literal(d)
406
-
407
- g.push_scope
408
-
409
- g.push_variables
410
- g.send :method_visibility, 0
411
- g.send :add_defn_method, 4
412
- end
413
-
414
- def in_module(name)
415
- case name
416
- when Symbol
417
- g.push_rubinius
418
- g.push_literal name
419
- g.push_scope
420
- g.send :open_module, 2
421
- when String
422
- levels = name.split(/::/).map { |s| s.to_sym }
423
- klass = levels.pop
424
-
425
- g.push_rubinius
426
- g.push_literal klass
427
-
428
- levels.each do |level|
429
- g.push_const level
430
- end
431
-
432
- g.send :open_module_under, 2
433
- end
434
-
435
- return unless block_given?
436
-
437
- d = new_generator(g, :Y)
438
-
439
- g.create_block d
440
-
441
- d.push_self
442
- d.add_scope
443
-
444
- yield d
445
-
446
- d.ret
447
-
448
- g.swap
449
- g.push_scope
450
- g.push_true
451
- g.send :call_under, 3
452
- end
453
-
454
- def save_exception
455
- idx = new_stack_local
456
- push_exception_state
457
- set_stack_local idx
458
- pop
459
-
460
- return idx
461
- end
462
-
463
- def restore_exception(idx)
464
- push_stack_local idx
465
- restore_exception_state
466
- end
467
-
468
- class Break
469
- def initialize(g)
470
- @label = g.new_label
471
- @original = g.break
472
- @emit = false
473
- end
474
-
475
- attr_accessor :label, :original, :emit
476
- end
477
-
478
- class Next < Break
479
- end
480
-
481
- class RescueBlock
482
- def initialize(g)
483
- @body = nil
484
- @conditions = []
485
- @else = nil
486
- @break = nil
487
- @next = nil
488
- @g = g
489
- end
490
-
491
- attr_reader :conditions, :current_break
492
- attr_accessor :saved_exc
493
-
494
- def set_break(b)
495
- @break = b
496
- end
497
-
498
- def body(&block)
499
- @body ||= block
500
- end
501
-
502
- def condition(klass, top_level = false, &block)
503
- @conditions << [klass, block, top_level]
504
- end
505
-
506
- def raw_condition(&block)
507
- @conditions << [nil, block, false]
508
- end
509
-
510
- def els(&block)
511
- @else ||= block
512
- end
513
-
514
- def new_break
515
- @break = Break.new(@g)
516
- end
517
-
518
- def new_next
519
- @next = Next.new(@g)
520
- end
521
-
522
- def clear_break
523
- @break = nil
524
- end
525
-
526
- def clear_next
527
- @next = nil
528
- end
529
-
530
- def break
531
- raise "no break info" unless @break
532
- @g.goto @break.label
533
- @break.emit = true
534
- end
535
-
536
- def next
537
- raise "no next info" unless @next
538
- @g.goto @next.label
539
- @next.emit = true
540
- end
541
-
542
- def restore_exception
543
- @g.restore_exception @saved_exc
544
- end
545
-
546
- end
547
-
548
- def for_rescue
549
- rb = RescueBlock.new(self)
550
- yield rb
551
-
552
- jump_retry = g.new_label
553
- jump_else = g.new_label
554
- jump_last = g.new_label
555
-
556
- g.push_modifiers
557
-
558
- rb.saved_exc = save_exception
559
-
560
- jump_retry.set!
561
-
562
- exc_lbl = g.new_label
563
- g.setup_unwind exc_lbl
564
-
565
- g.new_label.set!
566
-
567
- br = rb.new_break
568
- nx = rb.new_next
569
-
570
- rb.body.call
571
-
572
- g.pop_unwind
573
- g.goto jump_else
574
-
575
- if br.emit
576
- br.label.set!
577
- g.pop_unwind
578
-
579
- g.restore_exception rb.saved_exc
580
-
581
- if br.original
582
- g.goto br.original
583
- else
584
- g.goto jump_else
585
- end
586
- end
587
-
588
- if nx.emit
589
- nx.label.set!
590
-
591
- g.pop_unwind
592
-
593
- g.restore_exception rb.saved_exc
594
-
595
- if nx.original
596
- g.goto nx.original
597
- else
598
- g.ret
599
- end
600
- end
601
-
602
- exc_lbl.set!
603
-
604
- g.push_exception_state
605
- raised_state = g.new_stack_local
606
- g.set_stack_local raised_state
607
- g.pop
608
-
609
- g.push_current_exception
610
-
611
- rb.conditions.each do |klass, code, top_level|
612
- jump_body = g.new_label
613
- jump_next = g.new_label
614
-
615
- if klass
616
- g.dup
617
- if top_level
618
- g.push_cpath_top
619
- g.find_const klass
620
- else
621
- g.push_const klass
622
- end
623
- g.swap
624
- g.send :===, 1
625
- g.git jump_body
626
-
627
- g.goto jump_next
628
-
629
- jump_body.set!
630
-
631
- g.pop # remove the saved exception on the stack
632
- end
633
-
634
- br = rb.new_break
635
- nx = rb.new_next
636
-
637
- code.call(jump_body, jump_next)
638
-
639
- g.clear_exception
640
- g.goto jump_last
641
-
642
- if br.emit
643
- br.label.set!
644
- g.clear_exception
645
-
646
- g.restore_exception rb.saved_exc
647
-
648
- if br.original
649
- g.goto br.original
650
- else
651
- g.raise_break
652
- end
653
- end
654
-
655
- if nx.emit
656
- nx.label.set!
657
- g.clear_exception
658
-
659
- g.restore_exception rb.saved_exc
660
-
661
- if br.original
662
- g.goto br.original
663
- else
664
- g.ret
665
- end
666
- end
667
-
668
- jump_next.set!
669
- end
670
-
671
- g.pop
672
-
673
- g.push_stack_local raised_state
674
- g.restore_exception_state
675
- g.reraise
676
-
677
- jump_else.set!
678
-
679
- rb.els.call if rb.els
680
-
681
- jump_last.set!
682
-
683
- restore_exception rb.saved_exc
684
-
685
- g.pop_modifiers
686
- end
687
-
688
- class EnsureBlock
689
- def initialize
690
- @body = nil
691
- @handler = nil
692
- end
693
-
694
- def body(&block)
695
- @body ||= block
696
- end
697
-
698
- def handler(&block)
699
- @handler ||= block
700
- end
701
- end
702
-
703
- def for_ensure
704
- eb = EnsureBlock.new
705
-
706
- yield eb
707
-
708
- ensure_good = g.new_label
709
- ensure_bad = g.new_label
710
-
711
- g.setup_unwind ensure_bad
712
-
713
- jump_top = g.new_label
714
- jump_top.set!
715
-
716
- g.save_exception
717
-
718
- old_break = g.break
719
- new_break = g.new_label
720
- g.break = new_break
721
-
722
- eb.body.call
723
-
724
- g.break = old_break
725
-
726
- g.pop_unwind
727
- g.goto ensure_good
728
-
729
- check_break = nil
730
-
731
- if new_break.used?
732
- used_break_local = g.new_stack_local
733
- check_break = g.new_label
734
-
735
- new_break.set!
736
- g.pop_unwind
737
-
738
- g.push :true
739
- g.set_stack_local used_break_local
740
- g.pop
741
-
742
- g.goto check_break
743
- end
744
-
745
- ensure_bad.set!
746
- g.push_exception_state
747
-
748
- eb.handler.call
749
- g.restore_exception_state
750
- g.reraise
751
-
752
- ensure_good.set!
753
-
754
- if check_break
755
- g.push :false
756
- g.set_stack_local used_break_local
757
- g.pop
758
-
759
- check_break.set!
760
- end
761
-
762
- eb.handler.call
763
-
764
- if check_break
765
- post = g.new_label
766
-
767
- g.push_stack_local used_break_local
768
- g.gif post
769
-
770
- if g.break
771
- g.goto g.break
772
- else
773
- g.raise_break
774
- end
775
-
776
- post.set!
777
- end
778
- end
779
-
780
- def optional_arg(slot)
781
- if_set = g.new_label
782
- g.passed_arg slot
783
- g.git if_set
784
- g.push 42
785
- g.set_local slot
786
- g.pop
787
- if_set.set!
788
- end
789
-
790
- def block_arg(slot)
791
- g.push_proc
792
- g.set_local slot
793
- g.pop
794
- end
795
-
796
- def memoize
797
- memo = g.new_label
798
- g.add_literal nil
799
- slot = new_slot
800
- g.push_literal_at slot
801
- g.dup
802
- g.is_nil
803
- g.gif memo
804
- g.pop
805
-
806
- yield g
807
-
808
- g.set_literal slot
809
- memo.set!
810
- end
811
-
812
- def undef_bytecode(*names)
813
- last_name = names.last
814
- names.each do |name|
815
- g.push_scope
816
- g.push_literal name
817
- g.send :__undef_method__, 1
818
- g.pop unless name == last_name
819
- end
820
- end
821
-
822
- def cast_array
823
- unless @last and [:cast_array, :make_array].include? @last.first
824
- add :cast_array
825
- end
826
- end
827
- end
828
- end