From fd34c831f6f61691cb9f2d171c690c9769183437 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Sat, 4 Sep 2021 01:50:25 -0700 Subject: Allow special case of expandarray with nil --- test/ruby/test_yjit.rb | 13 +++++++++++++ yjit_codegen.c | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 94989dae9e..ccd0e6bae0 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -136,6 +136,19 @@ class TestYJIT < Test::Unit::TestCase RUBY end + def test_expandarray + assert_compiles(<<~'RUBY', insns: %i[expandarray], result: [1, 2]) + a, b = [1, 2] + RUBY + end + + def test_expandarray_nil + assert_compiles(<<~'RUBY', insns: %i[expandarray], result: [nil, nil]) + a, b = nil + [a, b] + RUBY + end + def test_compile_opt_getinlinecache assert_compiles(<<~RUBY, insns: %i[opt_getinlinecache], result: 123, min_calls: 2) def get_foo diff --git a/yjit_codegen.c b/yjit_codegen.c index f63166725a..9eff50b2e4 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -987,8 +987,19 @@ gen_expandarray(jitstate_t* jit, ctx_t* ctx) // num is the number of requested values. If there aren't enough in the // array then we're going to push on nils. rb_num_t num = (rb_num_t) jit_get_arg(jit, 0); + val_type_t array_type = ctx_get_opnd_type(ctx, OPND_STACK(0)); x86opnd_t array_opnd = ctx_stack_pop(ctx, 1); + if (array_type.type == ETYPE_NIL) { + // special case for a, b = nil pattern + // push N nils onto the stack + for (int i = 0; i < num; i++) { + x86opnd_t push = ctx_stack_push(ctx, TYPE_NIL); + mov(cb, push, imm_opnd(Qnil)); + } + return YJIT_KEEP_COMPILING; + } + // Move the array from the stack into REG0 and check that it's an array. mov(cb, REG0, array_opnd); guard_object_is_heap(cb, REG0, ctx, COUNTED_EXIT(side_exit, expandarray_not_array)); -- cgit v1.2.3