mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
merge revision(s) e0d600ec19
: [Backport #21012]
Avoid opt_aset_with optimization inside multiple assignment Previously, since the opt_aset_with optimization was introduced, use of the opt_aset_with optimization inside multiple assignment would result in a segfault or incorrect instructions. Fixes [Bug #21012] Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com>
This commit is contained in:
parent
845763fdf3
commit
f9adaab928
4 changed files with 17 additions and 2 deletions
|
@ -9321,7 +9321,8 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
|
||||||
/* optimization shortcut
|
/* optimization shortcut
|
||||||
* obj["literal"] = value -> opt_aset_with(obj, "literal", value)
|
* obj["literal"] = value -> opt_aset_with(obj, "literal", value)
|
||||||
*/
|
*/
|
||||||
if (mid == idASET && !private_recv_p(node) && node->nd_args &&
|
if (!ISEQ_COMPILE_DATA(iseq)->in_masgn &&
|
||||||
|
mid == idASET && !private_recv_p(node) && node->nd_args &&
|
||||||
nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 2 &&
|
nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 2 &&
|
||||||
nd_type_p(node->nd_args->nd_head, NODE_STR) &&
|
nd_type_p(node->nd_args->nd_head, NODE_STR) &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
|
@ -9519,7 +9520,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
|
||||||
}
|
}
|
||||||
|
|
||||||
case NODE_MASGN:{
|
case NODE_MASGN:{
|
||||||
|
bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn;
|
||||||
|
ISEQ_COMPILE_DATA(iseq)->in_masgn = true;
|
||||||
compile_massign(iseq, ret, node, popped);
|
compile_massign(iseq, ret, node, popped);
|
||||||
|
ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
iseq.h
1
iseq.h
|
@ -114,6 +114,7 @@ struct iseq_compile_data {
|
||||||
struct iseq_compile_data_storage *storage_current;
|
struct iseq_compile_data_storage *storage_current;
|
||||||
} insn;
|
} insn;
|
||||||
bool in_rescue;
|
bool in_rescue;
|
||||||
|
bool in_masgn;
|
||||||
int loopval_popped; /* used by NODE_BREAK */
|
int loopval_popped; /* used by NODE_BREAK */
|
||||||
int last_line;
|
int last_line;
|
||||||
int label_no;
|
int label_no;
|
||||||
|
|
|
@ -248,6 +248,16 @@ class TestAssignment < Test::Unit::TestCase
|
||||||
a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])
|
a,b,*c = *[*[1,2]]; assert_equal([1,2,[]], [a,b,c])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_massign_optimized_literal_bug_21012
|
||||||
|
a = []
|
||||||
|
def a.[]=(*args)
|
||||||
|
push args
|
||||||
|
end
|
||||||
|
a["a", "b"], = 1
|
||||||
|
a["a", 10], = 2
|
||||||
|
assert_equal [["a", "b", 1], ["a", 10, 2]], a
|
||||||
|
end
|
||||||
|
|
||||||
def test_assign_rescue
|
def test_assign_rescue
|
||||||
a = raise rescue 2; assert_equal(2, a)
|
a = raise rescue 2; assert_equal(2, a)
|
||||||
a, b = raise rescue [3,4]; assert_equal([3, 4], [a, b])
|
a, b = raise rescue [3,4]; assert_equal([3, 4], [a, b])
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||||
#define RUBY_VERSION_TEENY 6
|
#define RUBY_VERSION_TEENY 6
|
||||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||||
#define RUBY_PATCHLEVEL 249
|
#define RUBY_PATCHLEVEL 250
|
||||||
|
|
||||||
#include "ruby/version.h"
|
#include "ruby/version.h"
|
||||||
#include "ruby/internal/abi.h"
|
#include "ruby/internal/abi.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue