Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Default to VM_CALL_ARGS_SIMPLE
  • Loading branch information
kddnewton committed Nov 21, 2022
commit a1236fd6c4e4a22292e2a1d52facb95ecdc7a208
20 changes: 10 additions & 10 deletions lib/syntax_tree/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -253,13 +253,13 @@ def visit_alias(node)
iseq.putspecialobject(YARV::VM_SPECIAL_OBJECT_CBASE)
visit(node.left)
visit(node.right)
iseq.send(:"core#set_method_alias", 3, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:"core#set_method_alias", 3)
end

def visit_aref(node)
visit(node.collection)
visit(node.index)
iseq.send(:[], 1, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:[], 1)
end

def visit_arg_block(node)
Expand Down Expand Up @@ -313,7 +313,7 @@ def visit_assign(node)
visit(node.target.index)
visit(node.value)
iseq.setn(3)
iseq.send(:[]=, 2, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:[]=, 2)
iseq.pop
when ConstPathField
names = constant_names(node.target)
Expand All @@ -337,7 +337,7 @@ def visit_assign(node)
visit(node.target)
visit(node.value)
iseq.setn(2)
iseq.send(:"#{node.target.name.value}=", 1, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:"#{node.target.name.value}=", 1)
iseq.pop
when TopConstField
name = node.target.constant.value.to_sym
Expand Down Expand Up @@ -420,7 +420,7 @@ def visit_binary(node)
else
visit(node.left)
visit(node.right)
iseq.send(node.operator, 1, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(node.operator, 1)
end
end

Expand Down Expand Up @@ -981,7 +981,7 @@ def visit_mrhs(node)

def visit_not(node)
visit(node.statement)
iseq.send(:!, 0, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:!, 0)
end

def visit_opassign(node)
Expand Down Expand Up @@ -1367,7 +1367,7 @@ def visit_undef(node)
iseq.putspecialobject(YARV::VM_SPECIAL_OBJECT_VMCORE)
iseq.putspecialobject(YARV::VM_SPECIAL_OBJECT_CBASE)
visit(symbol)
iseq.send(:"core#undef_method", 2, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:"core#undef_method", 2)
end
end

Expand Down Expand Up @@ -1523,7 +1523,7 @@ def visit_xstring_literal(node)
def visit_yield(node)
parts = argument_parts(node.arguments)
visit_all(parts)
iseq.invokeblock(nil, parts.length, YARV::VM_CALL_ARGS_SIMPLE)
iseq.invokeblock(nil, parts.length)
end

def visit_zsuper(_node)
Expand Down Expand Up @@ -1759,12 +1759,12 @@ def with_opassign(node)
visit(node.target.index)

iseq.dupn(2)
iseq.send(:[], 1, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:[], 1)

yield

iseq.setn(3)
iseq.send(:[]=, 2, YARV::VM_CALL_ARGS_SIMPLE)
iseq.send(:[]=, 2)
iseq.pop
when ConstPathField
name = node.target.constant.value.to_sym
Expand Down
4 changes: 4 additions & 0 deletions lib/syntax_tree/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def BodyStmt(statements, rescue_clause, else_keyword, else_clause, ensure_clause
BodyStmt.new(statements: statements, rescue_clause: rescue_clause, else_keyword: else_keyword, else_clause: else_clause, ensure_clause: ensure_clause, location: Location.default)
end

def Break(arguments)
Break.new(arguments: arguments, location: Location.default)
end

def CallNode(receiver, operator, message, arguments)
CallNode.new(receiver: receiver, operator: operator, message: message, arguments: arguments, location: Location.default)
end
Expand Down
23 changes: 10 additions & 13 deletions lib/syntax_tree/yarv.rb
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ def intern
push([:intern])
end

def invokeblock(method_id, argc, flag)
def invokeblock(method_id, argc, flag = VM_CALL_ARGS_SIMPLE)
stack.change_by(-argc + 1)
push([:invokeblock, call_data(method_id, argc, flag)])
end
Expand Down Expand Up @@ -547,7 +547,7 @@ def opt_newarray_max(length)
push([:opt_newarray_max, length])
else
newarray(length)
send(:max, 0, VM_CALL_ARGS_SIMPLE)
send(:max, 0)
end
end

Expand All @@ -557,7 +557,7 @@ def opt_newarray_min(length)
push([:opt_newarray_min, length])
else
newarray(length)
send(:min, 0, VM_CALL_ARGS_SIMPLE)
send(:min, 0)
end
end

Expand All @@ -569,22 +569,20 @@ def opt_setinlinecache(inline_storage)
def opt_str_freeze(value)
if specialized_instruction
stack.change_by(+1)
push(
[:opt_str_freeze, value, call_data(:freeze, 0, VM_CALL_ARGS_SIMPLE)]
)
push([:opt_str_freeze, value, call_data(:freeze, 0)])
else
putstring(value)
send(:freeze, 0, VM_CALL_ARGS_SIMPLE)
send(:freeze, 0)
end
end

def opt_str_uminus(value)
if specialized_instruction
stack.change_by(+1)
push([:opt_str_uminus, value, call_data(:-@, 0, VM_CALL_ARGS_SIMPLE)])
push([:opt_str_uminus, value, call_data(:-@, 0)])
else
putstring(value)
send(:-@, 0, VM_CALL_ARGS_SIMPLE)
send(:-@, 0)
end
end

Expand Down Expand Up @@ -633,7 +631,7 @@ def putstring(object)
push([:putstring, object])
end

def send(method_id, argc, flag, block_iseq = nil)
def send(method_id, argc, flag = VM_CALL_ARGS_SIMPLE, block_iseq = nil)
stack.change_by(-(argc + 1) + 1)
cdata = call_data(method_id, argc, flag)

Expand Down Expand Up @@ -669,8 +667,7 @@ def send(method_id, argc, flag, block_iseq = nil)
when [:|, 1] then push([:opt_or, cdata])
when [:[]=, 2] then push([:opt_aset, cdata])
when [:!=, 1]
eql_data = call_data(:==, 1, VM_CALL_ARGS_SIMPLE)
push([:opt_neq, eql_data, cdata])
push([:opt_neq, call_data(:==, 1), cdata])
else
push([:opt_send_without_block, cdata])
end
Expand Down Expand Up @@ -762,7 +759,7 @@ def toregexp(options, length)

# This creates a call data object that is used as the operand for the
# send, invokesuper, and objtostring instructions.
def call_data(method_id, argc, flag)
def call_data(method_id, argc, flag = VM_CALL_ARGS_SIMPLE)
{ mid: method_id, flag: flag, orig_argc: argc }
end

Expand Down
33 changes: 16 additions & 17 deletions lib/syntax_tree/yarv/bf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ def visit_input(node)
iseq.getglobal(:$tape)
iseq.getglobal(:$cursor)
iseq.getglobal(:$stdin)
iseq.send(:getc, 0, VM_CALL_ARGS_SIMPLE)
iseq.send(:ord, 0, VM_CALL_ARGS_SIMPLE)
iseq.send(:[]=, 2, VM_CALL_ARGS_SIMPLE)
iseq.send(:getc, 0)
iseq.send(:ord, 0)
iseq.send(:[]=, 2)
end

def visit_loop(node)
Expand All @@ -273,9 +273,9 @@ def visit_loop(node)
# the loop.
iseq.getglobal(:$tape)
iseq.getglobal(:$cursor)
iseq.send(:[], 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:[], 1)
iseq.putobject(0)
iseq.send(:==, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:==, 1)
branchunless = iseq.branchunless(-1)

# Otherwise, here we'll execute the loop.
Expand All @@ -294,25 +294,24 @@ def visit_output(node)
iseq.getglobal(:$stdout)
iseq.getglobal(:$tape)
iseq.getglobal(:$cursor)
iseq.send(:[], 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:chr, 0, VM_CALL_ARGS_SIMPLE)
iseq.send(:putc, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:[], 1)
iseq.send(:chr, 0)
iseq.send(:putc, 1)
end

def visit_root(node)
iseq.duphash({ 0 => 0 })
iseq.setglobal(:$tape)
iseq.getglobal(:$tape)
iseq.putobject(0)
iseq.send(:default=, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:default=, 1)

iseq.putobject(0)
iseq.setglobal(:$cursor)

visit_nodes(node.nodes)

iseq.putself
iseq.send(:exit, 0, VM_CALL_ARGS_SIMPLE)
iseq.leave
iseq
end

Expand All @@ -331,28 +330,28 @@ def change_by(value)
iseq.getglobal(:$cursor)
iseq.getglobal(:$tape)
iseq.getglobal(:$cursor)
iseq.send(:[], 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:[], 1)

if value < 0
iseq.putobject(-value)
iseq.send(:-, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:-, 1)
else
iseq.putobject(value)
iseq.send(:+, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:+, 1)
end

iseq.send(:[]=, 2, VM_CALL_ARGS_SIMPLE)
iseq.send(:[]=, 2)
end

def shift_by(value)
iseq.getglobal(:$cursor)

if value < 0
iseq.putobject(-value)
iseq.send(:-, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:-, 1)
else
iseq.putobject(value)
iseq.send(:+, 1, VM_CALL_ARGS_SIMPLE)
iseq.send(:+, 1)
end

iseq.setglobal(:$cursor)
Expand Down
40 changes: 27 additions & 13 deletions lib/syntax_tree/yarv/disassembler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def initialize(iseq)
end

def to_ruby
Program(Statements(disassemble(iseq.insns)))
Program(disassemble(iseq))
end

private
Expand All @@ -31,12 +31,12 @@ def node_for(value)
end
end

def disassemble(insns)
def disassemble(iseq)
label = :label_0
clauses = {}
clause = []

insns.each do |insn|
iseq.insns.each do |insn|
if insn.is_a?(Symbol) && insn.start_with?("label_")
clause << Assign(label_field, node_for(insn)) unless clause.last.is_a?(Next)
clauses[label] = clause
Expand All @@ -61,7 +61,8 @@ def disassemble(insns)
clause << Assign(label_field, node_for(insn[1]))
clause << Next(Args([]))
when :leave
clause << ReturnNode(Args([clause.pop]))
value = Args([clause.pop])
clause << (iseq.type == :top ? Break(value) : ReturnNode(value))
when :opt_and
left, right = clause.pop(2)
clause << Binary(left, :&, right)
Expand Down Expand Up @@ -116,14 +117,27 @@ def disassemble(insns)
left, right = clause.pop(2)
clause << Binary(left, :+, right)
when :opt_send_without_block
if insn[1][:orig_argc] == 0
clause << CallNode(clause.pop, Period("."), Ident(insn[1][:mid]), nil)
elsif insn[1][:orig_argc] == 1 && insn[1][:mid].end_with?("=")
receiver, argument = clause.pop(2)
clause << Assign(CallNode(receiver, Period("."), Ident(insn[1][:mid][0..-2]), nil), argument)
if insn[1][:flag] & VM_CALL_FCALL > 0
if insn[1][:orig_argc] == 0
clause.pop
clause << CallNode(nil, nil, Ident(insn[1][:mid]), Args([]))
elsif insn[1][:orig_argc] == 1 && insn[1][:mid].end_with?("=")
_receiver, argument = clause.pop(2)
clause << Assign(CallNode(nil, nil, Ident(insn[1][:mid][0..-2]), nil), argument)
else
_receiver, *arguments = clause.pop(insn[1][:orig_argc] + 1)
clause << CallNode(nil, nil, Ident(insn[1][:mid]), ArgParen(Args(arguments)))
end
else
receiver, *arguments = clause.pop(insn[1][:orig_argc] + 1)
clause << CallNode(receiver, Period("."), Ident(insn[1][:mid]), ArgParen(Args(arguments)))
if insn[1][:orig_argc] == 0
clause << CallNode(clause.pop, Period("."), Ident(insn[1][:mid]), nil)
elsif insn[1][:orig_argc] == 1 && insn[1][:mid].end_with?("=")
receiver, argument = clause.pop(2)
clause << Assign(CallNode(receiver, Period("."), Ident(insn[1][:mid][0..-2]), nil), argument)
else
receiver, *arguments = clause.pop(insn[1][:orig_argc] + 1)
clause << CallNode(receiver, Period("."), Ident(insn[1][:mid]), ArgParen(Args(arguments)))
end
end
when :putobject
case insn[1]
Expand Down Expand Up @@ -166,7 +180,7 @@ def disassemble(insns)
# If there's only one clause, then we don't need a case statement, and
# we can just disassemble the first clause.
clauses[label] = clause
return clauses.values.first if clauses.size == 1
return Statements(clauses.values.first) if clauses.size == 1

# Here we're going to build up a big case statement that will handle all
# of the different labels.
Expand Down Expand Up @@ -196,7 +210,7 @@ def disassemble(insns)
# statement.
stack << Assign(label_field, node_for(:label_0))
stack << MethodAddBlock(CallNode(nil, nil, Ident("loop"), Args([])), BlockNode(Kw("do"), nil, BodyStmt(Statements([switch]), nil, nil, nil, nil)))
stack
Statements(stack)
end

def local_name(index, level)
Expand Down
Loading