mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Ensure we guard the value before we return
Otherwise you can end up not implicitly calling `to_ary`, which if it has side-effects will result in different behavior.
This commit is contained in:
parent
1943b27fe9
commit
9a436da064
2 changed files with 20 additions and 5 deletions
|
@ -1479,3 +1479,18 @@ assert_equal '2', %q{
|
||||||
expandarray_postarg
|
expandarray_postarg
|
||||||
expandarray_postarg
|
expandarray_postarg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert_equal '10', %q{
|
||||||
|
obj = Object.new
|
||||||
|
val = nil
|
||||||
|
obj.define_singleton_method(:to_ary) { val = 10; [] }
|
||||||
|
|
||||||
|
def expandarray_always_call_to_ary(object)
|
||||||
|
* = object
|
||||||
|
end
|
||||||
|
|
||||||
|
expandarray_always_call_to_ary(obj)
|
||||||
|
expandarray_always_call_to_ary(obj)
|
||||||
|
|
||||||
|
val
|
||||||
|
}
|
||||||
|
|
|
@ -774,16 +774,16 @@ gen_expandarray(jitstate_t* jit, ctx_t* ctx)
|
||||||
rb_num_t num = (rb_num_t) jit_get_arg(jit, 0);
|
rb_num_t num = (rb_num_t) jit_get_arg(jit, 0);
|
||||||
x86opnd_t array_opnd = ctx_stack_pop(ctx, 1);
|
x86opnd_t array_opnd = ctx_stack_pop(ctx, 1);
|
||||||
|
|
||||||
// If we don't actually want any values, then just return.
|
|
||||||
if (num == 0) {
|
|
||||||
return YJIT_KEEP_COMPILING;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the array from the stack into REG0 and check that it's an array.
|
// Move the array from the stack into REG0 and check that it's an array.
|
||||||
mov(cb, REG0, array_opnd);
|
mov(cb, REG0, array_opnd);
|
||||||
guard_object_is_heap(cb, REG0, ctx, COUNTED_EXIT(side_exit, expandarray_not_array));
|
guard_object_is_heap(cb, REG0, ctx, COUNTED_EXIT(side_exit, expandarray_not_array));
|
||||||
guard_object_is_array(cb, REG0, REG1, ctx, COUNTED_EXIT(side_exit, expandarray_not_array));
|
guard_object_is_array(cb, REG0, REG1, ctx, COUNTED_EXIT(side_exit, expandarray_not_array));
|
||||||
|
|
||||||
|
// If we don't actually want any values, then just return.
|
||||||
|
if (num == 0) {
|
||||||
|
return YJIT_KEEP_COMPILING;
|
||||||
|
}
|
||||||
|
|
||||||
// Pull out the embed flag to check if it's an embedded array.
|
// Pull out the embed flag to check if it's an embedded array.
|
||||||
x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
|
x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
|
||||||
mov(cb, REG1, flags_opnd);
|
mov(cb, REG1, flags_opnd);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue