@@ -52,6 +52,8 @@ def push(instruction)
52
52
@tail_node . next_node = node
53
53
@tail_node = node
54
54
end
55
+
56
+ node
55
57
end
56
58
end
57
59
@@ -98,15 +100,14 @@ class Label
98
100
# When we're serializing the instruction sequence, we need to be able to
99
101
# look up the label from the branch instructions and then access the
100
102
# subsequent node. So we'll store the reference here.
101
- attr_reader :node
103
+ attr_accessor :node
102
104
103
105
def initialize ( name = nil )
104
106
@name = name
105
107
end
106
108
107
- def patch! ( name , node )
109
+ def patch! ( name )
108
110
@name = name
109
- @node = node
110
111
end
111
112
end
112
113
@@ -222,8 +223,9 @@ def eval
222
223
def to_a
223
224
versions = RUBY_VERSION . split ( "." ) . map ( &:to_i )
224
225
225
- # First, specialize any instructions that need to be specialized .
226
+ # First, handle any compilation options that we need to.
226
227
specialize_instructions! if options . specialized_instruction?
228
+ peephole_optimize! if options . peephole_optimization?
227
229
228
230
# Next, set it up so that all of the labels get their correct name.
229
231
length = 0
@@ -232,7 +234,7 @@ def to_a
232
234
when Integer , Symbol
233
235
# skip
234
236
when Label
235
- value . patch! ( :"label_#{ length } " , node )
237
+ value . patch! ( :"label_#{ length } " )
236
238
else
237
239
length += value . length
238
240
end
@@ -383,6 +385,27 @@ def specialize_instructions!
383
385
end
384
386
end
385
387
388
+ def peephole_optimize!
389
+ insns . each_node do |node , value |
390
+ case value
391
+ when Jump
392
+ # jump LABEL
393
+ # ...
394
+ # LABEL:
395
+ # leave
396
+ # =>
397
+ # leave
398
+ # ...
399
+ # LABEL:
400
+ # leave
401
+ # case value.label.node.next_node&.value
402
+ # when Leave
403
+ # node.value = Leave.new
404
+ # end
405
+ end
406
+ end
407
+ end
408
+
386
409
##########################################################################
387
410
# Child instruction sequence methods
388
411
##########################################################################
@@ -421,15 +444,18 @@ def label
421
444
Label . new
422
445
end
423
446
424
- def push ( insn )
425
- insns . push ( insn )
447
+ def push ( value )
448
+ node = insns . push ( value )
426
449
427
- case insn
428
- when Array , Integer , Label , Symbol
429
- insn
450
+ case value
451
+ when Array , Integer , Symbol
452
+ value
453
+ when Label
454
+ value . node = node
455
+ value
430
456
else
431
- stack . change_by ( -insn . pops + insn . pushes )
432
- insn
457
+ stack . change_by ( -value . pops + value . pushes )
458
+ value
433
459
end
434
460
end
435
461
0 commit comments