summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--eval_proc.c12
-rw-r--r--string.c5
-rw-r--r--version.h6
-rw-r--r--vm.c91
-rw-r--r--yarvcore.c10
6 files changed, 72 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index a9bc22a4f2..3e96cefeb6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Jan 16 12:00:06 2007 Koichi Sasada <ko1@atdot.net>
+
+ * eval_proc.c (rb_proc_new): added.
+
+ * string.c (sym_to_proc): supported.
+
+ * vm.c (invoke_block, th_invoke_yield, th_invoke_proc): fix to support
+ rb_proc_new.
+
+ * yarvcore.c: add a test code.
+
Sat Jan 13 23:24:59 2007 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/win32ole.c (ole_free, ole_type_free,
diff --git a/eval_proc.c b/eval_proc.c
index 3ff3e3b1de..a53415294f 100644
--- a/eval_proc.c
+++ b/eval_proc.c
@@ -1023,6 +1023,18 @@ bmcall(VALUE args, VALUE method)
return rb_method_call(RARRAY_LEN(a), RARRAY_PTR(a), method);
}
+VALUE
+rb_proc_new(
+ VALUE (*func)(ANYARGS), /* VALUE yieldarg[, VALUE procarg] */
+ VALUE val)
+{
+ yarv_proc_t *proc;
+ VALUE procval = rb_iterate((VALUE(*)(VALUE))mproc, 0, func, val);
+ GetProcPtr(procval, proc);
+ ((NODE*)proc->block.iseq)->u3.state = 1;
+ return procval;
+}
+
/*
* call-seq:
* meth.to_proc => prc
diff --git a/string.c b/string.c
index 8046145178..7a5c7b45a3 100644
--- a/string.c
+++ b/string.c
@@ -4802,10 +4802,7 @@ sym_call(VALUE args, VALUE sym)
static VALUE
sym_to_proc(VALUE sym)
{
- rb_notimplement();
- return Qnil;
- // TODO
- // return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));
+ return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));
}
diff --git a/version.h b/version.h
index 2e15ca4a44..a0b44532e2 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2007-01-13"
+#define RUBY_RELEASE_DATE "2007-01-16"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20070113
+#define RUBY_RELEASE_CODE 20070116
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 1
-#define RUBY_RELEASE_DAY 13
+#define RUBY_RELEASE_DAY 16
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];
diff --git a/vm.c b/vm.c
index 5c6a20b93f..f171b559d9 100644
--- a/vm.c
+++ b/vm.c
@@ -662,50 +662,59 @@ th_yield_setup_args(yarv_iseq_t *iseq, int argc, VALUE *argv)
return argc;
}
-VALUE
-th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv)
+static VALUE
+invoke_block(yarv_thread_t *th, yarv_block_t *block, int argc, VALUE *argv, int magic)
{
- yarv_control_frame_t *cfp = th->cfp;
- yarv_block_t *block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
VALUE val;
+ if (BUILTIN_TYPE(block->iseq) != T_NODE) {
+ yarv_iseq_t *iseq = block->iseq;
+ int i;
+ th_set_finish_env(th);
- if (block == 0) {
- th_localjump_error("no block given", Qnil, 0);
+ /* TODO: check overflow */
+ for (i=0; i<argc; i++) {
+ th->cfp->sp[i] = argv[i];
+ }
+ argc = th_yield_setup_args(iseq, argc, th->cfp->sp);
+ th->cfp->sp += argc;
+
+ push_frame(th, iseq, magic,
+ block->self, GC_GUARDED_PTR(block->dfp),
+ iseq->iseq_encoded, th->cfp->sp, block->lfp,
+ iseq->local_size - argc);
+ val = th_eval_body(th);
}
else {
- if (BUILTIN_TYPE(block->iseq) != T_NODE) {
- yarv_iseq_t *iseq = block->iseq;
- int i;
- th_set_finish_env(th);
-
- /* TODO: check overflow */
- for (i=0; i<argc; i++) {
- th->cfp->sp[i] = argv[i];
- }
- argc = th_yield_setup_args(iseq, argc, th->cfp->sp);
- th->cfp->sp += argc;
-
- push_frame(th, iseq, FRAME_MAGIC_BLOCK,
- block->self, GC_GUARDED_PTR(block->dfp),
- iseq->iseq_encoded, th->cfp->sp, block->lfp,
- iseq->local_size - argc);
- val = th_eval_body(th);
- }
- else {
- val = th_invoke_yield_cfunc(th, block, block->self, argc, argv);
+ if (((NODE*)block->iseq)->u3.state == 1) {
+ VALUE args = rb_ary_new4(argc, argv);
+ argc = 1;
+ argv = &args;
}
+ val = th_invoke_yield_cfunc(th, block, block->self, argc, argv);
}
return val;
}
VALUE
+th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv)
+{
+ yarv_block_t *block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+
+ if (block == 0) {
+ th_localjump_error("no block given", Qnil, 0);
+ }
+
+ return invoke_block(th, block, argc, argv, FRAME_MAGIC_BLOCK);
+}
+
+VALUE
th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc,
VALUE self, int argc, VALUE *argv)
{
VALUE val = Qundef;
int state;
volatile int stored_safe = th->safe_level;
- volatile NODE *stored_special_cref_stack = 0;
+ volatile NODE *stored_special_cref_stack;
yarv_control_frame_t * volatile cfp = th->cfp;
TH_PUSH_TAG(th);
@@ -714,32 +723,8 @@ th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc,
lfp_set_special_cref(proc->block.lfp, proc->special_cref_stack);
th->safe_level = proc->safe_level;
- if (BUILTIN_TYPE(proc->block.iseq) == T_NODE) {
- val = th_invoke_yield_cfunc(th, &proc->block,
- proc->block.self, argc, argv);
- }
- else {
- yarv_iseq_t *iseq = proc->block.iseq;
- yarv_control_frame_t *cfp;
- int i;
-
- th_set_finish_env(th);
- cfp = th->cfp;
-
- /* TODO: check overflow */
- for (i=0; i<argc; i++) {
- cfp->sp[i] = argv[i];
- }
- argc = th_yield_setup_args(iseq, argc, cfp->sp);
- cfp->sp += argc;
-
- push_frame(th, iseq,
- proc->is_lambda ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_PROC,
- self, (VALUE)proc->block.dfp, iseq->iseq_encoded,
- cfp->sp, proc->block.lfp,
- iseq->local_size - argc);
- val = th_eval_body(th);
- }
+ val = invoke_block(th, &proc->block, argc, argv,
+ proc->is_lambda ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_PROC);
}
else {
if (state == TAG_BREAK ||
diff --git a/yarvcore.c b/yarvcore.c
index 3b510495e6..899ffb65e3 100644
--- a/yarvcore.c
+++ b/yarvcore.c
@@ -815,11 +815,15 @@ yarv_segv()
}
static VALUE
+proc_func(VALUE v)
+{
+ dp(v);
+}
+
+static VALUE
cfunc(void)
{
- rb_funcall(Qnil, rb_intern("rfunc"), 0, 0);
- rb_funcall(Qnil, rb_intern("rfunc"), 0, 0);
- return Qnil;
+ return rb_proc_new(proc_func, INT2FIX(12345));
}
// VALUE yarv_Hash_each();