Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7006456

Browse files
committed
Add an entire compile! step
1 parent b998a6e commit 7006456

File tree

6 files changed

+111
-44
lines changed

6 files changed

+111
-44
lines changed

lib/syntax_tree/yarv.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ def self.compile(source, options = Compiler::Options.new)
281281
def self.interpret(source, options = Compiler::Options.new)
282282
iseq = RubyVM::InstructionSequence.compile(source, **options)
283283
iseq = InstructionSequence.from(iseq.to_a)
284-
iseq.specialize_instructions!
285284
VM.new.run_top_frame(iseq)
286285
end
287286
end

lib/syntax_tree/yarv/bf.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def compile
7474
end
7575

7676
iseq.leave
77+
iseq.compile!
7778
iseq
7879
end
7980

lib/syntax_tree/yarv/compiler.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,7 @@ def visit_program(node)
13591359
node.location,
13601360
options
13611361
)
1362+
13621363
with_child_iseq(top_iseq) do
13631364
visit_all(preexes)
13641365

@@ -1372,6 +1373,9 @@ def visit_program(node)
13721373

13731374
iseq.leave
13741375
end
1376+
1377+
top_iseq.compile!
1378+
top_iseq
13751379
end
13761380

13771381
def visit_qsymbols(node)

lib/syntax_tree/yarv/disassembler.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ def disassemble(iseq)
5454
clauses = {}
5555
clause = []
5656

57-
iseq.to_a
5857
iseq.insns.each do |insn|
5958
case insn
6059
when InstructionSequence::Label
@@ -192,7 +191,7 @@ def disassemble(iseq)
192191
Assign(VarField(target), value)
193192
end
194193
else
195-
raise "Unknown instruction #{insn[0]}"
194+
raise "Unknown instruction #{insn}"
196195
end
197196
end
198197

lib/syntax_tree/yarv/instruction_sequence.rb

Lines changed: 62 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -232,24 +232,7 @@ def eval
232232
def to_a
233233
versions = RUBY_VERSION.split(".").map(&:to_i)
234234

235-
# First, handle any compilation options that we need to.
236-
specialize_instructions! if options.specialized_instruction?
237-
peephole_optimize! if options.peephole_optimization?
238-
239-
# Next, set it up so that all of the labels get their correct name.
240-
length = 0
241-
insns.each do |insn|
242-
case insn
243-
when Integer, Symbol
244-
# skip
245-
when Label
246-
insn.patch!(:"label_#{length}")
247-
else
248-
length += insn.length
249-
end
250-
end
251-
252-
# Next, dump all of the instructions into a flat list.
235+
# Dump all of the instructions into a flat list.
253236
dumped =
254237
insns.map do |insn|
255238
case insn
@@ -288,6 +271,65 @@ def to_a
288271
]
289272
end
290273

274+
def disasm
275+
output = StringIO.new
276+
output << "== disasm: #<ISeq:#{name}@<compiled>:1 (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})> (catch: FALSE)\n"
277+
278+
length = 0
279+
events = []
280+
281+
insns.each do |insn|
282+
case insn
283+
when Integer
284+
# skip
285+
when Symbol
286+
events << insn
287+
when Label
288+
# skip
289+
else
290+
output << "%04d " % length
291+
output << insn.disasm(self)
292+
output << "\n"
293+
end
294+
295+
length += insn.length
296+
end
297+
298+
output.string
299+
end
300+
301+
# This method converts our linked list of instructions into a final array
302+
# and performs any other compilation steps necessary.
303+
def compile!
304+
specialize_instructions! if options.specialized_instruction?
305+
306+
length = 0
307+
insns.each do |insn|
308+
case insn
309+
when Integer, Symbol
310+
# skip
311+
when Label
312+
insn.patch!(:"label_#{length}")
313+
when DefineClass
314+
insn.class_iseq.compile!
315+
length += insn.length
316+
when DefineMethod, DefineSMethod
317+
insn.method_iseq.compile!
318+
length += insn.length
319+
when InvokeSuper, Send
320+
insn.block_iseq.compile! if insn.block_iseq
321+
length += insn.length
322+
when Once
323+
insn.iseq.compile!
324+
length += insn.length
325+
else
326+
length += insn.length
327+
end
328+
end
329+
330+
@insns = insns.to_a
331+
end
332+
291333
def specialize_instructions!
292334
insns.each_node do |node, value|
293335
case value
@@ -333,8 +375,7 @@ def specialize_instructions!
333375
when Send
334376
calldata = value.calldata
335377

336-
if !value.block_iseq &&
337-
!calldata.flag?(CallData::CALL_ARGS_BLOCKARG)
378+
if !value.block_iseq && !calldata.flag?(CallData::CALL_ARGS_BLOCKARG)
338379
# Specialize the send instruction. If it doesn't have a block
339380
# attached, then we will replace it with an opt_send_without_block
340381
# and do further specializations based on the called method and
@@ -395,27 +436,6 @@ def specialize_instructions!
395436
end
396437
end
397438

398-
def peephole_optimize!
399-
# insns.each_node do |node, value|
400-
# case value
401-
# when Jump
402-
# # jump LABEL
403-
# # ...
404-
# # LABEL:
405-
# # leave
406-
# # =>
407-
# # leave
408-
# # ...
409-
# # LABEL:
410-
# # leave
411-
# # case value.label.node.next_node&.value
412-
# # when Leave
413-
# # node.value = Leave.new
414-
# # end
415-
# end
416-
# end
417-
end
418-
419439
##########################################################################
420440
# Child instruction sequence methods
421441
##########################################################################
@@ -1164,6 +1184,7 @@ def self.from(source, options = Compiler::Options.new, parent_iseq = nil)
11641184
end
11651185
end
11661186

1187+
iseq.compile! if iseq.type == :top
11671188
iseq
11681189
end
11691190
end

lib/syntax_tree/yarv/instructions.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ def initialize(
3333
@kw_arg = kw_arg
3434
end
3535

36+
def disasm
37+
flag_names = []
38+
flag_names << :ARGS_SPLAT if flag?(CALL_ARGS_SPLAT)
39+
flag_names << :ARGS_BLOCKARG if flag?(CALL_ARGS_BLOCKARG)
40+
flag_names << :FCALL if flag?(CALL_FCALL)
41+
flag_names << :VCALL if flag?(CALL_VCALL)
42+
flag_names << :ARGS_SIMPLE if flag?(CALL_ARGS_SIMPLE)
43+
flag_names << :BLOCKISEQ if flag?(CALL_BLOCKISEQ)
44+
flag_names << :KWARG if flag?(CALL_KWARG)
45+
flag_names << :KW_SPLAT if flag?(CALL_KW_SPLAT)
46+
flag_names << :TAILCALL if flag?(CALL_TAILCALL)
47+
flag_names << :SUPER if flag?(CALL_SUPER)
48+
flag_names << :ZSUPER if flag?(CALL_ZSUPER)
49+
flag_names << :OPT_SEND if flag?(CALL_OPT_SEND)
50+
flag_names << :KW_SPLAT_MUT if flag?(CALL_KW_SPLAT_MUT)
51+
52+
"<calldata!mid:#{method}, argc:#{argc}, #{flag_names.join("|")}>"
53+
end
54+
3655
def flag?(mask)
3756
(flags & mask) > 0
3857
end
@@ -1783,6 +1802,10 @@ def call(vm)
17831802
# ~~~
17841803
#
17851804
class Leave
1805+
def disasm(_iseq)
1806+
"leave"
1807+
end
1808+
17861809
def to_a(_iseq)
17871810
[:leave]
17881811
end
@@ -2973,6 +2996,10 @@ def initialize(calldata)
29732996
@calldata = calldata
29742997
end
29752998

2999+
def disasm(_iseq)
3000+
"%-38s %s" % ["opt_mult", calldata.disasm]
3001+
end
3002+
29763003
def to_a(_iseq)
29773004
[:opt_mult, calldata.to_h]
29783005
end
@@ -3288,6 +3315,10 @@ def initialize(calldata)
32883315
@calldata = calldata
32893316
end
32903317

3318+
def disasm(iseq)
3319+
"%-38s %s" % ["opt_plus", calldata.disasm]
3320+
end
3321+
32913322
def to_a(_iseq)
32923323
[:opt_plus, calldata.to_h]
32933324
end
@@ -3670,6 +3701,10 @@ def initialize(object)
36703701
@object = object
36713702
end
36723703

3704+
def disasm(_iseq)
3705+
"%-38s %s" % ["putobject", object.inspect]
3706+
end
3707+
36733708
def to_a(_iseq)
36743709
[:putobject, object]
36753710
end
@@ -3708,6 +3743,10 @@ def call(vm)
37083743
# ~~~
37093744
#
37103745
class PutObjectInt2Fix0
3746+
def disasm(_iseq)
3747+
"putobject_INT2FIX_0_"
3748+
end
3749+
37113750
def to_a(_iseq)
37123751
[:putobject_INT2FIX_0_]
37133752
end
@@ -3746,6 +3785,10 @@ def call(vm)
37463785
# ~~~
37473786
#
37483787
class PutObjectInt2Fix1
3788+
def disasm(_iseq)
3789+
"putobject_INT2FIX_1_"
3790+
end
3791+
37493792
def to_a(_iseq)
37503793
[:putobject_INT2FIX_1_]
37513794
end

0 commit comments

Comments
 (0)