[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