2000-05-01 05:42:38 -04:00
|
|
|
/**********************************************************************
|
1998-01-16 07:13:05 -05:00
|
|
|
|
|
|
|
eval.c -
|
|
|
|
|
|
|
|
$Author$
|
|
|
|
created at: Thu Jun 10 14:22:17 JST 1993
|
|
|
|
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
2000-05-01 05:42:38 -04:00
|
|
|
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
2000-05-09 00:53:16 -04:00
|
|
|
Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2000-05-01 05:42:38 -04:00
|
|
|
**********************************************************************/
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
#include "eval_intern.h"
|
* include/ruby/node.h, vm_core.h: move definition of
RUBY_VM_METHOD_NODE to node.h.
* class.c, common.mk: remove useless inclusion.
* compile.h, iseq.h, vm_core.h: rename compile.h to iseq.h.
move some definitions from vm_core.h to iseq.h.
* compile.c, iseq.c, vm.c: ditto.
* eval.c, compile.c: move some functions for parser
from eval.c to compile.c.
* eval_intern.h, vm_core.h: move va_init_list() macro to
vm_core.h.
* iseq.c (rb_iseq_new_top, rb_iseq_first_lineno): added.
* load.c, ruby.c: use rb_iseq_new_top() instead of
rb_iseq_new() with ISEQ_TYPE_TOP constant directly.
* proc.c: use rb_iseq_first_lineno() instead of accessing
iseq structure.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19472 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-23 03:49:45 -04:00
|
|
|
#include "iseq.h"
|
2009-04-19 01:43:20 -04:00
|
|
|
#include "gc.h"
|
2009-09-18 03:29:17 -04:00
|
|
|
#include "ruby/vm.h"
|
2009-11-07 06:59:16 -05:00
|
|
|
#include "ruby/encoding.h"
|
* internal.h: declare internal functions here.
* node.h: declare NODE dependent internal functions here.
* iseq.h: declare rb_iseq_t dependent internal functions here.
* vm_core.h: declare rb_thread_t dependent internal functions here.
* bignum.c, class.c, compile.c, complex.c, cont.c, dir.c, encoding.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c, io.c,
iseq.c, load.c, marshal.c, math.c, numeric.c, object.c, parse.y,
proc.c, process.c, range.c, rational.c, re.c, ruby.c, string.c,
thread.c, time.c, transcode.c, variable.c, vm.c,
tool/compile_prelude.rb: don't declare internal functions declared
in above headers. include above headers if required.
Note that rb_thread_mark() was declared as
void rb_thread_mark(rb_thread_t *th) in cont.c but defined as
void rb_thread_mark(void *ptr) in vm.c. Now it is declared as
the later in internal.h.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-17 18:43:38 -04:00
|
|
|
#include "internal.h"
|
2011-06-05 10:35:09 -04:00
|
|
|
#include "vm_core.h"
|
2012-11-29 12:55:54 -05:00
|
|
|
#include "probes_helper.h"
|
2003-12-12 19:01:28 -05:00
|
|
|
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
NORETURN(void rb_raise_jump(VALUE));
|
1998-01-16 07:19:22 -05:00
|
|
|
|
2012-08-02 07:34:19 -04:00
|
|
|
NODE *rb_vm_get_cref(const rb_iseq_t *, const VALUE *);
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE rb_eLocalJumpError;
|
|
|
|
VALUE rb_eSysStackError;
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2008-06-15 05:17:06 -04:00
|
|
|
#define exception_error GET_VM()->special_exceptions[ruby_error_reenter]
|
2007-08-14 06:53:53 -04:00
|
|
|
|
2007-12-20 04:29:46 -05:00
|
|
|
#include "eval_error.c"
|
|
|
|
#include "eval_jump.c"
|
1999-12-14 01:50:43 -05:00
|
|
|
|
2013-04-04 04:23:10 -04:00
|
|
|
#define CLASS_OR_MODULE_P(obj) \
|
|
|
|
(!SPECIAL_CONST_P(obj) && \
|
|
|
|
(BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
|
|
|
|
|
2012-06-13 22:22:08 -04:00
|
|
|
/* Initializes the Ruby VM and builtin libraries.
|
|
|
|
* @retval 0 if succeeded.
|
2013-05-18 23:10:21 -04:00
|
|
|
* @retval non-zero an error occurred.
|
2012-06-13 22:22:08 -04:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
ruby_setup(void)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
static int initialized = 0;
|
|
|
|
int state;
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
if (initialized)
|
2012-06-13 22:22:08 -04:00
|
|
|
return 0;
|
2006-12-31 10:02:22 -05:00
|
|
|
initialized = 1;
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2009-04-19 01:43:20 -04:00
|
|
|
ruby_init_stack((void *)&state);
|
* blockinlining.c: remove "yarv" prefix.
* array.c, numeric.c: ditto.
* insnhelper.ci, insns.def, vm_evalbody.ci: ditto.
* yarvcore.c: removed.
* yarvcore.h: renamed to core.h.
* cont.c, debug.c, error.c, process.c, signal.c : ditto.
* ext/probeprofiler/probeprofiler.c: ditto.
* id.c, id.h: added.
* inits.c: ditto.
* compile.c: rename internal functions.
* compile.h: fix debug flag.
* eval.c, object.c, vm.c: remove ruby_top_self.
use rb_vm_top_self() instead.
* eval_intern.h, eval_load: ditto.
* gc.c: rename yarv_machine_stack_mark() to
rb_gc_mark_machine_stack().
* insnhelper.h: remove unused macros.
* iseq.c: add iseq_compile() to create iseq object
from source string.
* proc.c: rename a internal function.
* template/insns.inc.tmpl: remove YARV prefix.
* thread.c:
* vm.c (rb_iseq_eval): added.
* vm.c: move some functions from yarvcore.c.
* vm_dump.c: fix to remove compiler warning.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12741 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-12 00:25:46 -04:00
|
|
|
Init_BareVM();
|
2006-12-31 10:02:22 -05:00
|
|
|
Init_heap();
|
|
|
|
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
rb_call_inits();
|
|
|
|
ruby_prog_init();
|
2012-06-16 05:31:50 -04:00
|
|
|
GET_VM()->running = 1;
|
1998-01-16 07:19:22 -05:00
|
|
|
}
|
2007-06-06 12:04:02 -04:00
|
|
|
POP_TAG();
|
1998-01-16 07:19:22 -05:00
|
|
|
|
2012-06-13 22:22:08 -04:00
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calls ruby_setup() and check error.
|
|
|
|
*
|
2013-05-18 23:10:21 -04:00
|
|
|
* Prints errors and calls exit(3) if an error occurred.
|
2012-06-13 22:22:08 -04:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
ruby_init(void)
|
|
|
|
{
|
|
|
|
int state = ruby_setup();
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state) {
|
|
|
|
error_print();
|
|
|
|
exit(EXIT_FAILURE);
|
2003-07-15 06:50:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/*! Processes command line arguments and compiles the Ruby source to execute.
|
|
|
|
*
|
|
|
|
* This function does:
|
2013-05-18 23:10:21 -04:00
|
|
|
* \li Processes the given command line flags and arguments for ruby(1)
|
2012-06-13 22:21:51 -04:00
|
|
|
* \li compiles the source code from the given argument, -e or stdin, and
|
|
|
|
* \li returns the compiled source as an opaque pointer to an internal data structure
|
|
|
|
*
|
|
|
|
* @return an opaque pointer to the compiled source or an internal special value.
|
|
|
|
* @sa ruby_executable_node().
|
|
|
|
*/
|
2012-07-10 23:25:16 -04:00
|
|
|
void *
|
2006-12-31 10:02:22 -05:00
|
|
|
ruby_options(int argc, char **argv)
|
2002-05-14 02:22:31 -04:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
int state;
|
2009-04-19 01:43:20 -04:00
|
|
|
void *volatile iseq = 0;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2009-04-19 01:43:20 -04:00
|
|
|
ruby_init_stack((void *)&iseq);
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
2009-02-21 23:04:31 -05:00
|
|
|
SAVE_ROOT_JMPBUF(GET_THREAD(), iseq = ruby_process_options(argc, argv));
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_clear_trace_func();
|
2007-09-30 21:52:32 -04:00
|
|
|
state = error_handle(state);
|
2009-02-21 23:04:31 -05:00
|
|
|
iseq = (void *)INT2FIX(state);
|
2002-05-14 02:22:31 -04:00
|
|
|
}
|
2007-04-24 21:35:13 -04:00
|
|
|
POP_TAG();
|
2009-02-21 23:04:31 -05:00
|
|
|
return iseq;
|
2002-05-14 02:22:31 -04:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static void
|
2007-02-07 08:34:18 -05:00
|
|
|
ruby_finalize_0(void)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if (EXEC_TAG() == 0) {
|
|
|
|
rb_trap_exit();
|
2003-05-02 02:41:33 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
POP_TAG();
|
|
|
|
rb_exec_end_proc();
|
2008-06-05 10:27:09 -04:00
|
|
|
rb_clear_trace_func();
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static void
|
2007-02-07 08:34:18 -05:00
|
|
|
ruby_finalize_1(void)
|
2002-12-20 03:33:17 -05:00
|
|
|
{
|
2007-11-30 09:08:58 -05:00
|
|
|
ruby_sig_finalize();
|
2007-06-14 23:22:51 -04:00
|
|
|
GET_THREAD()->errinfo = Qnil;
|
2007-04-19 06:37:08 -04:00
|
|
|
rb_gc_call_finalizer_at_exit();
|
2002-12-20 03:33:17 -05:00
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/** Runs the VM finalization processes.
|
|
|
|
*
|
2013-01-17 07:09:44 -05:00
|
|
|
* <code>END{}</code> and procs registered by <code>Kernel.#at_exit</code> are
|
2012-06-13 22:21:51 -04:00
|
|
|
* executed here. See the Ruby language spec for more details.
|
|
|
|
*
|
|
|
|
* @note This function is allowed to raise an exception if an error occurred.
|
|
|
|
*/
|
2002-12-20 03:33:17 -05:00
|
|
|
void
|
2006-12-31 10:02:22 -05:00
|
|
|
ruby_finalize(void)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
ruby_finalize_0();
|
|
|
|
ruby_finalize_1();
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/** Destructs the VM.
|
|
|
|
*
|
|
|
|
* Runs the VM finalization processes as well as ruby_finalize(), and frees
|
|
|
|
* resources used by the VM.
|
|
|
|
*
|
|
|
|
* @param ex Default value to the return value.
|
2013-05-18 23:10:21 -04:00
|
|
|
* @return If an error occurred returns a non-zero. If otherwise, returns the
|
2012-06-13 22:21:51 -04:00
|
|
|
* given ex.
|
|
|
|
* @note This function does not raise any exception.
|
|
|
|
*/
|
2006-12-31 10:02:22 -05:00
|
|
|
int
|
2009-02-28 07:56:10 -05:00
|
|
|
ruby_cleanup(volatile int ex)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2007-04-20 02:48:23 -04:00
|
|
|
int state;
|
2007-04-19 23:20:44 -04:00
|
|
|
volatile VALUE errs[2];
|
2007-04-20 02:48:23 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
int nerr;
|
2010-04-27 08:27:13 -04:00
|
|
|
|
|
|
|
rb_threadptr_interrupt(th);
|
|
|
|
rb_threadptr_check_signal(th);
|
2010-04-27 11:00:41 -04:00
|
|
|
PUSH_TAG();
|
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
2012-07-19 10:19:40 -04:00
|
|
|
SAVE_ROOT_JMPBUF(th, { RUBY_VM_CHECK_INTS(th); });
|
2010-04-27 11:00:41 -04:00
|
|
|
}
|
|
|
|
POP_TAG();
|
2007-04-19 23:20:44 -04:00
|
|
|
|
2007-04-20 02:48:23 -04:00
|
|
|
errs[1] = th->errinfo;
|
2007-04-19 23:20:44 -04:00
|
|
|
th->safe_level = 0;
|
2009-04-19 01:43:20 -04:00
|
|
|
ruby_init_stack(&errs[STACK_UPPER(errs, 0, 1)]);
|
2008-05-05 04:19:35 -04:00
|
|
|
|
|
|
|
PUSH_TAG();
|
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
SAVE_ROOT_JMPBUF(th, ruby_finalize_0());
|
|
|
|
}
|
|
|
|
POP_TAG();
|
|
|
|
|
2012-11-28 19:48:16 -05:00
|
|
|
/* protect from Thread#raise */
|
|
|
|
th->status = THREAD_KILLED;
|
|
|
|
|
2007-04-20 02:48:23 -04:00
|
|
|
errs[0] = th->errinfo;
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
* cont.c: support Fiber. Check test/ruby/test_fiber.rb for detail.
Fiber is known as "Micro Thread", "Coroutine", and other terms.
At this time, only Fiber#pass is supported to change context.
I want to know more suitable method name/API for Fiber (... do you
know more suitable class name instead of Fiber?) as "suspend/resume",
"call", "yield", "start/kick/stop/restart", ....
* eval.c, eval_intern.h, thread.c, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12395 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-05-27 15:12:43 -04:00
|
|
|
SAVE_ROOT_JMPBUF(th, rb_thread_terminate_all());
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
else if (ex == 0) {
|
|
|
|
ex = state;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2007-04-20 02:48:23 -04:00
|
|
|
th->errinfo = errs[1];
|
2006-12-31 10:02:22 -05:00
|
|
|
ex = error_handle(ex);
|
|
|
|
ruby_finalize_1();
|
2011-07-08 00:40:01 -04:00
|
|
|
|
|
|
|
/* unlock again if finalizer took mutexes. */
|
|
|
|
rb_threadptr_unlock_all_locking_mutexes(GET_THREAD());
|
2007-04-24 21:35:13 -04:00
|
|
|
POP_TAG();
|
2011-06-26 20:30:41 -04:00
|
|
|
rb_thread_stop_timer_thread(1);
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2010-10-31 09:24:19 -04:00
|
|
|
#if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1
|
|
|
|
switch (ex) {
|
|
|
|
#if EXIT_SUCCESS != 0
|
|
|
|
case 0: ex = EXIT_SUCCESS; break;
|
|
|
|
#endif
|
|
|
|
#if EXIT_FAILURE != 1
|
|
|
|
case 1: ex = EXIT_FAILURE; break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-09-18 03:29:17 -04:00
|
|
|
state = 0;
|
2009-07-18 04:05:32 -04:00
|
|
|
for (nerr = 0; nerr < numberof(errs); ++nerr) {
|
2007-04-20 02:48:23 -04:00
|
|
|
VALUE err = errs[nerr];
|
|
|
|
|
|
|
|
if (!RTEST(err)) continue;
|
2007-04-19 13:37:03 -04:00
|
|
|
|
|
|
|
/* th->errinfo contains a NODE while break'ing */
|
2011-09-29 07:07:45 -04:00
|
|
|
if (RB_TYPE_P(err, T_NODE)) continue;
|
2007-04-19 13:37:03 -04:00
|
|
|
|
|
|
|
if (rb_obj_is_kind_of(err, rb_eSystemExit)) {
|
2010-10-31 09:24:19 -04:00
|
|
|
ex = sysexit_status(err);
|
|
|
|
break;
|
2007-04-19 13:37:03 -04:00
|
|
|
}
|
|
|
|
else if (rb_obj_is_kind_of(err, rb_eSignal)) {
|
2007-04-19 23:20:44 -04:00
|
|
|
VALUE sig = rb_iv_get(err, "signo");
|
2009-09-18 03:29:17 -04:00
|
|
|
state = NUM2INT(sig);
|
|
|
|
break;
|
2007-04-19 13:37:03 -04:00
|
|
|
}
|
2010-10-31 09:24:19 -04:00
|
|
|
else if (ex == EXIT_SUCCESS) {
|
|
|
|
ex = EXIT_FAILURE;
|
2007-06-18 00:52:59 -04:00
|
|
|
}
|
|
|
|
}
|
2009-09-18 03:29:17 -04:00
|
|
|
ruby_vm_destruct(GET_VM());
|
|
|
|
if (state) ruby_default_signal(state);
|
2007-06-18 00:52:59 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return ex;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2012-07-10 23:25:16 -04:00
|
|
|
static int
|
|
|
|
ruby_exec_internal(void *n)
|
|
|
|
{
|
|
|
|
volatile int state;
|
|
|
|
VALUE iseq = (VALUE)n;
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
|
|
|
|
if (!n) return 0;
|
|
|
|
|
|
|
|
PUSH_TAG();
|
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
SAVE_ROOT_JMPBUF(th, {
|
|
|
|
th->base_block = 0;
|
|
|
|
rb_iseq_eval_main(iseq);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
POP_TAG();
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/*! Calls ruby_cleanup() and exits the process */
|
1999-01-19 23:59:39 -05:00
|
|
|
void
|
2007-02-07 08:34:18 -05:00
|
|
|
ruby_stop(int ex)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
exit(ruby_cleanup(ex));
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/*! Checks the return value of ruby_options().
|
|
|
|
* @param n return value of ruby_options().
|
|
|
|
* @param status pointer to the exit status of this process.
|
|
|
|
*
|
|
|
|
* ruby_options() sometimes returns a special value to indicate this process
|
|
|
|
* should immediately exit. This function checks if the case. Also stores the
|
|
|
|
* exit status that the caller have to pass to exit(3) into
|
|
|
|
* <code>*status</code>.
|
|
|
|
*
|
|
|
|
* @retval non-zero if the given opaque pointer is actually a compiled source.
|
|
|
|
* @retval 0 if the given value is such a special value.
|
|
|
|
*/
|
2009-10-12 06:48:35 -04:00
|
|
|
int
|
2012-07-10 23:25:16 -04:00
|
|
|
ruby_executable_node(void *n, int *status)
|
2009-10-12 06:48:35 -04:00
|
|
|
{
|
|
|
|
VALUE v = (VALUE)n;
|
|
|
|
int s;
|
|
|
|
|
|
|
|
switch (v) {
|
|
|
|
case Qtrue: s = EXIT_SUCCESS; break;
|
|
|
|
case Qfalse: s = EXIT_FAILURE; break;
|
|
|
|
default:
|
|
|
|
if (!FIXNUM_P(v)) return TRUE;
|
|
|
|
s = FIX2INT(v);
|
|
|
|
}
|
|
|
|
if (status) *status = s;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/*! Runs the given compiled source and exits this process.
|
2013-05-18 23:10:21 -04:00
|
|
|
* @retval 0 if successfully run the source
|
2012-06-13 22:21:51 -04:00
|
|
|
* @retval non-zero if an error occurred.
|
|
|
|
*/
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 04:12:18 -04:00
|
|
|
int
|
2012-07-10 23:25:16 -04:00
|
|
|
ruby_run_node(void *n)
|
2009-10-10 04:03:24 -04:00
|
|
|
{
|
2009-10-12 06:48:35 -04:00
|
|
|
int status;
|
2009-10-13 20:06:42 -04:00
|
|
|
if (!ruby_executable_node(n, &status)) {
|
|
|
|
ruby_cleanup(0);
|
|
|
|
return status;
|
|
|
|
}
|
2009-10-10 04:03:24 -04:00
|
|
|
return ruby_cleanup(ruby_exec_node(n));
|
|
|
|
}
|
|
|
|
|
2012-06-13 22:21:51 -04:00
|
|
|
/*! Runs the given compiled source */
|
2009-10-10 04:03:24 -04:00
|
|
|
int
|
2012-07-10 23:25:16 -04:00
|
|
|
ruby_exec_node(void *n)
|
1999-12-14 01:50:43 -05:00
|
|
|
{
|
2009-04-19 01:43:20 -04:00
|
|
|
ruby_init_stack((void *)&n);
|
2012-07-10 23:25:16 -04:00
|
|
|
return ruby_exec_internal(n);
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* Module.nesting -> array
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* Returns the list of +Modules+ nested at the point of call.
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* module M1
|
|
|
|
* module M2
|
|
|
|
* $a = Module.nesting
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* $a #=> [M1::M2, M1]
|
|
|
|
* $a[0].name #=> "M1::M2"
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_nesting(void)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE ary = rb_ary_new();
|
* vm.c: add a prefix "rb_" to exposed functions
vm_get_ruby_level_next_cfp(), rb_vm_make_env_object(),
vm_stack_to_heap(), vm_make_proc(), vm_invoke_proc(),
vm_get_sourceline(), vm_cref(), vm_localjump_error(),
vm_make_jump_tag_but_local_jump(), vm_jump_tag_but_local_jump().
This changes may affect only core because most of renamed functions
require a pointer of not-exposed struct such as rb_thread_t or NODE.
In short, they are core functions.
* cont.c, eval.c, eval_intern.h, load.c, proc.c, thread.c,
vm_core.h, vm_dump.c, vm_eval.c, vm_exec.c, vm_insnhelper.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-01-18 21:38:11 -05:00
|
|
|
const NODE *cref = rb_vm_cref();
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
while (cref && cref->nd_next) {
|
|
|
|
VALUE klass = cref->nd_clss;
|
2009-12-03 13:25:57 -05:00
|
|
|
if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) &&
|
|
|
|
!NIL_P(klass)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_ary_push(ary, klass);
|
|
|
|
}
|
|
|
|
cref = cref->nd_next;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
return ary;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* Module.constants -> array
|
2012-01-12 11:37:03 -05:00
|
|
|
* Module.constants(inherited) -> array
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2012-01-12 11:37:03 -05:00
|
|
|
* In the first form, returns an array of the names of all
|
|
|
|
* constants accessible from the point of call.
|
|
|
|
* This list includes the names of all modules and classes
|
|
|
|
* defined in the global scope.
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2012-01-12 11:37:03 -05:00
|
|
|
* Module.constants.first(4)
|
|
|
|
* # => [:ARGF, :ARGV, :ArgumentError, :Array]
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2012-01-12 11:37:03 -05:00
|
|
|
* Module.constants.include?(:SEEK_SET) # => false
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2012-01-12 11:37:03 -05:00
|
|
|
* class IO
|
|
|
|
* Module.constants.include?(:SEEK_SET) # => true
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* The second form calls the instance method +constants+.
|
2006-12-31 10:02:22 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_s_constants(int argc, VALUE *argv, VALUE mod)
|
2000-01-31 22:12:21 -05:00
|
|
|
{
|
* vm.c: add a prefix "rb_" to exposed functions
vm_get_ruby_level_next_cfp(), rb_vm_make_env_object(),
vm_stack_to_heap(), vm_make_proc(), vm_invoke_proc(),
vm_get_sourceline(), vm_cref(), vm_localjump_error(),
vm_make_jump_tag_but_local_jump(), vm_jump_tag_but_local_jump().
This changes may affect only core because most of renamed functions
require a pointer of not-exposed struct such as rb_thread_t or NODE.
In short, they are core functions.
* cont.c, eval.c, eval_intern.h, load.c, proc.c, thread.c,
vm_core.h, vm_dump.c, vm_eval.c, vm_exec.c, vm_insnhelper.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-01-18 21:38:11 -05:00
|
|
|
const NODE *cref = rb_vm_cref();
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE klass;
|
|
|
|
VALUE cbase = 0;
|
|
|
|
void *data = 0;
|
2000-01-31 22:12:21 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
if (argc > 0) {
|
|
|
|
return rb_mod_constants(argc, argv, rb_cModule);
|
2000-01-31 22:12:21 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
while (cref) {
|
|
|
|
klass = cref->nd_clss;
|
2011-03-31 01:54:34 -04:00
|
|
|
if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) &&
|
|
|
|
!NIL_P(klass)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
data = rb_mod_const_at(cref->nd_clss, data);
|
|
|
|
if (!cbase) {
|
|
|
|
cbase = klass;
|
|
|
|
}
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
cref = cref->nd_next;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
if (cbase) {
|
|
|
|
data = rb_mod_const_of(cbase, data);
|
|
|
|
}
|
|
|
|
return rb_const_list(data);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
1999-01-19 23:59:39 -05:00
|
|
|
void
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_frozen_class_p(VALUE klass)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2013-04-04 04:23:10 -04:00
|
|
|
if (SPECIAL_CONST_P(klass)) {
|
|
|
|
noclass:
|
|
|
|
Check_Type(klass, T_CLASS);
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
if (OBJ_FROZEN(klass)) {
|
2013-04-04 04:23:10 -04:00
|
|
|
const char *desc;
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
if (FL_TEST(klass, FL_SINGLETON))
|
|
|
|
desc = "object";
|
|
|
|
else {
|
2013-04-04 04:23:10 -04:00
|
|
|
switch (BUILTIN_TYPE(klass)) {
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
case T_MODULE:
|
|
|
|
case T_ICLASS:
|
2006-12-31 10:02:22 -05:00
|
|
|
desc = "module";
|
|
|
|
break;
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
case T_CLASS:
|
2006-12-31 10:02:22 -05:00
|
|
|
desc = "class";
|
|
|
|
break;
|
2013-04-04 04:23:10 -04:00
|
|
|
default:
|
|
|
|
goto noclass;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_error_frozen(desc);
|
2000-01-31 22:12:21 -05:00
|
|
|
}
|
1999-08-13 01:45:20 -04:00
|
|
|
}
|
|
|
|
|
2009-03-01 20:29:19 -05:00
|
|
|
NORETURN(static void rb_longjmp(int, volatile VALUE));
|
2001-11-19 00:03:03 -05:00
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
static void
|
2010-01-24 08:52:32 -05:00
|
|
|
setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE at;
|
2007-08-13 04:23:12 -04:00
|
|
|
VALUE e;
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 04:12:18 -04:00
|
|
|
const char *file;
|
2009-02-28 06:12:36 -05:00
|
|
|
volatile int line = 0;
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2011-05-18 09:36:46 -04:00
|
|
|
if (NIL_P(mesg)) {
|
2007-08-13 04:23:12 -04:00
|
|
|
mesg = th->errinfo;
|
2011-05-18 09:36:46 -04:00
|
|
|
if (INTERNAL_EXCEPTION_P(mesg)) JUMP_TAG(TAG_FATAL);
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
if (NIL_P(mesg)) {
|
|
|
|
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
|
|
|
|
}
|
2005-12-27 00:40:04 -05:00
|
|
|
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 04:12:18 -04:00
|
|
|
file = rb_sourcefile();
|
|
|
|
if (file) line = rb_sourceline();
|
|
|
|
if (file && !NIL_P(mesg)) {
|
2009-11-06 21:45:08 -05:00
|
|
|
if (mesg == sysstack_error) {
|
|
|
|
at = rb_enc_sprintf(rb_usascii_encoding(), "%s:%d", file, line);
|
2010-05-16 09:20:58 -04:00
|
|
|
at = rb_ary_new3(1, at);
|
2009-11-06 21:45:08 -05:00
|
|
|
rb_iv_set(mesg, "bt", at);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
at = get_backtrace(mesg);
|
|
|
|
if (NIL_P(at)) {
|
2012-05-24 02:09:23 -04:00
|
|
|
at = rb_vm_backtrace_object();
|
2009-11-06 21:45:08 -05:00
|
|
|
if (OBJ_FROZEN(mesg)) {
|
|
|
|
mesg = rb_obj_dup(mesg);
|
|
|
|
}
|
|
|
|
set_backtrace(mesg, at);
|
2008-06-15 05:17:06 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2005-12-27 00:40:04 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
if (!NIL_P(mesg)) {
|
2007-08-13 04:23:12 -04:00
|
|
|
th->errinfo = mesg;
|
2005-12-27 00:40:04 -05:00
|
|
|
}
|
|
|
|
|
2007-08-13 04:23:12 -04:00
|
|
|
if (RTEST(ruby_debug) && !NIL_P(e = th->errinfo) &&
|
|
|
|
!rb_obj_is_kind_of(e, rb_eSystemExit)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
int status;
|
2005-12-27 00:40:04 -05:00
|
|
|
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((status = EXEC_TAG()) == 0) {
|
2007-08-13 04:23:12 -04:00
|
|
|
RB_GC_GUARD(e) = rb_obj_as_string(e);
|
2010-03-04 08:54:13 -05:00
|
|
|
if (file && line) {
|
2013-06-24 09:03:35 -04:00
|
|
|
warn_printf("Exception `%s' at %s:%d - %"PRIsVALUE"\n",
|
|
|
|
rb_obj_classname(th->errinfo), file, line, e);
|
2007-09-25 08:40:17 -04:00
|
|
|
}
|
2010-03-04 08:54:13 -05:00
|
|
|
else if (file) {
|
2013-06-24 09:03:35 -04:00
|
|
|
warn_printf("Exception `%s' at %s - %"PRIsVALUE"\n",
|
|
|
|
rb_obj_classname(th->errinfo), file, e);
|
2010-03-04 08:54:13 -05:00
|
|
|
}
|
2007-09-25 08:40:17 -04:00
|
|
|
else {
|
2013-06-24 09:03:35 -04:00
|
|
|
warn_printf("Exception `%s' - %"PRIsVALUE"\n",
|
|
|
|
rb_obj_classname(th->errinfo), e);
|
2007-09-25 08:40:17 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
POP_TAG();
|
2007-08-13 04:23:12 -04:00
|
|
|
if (status == TAG_FATAL && th->errinfo == exception_error) {
|
|
|
|
th->errinfo = mesg;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else if (status) {
|
2009-06-08 12:14:06 -04:00
|
|
|
rb_threadptr_reset_raised(th);
|
2006-12-31 10:02:22 -05:00
|
|
|
JUMP_TAG(status);
|
|
|
|
}
|
2002-03-25 01:18:07 -05:00
|
|
|
}
|
2000-11-27 04:23:38 -05:00
|
|
|
|
2009-11-06 21:45:08 -05:00
|
|
|
if (rb_threadptr_set_raised(th)) {
|
|
|
|
th->errinfo = exception_error;
|
|
|
|
rb_threadptr_reset_raised(th);
|
|
|
|
JUMP_TAG(TAG_FATAL);
|
|
|
|
}
|
|
|
|
|
2010-01-05 00:59:23 -05:00
|
|
|
if (tag != TAG_FATAL) {
|
2012-12-01 10:25:28 -05:00
|
|
|
if (RUBY_DTRACE_RAISE_ENABLED()) {
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-12 16:52:12 -05:00
|
|
|
RUBY_DTRACE_RAISE(rb_obj_classname(th->errinfo),
|
2012-12-01 10:25:28 -05:00
|
|
|
rb_sourcefile(),
|
|
|
|
rb_sourceline());
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-12 16:52:12 -05:00
|
|
|
}
|
2012-11-20 04:48:24 -05:00
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0, mesg);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2010-01-24 08:52:32 -05:00
|
|
|
}
|
2007-06-14 23:22:51 -04:00
|
|
|
|
2010-01-24 08:52:32 -05:00
|
|
|
static void
|
|
|
|
rb_longjmp(int tag, volatile VALUE mesg)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
setup_exception(th, tag, mesg);
|
2008-03-12 01:47:10 -04:00
|
|
|
rb_thread_raised_clear(th);
|
2006-12-31 10:02:22 -05:00
|
|
|
JUMP_TAG(tag);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2009-10-29 00:55:10 -04:00
|
|
|
static VALUE make_exception(int argc, VALUE *argv, int isstr);
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
2007-12-24 04:25:27 -05:00
|
|
|
rb_exc_raise(VALUE mesg)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2009-08-06 14:22:57 -04:00
|
|
|
if (!NIL_P(mesg)) {
|
2009-11-02 00:52:55 -05:00
|
|
|
mesg = make_exception(1, &mesg, FALSE);
|
2009-08-06 14:22:57 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_longjmp(TAG_RAISE, mesg);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
1999-08-13 01:45:20 -04:00
|
|
|
void
|
2007-12-24 04:25:27 -05:00
|
|
|
rb_exc_fatal(VALUE mesg)
|
1999-08-13 01:45:20 -04:00
|
|
|
{
|
2009-08-06 14:22:57 -04:00
|
|
|
if (!NIL_P(mesg)) {
|
2009-11-02 00:52:55 -05:00
|
|
|
mesg = make_exception(1, &mesg, FALSE);
|
2009-08-06 14:22:57 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_longjmp(TAG_FATAL, mesg);
|
1999-08-13 01:45:20 -04:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
2007-07-06 02:21:27 -04:00
|
|
|
rb_interrupt(void)
|
2003-09-01 03:59:18 -04:00
|
|
|
{
|
2008-07-01 07:59:50 -04:00
|
|
|
rb_raise(rb_eInterrupt, "%s", "");
|
2003-09-01 03:59:18 -04:00
|
|
|
}
|
|
|
|
|
2007-12-23 10:43:00 -05:00
|
|
|
static VALUE get_errinfo(void);
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* raise
|
|
|
|
* raise(string)
|
|
|
|
* raise(exception [, string [, array]])
|
|
|
|
* fail
|
|
|
|
* fail(string)
|
|
|
|
* fail(exception [, string [, array]])
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* With no arguments, raises the exception in <code>$!</code> or raises
|
|
|
|
* a <code>RuntimeError</code> if <code>$!</code> is +nil+.
|
|
|
|
* With a single +String+ argument, raises a
|
|
|
|
* +RuntimeError+ with the string as a message. Otherwise,
|
|
|
|
* the first parameter should be the name of an +Exception+
|
|
|
|
* class (or an object that returns an +Exception+ object when sent
|
|
|
|
* an +exception+ message). The optional second parameter sets the
|
|
|
|
* message associated with the exception, and the third parameter is an
|
|
|
|
* array of callback information. Exceptions are caught by the
|
|
|
|
* +rescue+ clause of <code>begin...end</code> blocks.
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* raise "Failed to create socket"
|
|
|
|
* raise ArgumentError, "No parameters", caller
|
|
|
|
*/
|
2002-09-27 05:42:24 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static VALUE
|
|
|
|
rb_f_raise(int argc, VALUE *argv)
|
2000-05-15 22:46:57 -04:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE err;
|
|
|
|
if (argc == 0) {
|
|
|
|
err = get_errinfo();
|
|
|
|
if (!NIL_P(err)) {
|
|
|
|
argc = 1;
|
|
|
|
argv = &err;
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
|
|
|
}
|
2008-02-19 06:49:51 -05:00
|
|
|
rb_raise_jump(rb_make_exception(argc, argv));
|
2012-04-13 20:36:26 -04:00
|
|
|
|
|
|
|
UNREACHABLE;
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
|
|
|
|
2009-10-29 00:55:10 -04:00
|
|
|
static VALUE
|
|
|
|
make_exception(int argc, VALUE *argv, int isstr)
|
2000-05-15 22:46:57 -04:00
|
|
|
{
|
2013-06-13 01:44:31 -04:00
|
|
|
VALUE mesg, exc;
|
2006-12-31 10:02:22 -05:00
|
|
|
ID exception;
|
|
|
|
int n;
|
2000-05-15 22:46:57 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
mesg = Qnil;
|
|
|
|
switch (argc) {
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
case 0:
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
case 1:
|
2013-06-13 01:44:31 -04:00
|
|
|
exc = argv[0];
|
|
|
|
if (NIL_P(exc))
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
2009-10-29 00:55:10 -04:00
|
|
|
if (isstr) {
|
2013-06-13 01:44:31 -04:00
|
|
|
mesg = rb_check_string_type(exc);
|
2009-10-29 00:55:10 -04:00
|
|
|
if (!NIL_P(mesg)) {
|
|
|
|
mesg = rb_exc_new3(rb_eRuntimeError, mesg);
|
|
|
|
break;
|
|
|
|
}
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
n = 0;
|
|
|
|
goto exception_call;
|
2000-05-15 22:46:57 -04:00
|
|
|
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
case 2:
|
|
|
|
case 3:
|
2013-06-13 01:44:31 -04:00
|
|
|
exc = argv[0];
|
2006-12-31 10:02:22 -05:00
|
|
|
n = 1;
|
|
|
|
exception_call:
|
2013-06-13 01:44:31 -04:00
|
|
|
if (exc == sysstack_error) return exc;
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(exception, "exception");
|
2013-06-13 01:44:31 -04:00
|
|
|
mesg = rb_check_funcall(exc, exception, n, argv+1);
|
2009-10-29 00:55:10 -04:00
|
|
|
if (mesg == Qundef) {
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_raise(rb_eTypeError, "exception class/object expected");
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
default:
|
2012-03-14 17:10:34 -04:00
|
|
|
rb_check_arity(argc, 0, 3);
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (argc > 0) {
|
|
|
|
if (!rb_obj_is_kind_of(mesg, rb_eException))
|
|
|
|
rb_raise(rb_eTypeError, "exception object expected");
|
|
|
|
if (argc > 2)
|
|
|
|
set_backtrace(mesg, argv[2]);
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
return mesg;
|
2000-05-15 22:46:57 -04:00
|
|
|
}
|
|
|
|
|
2009-10-29 00:55:10 -04:00
|
|
|
VALUE
|
|
|
|
rb_make_exception(int argc, VALUE *argv)
|
|
|
|
{
|
2009-11-02 00:52:55 -05:00
|
|
|
return make_exception(argc, argv, TRUE);
|
2009-10-29 00:55:10 -04:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
2007-12-24 04:25:27 -05:00
|
|
|
rb_raise_jump(VALUE mesg)
|
2000-05-18 00:32:13 -04:00
|
|
|
{
|
2008-02-19 06:49:51 -05:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2010-01-24 08:52:32 -05:00
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
|
|
|
VALUE klass = cfp->me->klass;
|
|
|
|
VALUE self = cfp->self;
|
|
|
|
ID mid = cfp->me->called_id;
|
|
|
|
|
2008-02-19 06:49:51 -05:00
|
|
|
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
2010-01-24 08:52:32 -05:00
|
|
|
|
|
|
|
setup_exception(th, TAG_RAISE, mesg);
|
|
|
|
|
2012-11-20 04:48:24 -05:00
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, self, mid, klass, Qnil);
|
2010-01-24 08:52:32 -05:00
|
|
|
rb_thread_raised_clear(th);
|
|
|
|
JUMP_TAG(TAG_RAISE);
|
2000-05-18 00:32:13 -04:00
|
|
|
}
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
void
|
2007-12-24 04:25:27 -05:00
|
|
|
rb_jump_tag(int tag)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
JUMP_TAG(tag);
|
|
|
|
}
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
int
|
2007-12-24 04:25:27 -05:00
|
|
|
rb_block_given_p(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
* blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
eval_jump.h, eval_load.c, eval_safe.h, gc.c, proc.c, signal.c,
thread.c, thread_pthread.ci, thread_win32.ci, vm.c, vm.h,
vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fix typo (rb_thead_t -> rb_thread_t).
* eval_intern.h: remove unused definitions.
* common.mk: fix around vm_opts.h path
and remove harmful argument passed to insns2vm.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11658 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-08 01:37:46 -05:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2008-06-15 12:50:37 -04:00
|
|
|
|
2012-06-10 23:14:59 -04:00
|
|
|
if (rb_vm_control_frame_block_ptr(th->cfp)) {
|
2009-07-18 04:05:32 -04:00
|
|
|
return TRUE;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
else {
|
2009-07-18 04:05:32 -04:00
|
|
|
return FALSE;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2003-10-09 18:50:57 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
int
|
* cont.c (rb_fiber_current), dln.c (dln_print_undef, dln_undefined),
eval.c (rb_iterator_p, rb_need_block), load.c: (Init_load), ruby.c
(uscore_get, rb_f_chop), st.c (stat_col), signal.c
(rb_signal_buff_size, ruby_sig_finalize), thread.c
(rb_thread_sleep_forever, rb_thread_sleep_deadly, rb_thread_alone):
protoized.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-02-01 07:51:44 -05:00
|
|
|
rb_iterator_p(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
return rb_block_given_p();
|
|
|
|
}
|
2000-05-25 01:55:12 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE rb_eThreadError;
|
|
|
|
|
|
|
|
void
|
* cont.c (rb_fiber_current), dln.c (dln_print_undef, dln_undefined),
eval.c (rb_iterator_p, rb_need_block), load.c: (Init_load), ruby.c
(uscore_get, rb_f_chop), st.c (stat_col), signal.c
(rb_signal_buff_size, ruby_sig_finalize), thread.c
(rb_thread_sleep_forever, rb_thread_sleep_deadly, rb_thread_alone):
protoized.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-02-01 07:51:44 -05:00
|
|
|
rb_need_block(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
if (!rb_block_given_p()) {
|
* vm.c: add a prefix "rb_" to exposed functions
vm_get_ruby_level_next_cfp(), rb_vm_make_env_object(),
vm_stack_to_heap(), vm_make_proc(), vm_invoke_proc(),
vm_get_sourceline(), vm_cref(), vm_localjump_error(),
vm_make_jump_tag_but_local_jump(), vm_jump_tag_but_local_jump().
This changes may affect only core because most of renamed functions
require a pointer of not-exposed struct such as rb_thread_t or NODE.
In short, they are core functions.
* cont.c, eval.c, eval_intern.h, load.c, proc.c, thread.c,
vm_core.h, vm_dump.c, vm_eval.c, vm_exec.c, vm_insnhelper.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-01-18 21:38:11 -05:00
|
|
|
rb_vm_localjump_error("no block given", Qnil, 0);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2000-01-04 23:41:21 -05:00
|
|
|
VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_rescue2(VALUE (* b_proc) (ANYARGS), VALUE data1,
|
|
|
|
VALUE (* r_proc) (ANYARGS), VALUE data2, ...)
|
2000-01-04 23:41:21 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
int state;
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2007-04-12 04:13:20 -04:00
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
2006-12-31 10:02:22 -05:00
|
|
|
volatile VALUE result;
|
2007-04-12 04:13:20 -04:00
|
|
|
volatile VALUE e_info = th->errinfo;
|
2006-12-31 10:02:22 -05:00
|
|
|
va_list args;
|
2000-01-04 23:41:21 -05:00
|
|
|
|
2012-10-19 03:57:56 -04:00
|
|
|
TH_PUSH_TAG(th);
|
|
|
|
if ((state = TH_EXEC_TAG()) == 0) {
|
2006-12-31 10:02:22 -05:00
|
|
|
retry_entry:
|
|
|
|
result = (*b_proc) (data1);
|
2000-01-04 23:41:21 -05:00
|
|
|
}
|
2007-04-12 04:13:20 -04:00
|
|
|
else {
|
|
|
|
th->cfp = cfp; /* restore */
|
|
|
|
|
|
|
|
if (state == TAG_RAISE) {
|
2009-07-18 04:05:32 -04:00
|
|
|
int handle = FALSE;
|
2007-04-12 04:13:20 -04:00
|
|
|
VALUE eclass;
|
2000-01-04 23:41:21 -05:00
|
|
|
|
2007-04-12 04:13:20 -04:00
|
|
|
va_init_list(args, data2);
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 04:12:18 -04:00
|
|
|
while ((eclass = va_arg(args, VALUE)) != 0) {
|
2007-04-12 04:13:20 -04:00
|
|
|
if (rb_obj_is_kind_of(th->errinfo, eclass)) {
|
2009-07-18 04:05:32 -04:00
|
|
|
handle = TRUE;
|
2007-04-12 04:13:20 -04:00
|
|
|
break;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2007-04-12 04:13:20 -04:00
|
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
if (handle) {
|
|
|
|
if (r_proc) {
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2007-04-12 04:13:20 -04:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
result = (*r_proc) (data2, th->errinfo);
|
|
|
|
}
|
|
|
|
POP_TAG();
|
|
|
|
if (state == TAG_RETRY) {
|
|
|
|
state = 0;
|
|
|
|
th->errinfo = Qnil;
|
|
|
|
goto retry_entry;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
result = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
state = 0;
|
|
|
|
}
|
2007-04-12 04:13:20 -04:00
|
|
|
if (state == 0) {
|
|
|
|
th->errinfo = e_info;
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-19 03:57:56 -04:00
|
|
|
TH_POP_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state)
|
|
|
|
JUMP_TAG(state);
|
2003-12-27 19:02:59 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return result;
|
|
|
|
}
|
2003-12-27 19:02:59 -05:00
|
|
|
|
1999-08-13 01:45:20 -04:00
|
|
|
VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_rescue(VALUE (* b_proc)(ANYARGS), VALUE data1,
|
|
|
|
VALUE (* r_proc)(ANYARGS), VALUE data2)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError,
|
|
|
|
(VALUE)0);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
1999-08-13 01:45:20 -04:00
|
|
|
VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_protect(VALUE (* proc) (VALUE), VALUE data, int * state)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2009-04-19 01:43:20 -04:00
|
|
|
volatile VALUE result = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
int status;
|
2007-04-12 03:08:28 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
2010-01-25 13:22:58 -05:00
|
|
|
struct rb_vm_protect_tag protect_tag;
|
2007-12-13 18:19:14 -05:00
|
|
|
rb_jmpbuf_t org_jmpbuf;
|
2007-07-20 03:11:35 -04:00
|
|
|
|
2010-01-25 13:22:58 -05:00
|
|
|
protect_tag.prev = th->protect_tag;
|
|
|
|
|
2012-10-19 03:57:56 -04:00
|
|
|
TH_PUSH_TAG(th);
|
2010-01-25 13:22:58 -05:00
|
|
|
th->protect_tag = &protect_tag;
|
2007-12-13 18:19:14 -05:00
|
|
|
MEMCPY(&org_jmpbuf, &(th)->root_jmpbuf, rb_jmpbuf_t, 1);
|
2012-10-19 03:57:56 -04:00
|
|
|
if ((status = TH_EXEC_TAG()) == 0) {
|
* cont.c: support Fiber. Check test/ruby/test_fiber.rb for detail.
Fiber is known as "Micro Thread", "Coroutine", and other terms.
At this time, only Fiber#pass is supported to change context.
I want to know more suitable method name/API for Fiber (... do you
know more suitable class name instead of Fiber?) as "suspend/resume",
"call", "yield", "start/kick/stop/restart", ....
* eval.c, eval_intern.h, thread.c, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12395 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-05-27 15:12:43 -04:00
|
|
|
SAVE_ROOT_JMPBUF(th, result = (*proc) (data));
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2007-12-13 18:19:14 -05:00
|
|
|
MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
|
2010-01-25 13:22:58 -05:00
|
|
|
th->protect_tag = protect_tag.prev;
|
2012-10-19 03:57:56 -04:00
|
|
|
TH_POP_TAG();
|
2007-04-12 03:08:28 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state) {
|
|
|
|
*state = status;
|
|
|
|
}
|
|
|
|
if (status != 0) {
|
2007-04-12 03:08:28 -04:00
|
|
|
th->cfp = cfp;
|
2006-12-31 10:02:22 -05:00
|
|
|
return Qnil;
|
|
|
|
}
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return result;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE
|
|
|
|
rb_ensure(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*e_proc)(ANYARGS), VALUE data2)
|
2006-09-23 17:29:47 -04:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
int state;
|
|
|
|
volatile VALUE result = Qnil;
|
2013-02-08 02:09:48 -05:00
|
|
|
volatile VALUE errinfo;
|
|
|
|
rb_thread_t *const th = GET_THREAD();
|
2006-09-23 17:29:47 -04:00
|
|
|
|
2007-04-24 21:35:13 -04:00
|
|
|
PUSH_TAG();
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
result = (*b_proc) (data1);
|
|
|
|
}
|
|
|
|
POP_TAG();
|
* call_cfunc.ci, compile.c, compile.h, debug.h, eval.c,
eval_error.h, eval_jump.h, eval_load.c, eval_thread.c, gc.c,
insnhelper.h, insns.def, iseq.c, main.c, numeric.c, parse.y,
range.c, regenc.h, ruby.h, signal.c, thread.c, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fixed indents and non-C90 comments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11620 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-02 11:26:04 -05:00
|
|
|
/* TODO: fix me */
|
|
|
|
/* retval = prot_tag ? prot_tag->retval : Qnil; */ /* save retval */
|
2013-02-08 02:09:48 -05:00
|
|
|
errinfo = th->errinfo;
|
2006-12-31 10:02:22 -05:00
|
|
|
(*e_proc) (data2);
|
2013-02-08 02:09:48 -05:00
|
|
|
th->errinfo = errinfo;
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state)
|
|
|
|
JUMP_TAG(state);
|
|
|
|
return result;
|
2006-09-23 17:29:47 -04:00
|
|
|
}
|
|
|
|
|
2011-05-05 02:32:37 -04:00
|
|
|
static const rb_method_entry_t *
|
|
|
|
method_entry_of_iseq(rb_control_frame_t *cfp, rb_iseq_t *iseq)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_control_frame_t *cfp_limit;
|
|
|
|
|
|
|
|
cfp_limit = (rb_control_frame_t *)(th->stack + th->stack_size);
|
|
|
|
while (cfp_limit > cfp) {
|
|
|
|
if (cfp->iseq == iseq)
|
|
|
|
return cfp->me;
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
static ID
|
|
|
|
frame_func_id(rb_control_frame_t *cfp)
|
2006-09-23 17:29:47 -04:00
|
|
|
{
|
2011-05-05 02:32:37 -04:00
|
|
|
const rb_method_entry_t *me_local;
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
rb_iseq_t *iseq = cfp->iseq;
|
2011-05-05 02:32:37 -04:00
|
|
|
if (cfp->me) {
|
2009-08-27 22:45:41 -04:00
|
|
|
return cfp->me->def->original_id;
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
}
|
|
|
|
while (iseq) {
|
|
|
|
if (RUBY_VM_IFUNC_P(iseq)) {
|
2010-07-14 07:23:10 -04:00
|
|
|
NODE *ifunc = (NODE *)iseq;
|
|
|
|
if (ifunc->nd_aid) return ifunc->nd_aid;
|
2013-04-30 22:40:41 -04:00
|
|
|
return idIFUNC;
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
}
|
2011-05-05 02:32:37 -04:00
|
|
|
me_local = method_entry_of_iseq(cfp, iseq);
|
|
|
|
if (me_local) {
|
2011-05-05 04:39:22 -04:00
|
|
|
cfp->me = me_local;
|
2011-05-05 02:32:37 -04:00
|
|
|
return me_local->def->original_id;
|
|
|
|
}
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
if (iseq->defined_method_id) {
|
|
|
|
return iseq->defined_method_id;
|
|
|
|
}
|
|
|
|
if (iseq->local_iseq == iseq) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iseq = iseq->parent_iseq;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
return 0;
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2012-07-03 22:11:37 -04:00
|
|
|
static ID
|
|
|
|
frame_called_id(rb_control_frame_t *cfp)
|
2003-12-13 04:13:39 -05:00
|
|
|
{
|
2012-07-03 22:11:37 -04:00
|
|
|
const rb_method_entry_t *me_local;
|
|
|
|
rb_iseq_t *iseq = cfp->iseq;
|
|
|
|
if (cfp->me) {
|
|
|
|
return cfp->me->called_id;
|
|
|
|
}
|
|
|
|
while (iseq) {
|
|
|
|
if (RUBY_VM_IFUNC_P(iseq)) {
|
|
|
|
NODE *ifunc = (NODE *)iseq;
|
|
|
|
if (ifunc->nd_aid) return ifunc->nd_aid;
|
2013-04-30 22:40:41 -04:00
|
|
|
return idIFUNC;
|
2012-07-03 22:11:37 -04:00
|
|
|
}
|
|
|
|
me_local = method_entry_of_iseq(cfp, iseq);
|
|
|
|
if (me_local) {
|
|
|
|
cfp->me = me_local;
|
|
|
|
return me_local->called_id;
|
|
|
|
}
|
|
|
|
if (iseq->defined_method_id) {
|
|
|
|
return iseq->defined_method_id;
|
|
|
|
}
|
|
|
|
if (iseq->local_iseq == iseq) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iseq = iseq->parent_iseq;
|
|
|
|
}
|
|
|
|
return 0;
|
2003-12-13 04:13:39 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
ID
|
2012-07-03 22:11:37 -04:00
|
|
|
rb_frame_this_func(void)
|
2008-12-27 02:22:01 -05:00
|
|
|
{
|
|
|
|
return frame_func_id(GET_THREAD()->cfp);
|
|
|
|
}
|
|
|
|
|
2013-05-24 22:24:33 -04:00
|
|
|
ID
|
|
|
|
rb_frame_callee(void)
|
|
|
|
{
|
|
|
|
return frame_called_id(GET_THREAD()->cfp);
|
|
|
|
}
|
|
|
|
|
2012-07-03 22:11:37 -04:00
|
|
|
static rb_control_frame_t *
|
|
|
|
previous_frame(rb_thread_t *th)
|
2003-12-13 04:13:39 -05:00
|
|
|
{
|
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
|
|
|
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
2007-02-04 14:12:52 -05:00
|
|
|
/* check if prev_cfp can be accessible */
|
|
|
|
if ((void *)(th->stack + th->stack_size) == (void *)(prev_cfp)) {
|
|
|
|
return 0;
|
|
|
|
}
|
2012-07-03 22:11:37 -04:00
|
|
|
return prev_cfp;
|
|
|
|
}
|
|
|
|
|
2013-05-24 22:24:33 -04:00
|
|
|
static ID
|
|
|
|
prev_frame_callee(void)
|
2012-07-03 22:11:37 -04:00
|
|
|
{
|
|
|
|
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
|
|
|
if (!prev_cfp) return 0;
|
|
|
|
return frame_called_id(prev_cfp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static ID
|
2013-05-24 22:24:33 -04:00
|
|
|
prev_frame_func(void)
|
2012-07-03 22:11:37 -04:00
|
|
|
{
|
|
|
|
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
|
|
|
if (!prev_cfp) return 0;
|
2007-02-04 14:12:52 -05:00
|
|
|
return frame_func_id(prev_cfp);
|
2003-12-13 04:13:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_frame_pop(void)
|
2003-12-13 04:13:39 -05:00
|
|
|
{
|
* blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
eval_jump.h, eval_load.c, eval_safe.h, gc.c, proc.c, signal.c,
thread.c, thread_pthread.ci, thread_win32.ci, vm.c, vm.h,
vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fix typo (rb_thead_t -> rb_thread_t).
* eval_intern.h: remove unused definitions.
* common.mk: fix around vm_opts.h path
and remove harmful argument passed to insns2vm.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11658 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-08 01:37:46 -05:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
|
|
|
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
2003-12-13 04:13:39 -05:00
|
|
|
}
|
|
|
|
|
2003-12-27 19:02:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* append_features(mod) -> mod
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* When this module is included in another, Ruby calls
|
|
|
|
* <code>append_features</code> in this module, passing it the
|
|
|
|
* receiving module in _mod_. Ruby's default implementation is
|
|
|
|
* to add the constants, methods, and module variables of this module
|
|
|
|
* to _mod_ if this module has not already been added to
|
|
|
|
* _mod_ or one of its ancestors. See also <code>Module#include</code>.
|
2003-12-27 19:02:59 -05:00
|
|
|
*/
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_mod_append_features(VALUE module, VALUE include)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2013-04-04 04:23:10 -04:00
|
|
|
if (!CLASS_OR_MODULE_P(include)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
Check_Type(include, T_CLASS);
|
|
|
|
}
|
|
|
|
rb_include_module(include, module);
|
1998-01-16 07:13:05 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return module;
|
|
|
|
}
|
2003-12-27 19:02:59 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* include(module, ...) -> self
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2009-08-03 09:22:07 -04:00
|
|
|
* Invokes <code>Module.append_features</code> on each parameter in reverse order.
|
2003-12-27 19:02:59 -05:00
|
|
|
*/
|
|
|
|
|
1998-01-16 07:13:05 -05:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_mod_include(int argc, VALUE *argv, VALUE module)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
int i;
|
2012-09-26 22:36:36 -04:00
|
|
|
ID id_append_features, id_included;
|
|
|
|
|
|
|
|
CONST_ID(id_append_features, "append_features");
|
|
|
|
CONST_ID(id_included, "included");
|
1999-08-13 01:45:20 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
Check_Type(argv[i], T_MODULE);
|
|
|
|
while (argc--) {
|
2012-09-26 22:36:36 -04:00
|
|
|
rb_funcall(argv[argc], id_append_features, 1, module);
|
|
|
|
rb_funcall(argv[argc], id_included, 1, module);
|
1999-08-13 01:45:20 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
return module;
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
|
2012-06-27 03:48:50 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* prepend_features(mod) -> mod
|
|
|
|
*
|
|
|
|
* When this module is prepended in another, Ruby calls
|
|
|
|
* <code>prepend_features</code> in this module, passing it the
|
|
|
|
* receiving module in _mod_. Ruby's default implementation is
|
|
|
|
* to overlay the constants, methods, and module variables of this module
|
|
|
|
* to _mod_ if this module has not already been added to
|
|
|
|
* _mod_ or one of its ancestors. See also <code>Module#prepend</code>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_prepend_features(VALUE module, VALUE prepend)
|
|
|
|
{
|
2013-04-04 04:23:10 -04:00
|
|
|
if (!CLASS_OR_MODULE_P(prepend)) {
|
2012-06-27 03:48:50 -04:00
|
|
|
Check_Type(prepend, T_CLASS);
|
|
|
|
}
|
|
|
|
rb_prepend_module(prepend, module);
|
|
|
|
|
|
|
|
return module;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* prepend(module, ...) -> self
|
|
|
|
*
|
|
|
|
* Invokes <code>Module.prepend_features</code> on each parameter in reverse order.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_prepend(int argc, VALUE *argv, VALUE module)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
ID id_prepend_features, id_prepended;
|
|
|
|
|
|
|
|
CONST_ID(id_prepend_features, "prepend_features");
|
|
|
|
CONST_ID(id_prepended, "prepended");
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
Check_Type(argv[i], T_MODULE);
|
|
|
|
while (argc--) {
|
|
|
|
rb_funcall(argv[argc], id_prepend_features, 1, module);
|
|
|
|
rb_funcall(argv[argc], id_prepended, 1, module);
|
|
|
|
}
|
|
|
|
return module;
|
|
|
|
}
|
|
|
|
|
2012-10-01 09:56:37 -04:00
|
|
|
static VALUE
|
2012-10-08 10:02:46 -04:00
|
|
|
hidden_identity_hash_new()
|
2012-10-01 09:56:37 -04:00
|
|
|
{
|
|
|
|
VALUE hash = rb_hash_new();
|
|
|
|
|
|
|
|
rb_funcall(hash, rb_intern("compare_by_identity"), 0);
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 06:49:11 -04:00
|
|
|
RBASIC_CLEAR_CLASS(hash); /* hide from ObjectSpace */
|
2012-10-01 09:56:37 -04:00
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2012-08-02 07:34:19 -04:00
|
|
|
void
|
2012-10-08 10:02:46 -04:00
|
|
|
rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
|
2012-08-02 07:34:19 -04:00
|
|
|
{
|
|
|
|
VALUE iclass, c, superclass = klass;
|
|
|
|
|
2012-12-07 10:49:21 -05:00
|
|
|
Check_Type(klass, T_CLASS);
|
2012-08-02 07:34:19 -04:00
|
|
|
Check_Type(module, T_MODULE);
|
2012-10-08 10:02:46 -04:00
|
|
|
if (NIL_P(cref->nd_refinements)) {
|
|
|
|
cref->nd_refinements = hidden_identity_hash_new();
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (cref->flags & NODE_FL_CREF_OMOD_SHARED) {
|
2012-10-08 10:02:46 -04:00
|
|
|
cref->nd_refinements = rb_hash_dup(cref->nd_refinements);
|
2012-08-02 07:34:19 -04:00
|
|
|
cref->flags &= ~NODE_FL_CREF_OMOD_SHARED;
|
|
|
|
}
|
2012-10-08 10:02:46 -04:00
|
|
|
if (!NIL_P(c = rb_hash_lookup(cref->nd_refinements, klass))) {
|
2012-08-02 07:34:19 -04:00
|
|
|
superclass = c;
|
2012-12-29 07:22:01 -05:00
|
|
|
while (c && RB_TYPE_P(c, T_ICLASS)) {
|
2012-08-02 07:34:19 -04:00
|
|
|
if (RBASIC(c)->klass == module) {
|
2012-10-08 10:02:46 -04:00
|
|
|
/* already used refinement */
|
2012-08-02 07:34:19 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
c = RCLASS_SUPER(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-08-06 01:55:19 -04:00
|
|
|
FL_SET(module, RMODULE_IS_OVERLAID);
|
2012-08-02 07:34:19 -04:00
|
|
|
c = iclass = rb_include_class_new(module, superclass);
|
2012-08-06 03:00:19 -04:00
|
|
|
RCLASS_REFINED_CLASS(c) = klass;
|
2013-06-22 16:48:35 -04:00
|
|
|
|
2013-06-22 17:54:10 -04:00
|
|
|
RCLASS_M_TBL(OBJ_WB_UNPROTECT(c)) = RCLASS_M_TBL(OBJ_WB_UNPROTECT(module));
|
2013-06-22 16:48:35 -04:00
|
|
|
|
2012-08-02 07:34:19 -04:00
|
|
|
module = RCLASS_SUPER(module);
|
* fix the behavior when a module is included into a refinement.
This change is a little tricky, so it might be better to prohibit
module inclusion to refinements.
* include/ruby/ruby.h (RMODULE_INCLUDED_INTO_REFINEMENT): new flag
to represent that a module (iclass) is included into a refinement.
* class.c (include_modules_at): set RMODULE_INCLUDED_INTO_REFINEMENT
if klass is a refinement.
* eval.c (rb_mod_refine): set the superclass of a refinement to the
refined class for super.
* eval.c (rb_using_refinement): skip the above superclass (the
refined class) when creating iclasses for refinements. Otherwise,
`using Refinement1; using Refinement2' creates iclasses:
<Refinement2> -> <RefinedClass> -> <Refinement1> -> RefinedClass,
where <Module> is an iclass for Module, so RefinedClass is
searched before Refinement1. The correct iclasses should be
<Refinement2> -> <Refinement1> -> RefinedClass.
* vm_insnhelper.c (vm_search_normal_superclass): if klass is an
iclass for a refinement, use the refinement's superclass instead
of the iclass's superclass. Otherwise, multiple refinements are
searched by super. For example, if a refinement Refinement2
includes a module M (i.e., Refinement2 -> <M> -> RefinedClass,
and if refinements iclasses are <Refinement2> -> <M>' ->
<Refinement1> -> RefinedClass, then super in <Refinement2> should
use Refinement2's superclass <M> instead of <Refinement2>'s
superclass <M>'.
* vm_insnhelper.c (vm_search_super_method): do not raise a
NotImplementError if current_defind_class is a module included
into a refinement. Because of the change of
vm_search_normal_superclass(), the receiver might not be an
instance of the module('s iclass).
* test/ruby/test_refinement.rb: related test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38298 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-10 11:05:45 -05:00
|
|
|
while (module && module != klass) {
|
2012-08-06 01:55:19 -04:00
|
|
|
FL_SET(module, RMODULE_IS_OVERLAID);
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 06:49:11 -04:00
|
|
|
c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c)));
|
2012-08-06 03:00:19 -04:00
|
|
|
RCLASS_REFINED_CLASS(c) = klass;
|
2012-08-02 07:34:19 -04:00
|
|
|
module = RCLASS_SUPER(module);
|
|
|
|
}
|
2012-10-08 10:02:46 -04:00
|
|
|
rb_hash_aset(cref->nd_refinements, klass, iclass);
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
|
|
|
|
2012-11-01 01:45:28 -04:00
|
|
|
static int
|
|
|
|
using_refinement(VALUE klass, VALUE module, VALUE arg)
|
2012-08-02 07:34:19 -04:00
|
|
|
{
|
|
|
|
NODE *cref = (NODE *) arg;
|
|
|
|
|
2012-10-08 10:02:46 -04:00
|
|
|
rb_using_refinement(cref, klass, module);
|
2012-08-02 07:34:19 -04:00
|
|
|
return ST_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2013-06-30 23:57:16 -04:00
|
|
|
static void
|
|
|
|
using_module_recursive(NODE *cref, VALUE klass)
|
2012-08-02 07:34:19 -04:00
|
|
|
{
|
2012-10-08 10:02:46 -04:00
|
|
|
ID id_refinements;
|
2013-06-30 23:57:16 -04:00
|
|
|
VALUE super, module, refinements;
|
2012-08-02 07:34:19 -04:00
|
|
|
|
2013-06-30 23:57:16 -04:00
|
|
|
super = RCLASS_SUPER(klass);
|
|
|
|
if (super) {
|
|
|
|
using_module_recursive(cref, super);
|
|
|
|
}
|
|
|
|
switch (BUILTIN_TYPE(klass)) {
|
|
|
|
case T_MODULE:
|
|
|
|
module = klass;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case T_ICLASS:
|
|
|
|
module = RBASIC(klass)->klass;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected Module)",
|
|
|
|
rb_obj_classname(klass));
|
|
|
|
break;
|
|
|
|
}
|
2012-10-08 10:02:46 -04:00
|
|
|
CONST_ID(id_refinements, "__refinements__");
|
|
|
|
refinements = rb_attr_get(module, id_refinements);
|
|
|
|
if (NIL_P(refinements)) return;
|
2012-11-01 01:45:28 -04:00
|
|
|
rb_hash_foreach(refinements, using_refinement, (VALUE) cref);
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
|
|
|
|
2013-06-30 23:57:16 -04:00
|
|
|
void
|
|
|
|
rb_using_module(NODE *cref, VALUE module)
|
|
|
|
{
|
|
|
|
Check_Type(module, T_MODULE);
|
|
|
|
using_module_recursive(cref, module);
|
|
|
|
}
|
|
|
|
|
2013-09-09 01:17:17 -04:00
|
|
|
VALUE
|
|
|
|
rb_refinement_module_get_refined_class(VALUE module)
|
* revised r37993 to avoid SEGV/ILL in tests. In r37993, a method
entry with VM_METHOD_TYPE_REFINED holds only the original method
definition, so ci->me is set to a method entry allocated in the
stack, and it causes SEGV/ILL. In this commit, a method entry
with VM_METHOD_TYPE_REFINED holds the whole original method entry.
Furthermore, rb_thread_mark() is changed to mark cfp->klass to
avoid GC for iclasses created by copy_refinement_iclass().
* vm_method.c (rb_method_entry_make): add a method entry with
VM_METHOD_TYPE_REFINED to the class refined by the refinement if
the target module is a refinement. When a method entry with
VM_METHOD_TYPE_UNDEF is invoked by vm_call_method(), a method with
the same name is searched in refinements. If such a method is
found, the method is invoked. Otherwise, the original method in
the refined class (rb_method_definition_t::body.orig_me) is
invoked. This change is made to simplify the normal method lookup
and to improve the performance of normal method calls.
* vm_method.c (EXPR1, search_method, rb_method_entry),
vm_eval.c (rb_call0, rb_search_method_entry): do not use
refinements for method lookup.
* vm_insnhelper.c (vm_call_method): search methods in refinements if
ci->me is VM_METHOD_TYPE_REFINED. If the method is called by
super (i.e., ci->call == vm_call_super_method), skip the same
method entry as the current method to avoid infinite call of the
same method.
* class.c (include_modules_at): add a refined method entry for each
method defined in a module included in a refinement.
* class.c (rb_prepend_module): set an empty table to
RCLASS_M_TBL(klass) to add refined method entries, because
refinements should have priority over prepended modules.
* proc.c (mnew): use rb_method_entry_with_refinements() to get
a refined method.
* vm.c (rb_thread_mark): mark cfp->klass for iclasses created by
copy_refinement_iclass().
* vm.c (Init_VM), cont.c (fiber_init): initialize th->cfp->klass.
* test/ruby/test_refinement.rb (test_inline_method_cache): do not skip
the test because it should pass successfully.
* test/ruby/test_refinement.rb (test_redefine_refined_method): new
test for the case a refined method is redefined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-06 08:08:41 -05:00
|
|
|
{
|
|
|
|
ID id_refined_class;
|
|
|
|
|
|
|
|
CONST_ID(id_refined_class, "__refined_class__");
|
|
|
|
return rb_attr_get(module, id_refined_class);
|
|
|
|
}
|
|
|
|
|
2012-12-07 21:37:16 -05:00
|
|
|
static void
|
|
|
|
add_activated_refinement(VALUE activated_refinements,
|
|
|
|
VALUE klass, VALUE refinement)
|
|
|
|
{
|
|
|
|
VALUE iclass, c, superclass = klass;
|
|
|
|
|
|
|
|
if (!NIL_P(c = rb_hash_lookup(activated_refinements, klass))) {
|
|
|
|
superclass = c;
|
2012-12-29 07:22:01 -05:00
|
|
|
while (c && RB_TYPE_P(c, T_ICLASS)) {
|
2012-12-07 21:37:16 -05:00
|
|
|
if (RBASIC(c)->klass == refinement) {
|
|
|
|
/* already used refinement */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
c = RCLASS_SUPER(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FL_SET(refinement, RMODULE_IS_OVERLAID);
|
|
|
|
c = iclass = rb_include_class_new(refinement, superclass);
|
|
|
|
RCLASS_REFINED_CLASS(c) = klass;
|
|
|
|
refinement = RCLASS_SUPER(refinement);
|
|
|
|
while (refinement) {
|
|
|
|
FL_SET(refinement, RMODULE_IS_OVERLAID);
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 06:49:11 -04:00
|
|
|
c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
|
2012-12-07 21:37:16 -05:00
|
|
|
RCLASS_REFINED_CLASS(c) = klass;
|
|
|
|
refinement = RCLASS_SUPER(refinement);
|
|
|
|
}
|
|
|
|
rb_hash_aset(activated_refinements, klass, iclass);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
|
|
|
|
|
2012-08-02 07:34:19 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2012-08-02 10:38:48 -04:00
|
|
|
* refine(klass) { block } -> module
|
2012-08-02 07:34:19 -04:00
|
|
|
*
|
|
|
|
* Refine <i>klass</i> in the receiver.
|
2012-08-02 10:38:48 -04:00
|
|
|
*
|
2012-08-06 01:55:19 -04:00
|
|
|
* Returns an overlaid module.
|
2012-08-02 07:34:19 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_refine(VALUE module, VALUE klass)
|
|
|
|
{
|
2012-12-07 21:37:16 -05:00
|
|
|
VALUE refinement;
|
|
|
|
ID id_refinements, id_activated_refinements,
|
|
|
|
id_refined_class, id_defined_at;
|
|
|
|
VALUE refinements, activated_refinements;
|
2012-12-07 22:06:13 -05:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_block_t *block = rb_vm_control_frame_block_ptr(th->cfp);
|
2012-08-02 07:34:19 -04:00
|
|
|
|
2012-12-07 22:06:13 -05:00
|
|
|
if (!block) {
|
2012-10-30 10:58:47 -04:00
|
|
|
rb_raise(rb_eArgError, "no block given");
|
|
|
|
}
|
2012-12-07 22:06:13 -05:00
|
|
|
if (block->proc) {
|
|
|
|
rb_raise(rb_eArgError,
|
|
|
|
"can't pass a Proc as a block to Module#refine");
|
|
|
|
}
|
2012-12-07 10:49:21 -05:00
|
|
|
Check_Type(klass, T_CLASS);
|
2012-10-08 10:02:46 -04:00
|
|
|
CONST_ID(id_refinements, "__refinements__");
|
|
|
|
refinements = rb_attr_get(module, id_refinements);
|
|
|
|
if (NIL_P(refinements)) {
|
|
|
|
refinements = hidden_identity_hash_new();
|
|
|
|
rb_ivar_set(module, id_refinements, refinements);
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
2012-12-07 21:37:16 -05:00
|
|
|
CONST_ID(id_activated_refinements, "__activated_refinements__");
|
|
|
|
activated_refinements = rb_attr_get(module, id_activated_refinements);
|
|
|
|
if (NIL_P(activated_refinements)) {
|
|
|
|
activated_refinements = hidden_identity_hash_new();
|
|
|
|
rb_ivar_set(module, id_activated_refinements,
|
|
|
|
activated_refinements);
|
|
|
|
}
|
|
|
|
refinement = rb_hash_lookup(refinements, klass);
|
|
|
|
if (NIL_P(refinement)) {
|
|
|
|
refinement = rb_module_new();
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 06:49:11 -04:00
|
|
|
RCLASS_SET_SUPER(refinement, klass);
|
2012-12-07 21:37:16 -05:00
|
|
|
FL_SET(refinement, RMODULE_IS_REFINEMENT);
|
2012-08-02 07:34:19 -04:00
|
|
|
CONST_ID(id_refined_class, "__refined_class__");
|
2012-12-07 21:37:16 -05:00
|
|
|
rb_ivar_set(refinement, id_refined_class, klass);
|
2012-11-02 04:53:06 -04:00
|
|
|
CONST_ID(id_defined_at, "__defined_at__");
|
2012-12-07 21:37:16 -05:00
|
|
|
rb_ivar_set(refinement, id_defined_at, module);
|
|
|
|
rb_hash_aset(refinements, klass, refinement);
|
|
|
|
add_activated_refinement(activated_refinements, klass, refinement);
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
2012-12-07 21:37:16 -05:00
|
|
|
rb_yield_refine_block(refinement, activated_refinements);
|
|
|
|
return refinement;
|
2012-08-02 07:34:19 -04:00
|
|
|
}
|
|
|
|
|
2013-06-12 10:33:59 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* using(module) -> self
|
|
|
|
*
|
|
|
|
* Import class refinements from <i>module</i> into the current class or
|
|
|
|
* module definition.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
mod_using(VALUE self, VALUE module)
|
|
|
|
{
|
|
|
|
NODE *cref = rb_vm_cref();
|
|
|
|
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
|
|
|
|
|
|
|
if (prev_frame_func()) {
|
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"Module#using is not permitted in methods");
|
|
|
|
}
|
|
|
|
if (prev_cfp && prev_cfp->self != self) {
|
|
|
|
rb_raise(rb_eRuntimeError, "Module#using is not called on self");
|
|
|
|
}
|
|
|
|
Check_Type(module, T_MODULE);
|
|
|
|
rb_using_module(cref, module);
|
* insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split
ruby_vm_global_state_version into two separate counters - one for the
global method state and one for the global constant state. This means
changes to constants do not affect method caches, and changes to
methods do not affect constant caches. In particular, this means
inclusions of modules containing constants no longer globally
invalidate the method cache.
* class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
rename rb_clear_cache_by_class to rb_clear_method_cache_by_class
* class.c, include/ruby/intern.h, variable.c, vm_method.c: add
rb_clear_constant_cache
* compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
rb_call_info_struct to method_state
* vm_method.c: rename vmstat field in struct cache_entry to method_state
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-10-28 20:52:38 -04:00
|
|
|
rb_clear_method_cache_by_class(rb_cObject);
|
2013-06-12 10:33:59 -04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1999-01-19 23:59:39 -05:00
|
|
|
void
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
PASS_PASSED_BLOCK();
|
* 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
2008-05-24 13:50:17 -04:00
|
|
|
rb_funcall2(obj, idInitialize, argc, argv);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2005-06-12 12:56:06 -04:00
|
|
|
void
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_extend_object(VALUE obj, VALUE module)
|
1998-01-16 07:13:05 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_include_module(rb_singleton_class(obj), module);
|
1998-01-16 07:13:05 -05:00
|
|
|
}
|
|
|
|
|
2003-12-27 19:02:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* extend_object(obj) -> obj
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* Extends the specified object by adding this module's constants and
|
|
|
|
* methods (which are added as singleton methods). This is the callback
|
|
|
|
* method used by <code>Object#extend</code>.
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* module Picky
|
|
|
|
* def Picky.extend_object(o)
|
|
|
|
* if String === o
|
|
|
|
* puts "Can't add Picky to a String"
|
|
|
|
* else
|
|
|
|
* puts "Picky added to #{o.class}"
|
|
|
|
* super
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* (s = Array.new).extend Picky # Call Object.extend
|
|
|
|
* (s = "quick brown fox").extend Picky
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2003-12-27 19:02:59 -05:00
|
|
|
* <em>produces:</em>
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* Picky added to Array
|
|
|
|
* Can't add Picky to a String
|
2003-12-27 19:02:59 -05:00
|
|
|
*/
|
|
|
|
|
2000-10-11 02:29:16 -04:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_mod_extend_object(VALUE mod, VALUE obj)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_extend_object(obj, mod);
|
|
|
|
return obj;
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
|
2003-12-27 19:02:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* obj.extend(module, ...) -> obj
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* Adds to _obj_ the instance methods from each module given as a
|
|
|
|
* parameter.
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* module Mod
|
|
|
|
* def hello
|
|
|
|
* "Hello from Mod.\n"
|
|
|
|
* end
|
|
|
|
* end
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* class Klass
|
|
|
|
* def hello
|
|
|
|
* "Hello from Klass.\n"
|
|
|
|
* end
|
|
|
|
* end
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* k = Klass.new
|
|
|
|
* k.hello #=> "Hello from Klass.\n"
|
|
|
|
* k.extend(Mod) #=> #<Klass:0x401b3bc8>
|
|
|
|
* k.hello #=> "Hello from Mod.\n"
|
2003-12-27 19:02:59 -05:00
|
|
|
*/
|
|
|
|
|
1999-01-19 23:59:39 -05:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_obj_extend(int argc, VALUE *argv, VALUE obj)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
int i;
|
2012-09-26 22:36:36 -04:00
|
|
|
ID id_extend_object, id_extended;
|
|
|
|
|
|
|
|
CONST_ID(id_extend_object, "extend_object");
|
|
|
|
CONST_ID(id_extended, "extended");
|
1999-01-19 23:59:39 -05:00
|
|
|
|
2012-03-14 17:10:34 -04:00
|
|
|
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
2006-12-31 10:02:22 -05:00
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
Check_Type(argv[i], T_MODULE);
|
|
|
|
while (argc--) {
|
2012-09-26 22:36:36 -04:00
|
|
|
rb_funcall(argv[argc], id_extend_object, 1, obj);
|
|
|
|
rb_funcall(argv[argc], id_extended, 1, obj);
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
return obj;
|
2001-06-05 03:19:39 -04:00
|
|
|
}
|
|
|
|
|
2003-12-27 19:02:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* include(module, ...) -> self
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2006-12-31 10:02:22 -05:00
|
|
|
* Invokes <code>Module.append_features</code>
|
|
|
|
* on each parameter in turn. Effectively adds the methods and constants
|
|
|
|
* in each module to the receiver.
|
2003-12-27 19:02:59 -05:00
|
|
|
*/
|
|
|
|
|
2001-06-05 03:19:39 -04:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
top_include(int argc, VALUE *argv, VALUE self)
|
2001-06-05 03:19:39 -04:00
|
|
|
{
|
2007-02-25 11:29:26 -05:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
|
|
|
|
if (th->top_wrapper) {
|
2012-11-01 19:23:23 -04:00
|
|
|
rb_warning("main.include in the wrapped load is effective only in wrapper module");
|
2007-02-25 11:29:26 -05:00
|
|
|
return rb_mod_include(argc, argv, th->top_wrapper);
|
2001-06-05 03:19:39 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
return rb_mod_include(argc, argv, rb_cObject);
|
2001-06-05 03:19:39 -04:00
|
|
|
}
|
|
|
|
|
2012-08-02 07:34:19 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* using(module) -> self
|
|
|
|
*
|
|
|
|
* Import class refinements from <i>module</i> into the scope where
|
|
|
|
* <code>using</code> is called.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2012-11-11 01:14:16 -05:00
|
|
|
top_using(VALUE self, VALUE module)
|
2012-08-02 07:34:19 -04:00
|
|
|
{
|
|
|
|
NODE *cref = rb_vm_cref();
|
2012-12-08 08:35:12 -05:00
|
|
|
rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());
|
2012-08-02 07:34:19 -04:00
|
|
|
|
2012-12-08 08:35:12 -05:00
|
|
|
if (cref->nd_next || (prev_cfp && prev_cfp->me)) {
|
2013-06-12 10:33:59 -04:00
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"main.using is permitted only at toplevel");
|
2012-12-08 08:35:12 -05:00
|
|
|
}
|
2012-09-28 22:21:27 -04:00
|
|
|
Check_Type(module, T_MODULE);
|
2012-08-02 07:34:19 -04:00
|
|
|
rb_using_module(cref, module);
|
* insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split
ruby_vm_global_state_version into two separate counters - one for the
global method state and one for the global constant state. This means
changes to constants do not affect method caches, and changes to
methods do not affect constant caches. In particular, this means
inclusions of modules containing constants no longer globally
invalidate the method cache.
* class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
rename rb_clear_cache_by_class to rb_clear_method_cache_by_class
* class.c, include/ruby/intern.h, variable.c, vm_method.c: add
rb_clear_constant_cache
* compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
rb_call_info_struct to method_state
* vm_method.c: rename vmstat field in struct cache_entry to method_state
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-10-28 20:52:38 -04:00
|
|
|
rb_clear_method_cache_by_class(rb_cObject);
|
2012-08-02 07:34:19 -04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-08-18 00:26:48 -04:00
|
|
|
static VALUE *
|
2009-10-10 01:13:08 -04:00
|
|
|
errinfo_place(rb_thread_t *th)
|
2000-11-27 04:23:38 -05:00
|
|
|
{
|
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
|
|
|
rb_control_frame_t *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);
|
2000-11-27 04:23:38 -05:00
|
|
|
|
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
|
|
|
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
|
|
|
|
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
|
2012-06-10 23:14:59 -04:00
|
|
|
return &cfp->ep[-2];
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
|
2012-06-10 23:14:59 -04:00
|
|
|
!RB_TYPE_P(cfp->ep[-2], T_NODE) &&
|
|
|
|
!FIXNUM_P(cfp->ep[-2])) {
|
|
|
|
return &cfp->ep[-2];
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2000-11-27 04:23:38 -05:00
|
|
|
}
|
* blockinlining.c, compile.c, compile.h, error.c, eval.c,
eval_intern.h, eval_jump.h, eval_load.c, eval_method.h,
eval_safe.h, gc.c, insnhelper.h, insns.def, iseq.c, proc.c,
process.c, signal.c, thread.c, thread_pthread.ci, thread_win32.ci,
vm.c, vm.h, vm_dump.c, vm_evalbody.ci, vm_macro.def,
yarv.h, yarvcore.h, yarvcore.c: change type and macro names:
* yarv_*_t -> rb_*_t
* yarv_*_struct -> rb_*_struct
* yarv_tag -> rb_vm_tag
* YARV_* -> RUBY_VM_*
* proc.c, vm.c: move functions about env object creation
from proc.c to vm.c.
* proc.c, yarvcore.c: fix rb_cVM initialization place.
* inits.c: change Init_ISeq() order (after Init_VM).
* ruby.h, proc.c: change declaration place of rb_cEnv
from proc.c to ruby.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11651 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 14:00:03 -05:00
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
2000-11-27 04:23:38 -05:00
|
|
|
}
|
2007-08-18 00:26:48 -04:00
|
|
|
return 0;
|
2000-11-27 04:23:38 -05:00
|
|
|
}
|
|
|
|
|
1999-01-19 23:59:39 -05:00
|
|
|
static VALUE
|
2009-10-10 01:13:08 -04:00
|
|
|
get_thread_errinfo(rb_thread_t *th)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2009-10-10 01:13:08 -04:00
|
|
|
VALUE *ptr = errinfo_place(th);
|
2007-08-18 00:26:48 -04:00
|
|
|
if (ptr) {
|
|
|
|
return *ptr;
|
|
|
|
}
|
|
|
|
else {
|
2008-12-26 23:45:28 -05:00
|
|
|
return th->errinfo;
|
2007-08-18 00:26:48 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
1999-01-19 23:59:39 -05:00
|
|
|
|
2009-10-10 01:13:08 -04:00
|
|
|
static VALUE
|
|
|
|
get_errinfo(void)
|
|
|
|
{
|
|
|
|
return get_thread_errinfo(GET_THREAD());
|
|
|
|
}
|
|
|
|
|
2007-08-18 00:26:48 -04:00
|
|
|
static VALUE
|
|
|
|
errinfo_getter(ID id)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
return get_errinfo();
|
|
|
|
}
|
2000-09-20 05:16:32 -04:00
|
|
|
|
2007-08-18 00:26:48 -04:00
|
|
|
#if 0
|
2006-12-31 10:02:22 -05:00
|
|
|
static void
|
|
|
|
errinfo_setter(VALUE val, ID id, VALUE *var)
|
|
|
|
{
|
|
|
|
if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
|
|
|
|
rb_raise(rb_eTypeError, "assigning non-exception to $!");
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
else {
|
2009-10-10 01:13:08 -04:00
|
|
|
VALUE *ptr = errinfo_place(GET_THREAD());
|
2007-08-18 00:26:48 -04:00
|
|
|
if (ptr) {
|
|
|
|
*ptr = val;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eRuntimeError, "errinfo_setter: not in rescue clause.");
|
|
|
|
}
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
}
|
2007-08-18 00:26:48 -04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_errinfo(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
return th->errinfo;
|
|
|
|
}
|
1999-01-19 23:59:39 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
|
|
|
rb_set_errinfo(VALUE err)
|
|
|
|
{
|
2007-08-18 00:26:48 -04:00
|
|
|
if (!NIL_P(err) && !rb_obj_is_kind_of(err, rb_eException)) {
|
|
|
|
rb_raise(rb_eTypeError, "assigning non-exception to $!");
|
|
|
|
}
|
|
|
|
GET_THREAD()->errinfo = err;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_rubylevel_errinfo(void)
|
|
|
|
{
|
|
|
|
return get_errinfo();
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2003-12-21 02:28:54 -05:00
|
|
|
|
1999-01-19 23:59:39 -05:00
|
|
|
static VALUE
|
2006-12-31 10:02:22 -05:00
|
|
|
errat_getter(ID id)
|
1999-01-19 23:59:39 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE err = get_errinfo();
|
|
|
|
if (!NIL_P(err)) {
|
|
|
|
return get_backtrace(err);
|
2000-08-02 05:22:27 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
else {
|
|
|
|
return Qnil;
|
1999-01-19 23:59:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static void
|
|
|
|
errat_setter(VALUE val, ID id, VALUE *var)
|
2000-01-31 22:12:21 -05:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE err = get_errinfo();
|
|
|
|
if (NIL_P(err)) {
|
|
|
|
rb_raise(rb_eArgError, "$! not set");
|
|
|
|
}
|
|
|
|
set_backtrace(err, val);
|
2000-01-31 22:12:21 -05:00
|
|
|
}
|
|
|
|
|
2007-03-20 03:21:37 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-17 17:07:33 -04:00
|
|
|
* __method__ -> symbol
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
*
|
2013-05-24 22:24:33 -04:00
|
|
|
* Returns the name at the definition of the current method as a
|
|
|
|
* Symbol.
|
2007-03-20 03:21:37 -04:00
|
|
|
* If called outside of a method, it returns <code>nil</code>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_f_method_name(void)
|
|
|
|
{
|
2013-05-24 22:24:33 -04:00
|
|
|
ID fname = prev_frame_func(); /* need *method* ID */
|
2007-03-20 03:21:37 -04:00
|
|
|
|
|
|
|
if (fname) {
|
|
|
|
return ID2SYM(fname);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-24 22:24:33 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* __callee__ -> symbol
|
|
|
|
*
|
|
|
|
* Returns the called name of the current method as a Symbol.
|
|
|
|
* If called outside of a method, it returns <code>nil</code>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-07-03 22:11:37 -04:00
|
|
|
static VALUE
|
|
|
|
rb_f_callee_name(void)
|
|
|
|
{
|
2013-05-24 22:24:33 -04:00
|
|
|
ID fname = prev_frame_callee(); /* need *callee* ID */
|
2012-07-03 22:11:37 -04:00
|
|
|
|
|
|
|
if (fname) {
|
|
|
|
return ID2SYM(fname);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-02 21:37:50 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* __dir__ -> string
|
|
|
|
*
|
2013-01-23 23:20:33 -05:00
|
|
|
* Returns the canonicalized absolute path of the directory of the file from
|
|
|
|
* which this method is called. It means symlinks in the path is resolved.
|
2012-11-02 21:37:50 -04:00
|
|
|
* If <code>__FILE__</code> is <code>nil</code>, it returns <code>nil</code>.
|
2013-01-24 01:55:24 -05:00
|
|
|
* The return value equals to <code>File.dirname(File.realpath(__FILE__))</code>.
|
2012-11-02 21:37:50 -04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
f_current_dirname(void)
|
|
|
|
{
|
|
|
|
VALUE base = rb_current_realfilepath();
|
|
|
|
if (NIL_P(base)) {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
base = rb_file_dirname(base);
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
2007-02-07 08:34:18 -05:00
|
|
|
Init_eval(void)
|
2003-07-16 03:11:30 -04:00
|
|
|
{
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_virtual_variable("$@", errat_getter, errat_setter);
|
2007-08-18 00:26:48 -04:00
|
|
|
rb_define_virtual_variable("$!", errinfo_getter, 0);
|
2003-07-16 03:11:30 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_global_function("raise", rb_f_raise, -1);
|
|
|
|
rb_define_global_function("fail", rb_f_raise, -1);
|
2003-12-27 19:02:59 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_global_function("global_variables", rb_f_global_variables, 0); /* in variable.c */
|
2003-07-16 03:11:30 -04:00
|
|
|
|
2007-03-20 03:21:37 -04:00
|
|
|
rb_define_global_function("__method__", rb_f_method_name, 0);
|
2012-07-03 22:11:37 -04:00
|
|
|
rb_define_global_function("__callee__", rb_f_callee_name, 0);
|
2012-11-02 21:37:50 -04:00
|
|
|
rb_define_global_function("__dir__", f_current_dirname, 0);
|
* compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
pack.c, parse.y, re.c, thread.c, vm.c, vm_dump.c, call_cfunc.ci,
thread_pthread.ci, thread_win32.ci: fixed indentation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-05 00:25:10 -04:00
|
|
|
|
2013-09-03 08:42:01 -04:00
|
|
|
rb_define_method(rb_cModule, "include", rb_mod_include, -1);
|
|
|
|
rb_define_method(rb_cModule, "prepend", rb_mod_prepend, -1);
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
|
2012-06-27 03:48:50 -04:00
|
|
|
rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
|
2013-01-07 06:22:31 -05:00
|
|
|
rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
|
2013-06-12 10:33:59 -04:00
|
|
|
rb_define_private_method(rb_cModule, "using", mod_using, 1);
|
2013-01-07 06:22:31 -05:00
|
|
|
rb_undef_method(rb_cClass, "refine");
|
2000-01-31 22:12:21 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_undef_method(rb_cClass, "module_function");
|
* array.c: replace rb_protect_inspect() and rb_inspecting_p() by
rb_exec_recursive() in eval.c.
* eval.c (rb_exec_recursive): new function.
* array.c (rb_ary_join): use rb_exec_recursive().
* array.c (rb_ary_inspect, rb_ary_hash): ditto.
* file.c (rb_file_join): ditto.
* hash.c (rb_hash_inspect, rb_hash_to_s, rb_hash_hash): ditto.
* io.c (rb_io_puts): ditto.
* object.c (rb_obj_inspect): ditto
* struct.c (rb_struct_inspect): ditto.
* lib/set.rb (SortedSet::setup): a hack to shut up warning.
[ruby-talk:132866]
* lib/time.rb (Time::strptime): add new function. inspired by
[ruby-talk:132815].
* lib/parsedate.rb (ParseDate::strptime): ditto.
* regparse.c: move st_*_strend() functions from st.c. fixed some
potential memory leaks.
* exception error messages updated. [ruby-core:04497]
* ext/socket/socket.c (Init_socket): add bunch of Socket
constants. Patch from Sam Roberts <sroberts@uniserve.com>.
[ruby-core:04409]
* array.c (rb_ary_s_create): no need for negative argc check.
[ruby-core:04463]
* array.c (rb_ary_unshift_m): ditto.
* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass
of StandardError class, not Exception class. [ruby-core:04429]
* parse.y (fcall_gen): lvar(arg) will be evaluated as
lvar.call(arg) when lvar is a defined local variable. [new]
* object.c (rb_class_initialize): call inherited method before
calling initializing block.
* eval.c (rb_thread_start_1): initialize newly pushed frame.
* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.
fixed: [ruby-core:04444]
* eval.c (is_defined): NODE_IASGN is an assignment.
* ext/readline/readline.c (Readline.readline): use rl_outstream
and rl_instream. [ruby-dev:25699]
* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check
[ruby-dev:25675]
* misc/ruby-mode.el: [ruby-core:04415]
* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]
* lib/rdoc/generators/ri_generator.rb: ditto.
* struct.c (make_struct): fixed: [ruby-core:04402]
* ext/curses/curses.c (window_color_set): [ruby-core:04393]
* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.
[ruby-talk:130092]
* object.c: [ruby-doc:818]
* parse.y (open_args): fix too verbose warnings for the space
before argument parentheses. [ruby-dev:25492]
* parse.y (parser_yylex): ditto.
* parse.y (parser_yylex): the first expression in the parentheses
should not be a command. [ruby-dev:25492]
* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]
* object.c (Init_Object): remove Object#type. [ruby-core:04335]
* st.c (st_foreach): report success/failure by return value.
[ruby-Bugs-1396]
* parse.y: forgot to initialize parser struct. [ruby-dev:25492]
* parse.y (parser_yylex): no tLABEL on EXPR_BEG.
[ruby-talk:127711]
* document updates - [ruby-core:04296], [ruby-core:04301],
[ruby-core:04302], [ruby-core:04307]
* dir.c (rb_push_glob): should work for NUL delimited patterns.
* dir.c (rb_glob2): should aware of offset in the pattern.
* string.c (rb_str_new4): should propagate taintedness.
* env.h: rename member names in struct FRAME; last_func -> callee,
orig_func -> this_func, last_class -> this_class.
* struct.c (rb_struct_set): use original method name, not callee
name, to retrieve member slot. [ruby-core:04268]
* time.c (time_strftime): protect from format modification from GC
finalizers.
* object.c (Init_Object): remove rb_obj_id_obsolete()
* eval.c (rb_mod_define_method): incomplete subclass check.
[ruby-dev:25464]
* gc.c (rb_data_object_alloc): klass may be NULL.
[ruby-list:40498]
* bignum.c (rb_big_rand): should return positive random number.
[ruby-dev:25401]
* bignum.c (rb_big_rand): do not use rb_big_modulo to generate
random bignums. [ruby-dev:25396]
* variable.c (rb_autoload): [ruby-dev:25373]
* eval.c (svalue_to_avalue): [ruby-dev:25366]
* string.c (rb_str_justify): [ruby-dev:25367]
* io.c (rb_f_select): [ruby-dev:25312]
* ext/socket/socket.c (sock_s_getservbyport): [ruby-talk:124072]
* struct.c (make_struct): [ruby-dev:25249]
* dir.c (dir_open_dir): new function. [ruby-dev:25242]
* io.c (rb_f_open): add type check for return value from to_open.
* lib/pstore.rb (PStore#transaction): Use the empty content when a
file is not found. [ruby-dev:24561]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8068 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-03-04 01:47:45 -05:00
|
|
|
|
* method.h, internal.h iseq.h: declare internal functions.
* compile.c, eval.c, iseq.c, object.c, parse.y, proc.c, process.c,
thread.c, vm.c, vm_eval.c, vm_insnhelper.c, vm_method.c: don't
declare internal functions.
Note that rb_method_entry_eq() is defined in vm_method.c but
there was a declaration in proc.c with different const-ness.
Now it is declared in method.h with same const-ness to the
definition.
* object.c (rb_mod_module_exec): don't declare functions declared in
include/ruby/intern.h.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-17 23:49:33 -04:00
|
|
|
Init_vm_eval();
|
|
|
|
Init_eval_method();
|
2003-12-27 19:02:59 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
|
|
|
|
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
|
2003-12-27 19:02:59 -05:00
|
|
|
|
2013-01-07 06:55:17 -05:00
|
|
|
rb_define_private_method(rb_singleton_class(rb_vm_top_self()),
|
|
|
|
"include", top_include, -1);
|
2013-01-07 06:22:31 -05:00
|
|
|
rb_define_private_method(rb_singleton_class(rb_vm_top_self()),
|
|
|
|
"using", top_using, 1);
|
2012-08-02 07:34:19 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
|
2003-12-28 22:56:22 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_define_global_function("trace_var", rb_f_trace_var, -1); /* in variable.c */
|
|
|
|
rb_define_global_function("untrace_var", rb_f_untrace_var, -1); /* in variable.c */
|
1998-01-16 07:19:22 -05:00
|
|
|
|
2008-07-03 08:06:22 -04:00
|
|
|
exception_error = rb_exc_new3(rb_eFatal,
|
2008-07-02 18:02:58 -04:00
|
|
|
rb_obj_freeze(rb_str_new2("exception reentered")));
|
2008-06-15 05:17:06 -04:00
|
|
|
OBJ_TAINT(exception_error);
|
|
|
|
OBJ_FREEZE(exception_error);
|
1998-01-16 07:19:22 -05:00
|
|
|
}
|