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

source_changes at macosforge.org source_changes at macosforge.org
Fri Mar 20 14:02:02 PDT 2009


Revision: 1026
          http://trac.macosforge.org/projects/ruby/changeset/1026
Author:   lsansonetti at apple.com
Date:     2009-03-20 14:02:02 -0700 (Fri, 20 Mar 2009)
Log Message:
-----------
implemented NODE_IFUNC-type blocks

Modified Paths:
--------------
    MacRuby/branches/experimental/array.c
    MacRuby/branches/experimental/enum.c
    MacRuby/branches/experimental/include/ruby/ruby.h
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/roxor.h
    MacRuby/branches/experimental/test_roxor.rb
    MacRuby/branches/experimental/vm_eval.c

Modified: MacRuby/branches/experimental/array.c
===================================================================
--- MacRuby/branches/experimental/array.c	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/array.c	2009-03-20 21:02:02 UTC (rev 1026)
@@ -1963,8 +1963,12 @@
 static VALUE
 take_i(VALUE val, VALUE *args, int argc, VALUE *argv)
 {
-    if (args[1]-- == 0) rb_iter_break();
-    if (argc > 1) val = rb_ary_new4(argc, argv);
+    if (args[1]-- == 0) {
+	rb_iter_break();
+    }
+    if (argc > 1) {
+	val = rb_ary_new4(argc, argv);
+    }
     rb_ary_push(args[0], val);
     return Qnil;
 }

Modified: MacRuby/branches/experimental/enum.c
===================================================================
--- MacRuby/branches/experimental/enum.c	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/enum.c	2009-03-20 21:02:02 UTC (rev 1026)
@@ -518,7 +518,9 @@
 	break;
     }
     rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);
-    if (memo[0] == Qundef) return Qnil;
+    if (memo[0] == Qundef) {
+	return Qnil;
+    }
     return memo[0];
 }
 
@@ -799,31 +801,15 @@
     else {
 	ary = rb_ary_new();
     }
-#if !WITH_OBJC
-    RBASIC(ary)->klass = 0;
-#endif
     rb_block_call(obj, id_each, 0, 0, sort_by_i, ary);
     if (RARRAY_LEN(ary) > 1) {
-#if WITH_OBJC
 	CFArraySortValues((CFMutableArrayRef)ary, 
 	    CFRangeMake(0, RARRAY_LEN(ary)),
 	    (CFComparatorFunction)sort_by_cmp, (void *)ary);
-#else
-	ruby_qsort(RARRAY_PTR(ary), RARRAY_LEN(ary), sizeof(VALUE),
-		   sort_by_cmp, (void *)ary);
-#endif
     }
-#if !WITH_OBJC
-    if (RBASIC(ary)->klass) {
-	rb_raise(rb_eRuntimeError, "sort_by reentered");
-    }
-#endif
     for (i=0; i<RARRAY_LEN(ary); i++) {
 	rb_ary_store(ary, i, RNODE(RARRAY_AT(ary, i))->u2.value);
     }
-#if !WITH_OBJC
-    RBASIC(ary)->klass = rb_cArray;
-#endif
     return ary;
 }
 

Modified: MacRuby/branches/experimental/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/ruby.h	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/include/ruby/ruby.h	2009-03-20 21:02:02 UTC (rev 1026)
@@ -962,6 +962,8 @@
 void rb_need_block(void);
 VALUE rb_iterate(VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE);
 VALUE rb_block_call(VALUE,ID,int,VALUE*,VALUE(*)(ANYARGS),VALUE);
+VALUE rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv,
+	VALUE (*bl_proc) (ANYARGS), VALUE data2);
 VALUE rb_rescue(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);
 VALUE rb_rescue2(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE,...);
 VALUE rb_ensure(VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE);

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-20 21:02:02 UTC (rev 1026)
@@ -160,23 +160,7 @@
 
 	Value *compile_node(NODE *node);
 
-	Function *compile_main_function(NODE *node) {
-	    rb_objc_retain((void *)node);
-
-	    current_instance_method = true;
-
-	    Value *val = compile_node(node);
-	    assert(Function::classof(val));
-	    Function *function = cast<Function>(val);
-
-	    Value *klass = ConstantInt::get(RubyObjTy, (long)rb_cTopLevel);
-	    BasicBlock::InstListType &list = 
-		function->getEntryBlock().getInstList();
-	    compile_ivar_slots(klass, list, list.begin());
-
-	    return function;
-	}
-
+	Function *compile_main_function(NODE *node);
 	Function *compile_read_attr(ID name);
 	Function *compile_write_attr(ID name);
 
@@ -3869,6 +3853,25 @@
 }
 
 Function *
+RoxorCompiler::compile_main_function(NODE *node)
+{
+    rb_objc_retain((void *)node);
+
+    current_instance_method = true;
+
+    Value *val = compile_node(node);
+    assert(Function::classof(val));
+    Function *function = cast<Function>(val);
+
+    Value *klass = ConstantInt::get(RubyObjTy, (long)rb_cTopLevel);
+    BasicBlock::InstListType &list = 
+	function->getEntryBlock().getInstList();
+    compile_ivar_slots(klass, list, list.begin());
+
+    return function;
+}
+
+Function *
 RoxorCompiler::compile_read_attr(ID name)
 {
     Function *f = cast<Function>(module->getOrInsertFunction("",
@@ -4863,7 +4866,7 @@
 }
 
 extern "C"
-void *
+rb_vm_block_t *
 rb_vm_block_create(IMP imp, NODE *node, VALUE self, int dvars_size, ...)
 {
     std::map<IMP, rb_vm_block_t *>::iterator iter =
@@ -4875,7 +4878,6 @@
 	b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t) + (sizeof(VALUE) * dvars_size));
 
 	b->imp = imp;
-	b->node = node;
 	b->is_lambda = true;
 	b->dvars_size = dvars_size;
 
@@ -4888,6 +4890,8 @@
     }
 
     b->self = self;
+    b->node = node;
+
     if (dvars_size > 0) {
 	va_list ar;
 	va_start(ar, dvars_size);
@@ -4959,6 +4963,20 @@
     return GET_VM()->top_block();
 }
 
+extern "C"
+void
+rb_vm_push_block(rb_vm_block_t *block)
+{
+    GET_VM()->push_block(block);
+}
+
+extern "C"
+void
+rb_vm_pop_block(void)
+{
+    GET_VM()->pop_block();
+}
+
 extern "C" VALUE rb_proc_alloc_with_block(VALUE klass, rb_vm_block_t *proc);
 
 extern "C"
@@ -5026,7 +5044,17 @@
 VALUE
 rb_vm_block_eval(rb_vm_block_t *b, int argc, const VALUE *argv)
 {
-    if (nd_type(b->node) == NODE_SCOPE && b->node->nd_body == NULL) {
+    if (nd_type(b->node) == NODE_IFUNC) {
+	// Special case for blocks passed with rb_objc_block_call(), to
+	// preserve API compatibility.
+	VALUE data = (VALUE)b->node->u2.node;
+	
+	VALUE (*pimp)(VALUE, VALUE, int, const VALUE *) =
+	    (VALUE (*)(VALUE, VALUE, int, const VALUE *))b->imp;
+
+	return (*pimp)(argc == 0 ? Qnil : argv[0], data, argc, argv);
+    }
+    else if (nd_type(b->node) == NODE_SCOPE && b->node->nd_body == NULL) {
 	// Trying to call an empty block!
 	return Qnil;
     }
@@ -5044,8 +5072,10 @@
 	    }
 	    argv = new_argv;
 	    argc = ary_len;
-	    if (dvars_size == 0 && argc >= arity.min && (argc <= arity.max || arity.max == -1)) {
-		return __rb_vm_rcall(b->self, b->node, b->imp, arity, argc, argv);
+	    if (dvars_size == 0 && argc >= arity.min
+		&& (argc <= arity.max || arity.max == -1)) {
+		return __rb_vm_rcall(b->self, b->node, b->imp, arity, argc,
+				     argv);
 	    }
 	}
 	int new_argc;
@@ -5077,7 +5107,8 @@
 	}
     }
 #if ROXOR_DEBUG
-    printf("yield block %p argc %d arity %d dvars %d\n", b, argc, arity.real, b->dvars_size);
+    printf("yield block %p argc %d arity %d dvars %d\n", b, argc, arity.real,
+	    b->dvars_size);
 #endif
 
     // We need to preserve dynamic variable slots here because our block may
@@ -5500,7 +5531,7 @@
 void
 rb_iter_break(void)
 {
-    // TODO
+    // TODO should be a #define that calls return
     abort();
 }
 

Modified: MacRuby/branches/experimental/roxor.h
===================================================================
--- MacRuby/branches/experimental/roxor.h	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/roxor.h	2009-03-20 21:02:02 UTC (rev 1026)
@@ -93,7 +93,10 @@
    return (rb_vm_block_t *)DATA_PTR(proc);
 }
 
+rb_vm_block_t *rb_vm_block_create(IMP imp, NODE *node, VALUE self, int dvars_size, ...);
 rb_vm_block_t *rb_vm_current_block(void);
+void rb_vm_push_block(rb_vm_block_t *block);
+void rb_vm_pop_block(void);
 VALUE rb_vm_block_eval(rb_vm_block_t *block, int argc, const VALUE *argv);
 
 struct rb_float_cache {

Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/test_roxor.rb	2009-03-20 21:02:02 UTC (rev 1026)
@@ -830,8 +830,20 @@
       end
     end
     p trans([1,2,3,4,5])
-  }
+  }, :archs => ['i386']
 
+  assert "[[1, 0, 1, 0, 1], [0, 1, 1, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]", %q{
+    def trans(xs)
+      (0..xs[0].size - 1).collect do |i|
+        xs.collect{ |x| x[i] }
+      end
+    end
+    p trans([1,2,3,4,5])
+  }, :archs => ['x86_64']
+
+  assert '45', "p (5..10).inject {|sum, n| sum + n }"
+  assert '151200', "p (5..10).inject(1) {|product, n| product * n }" 
+
   assert "42", "def foo(x); yield x; end; p = proc { |x| p x }; foo(42, &p)"
   assert "42", %q{
     class X

Modified: MacRuby/branches/experimental/vm_eval.c
===================================================================
--- MacRuby/branches/experimental/vm_eval.c	2009-03-20 21:01:52 UTC (rev 1025)
+++ MacRuby/branches/experimental/vm_eval.c	2009-03-20 21:02:02 UTC (rev 1026)
@@ -274,12 +274,33 @@
 }
 
 VALUE
-rb_block_call(VALUE obj, ID mid, int argc, VALUE * argv,
+rb_objc_block_call(VALUE obj, SEL sel, int argc, VALUE *argv, 
+		   VALUE (*bl_proc) (ANYARGS), VALUE data2)
+{
+    NODE *node = NEW_IFUNC(bl_proc, data2);
+    rb_vm_block_t *b = rb_vm_block_create((IMP)bl_proc, node, obj, 0);
+
+    rb_vm_push_block(b);
+    VALUE val = rb_vm_call(obj, sel, argc, argv, false);
+    rb_vm_pop_block();
+
+    return val;
+}
+
+VALUE
+rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv,
 	      VALUE (*bl_proc) (ANYARGS), VALUE data2)
 {
-    // Prototype is: Value foo(VALUE i, VALUE data2, int argc, VALUE *argv)
-    // TODO
-    return Qnil;
+    SEL sel;
+    if (argc == 0) {
+	sel = sel_registerName(rb_id2name(mid));
+    }
+    else {
+	char buf[100];
+	snprintf(buf, sizeof buf, "%s:", rb_id2name(mid));
+	sel = sel_registerName(buf);
+    }
+    return rb_objc_block_call(obj, sel, argc, argv, bl_proc, data2);
 }
 
 VALUE
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090320/73067028/attachment-0001.html>


More information about the macruby-changes mailing list