* 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
This commit is contained in:
ko1 2007-01-16 03:06:01 +00:00
parent d2907d42be
commit 7eb928624f
6 changed files with 72 additions and 63 deletions

View File

@ -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> Sat Jan 13 23:24:59 2007 Masaki Suketa <masaki.suketa@nifty.ne.jp>
* ext/win32ole/win32ole.c (ole_free, ole_type_free, * ext/win32ole/win32ole.c (ole_free, ole_type_free,

View File

@ -1023,6 +1023,18 @@ bmcall(VALUE args, VALUE method)
return rb_method_call(RARRAY_LEN(a), RARRAY_PTR(a), 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: * call-seq:
* meth.to_proc => prc * meth.to_proc => prc

View File

@ -4802,10 +4802,7 @@ sym_call(VALUE args, VALUE sym)
static VALUE static VALUE
sym_to_proc(VALUE sym) sym_to_proc(VALUE sym)
{ {
rb_notimplement(); return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));
return Qnil;
// TODO
// return rb_proc_new(sym_call, (VALUE)SYM2ID(sym));
} }

View File

@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0" #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_VERSION_CODE 190
#define RUBY_RELEASE_CODE 20070113 #define RUBY_RELEASE_CODE 20070116
#define RUBY_PATCHLEVEL 0 #define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MAJOR 1
@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0 #define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007 #define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 1 #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_version[];
RUBY_EXTERN const char ruby_release_date[]; RUBY_EXTERN const char ruby_release_date[];

61
vm.c
View File

@ -662,17 +662,10 @@ th_yield_setup_args(yarv_iseq_t *iseq, int argc, VALUE *argv)
return argc; return argc;
} }
VALUE static VALUE
th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv) 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; VALUE val;
if (block == 0) {
th_localjump_error("no block given", Qnil, 0);
}
else {
if (BUILTIN_TYPE(block->iseq) != T_NODE) { if (BUILTIN_TYPE(block->iseq) != T_NODE) {
yarv_iseq_t *iseq = block->iseq; yarv_iseq_t *iseq = block->iseq;
int i; int i;
@ -685,19 +678,35 @@ th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv)
argc = th_yield_setup_args(iseq, argc, th->cfp->sp); argc = th_yield_setup_args(iseq, argc, th->cfp->sp);
th->cfp->sp += argc; th->cfp->sp += argc;
push_frame(th, iseq, FRAME_MAGIC_BLOCK, push_frame(th, iseq, magic,
block->self, GC_GUARDED_PTR(block->dfp), block->self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded, th->cfp->sp, block->lfp, iseq->iseq_encoded, th->cfp->sp, block->lfp,
iseq->local_size - argc); iseq->local_size - argc);
val = th_eval_body(th); val = th_eval_body(th);
} }
else { else {
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); val = th_invoke_yield_cfunc(th, block, block->self, argc, argv);
} }
}
return val; 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 VALUE
th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc, th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc,
VALUE self, int argc, VALUE *argv) VALUE self, int argc, VALUE *argv)
@ -705,7 +714,7 @@ th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc,
VALUE val = Qundef; VALUE val = Qundef;
int state; int state;
volatile int stored_safe = th->safe_level; 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; yarv_control_frame_t * volatile cfp = th->cfp;
TH_PUSH_TAG(th); 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); lfp_set_special_cref(proc->block.lfp, proc->special_cref_stack);
th->safe_level = proc->safe_level; th->safe_level = proc->safe_level;
if (BUILTIN_TYPE(proc->block.iseq) == T_NODE) { val = invoke_block(th, &proc->block, argc, argv,
val = th_invoke_yield_cfunc(th, &proc->block, proc->is_lambda ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_PROC);
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);
}
} }
else { else {
if (state == TAG_BREAK || if (state == TAG_BREAK ||

View File

@ -814,12 +814,16 @@ yarv_segv()
return Qnil; return Qnil;
} }
static VALUE
proc_func(VALUE v)
{
dp(v);
}
static VALUE static VALUE
cfunc(void) cfunc(void)
{ {
rb_funcall(Qnil, rb_intern("rfunc"), 0, 0); return rb_proc_new(proc_func, INT2FIX(12345));
rb_funcall(Qnil, rb_intern("rfunc"), 0, 0);
return Qnil;
} }
// VALUE yarv_Hash_each(); // VALUE yarv_Hash_each();