rubinius-compiler 2.3.1 → 3.0

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