Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

* vm_insnhelper.c (vm_caller_setup_args): save and restore

  ci->argc and ci->blockptr before and after method invocations
  because these method dispatches override call_info.
* bootstraptest/test_method.rb: add tests for this fix.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37641 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
commit ffd3cbdc759841c984ec35bfecfb9f7ed28d4faa 1 parent db31b3d
Koichi Sasada authored November 13, 2012
8  ChangeLog
... ...
@@ -1,3 +1,11 @@
  1
+Tue Nov 13 17:28:47 2012  Koichi Sasada  <ko1@atdot.net>
  2
+
  3
+	* vm_insnhelper.c (vm_caller_setup_args): save and restore
  4
+	  ci->argc and ci->blockptr before and after method invocations
  5
+	  because these method dispatches override call_info.
  6
+
  7
+	* bootstraptest/test_method.rb: add tests for this fix.
  8
+
1 9
 Tue Nov 13 16:38:02 2012  NARUSE, Yui  <naruse@ruby-lang.org>
2 10
 
3 11
 	* common.mk (dmyprobes.h): always create for make dist.
58  bootstraptest/test_method.rb
@@ -1204,3 +1204,61 @@ def m *args
1204 1204
     'ok'
1205 1205
   end
1206 1206
 }
  1207
+
  1208
+assert_equal 'DC', %q{
  1209
+  $result = []
  1210
+
  1211
+  class C
  1212
+    def foo *args
  1213
+      $result << 'C'
  1214
+    end
  1215
+  end
  1216
+  class D
  1217
+    def foo *args
  1218
+      $result << 'D'
  1219
+    end
  1220
+  end
  1221
+
  1222
+  o1 = $o1 = C.new
  1223
+  o2 = $o2 = D.new
  1224
+
  1225
+  args = Object.new
  1226
+  def args.to_a
  1227
+    test1 $o2, nil
  1228
+    []
  1229
+  end
  1230
+  def test1 o, args
  1231
+    o.foo(*args)
  1232
+  end
  1233
+  test1 o1, args
  1234
+  $result.join
  1235
+}
  1236
+
  1237
+assert_equal 'DC', %q{
  1238
+  $result = []
  1239
+
  1240
+  class C
  1241
+    def foo *args
  1242
+      $result << 'C'
  1243
+    end
  1244
+  end
  1245
+  class D
  1246
+    def foo *args
  1247
+      $result << 'D'
  1248
+    end
  1249
+  end
  1250
+
  1251
+  o1 = $o1 = C.new
  1252
+  o2 = $o2 = D.new
  1253
+
  1254
+  block = Object.new
  1255
+  def block.to_proc
  1256
+    test2 $o2, %w(a, b, c), nil
  1257
+    Proc.new{}
  1258
+  end
  1259
+  def test2 o, args, block
  1260
+    o.foo(*args, &block)
  1261
+  end
  1262
+  test2 o1, [], block
  1263
+  $result.join
  1264
+}
15  vm_insnhelper.c
@@ -1036,6 +1036,12 @@ vm_base_ptr(rb_control_frame_t *cfp)
1036 1036
 static void
1037 1037
 vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci)
1038 1038
 {
  1039
+#define SAVE_RESTORE_CI(expr, ci) do { \
  1040
+    int saved_argc = (ci)->argc; rb_block_t *saved_blockptr = (ci)->blockptr; /* save */ \
  1041
+    expr; \
  1042
+    (ci)->argc = saved_argc; (ci)->blockptr = saved_blockptr; /* restore */ \
  1043
+} while (0)
  1044
+
1039 1045
     if (UNLIKELY(ci->flag & VM_CALL_ARGS_BLOCKARG)) {
1040 1046
 	rb_proc_t *po;
1041 1047
 	VALUE proc;
@@ -1044,7 +1050,10 @@ vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_inf
1044 1050
 
1045 1051
 	if (proc != Qnil) {
1046 1052
 	    if (!rb_obj_is_proc(proc)) {
1047  
-		VALUE b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
  1053
+		VALUE b;
  1054
+
  1055
+		SAVE_RESTORE_CI(b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc"), ci);
  1056
+
1048 1057
 		if (NIL_P(b) || !rb_obj_is_proc(b)) {
1049 1058
 		    rb_raise(rb_eTypeError,
1050 1059
 			     "wrong argument type %s (expected Proc)",
@@ -1069,7 +1078,9 @@ vm_caller_setup_args(const rb_thread_t *th, rb_control_frame_t *cfp, rb_call_inf
1069 1078
 	VALUE ary = *(cfp->sp - 1);
1070 1079
 	VALUE *ptr;
1071 1080
 	int i;
1072  
-	VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
  1081
+	VALUE tmp;
  1082
+
  1083
+	SAVE_RESTORE_CI(tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a"), ci);
1073 1084
 
1074 1085
 	if (NIL_P(tmp)) {
1075 1086
 	    /* do nothing */

0 notes on commit ffd3cbd

Please sign in to comment.
Something went wrong with that request. Please try again.