summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-16 03:06:01 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2007-01-16 03:06:01 +0000
commit7eb928624f84135634075ea575d6f10d759f2263 (patch)
tree78f4c48ed4d1b7b3116d0bba7c8f6f60362fbc69 /vm.c
parentd2907d42bea13a670d5fb52c32e8761fa57efff1 (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11536 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c91
1 files changed, 38 insertions, 53 deletions
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 ||