зеркало из https://github.com/github/ruby.git
Fix intermediate array off-by-one error
Co-authored-by: Adam Hess <HParker@github.com>
This commit is contained in:
Родитель
f77517f473
Коммит
30038656aa
51
iseq.c
51
iseq.c
|
@ -1569,6 +1569,48 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
|
|||
return iseqw_s_compile_parser(argc, argv, self, rb_ruby_prism_p());
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* InstructionSequence.compile_parsey(source[, file[, path[, line[, options]]]]) -> iseq
|
||||
*
|
||||
* Takes +source+, which can be a string of Ruby code, or an open +File+ object.
|
||||
* that contains Ruby source code. It parses and compiles using parse.y.
|
||||
*
|
||||
* Optionally takes +file+, +path+, and +line+ which describe the file path,
|
||||
* real path and first line number of the ruby code in +source+ which are
|
||||
* metadata attached to the returned +iseq+.
|
||||
*
|
||||
* +file+ is used for `__FILE__` and exception backtrace. +path+ is used for
|
||||
* +require_relative+ base. It is recommended these should be the same full
|
||||
* path.
|
||||
*
|
||||
* +options+, which can be +true+, +false+ or a +Hash+, is used to
|
||||
* modify the default behavior of the Ruby iseq compiler.
|
||||
*
|
||||
* For details regarding valid compile options see ::compile_option=.
|
||||
*
|
||||
* RubyVM::InstructionSequence.compile_parsey("a = 1 + 2")
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
|
||||
*
|
||||
* path = "test.rb"
|
||||
* RubyVM::InstructionSequence.compile_parsey(File.read(path), path, File.expand_path(path))
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>
|
||||
*
|
||||
* file = File.open("test.rb")
|
||||
* RubyVM::InstructionSequence.compile_parsey(file)
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>
|
||||
*
|
||||
* path = File.expand_path("test.rb")
|
||||
* RubyVM::InstructionSequence.compile_parsey(File.read(path), path, path)
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
|
||||
*
|
||||
*/
|
||||
static VALUE
|
||||
iseqw_s_compile_parsey(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
return iseqw_s_compile_parser(argc, argv, self, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* InstructionSequence.compile_prism(source[, file[, path[, line[, options]]]]) -> iseq
|
||||
|
@ -1589,19 +1631,19 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self)
|
|||
*
|
||||
* For details regarding valid compile options see ::compile_option=.
|
||||
*
|
||||
* RubyVM::InstructionSequence.compile("a = 1 + 2")
|
||||
* RubyVM::InstructionSequence.compile_prism("a = 1 + 2")
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
|
||||
*
|
||||
* path = "test.rb"
|
||||
* RubyVM::InstructionSequence.compile(File.read(path), path, File.expand_path(path))
|
||||
* RubyVM::InstructionSequence.compile_prism(File.read(path), path, File.expand_path(path))
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>
|
||||
*
|
||||
* file = File.open("test.rb")
|
||||
* RubyVM::InstructionSequence.compile(file)
|
||||
* RubyVM::InstructionSequence.compile_prism(file)
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>
|
||||
*
|
||||
* path = File.expand_path("test.rb")
|
||||
* RubyVM::InstructionSequence.compile(File.read(path), path, path)
|
||||
* RubyVM::InstructionSequence.compile_prism(File.read(path), path, path)
|
||||
* #=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
|
||||
*
|
||||
*/
|
||||
|
@ -4283,6 +4325,7 @@ Init_ISeq(void)
|
|||
(void)iseq_s_load;
|
||||
|
||||
rb_define_singleton_method(rb_cISeq, "compile", iseqw_s_compile, -1);
|
||||
rb_define_singleton_method(rb_cISeq, "compile_parsey", iseqw_s_compile_parsey, -1);
|
||||
rb_define_singleton_method(rb_cISeq, "compile_prism", iseqw_s_compile_prism, -1);
|
||||
rb_define_singleton_method(rb_cISeq, "compile_file_prism", iseqw_s_compile_file_prism, -1);
|
||||
rb_define_singleton_method(rb_cISeq, "new", iseqw_s_compile, -1);
|
||||
|
|
|
@ -6797,6 +6797,8 @@ pm_compile_array_node(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_list
|
|||
// Create the temporary array.
|
||||
for (; tmp_array_size; tmp_array_size--)
|
||||
rb_ary_push(tmp_array, pm_static_literal_value(iseq, elements->nodes[index++], scope_node));
|
||||
|
||||
index--; // about to be incremented by for loop
|
||||
OBJ_FREEZE(tmp_array);
|
||||
|
||||
// Emit the optimized code.
|
||||
|
|
|
@ -768,6 +768,9 @@ module Prism
|
|||
assert_prism_eval("a = [1,2]; [0, *a, 3, 4, *5..6, 7, 8, *9..11]")
|
||||
assert_prism_eval("[[*1..2], 3, *4..5]")
|
||||
|
||||
elements = Array.new(64) { ":foo" }
|
||||
assert_prism_eval("[#{elements.join(", ")}, bar: 1, baz: 2]")
|
||||
|
||||
# Test keyword splat inside of array
|
||||
assert_prism_eval("[**{x: 'hello'}]")
|
||||
|
||||
|
@ -2628,7 +2631,7 @@ end
|
|||
def compare_eval(source, raw:, location:)
|
||||
source = raw ? source : "class Prism::TestCompilePrism\n#{source}\nend"
|
||||
|
||||
ruby_eval = RubyVM::InstructionSequence.compile(source).eval
|
||||
ruby_eval = RubyVM::InstructionSequence.compile_parsey(source).eval
|
||||
prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval
|
||||
|
||||
if ruby_eval.is_a? Proc
|
||||
|
|
Загрузка…
Ссылка в новой задаче