From 59c061235f7bb39d6a33b7e2b7fb4e3db57305db Mon Sep 17 00:00:00 2001 From: ko1 Date: Sat, 24 May 2008 17:50:17 +0000 Subject: * eval_method.c: renamed from vm_method.c. "vm_method.c" is included by "vm.c". * vm_eval.c: added. Some codes are moved from "eval.c" * common.mk: fix for above changes. * compile.c: make a vm_eval(0) * eval.c, eval_error.c, eval_intern.h, eval_jump.c, proc.c, vm.c, id.c, id.h, vm_core.h, vm_dump.c, vm_evalbody.c, vm_insnhelper.c, blockinlining.c: fix for above changes. and do some refactoring. this changes improve rb_yield() performance. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- eval_jump.c | 158 ------------------------------------------------------------ 1 file changed, 158 deletions(-) (limited to 'eval_jump.c') diff --git a/eval_jump.c b/eval_jump.c index f3eb30fc56..1d6a84d815 100644 --- a/eval_jump.c +++ b/eval_jump.c @@ -5,162 +5,6 @@ #include "eval_intern.h" -NORETURN(static VALUE rb_f_throw _((int, VALUE *))); - -/* - * call-seq: - * throw(symbol [, obj]) - * - * Transfers control to the end of the active +catch+ block - * waiting for _symbol_. Raises +NameError+ if there - * is no +catch+ block for the symbol. The optional second - * parameter supplies a return value for the +catch+ block, - * which otherwise defaults to +nil+. For examples, see - * Kernel::catch. - */ - -static VALUE -rb_f_throw(int argc, VALUE *argv) -{ - VALUE tag, value; - rb_thread_t *th = GET_THREAD(); - struct rb_vm_tag *tt = th->tag; - - rb_scan_args(argc, argv, "11", &tag, &value); - while (tt) { - if (tt->tag == tag) { - tt->retval = value; - break; - } - tt = tt->prev; - } - if (!tt) { - VALUE desc = rb_inspect(tag); - rb_raise(rb_eArgError, "uncaught throw %s", RSTRING_PTR(desc)); - } - rb_trap_restore_mask(); - th->errinfo = NEW_THROW_OBJECT(tag, 0, TAG_THROW); - - JUMP_TAG(TAG_THROW); -#ifndef __GNUC__ - return Qnil; /* not reached */ -#endif -} - -void -rb_throw(const char *tag, VALUE val) -{ - VALUE argv[2]; - - argv[0] = ID2SYM(rb_intern(tag)); - argv[1] = val; - rb_f_throw(2, argv); -} - -void -rb_throw_obj(VALUE tag, VALUE val) -{ - VALUE argv[2]; - - argv[0] = tag; - argv[1] = val; - rb_f_throw(2, argv); -} - -/* - * call-seq: - * catch(symbol) {| | block } > obj - * - * +catch+ executes its block. If a +throw+ is - * executed, Ruby searches up its stack for a +catch+ block - * with a tag corresponding to the +throw+'s - * _symbol_. If found, that block is terminated, and - * +catch+ returns the value given to +throw+. If - * +throw+ is not called, the block terminates normally, and - * the value of +catch+ is the value of the last expression - * evaluated. +catch+ expressions may be nested, and the - * +throw+ call need not be in lexical scope. - * - * def routine(n) - * puts n - * throw :done if n <= 0 - * routine(n-1) - * end - * - * - * catch(:done) { routine(3) } - * - * produces: - * - * 3 - * 2 - * 1 - * 0 - */ - -static VALUE -rb_f_catch(int argc, VALUE *argv) -{ - VALUE tag; - int state; - VALUE val = Qnil; /* OK */ - rb_thread_t *th = GET_THREAD(); - rb_control_frame_t *saved_cfp = th->cfp; - - if (argc == 0) { - tag = rb_obj_alloc(rb_cObject); - } - else { - rb_scan_args(argc, argv, "01", &tag); - } - PUSH_TAG(); - - th->tag->tag = tag; - - if ((state = EXEC_TAG()) == 0) { - val = rb_yield_0(1, &tag); - } - else if (state == TAG_THROW && RNODE(th->errinfo)->u1.value == tag) { - th->cfp = saved_cfp; - val = th->tag->retval; - th->errinfo = Qnil; - state = 0; - } - POP_TAG(); - if (state) - JUMP_TAG(state); - - return val; -} - -static VALUE -catch_null_i(VALUE dmy) -{ - return rb_funcall(Qnil, rb_intern("catch"), 0, 0); -} - -static VALUE -catch_i(VALUE tag) -{ - return rb_funcall(Qnil, rb_intern("catch"), 1, tag); -} - -VALUE -rb_catch(const char *tag, VALUE (*func)(), VALUE data) -{ - if (!tag) { - return rb_iterate(catch_null_i, 0, func, data); - } - return rb_iterate(catch_i, ID2SYM(rb_intern(tag)), func, data); -} - -VALUE -rb_catch_obj(VALUE tag, VALUE (*func)(), VALUE data) -{ - return rb_iterate((VALUE (*)_((VALUE)))catch_i, tag, func, data); -} - - /* exit */ void @@ -303,7 +147,5 @@ rb_exec_end_proc(void) void Init_jump(void) { - rb_define_global_function("catch", rb_f_catch, -1); - rb_define_global_function("throw", rb_f_throw, -1); rb_define_global_function("at_exit", rb_f_at_exit, 0); } -- cgit v1.2.3