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

ruby-changes:48476

From: nobu <ko1@a...>
Date: Tue, 31 Oct 2017 18:33:25 +0900 (JST)
Subject: [ruby-changes:48476] nobu:r60590 (trunk): compile.c: ensure after return in library toplevel

nobu	2017-10-31 18:33:22 +0900 (Tue, 31 Oct 2017)

  New Revision: 60590

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60590

  Log:
    compile.c: ensure after return in library toplevel
    
    * compile.c (compile_return): execute ensure clause after toplevel
      return even in library toplevel other than the main script.
      [ruby-core:83589] [Bug #14061]
    
    test

  Modified files:
    trunk/compile.c
    trunk/test/ruby/test_syntax.rb
Index: compile.c
===================================================================
--- compile.c	(revision 60589)
+++ compile.c	(revision 60590)
@@ -5111,27 +5111,18 @@ compile_return(rb_iseq_t *iseq, LINK_ANC https://github.com/ruby/ruby/blob/trunk/compile.c#L5111
 	enum iseq_type type = iseq->body->type;
 	const rb_iseq_t *parent_iseq = iseq->body->parent_iseq;
 	enum iseq_type parent_type;
+	const NODE *retval = node->nd_stts;
 	LABEL *splabel = 0;
 
 	if (type == ISEQ_TYPE_TOP) {
-	    splabel = NEW_LABEL(line);
-	    ADD_LABEL(ret, splabel);
-	    ADD_ADJUST(ret, line, 0);
-	    ADD_INSN(ret, line, putnil);
-	    ADD_INSN(ret, line, leave);
-	    ADD_ADJUST_RESTORE(ret, splabel);
-	    return COMPILE_OK;
+	    retval = 0;
+	    type = ISEQ_TYPE_METHOD;
 	}
 	else if ((type == ISEQ_TYPE_RESCUE || type == ISEQ_TYPE_ENSURE || type == ISEQ_TYPE_MAIN) &&
 		 parent_iseq &&
 		 ((parent_type = parent_iseq->body->type) == ISEQ_TYPE_TOP ||
 		  parent_type == ISEQ_TYPE_MAIN)) {
-	    ADD_INSN(ret, line, putnil);
-	    ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETURN));
-	    if (popped) {
-		ADD_INSN(ret, line, pop);
-	    }
-	    return COMPILE_OK;
+	    retval = 0;
 	}
 
 	if (type == ISEQ_TYPE_METHOD) {
@@ -5140,7 +5131,7 @@ compile_return(rb_iseq_t *iseq, LINK_ANC https://github.com/ruby/ruby/blob/trunk/compile.c#L5131
 	    ADD_ADJUST(ret, line, 0);
 	}
 
-	CHECK(COMPILE(ret, "return nd_stts (return val)", node->nd_stts));
+	CHECK(COMPILE(ret, "return nd_stts (return val)", retval));
 
 	if (type == ISEQ_TYPE_METHOD) {
 	    add_ensure_iseq(ret, iseq, 1);
Index: test/ruby/test_syntax.rb
===================================================================
--- test/ruby/test_syntax.rb	(revision 60589)
+++ test/ruby/test_syntax.rb	(revision 60590)
@@ -990,7 +990,8 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L990
 
   def test_return_toplevel
     feature4840 = '[ruby-core:36785] [Feature #4840]'
-    code = "#{<<~"begin;"}\n#{<<~'end;'}"
+    line = __LINE__+2
+    code = "#{<<~"begin;"}#{<<~'end;'}"
     begin;
       return; raise
       begin return; rescue SystemExit; exit false; end
@@ -1006,10 +1007,20 @@ eom https://github.com/ruby/ruby/blob/trunk/test/ruby/test_syntax.rb#L1007
       begin raise; ensure return; end and self
       nil&defined?0--begin e=no_method_error(); return; 0;end
     end;
-    all_assertions_foreach(feature4840, *code.split(/\n/)) do |s|
-      assert_in_out_err(%[-W0], s, [*s[/#=> (.*)/, 1]], [],
-                        proc {RubyVM::InstructionSequence.compile(s).disasm},
-                        success: true)
+      .split(/\n/).map {|s|[(line+=1), *s.split(/#=> /, 2)]}
+    failed = proc do |n, s|
+      RubyVM::InstructionSequence.compile(s, __FILE__, nil, n).disasm
+    end
+    all_assertions_foreach(feature4840, *code) do |n, s, *ex|
+      assert_in_out_err(%[-W0], src = s, ex, [], proc {failed[n, s]}, success: true)
+    end
+    Tempfile.create(%w"test_return_ .rb") do |lib|
+      lib.close
+      args = %W[-W0 -r#{lib.path}]
+      all_assertions_foreach(feature4840, *code) do |n, s, *ex|
+        File.write(lib, s)
+        assert_in_out_err(args, "", ex, [], proc {failed[n, s]}, success: true)
+      end
     end
   end
 

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

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