[前][次][番号順一覧][スレッド一覧]

ruby-changes:69128

From: Kevin <ko1@a...>
Date: Thu, 21 Oct 2021 08:20:56 +0900 (JST)
Subject: [ruby-changes:69128] 9a436da064 (master): Ensure we guard the value before we return

https://git.ruby-lang.org/ruby.git/commit/?id=9a436da064

From 9a436da064b966c1278ac530c6d6f2d02b0636dc Mon Sep 17 00:00:00 2001
From: Kevin Newton <kddnewton@g...>
Date: Thu, 15 Jul 2021 15:35:20 -0400
Subject: 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.
---
 bootstraptest/test_yjit.rb | 15 +++++++++++++++
 yjit_codegen.c             | 10 +++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 9541be0570..725eca5eb5 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1479,3 +1479,18 @@ assert_equal '2', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L1479
   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
+}
diff --git a/yjit_codegen.c b/yjit_codegen.c
index efafb68665..f126407dc8 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -774,16 +774,16 @@ gen_expandarray(jitstate_t* jit, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/yjit_codegen.c#L774
     rb_num_t num = (rb_num_t) jit_get_arg(jit, 0);
     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.
     mov(cb, REG0, array_opnd);
     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));
 
+    // 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.
     x86opnd_t flags_opnd = member_opnd(REG0, struct RBasic, flags);
     mov(cb, REG1, flags_opnd);
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]