[macruby-changes] [2213] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Tue Aug 4 19:58:50 PDT 2009
Revision: 2213
http://trac.macosforge.org/projects/ruby/changeset/2213
Author: lsansonetti at apple.com
Date: 2009-08-04 19:58:50 -0700 (Tue, 04 Aug 2009)
Log Message:
-----------
Proc: fixing bugs and implementing missing features
Modified Paths:
--------------
MacRuby/branches/experimental/proc.c
MacRuby/branches/experimental/vm.cpp
MacRuby/branches/experimental/vm.h
Modified: MacRuby/branches/experimental/proc.c
===================================================================
--- MacRuby/branches/experimental/proc.c 2009-08-05 02:44:01 UTC (rev 2212)
+++ MacRuby/branches/experimental/proc.c 2009-08-05 02:58:50 UTC (rev 2213)
@@ -37,8 +37,13 @@
VALUE
rb_proc_alloc_with_block(VALUE klass, rb_vm_block_t *proc)
{
+ if (proc->proc != Qnil) {
+ return proc->proc;
+ }
+
VALUE obj;
obj = Data_Wrap_Struct(klass, NULL, NULL, proc);
+ GC_WB(&proc->proc, obj);
if (!(proc->flags & VM_BLOCK_PROC)) {
proc->flags |= VM_BLOCK_PROC;
if (!(proc->flags & VM_BLOCK_METHOD)) {
@@ -63,21 +68,9 @@
static VALUE
proc_dup(VALUE self, SEL sel)
{
- VALUE procval = rb_proc_alloc(rb_cProc);
- rb_vm_block_t *src, *dst;
+ rb_vm_block_t *src;
GetProcPtr(self, src);
- GetProcPtr(procval, dst);
-
- // TODO
-#if 0
- dst->block = src->block;
- GC_WB(&dst->block.proc, procval);
- GC_WB(&dst->envval, src->envval);
- dst->safe_level = src->safe_level;
- dst->is_lambda = src->is_lambda;
-#endif
-
- return procval;
+ return Data_Wrap_Struct(CLASS_OF(self), NULL, NULL, src);
}
static VALUE
@@ -196,7 +189,8 @@
rb_vm_block_t *proc;
GetProcPtr(procval, proc);
- return proc->flags & VM_BLOCK_LAMBDA ? Qtrue : Qfalse;
+ return (proc->flags & VM_BLOCK_LAMBDA) == VM_BLOCK_LAMBDA
+ ? Qtrue : Qfalse;
}
/* Binding */
@@ -297,13 +291,16 @@
}
static VALUE
-proc_new(VALUE klass, int is_lambda)
+proc_new(VALUE klass, bool is_lambda)
{
rb_vm_block_t *block = rb_vm_first_block();
if (block == NULL) {
rb_raise(rb_eArgError,
"tried to create Proc object without a block");
}
+ if (is_lambda) {
+ block->flags |= VM_BLOCK_LAMBDA;
+ }
return rb_proc_alloc_with_block(klass, block);
}
@@ -327,7 +324,7 @@
static VALUE
rb_proc_s_new(VALUE klass, SEL sel, int argc, VALUE *argv)
{
- VALUE block = proc_new(klass, Qfalse);
+ VALUE block = proc_new(klass, false);
rb_obj_call_init(block, argc, argv);
return block;
@@ -343,7 +340,7 @@
VALUE
rb_block_proc(void)
{
- return proc_new(rb_cProc, Qfalse);
+ return proc_new(rb_cProc, false);
}
VALUE
@@ -355,7 +352,7 @@
VALUE
rb_block_lambda(void)
{
- return proc_new(rb_cProc, Qtrue);
+ return proc_new(rb_cProc, true);
}
VALUE
@@ -485,30 +482,14 @@
static VALUE
proc_arity(VALUE self, SEL sel)
{
-#if 0 // TODO
- rb_proc_t *proc;
- rb_iseq_t *iseq;
- GetProcPtr(self, proc);
- iseq = proc->block.iseq;
- if (iseq) {
- if (BUILTIN_TYPE(iseq) != T_NODE) {
- if (iseq->arg_rest < 0) {
- return INT2FIX(iseq->argc);
- }
- else {
- return INT2FIX(-(iseq->argc + 1 + iseq->arg_post_len));
- }
- }
- else {
- NODE *node = (NODE *)iseq;
- if (nd_type(node) == NODE_IFUNC && node->nd_cfnc == bmcall) {
- /* method(:foo).to_proc.arity */
- return INT2FIX(method_arity(node->nd_tval));
- }
- }
+ rb_vm_block_t *b;
+ GetProcPtr(self, b);
+
+ int arity = b->arity.min;
+ if (b->arity.min != b->arity.max) {
+ arity = -arity - 1;
}
-#endif
- return INT2FIX(-1);
+ return INT2FIX(arity);
}
int
@@ -560,23 +541,15 @@
static VALUE
proc_eq(VALUE self, SEL sel, VALUE other)
{
-#if 0 // TODO
if (self == other) {
return Qtrue;
}
- else {
- if (TYPE(other) == T_DATA &&
- RBASIC(other)->klass == rb_cProc &&
- CLASS_OF(self) == CLASS_OF(other)) {
- rb_proc_t *p1, *p2;
- GetProcPtr(self, p1);
- GetProcPtr(other, p2);
- if (p1->block.iseq == p2->block.iseq && p1->envval == p2->envval) {
- return Qtrue;
- }
- }
+ else if (rb_obj_is_kind_of(other, rb_cProc)) {
+ rb_vm_block_t *self_b, *other_b;
+ GetProcPtr(self, self_b);
+ GetProcPtr(other, other_b);
+ return self_b == other_b ? Qtrue : Qfalse;
}
-#endif
return Qfalse;
}
@@ -590,16 +563,9 @@
static VALUE
proc_hash(VALUE self, SEL sel)
{
-#if 0 // TODO
- int hash;
- rb_proc_t *proc;
- GetProcPtr(self, proc);
- hash = (long)proc->block.iseq;
- hash ^= (long)proc->envval;
- hash ^= (long)proc->block.lfp >> 16;
- return INT2FIX(hash);
-#endif
- return Qnil;
+ rb_vm_block_t *b;
+ GetProcPtr(self, b);
+ return LONG2FIX(b);
}
/*
@@ -1422,51 +1388,8 @@
return Data_Wrap_Struct(rb_cBinding, NULL, NULL, binding);
}
-//static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE *argv);
-
-static VALUE
-make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
-{
- // TODO
- return Qnil;
-#if 0
-#if WITH_OBJC
- VALUE args = rb_ary_new3(3, proc, passed, arity);
-#else
- VALUE args = rb_ary_new2(3);
- RARRAY_PTR(args)[0] = proc;
- RARRAY_PTR(args)[1] = passed;
- RARRAY_PTR(args)[2] = arity;
- RARRAY_LEN(args) = 3;
-#endif
- rb_ary_freeze(passed);
- rb_ary_freeze(args);
- return rb_proc_new(curry, args);
-#endif
-}
-
-#if 0
-static VALUE
-curry(VALUE dummy, VALUE args, int argc, VALUE *argv)
-{
- VALUE proc, passed, arity;
- proc = RARRAY_AT(args, 0);
- passed = RARRAY_AT(args, 1);
- arity = RARRAY_AT(args, 2);
-
- passed = rb_ary_plus(passed, rb_ary_new4(argc, argv));
- rb_ary_freeze(passed);
- if(RARRAY_LEN(passed) < FIX2INT(arity)) {
- arity = make_curry_proc(proc, passed, arity);
- return arity;
- }
- arity = rb_proc_call(proc, passed);
- return arity;
-}
-#endif
-
/*
- curry* call-seq:
+ * call-seq:
* prc.curry => a_proc
* prc.curry(arity) => a_proc
*
@@ -1529,7 +1452,7 @@
}
}
- return make_curry_proc(self, rb_ary_new(), arity);
+ return rb_vm_make_curry_proc(self, rb_ary_new(), arity);
}
/*
@@ -1561,6 +1484,7 @@
rb_objc_define_method(*(VALUE *)rb_cProc, "new", rb_proc_s_new, -1);
rb_objc_define_method(rb_cProc, "call", proc_call, -1);
rb_objc_define_method(rb_cProc, "[]", proc_call, -1);
+ rb_objc_define_method(rb_cProc, "===", proc_call, -1);
rb_objc_define_method(rb_cProc, "yield", proc_call, -1);
rb_objc_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_objc_define_method(rb_cProc, "arity", proc_arity, 0);
Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp 2009-08-05 02:44:01 UTC (rev 2212)
+++ MacRuby/branches/experimental/vm.cpp 2009-08-05 02:58:50 UTC (rev 2213)
@@ -279,6 +279,7 @@
b = (rb_vm_block_t *)xmalloc(block_size);
memcpy(b, orig, block_size);
+ GC_WB(&b->proc, orig->proc);
GC_WB(&b->self, orig->self);
GC_WB(&b->locals, orig->locals);
GC_WB(&b->parent_block, orig->parent_block); // XXX not sure
@@ -2931,6 +2932,7 @@
rb_vm_block_t *new_b = (rb_vm_block_t *)xmalloc(block_size);
memcpy(new_b, src_b, block_size);
+ GC_WB(&new_b->proc, src_b->proc);
GC_WB(&new_b->parent_block, src_b->parent_block);
GC_WB(&new_b->self, src_b->self);
new_b->flags = src_b->flags & ~VM_BLOCK_ACTIVE;
@@ -3023,6 +3025,7 @@
assert((b->flags & flags) == flags);
}
+ b->proc = Qnil;
b->self = self;
b->parent_var_uses = parent_var_uses;
GC_WB(&b->parent_block, parent_block);
@@ -3365,9 +3368,6 @@
{
rb_vm_block_t *b = GET_VM()->current_block();
if (b != NULL) {
-#if ROXOR_VM_DEBUG
- printf("create Proc object based on block %p\n", b);
-#endif
return rb_proc_alloc_with_block(rb_cProc, b);
}
return Qnil;
@@ -3442,6 +3442,7 @@
{
rb_vm_block_t *b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t));
+ b->proc = Qnil;
GC_WB(&b->self, method->recv);
b->arity = method->node == NULL
? rb_vm_arity(method->arity) : method->node->arity;
@@ -3472,6 +3473,7 @@
rb_vm_block_t *b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t)
+ sizeof(VALUE *));
+ b->proc = Qnil;
b->arity = rb_vm_arity(1);
b->flags = VM_BLOCK_PROC;
b->imp = (IMP)rb_vm_block_call_sel;
@@ -3480,6 +3482,44 @@
return b;
}
+static VALUE
+rb_vm_block_curry(VALUE rcv, SEL sel, VALUE **dvars, rb_vm_block_t *b,
+ VALUE args)
+{
+ VALUE proc = (VALUE)dvars[0];
+ VALUE passed = (VALUE)dvars[1];
+ VALUE arity = (VALUE)dvars[2];
+
+ passed = rb_ary_plus(passed, args);
+ rb_ary_freeze(passed);
+ if (RARRAY_LEN(passed) < FIX2INT(arity)) {
+ return rb_vm_make_curry_proc(proc, passed, arity);
+ }
+ return rb_proc_call(proc, passed);
+}
+
+extern "C"
+VALUE
+rb_vm_make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
+{
+ // Proc.new { |*args| curry... }
+ rb_vm_block_t *b = (rb_vm_block_t *)xmalloc(sizeof(rb_vm_block_t)
+ + (3 * sizeof(VALUE *)));
+
+ b->proc = Qnil;
+ b->arity.min = 0;
+ b->arity.max = -1;
+ b->arity.left_req = 0;
+ b->arity.real = 1;
+ b->flags = VM_BLOCK_PROC;
+ b->imp = (IMP)rb_vm_block_curry;
+ b->dvars[0] = (VALUE *)proc;
+ b->dvars[1] = (VALUE *)passed;
+ b->dvars[2] = (VALUE *)arity;
+
+ return rb_proc_alloc_with_block(rb_cProc, b);
+}
+
static inline VALUE
rb_vm_block_eval0(rb_vm_block_t *b, VALUE self, int argc, const VALUE *argv)
{
@@ -3499,6 +3539,11 @@
rb_vm_arity_t arity = b->arity;
if (argc < arity.min || argc > arity.max) {
+ if (arity.max != -1
+ && (b->flags & VM_BLOCK_LAMBDA) == VM_BLOCK_LAMBDA) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+ argc, arity.min);
+ }
VALUE *new_argv;
if (argc == 1 && TYPE(argv[0]) == T_ARRAY
&& (arity.min > 1 || (arity.min == 1 && arity.min != arity.max))) {
Modified: MacRuby/branches/experimental/vm.h
===================================================================
--- MacRuby/branches/experimental/vm.h 2009-08-05 02:44:01 UTC (rev 2212)
+++ MacRuby/branches/experimental/vm.h 2009-08-05 02:58:50 UTC (rev 2213)
@@ -36,6 +36,7 @@
#define VM_BLOCK_AOT 0x1000 // block is created by the AOT compiler (temporary)
typedef struct rb_vm_block {
+ VALUE proc; // a reference to a Proc object, or nil
VALUE self;
VALUE userdata; // if VM_BLOCK_IFUNC, contains the user data, otherwise
// contains the key used in the blocks cache.
@@ -336,11 +337,12 @@
rb_vm_method_t *rb_vm_get_method(VALUE klass, VALUE obj, ID mid, int scope);
rb_vm_block_t *rb_vm_create_block_from_method(rb_vm_method_t *method);
rb_vm_block_t *rb_vm_create_block_calling_sel(SEL sel);
+VALUE rb_vm_make_curry_proc(VALUE proc, VALUE passed, VALUE arity);
static inline rb_vm_block_t *
rb_proc_get_block(VALUE proc)
{
- return (rb_vm_block_t *)DATA_PTR(proc);
+ return (rb_vm_block_t *)DATA_PTR(proc);
}
void rb_vm_add_block_lvar_use(rb_vm_block_t *block);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090804/4075ee90/attachment-0001.html>
More information about the macruby-changes
mailing list