mirror of
https://github.com/ruby/ruby.git
synced 2025-08-24 21:44:30 +02:00

This commit is the initial sync of all files from ruby/yarp into ruby/ruby. Notably, it does the following: * Sync all ruby/yarp/lib/ files to ruby/ruby/lib/yarp * Sync all ruby/yarp/src/ files to ruby/ruby/yarp/ * Sync all ruby/yarp/test/ files to ruby/ruby/test/yarp
212 lines
5.4 KiB
Ruby
212 lines
5.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "yarp_test_helper"
|
|
|
|
class CompileTest < Test::Unit::TestCase
|
|
def test_AliasNode
|
|
assert_compiles("alias foo bar")
|
|
end
|
|
|
|
def test_AndNode
|
|
assert_compiles("true && false")
|
|
end
|
|
|
|
def test_ArrayNode
|
|
assert_compiles("[]")
|
|
assert_compiles("[foo, bar, baz]")
|
|
end
|
|
|
|
def test_AssocNode
|
|
assert_compiles("{ foo: bar }")
|
|
end
|
|
|
|
def test_BlockNode
|
|
assert_compiles("foo { bar }")
|
|
end
|
|
|
|
def test_BlockNode_with_optionals
|
|
assert_compiles("foo { |x = 1| bar }")
|
|
end
|
|
|
|
def test_CallNode
|
|
assert_compiles("foo")
|
|
assert_compiles("foo(bar)")
|
|
end
|
|
|
|
def test_ClassVariableReadNode
|
|
assert_compiles("@@foo")
|
|
end
|
|
|
|
def test_ClassVariableWriteNode
|
|
assert_compiles("@@foo = 1")
|
|
end
|
|
|
|
def test_FalseNode
|
|
assert_compiles("false")
|
|
end
|
|
|
|
def test_GlobalVariableReadNode
|
|
assert_compiles("$foo")
|
|
end
|
|
|
|
def test_GlobalVariableWriteNode
|
|
assert_compiles("$foo = 1")
|
|
end
|
|
|
|
def test_HashNode
|
|
assert_compiles("{ foo: bar }")
|
|
end
|
|
|
|
def test_InstanceVariableReadNode
|
|
assert_compiles("@foo")
|
|
end
|
|
|
|
def test_InstanceVariableWriteNode
|
|
assert_compiles("@foo = 1")
|
|
end
|
|
|
|
def test_IntegerNode
|
|
assert_compiles("1")
|
|
assert_compiles("1_000")
|
|
end
|
|
|
|
def test_InterpolatedStringNode
|
|
assert_compiles("\"foo \#{bar} baz\"")
|
|
end
|
|
|
|
def test_LocalVariableWriteNode
|
|
assert_compiles("foo = 1")
|
|
end
|
|
|
|
def test_LocalVariableReadNode
|
|
assert_compiles("[foo = 1, foo]")
|
|
end
|
|
|
|
def test_NilNode
|
|
assert_compiles("nil")
|
|
end
|
|
|
|
def test_OrNode
|
|
assert_compiles("true || false")
|
|
end
|
|
|
|
def test_ParenthesesNode
|
|
assert_compiles("()")
|
|
end
|
|
|
|
def test_ProgramNode
|
|
assert_compiles("")
|
|
end
|
|
|
|
def test_RangeNode
|
|
assert_compiles("foo..bar")
|
|
assert_compiles("foo...bar")
|
|
assert_compiles("(foo..)")
|
|
assert_compiles("(foo...)")
|
|
assert_compiles("(..bar)")
|
|
assert_compiles("(...bar)")
|
|
end
|
|
|
|
def test_SelfNode
|
|
assert_compiles("self")
|
|
end
|
|
|
|
def test_StringNode
|
|
assert_compiles("\"foo\"")
|
|
end
|
|
|
|
def test_SymbolNode
|
|
assert_compiles(":foo")
|
|
end
|
|
|
|
def test_TrueNode
|
|
assert_compiles("true")
|
|
end
|
|
|
|
def test_UndefNode
|
|
assert_compiles("undef :foo, :bar, :baz")
|
|
end
|
|
|
|
def test_XStringNode
|
|
assert_compiles("`foo`")
|
|
end
|
|
|
|
private
|
|
|
|
def assert_compiles(source)
|
|
assert_equal_iseqs(rubyvm_compile(source), YARP.compile(source))
|
|
end
|
|
|
|
# Instruction sequences have 13 elements in their lists. We don't currently
|
|
# support all of the fields, so we can't compare the iseqs directly. Instead,
|
|
# we compare the elements that we do support.
|
|
def assert_equal_iseqs(expected, actual)
|
|
# The first element is the magic comment string.
|
|
assert_equal expected[0], actual[0]
|
|
|
|
# The next three elements are the major, minor, and patch version numbers.
|
|
# TODO: Insert this check once Ruby 3.3 is released, and the TruffleRuby
|
|
# GitHub workflow also checks against Ruby 3.3
|
|
# assert_equal expected[1...4], actual[1...4]
|
|
|
|
# The next element is a set of options for the iseq. It has lots of
|
|
# different information, some of which we support and some of which we
|
|
# don't.
|
|
assert_equal expected[4][:arg_size], actual[4][:arg_size], "Unexpected difference in arg_size"
|
|
assert_equal expected[4][:stack_max], actual[4][:stack_max], "Unexpected difference in stack_max"
|
|
|
|
assert_kind_of Integer, actual[4][:local_size]
|
|
assert_kind_of Integer, actual[4][:node_id]
|
|
|
|
assert_equal expected[4][:code_location].length, actual[4][:code_location].length, "Unexpected difference in code_location length"
|
|
assert_equal expected[4][:node_ids].length, actual[4][:node_ids].length, "Unexpected difference in node_ids length"
|
|
|
|
# Then we have the name of the iseq, the relative file path, the absolute
|
|
# file path, and the line number. We don't have this working quite yet.
|
|
assert_kind_of String, actual[5]
|
|
assert_kind_of String, actual[6]
|
|
assert_kind_of String, actual[7]
|
|
assert_kind_of Integer, actual[8]
|
|
|
|
# Next we have the type of the iseq.
|
|
assert_equal expected[9], actual[9]
|
|
|
|
# Next we have the list of local variables. We don't support this yet.
|
|
assert_kind_of Array, actual[10]
|
|
|
|
# Next we have the argument options. These are used in block and method
|
|
# iseqs to reflect how the arguments are passed.
|
|
assert_equal expected[11], actual[11], "Unexpected difference in argument options"
|
|
|
|
# Next we have the catch table entries. We don't have this working yet.
|
|
assert_kind_of Array, actual[12]
|
|
|
|
# Finally we have the actual instructions. We support some of this, but omit
|
|
# line numbers and some tracepoint events.
|
|
expected[13].each do |insn|
|
|
case insn
|
|
in [:send, opnds, expected_block] unless expected_block.nil?
|
|
actual[13].shift => [:send, ^(opnds), actual_block]
|
|
assert_equal_iseqs expected_block, actual_block
|
|
in Array | :RUBY_EVENT_B_CALL | :RUBY_EVENT_B_RETURN | /^label_\d+/
|
|
assert_equal insn, actual[13].shift
|
|
in Integer | /^RUBY_EVENT_/
|
|
# skip these for now
|
|
else
|
|
flunk "Unexpected instruction: #{insn.inspect}"
|
|
end
|
|
end
|
|
end
|
|
|
|
def rubyvm_compile(source)
|
|
options = {
|
|
peephole_optimization: false,
|
|
specialized_instruction: false,
|
|
operands_unification: false,
|
|
instructions_unification: false,
|
|
frozen_string_literal: false
|
|
}
|
|
|
|
RubyVM::InstructionSequence.compile(source, **options).to_a
|
|
end
|
|
end
|