[macruby-changes] [1549] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Wed May 6 22:18:58 PDT 2009


Revision: 1549
          http://trac.macosforge.org/projects/ruby/changeset/1549
Author:   lsansonetti at apple.com
Date:     2009-05-06 22:18:58 -0700 (Wed, 06 May 2009)
Log Message:
-----------
when compiling a dispatch call, nullify+restore the block state during receiver and arguments compilation

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/test_vm/block.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-05-07 00:40:58 UTC (rev 1548)
+++ MacRuby/branches/experimental/roxor.cpp	2009-05-07 05:18:58 UTC (rev 1549)
@@ -3888,15 +3888,18 @@
 		    assert(recv == NULL);
 		}
 
-		const bool block_given = current_block_func != NULL && current_block_node != NULL;
-		const bool super_call = nd_type(node) == NODE_SUPER || nd_type(node) == NODE_ZSUPER;
+		const bool block_given = current_block_func != NULL
+		    && current_block_node != NULL;
+		const bool super_call = nd_type(node) == NODE_SUPER
+		    || nd_type(node) == NODE_ZSUPER;
 
 		if (super_call) {
 		    mid = current_mid;
 		}
 		assert(mid > 0);
 
-		Function::ArgumentListType &fargs = bb->getParent()->getArgumentList();
+		Function::ArgumentListType &fargs =
+		    bb->getParent()->getArgumentList();
 		const int fargs_arity = fargs.size() - 2;
 
 		bool splat_args = false;
@@ -3939,7 +3942,8 @@
 		if (!block_given && !super_call && !splat_args
 		    && positive_arity && mid == current_mid && recv == NULL) {
 
-		    // TODO check if both functions have the same arity (paranoid?)
+		    // TODO check if both functions have the same arity
+		    // (paranoid?)
 
 		    Function *f = bb->getParent();
 		    std::vector<Value *> params;
@@ -3953,11 +3957,19 @@
 			params.push_back(compile_node(n->nd_head));
 		    }
 
-		    CallInst *inst = CallInst::Create(f, params.begin(), params.end(), "", bb);
+		    CallInst *inst = CallInst::Create(f, params.begin(),
+			    params.end(), "", bb);
 		    inst->setTailCall(true);
 		    return cast<Value>(inst);
 		}
 
+		// Let's set the block state as NULL temporarily, when we
+		// compile the receiver and the arguments. 
+		Function *old_current_block_func = current_block_func;
+		NODE *old_current_block_node = current_block_node;
+		current_block_func = NULL;
+		current_block_node = NULL;
+
 		// Prepare the dispatcher parameters.
 		std::vector<Value *> params;
 
@@ -3967,16 +3979,18 @@
 		params.push_back(compile_const_pointer(cache));
 
 		// Self.
-		params.push_back(recv == NULL ? current_self : compile_node(recv));
+		params.push_back(recv == NULL ? current_self
+			: compile_node(recv));
 
 		// Selector.
 		params.push_back(compile_const_pointer((void *)sel));
 
-		// RubySpec requires that we compile the block *after* the arguments, so we
-		// do pass NULL as the block for the moment...
+		// RubySpec requires that we compile the block *after* the
+		// arguments, so we do pass NULL as the block for the moment.
 		params.push_back(compile_const_pointer(NULL));
 		NODE *real_args = args;
-		if (real_args != NULL && nd_type(real_args) == NODE_BLOCK_PASS) {
+		if (real_args != NULL
+		    && nd_type(real_args) == NODE_BLOCK_PASS) {
 		    real_args = args->nd_head;
 		}
 
@@ -3991,7 +4005,8 @@
 		// Arguments.
 		int argc = 0;
 		if (nd_type(node) == NODE_ZSUPER) {
-		    params.push_back(ConstantInt::get(Type::Int32Ty, fargs_arity));
+		    params.push_back(ConstantInt::get(Type::Int32Ty,
+				fargs_arity));
 		    Function::ArgumentListType::iterator iter = fargs.begin();
 		    iter++; // skip self
 		    iter++; // skip sel
@@ -4014,6 +4029,10 @@
 		    params.push_back(ConstantInt::get(Type::Int32Ty, 0));
 		}
 
+		// Restore the block state.
+		current_block_func = old_current_block_func;
+		current_block_node = old_current_block_node;
+
 		// Now compile the block and insert it in the params list!
 		Value *blockVal;
 		if (args != NULL && nd_type(args) == NODE_BLOCK_PASS) {

Modified: MacRuby/branches/experimental/test_vm/block.rb
===================================================================
--- MacRuby/branches/experimental/test_vm/block.rb	2009-05-07 00:40:58 UTC (rev 1548)
+++ MacRuby/branches/experimental/test_vm/block.rb	2009-05-07 05:18:58 UTC (rev 1549)
@@ -389,3 +389,15 @@
 
 # Enumerator 
 assert "[\"f\", \"o\", \"o\"]", "p 'foo'.chars.to_a"
+
+assert ':ok', %{
+  def foo(x); p :ok if block_given?; end
+  def bar; p :ok if block_given?; end
+  foo(bar) {}
+}
+
+assert ':ok', %{
+  def foo; p :ok if block_given?; self; end
+  def bar; p :ok if block_given?; self; end
+  foo.bar {}
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090506/5becea37/attachment-0001.html>


More information about the macruby-changes mailing list