2006-12-31 10:02:22 -05:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
vm.c -
|
|
|
|
|
|
|
|
$Author$
|
|
|
|
|
2007-02-05 07:21:01 -05:00
|
|
|
Copyright (C) 2004-2007 Koichi Sasada
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
2014-11-15 06:49:06 -05:00
|
|
|
#include "internal.h"
|
2010-10-13 06:28:25 -04:00
|
|
|
#include "ruby/vm.h"
|
2007-06-09 23:06:15 -04:00
|
|
|
#include "ruby/st.h"
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04: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
|
|
|
#include "gc.h"
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
#include "vm_core.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"
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
#include "eval_intern.h"
|
* 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
|
|
|
#include "probes.h"
|
2012-11-18 11:30:10 -05:00
|
|
|
#include "probes_helper.h"
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-04-05 04:15:22 -04:00
|
|
|
VALUE rb_str_concat_literals(size_t, const VALUE*);
|
2015-09-29 03:37:40 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
PUREFUNC(static inline const VALUE *VM_EP_LEP(const VALUE *));
|
|
|
|
static inline const VALUE *
|
|
|
|
VM_EP_LEP(const VALUE *ep)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
while (!VM_ENV_LOCAL_P(ep)) {
|
|
|
|
ep = VM_ENV_PREV_EP(ep);
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
2013-04-29 04:44:16 -04:00
|
|
|
return ep;
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static inline const rb_control_frame_t *
|
|
|
|
rb_vm_search_cf_from_ep(const rb_thread_t * const th, const rb_control_frame_t *cfp, const VALUE * const ep)
|
2015-01-15 21:54:22 -05:00
|
|
|
{
|
|
|
|
if (!ep) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const rb_control_frame_t * const eocfp = RUBY_VM_END_CONTROL_FRAME(th); /* end of control frame pointer */
|
|
|
|
|
|
|
|
while (cfp < eocfp) {
|
|
|
|
if (cfp->ep == ep) {
|
|
|
|
return cfp;
|
|
|
|
}
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
|
2015-06-12 09:01:40 -04:00
|
|
|
return NULL;
|
2015-01-15 21:54:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
const VALUE *
|
|
|
|
rb_vm_ep_local_ep(const VALUE *ep)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
|
|
|
return VM_EP_LEP(ep);
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
PUREFUNC(static inline const VALUE *VM_CF_LEP(const rb_control_frame_t * const cfp));
|
|
|
|
static inline const VALUE *
|
2015-01-16 03:21:49 -05:00
|
|
|
VM_CF_LEP(const rb_control_frame_t * const cfp)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
|
|
|
return VM_EP_LEP(cfp->ep);
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static inline const VALUE *
|
2015-01-16 03:21:49 -05:00
|
|
|
VM_CF_PREV_EP(const rb_control_frame_t * const cfp)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
return VM_ENV_PREV_EP(cfp->ep);
|
|
|
|
}
|
|
|
|
|
|
|
|
PUREFUNC(static inline VALUE VM_CF_BLOCK_HANDLER(const rb_control_frame_t * const cfp));
|
|
|
|
static inline VALUE
|
|
|
|
VM_CF_BLOCK_HANDLER(const rb_control_frame_t * const cfp)
|
|
|
|
{
|
|
|
|
const VALUE *ep = VM_CF_LEP(cfp);
|
|
|
|
return VM_ENV_BLOCK_HANDLER(ep);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
return VM_CF_BLOCK_HANDLER(cfp);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if VM_CHECK_MODE > 0
|
|
|
|
static int
|
|
|
|
VM_CFP_IN_HEAP_P(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
const VALUE *start = th->stack;
|
|
|
|
const VALUE *end = (VALUE *)th->stack + th->stack_size;
|
|
|
|
if (start <= (VALUE *)cfp && (VALUE *)cfp < end) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int envval_p(VALUE envval);
|
|
|
|
|
|
|
|
static int
|
|
|
|
VM_EP_IN_HEAP_P(const rb_thread_t *th, const VALUE *ep)
|
|
|
|
{
|
|
|
|
const VALUE *start = th->stack;
|
|
|
|
const VALUE *end = (VALUE *)th->cfp;
|
|
|
|
if (start <= ep && ep < end) {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vm_ep_in_heap_p_(const rb_thread_t *th, const VALUE *ep)
|
|
|
|
{
|
|
|
|
if (VM_EP_IN_HEAP_P(th, ep)) {
|
|
|
|
VALUE envval = ep[VM_ENV_DATA_INDEX_ENV]; /* VM_ENV_ENVVAL(ep); */
|
|
|
|
|
|
|
|
if (envval != Qundef) {
|
|
|
|
rb_env_t *env;
|
|
|
|
|
|
|
|
VM_ASSERT(VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED));
|
|
|
|
VM_ASSERT(envval_p(envval));
|
|
|
|
GetEnvPtr(envval, env);
|
|
|
|
VM_ASSERT(env->ep == ep);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rb_vm_ep_in_heap_p(const VALUE *ep)
|
|
|
|
{
|
|
|
|
return vm_ep_in_heap_p_(GET_THREAD(), ep);
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
2016-07-28 07:02:30 -04:00
|
|
|
#endif
|
2012-06-10 23:14:59 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static struct rb_captured_block *
|
|
|
|
VM_CFP_TO_CAPTURED_BLOCK(const rb_control_frame_t *cfp)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ASSERT(!VM_CFP_IN_HEAP_P(GET_THREAD(), cfp));
|
|
|
|
return (struct rb_captured_block *)&cfp->self;
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static rb_control_frame_t *
|
|
|
|
VM_CAPTURED_BLOCK_TO_CFP(const struct rb_captured_block *captured)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_control_frame_t *cfp = ((rb_control_frame_t *)((VALUE *)(captured) - 3));
|
|
|
|
VM_ASSERT(!VM_CFP_IN_HEAP_P(GET_THREAD(), cfp));
|
|
|
|
VM_ASSERT(sizeof(rb_control_frame_t)/sizeof(VALUE) == 6 + VM_DEBUG_BP_CHECK ? 1 : 0);
|
|
|
|
return cfp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
VM_BH_FROM_CFP_P(VALUE block_handler, const rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
const struct rb_captured_block *captured = VM_CFP_TO_CAPTURED_BLOCK(cfp);
|
|
|
|
return VM_TAGGED_PTR_REF(block_handler, 0x03) == captured;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
vm_passed_block_handler(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
VALUE block_handler = th->passed_block_handler;
|
|
|
|
th->passed_block_handler = VM_BLOCK_HANDLER_NONE;
|
|
|
|
return block_handler;
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
|
|
|
|
2015-03-08 17:22:43 -04:00
|
|
|
static rb_cref_t *
|
2015-11-13 15:02:19 -05:00
|
|
|
vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int use_prev_prev)
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
{
|
2015-11-13 15:02:19 -05:00
|
|
|
VALUE refinements = Qnil;
|
|
|
|
int omod_shared = FALSE;
|
2016-02-21 05:42:40 -05:00
|
|
|
rb_cref_t *cref;
|
2015-11-13 15:02:19 -05:00
|
|
|
|
|
|
|
/* scope */
|
2015-06-05 07:42:34 -04:00
|
|
|
union {
|
|
|
|
rb_scope_visibility_t visi;
|
|
|
|
VALUE value;
|
|
|
|
} scope_visi;
|
2015-11-13 15:02:19 -05:00
|
|
|
|
2015-06-05 07:42:34 -04:00
|
|
|
scope_visi.visi.method_visi = visi;
|
2015-11-13 15:02:19 -05:00
|
|
|
scope_visi.visi.module_func = module_func;
|
|
|
|
|
|
|
|
/* refinements */
|
|
|
|
if (prev_cref != NULL && prev_cref != (void *)1 /* TODO: why CREF_NEXT(cref) is 1? */) {
|
|
|
|
refinements = CREF_REFINEMENTS(prev_cref);
|
|
|
|
|
|
|
|
if (!NIL_P(refinements)) {
|
|
|
|
omod_shared = TRUE;
|
|
|
|
CREF_OMOD_SHARED_SET(prev_cref);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cref = (rb_cref_t *)rb_imemo_new(imemo_cref, klass, (VALUE)(use_prev_prev ? CREF_NEXT(prev_cref) : prev_cref), scope_visi.value, refinements);
|
|
|
|
|
|
|
|
if (pushed_by_eval) CREF_PUSHED_BY_EVAL_SET(cref);
|
|
|
|
if (omod_shared) CREF_OMOD_SHARED_SET(cref);
|
|
|
|
|
|
|
|
return cref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static rb_cref_t *
|
|
|
|
vm_cref_new(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
|
|
|
|
{
|
|
|
|
return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static rb_cref_t *
|
|
|
|
vm_cref_new_use_prev(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
|
|
|
|
{
|
|
|
|
return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static rb_cref_t *
|
|
|
|
vm_cref_dup(const rb_cref_t *cref)
|
|
|
|
{
|
|
|
|
VALUE klass = CREF_CLASS(cref);
|
|
|
|
const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
|
2015-11-19 19:17:25 -05:00
|
|
|
rb_cref_t *next_cref = CREF_NEXT(cref), *new_cref;
|
2015-11-13 15:02:19 -05:00
|
|
|
int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
|
2015-06-05 07:42:34 -04:00
|
|
|
|
2015-11-19 19:17:25 -05:00
|
|
|
new_cref = vm_cref_new(klass, visi->method_visi, visi->module_func, next_cref, pushed_by_eval);
|
|
|
|
|
|
|
|
if (!NIL_P(CREF_REFINEMENTS(cref))) {
|
|
|
|
CREF_REFINEMENTS_SET(new_cref, rb_hash_dup(CREF_REFINEMENTS(cref)));
|
|
|
|
CREF_OMOD_SHARED_UNSET(new_cref);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new_cref;
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
}
|
|
|
|
|
2015-03-08 17:22:43 -04:00
|
|
|
static rb_cref_t *
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
vm_cref_new_toplevel(rb_thread_t *th)
|
|
|
|
{
|
2015-11-13 15:02:19 -05:00
|
|
|
rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, FALSE, NULL, FALSE);
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
|
|
|
|
if (th->top_wrapper) {
|
2015-11-13 15:02:19 -05:00
|
|
|
cref = vm_cref_new(th->top_wrapper, METHOD_VISI_PRIVATE, FALSE, cref, FALSE);
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return cref;
|
|
|
|
}
|
|
|
|
|
2015-05-21 04:45:57 -04:00
|
|
|
rb_cref_t *
|
|
|
|
rb_vm_cref_new_toplevel(void)
|
|
|
|
{
|
|
|
|
return vm_cref_new_toplevel(GET_THREAD());
|
|
|
|
}
|
|
|
|
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
static void
|
2015-03-08 17:22:43 -04:00
|
|
|
vm_cref_dump(const char *mesg, const rb_cref_t *cref)
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
{
|
|
|
|
fprintf(stderr, "vm_cref_dump: %s (%p)\n", mesg, cref);
|
|
|
|
|
|
|
|
while (cref) {
|
2015-03-08 15:50:37 -04:00
|
|
|
fprintf(stderr, "= cref| klass: %s\n", RSTRING_PTR(rb_class_path(CREF_CLASS(cref))));
|
|
|
|
cref = CREF_NEXT(cref);
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static void
|
|
|
|
vm_bind_update_env(rb_binding_t *bind, VALUE envval)
|
|
|
|
{
|
|
|
|
rb_env_t *env;
|
|
|
|
GetEnvPtr(envval, env);
|
|
|
|
bind->block.as.captured.code.iseq = env->iseq;
|
|
|
|
bind->block.as.captured.ep = env->ep;
|
|
|
|
}
|
|
|
|
|
2012-11-22 02:23:40 -05:00
|
|
|
#if VM_COLLECT_USAGE_DETAILS
|
2012-10-04 08:31:05 -04:00
|
|
|
static void vm_collect_usage_operand(int insn, int n, VALUE op);
|
|
|
|
static void vm_collect_usage_insn(int insn);
|
* 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
|
|
|
static void vm_collect_usage_register(int reg, int isset);
|
2012-10-04 08:31:05 -04:00
|
|
|
#endif
|
|
|
|
|
2015-07-14 12:23:17 -04:00
|
|
|
static VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static VALUE vm_invoke_bmethod(rb_thread_t *th, rb_proc_t *proc, VALUE self,
|
|
|
|
int argc, const VALUE *argv, VALUE block_handler);
|
|
|
|
static VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
|
|
|
|
int argc, const VALUE *argv, VALUE block_handler);
|
2012-08-20 07:36:34 -04:00
|
|
|
|
2013-12-09 05:51:02 -05:00
|
|
|
static rb_serial_t ruby_vm_global_method_state = 1;
|
|
|
|
static rb_serial_t ruby_vm_global_constant_state = 1;
|
2013-11-08 22:34:49 -05:00
|
|
|
static rb_serial_t ruby_vm_class_serial = 1;
|
* class.c, compile.c, eval.c, gc.h, insns.def, internal.h, method.h,
variable.c, vm.c, vm_core.c, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: Implement class hierarchy method cache invalidation.
[ruby-core:55053] [Feature #8426] [GH-387]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42822 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-04 01:25:06 -04:00
|
|
|
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
#include "vm_insnhelper.h"
|
|
|
|
#include "vm_exec.h"
|
2016-07-28 07:02:30 -04:00
|
|
|
#include "vm_insnhelper.c"
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
#include "vm_exec.c"
|
|
|
|
|
|
|
|
#include "vm_method.c"
|
* 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
|
|
|
#include "vm_eval.c"
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2007-06-24 13:19:22 -04:00
|
|
|
#define PROCDEBUG 0
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2013-11-08 22:34:49 -05:00
|
|
|
rb_serial_t
|
|
|
|
rb_next_class_serial(void)
|
* class.c, compile.c, eval.c, gc.h, insns.def, internal.h, method.h,
variable.c, vm.c, vm_core.c, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: Implement class hierarchy method cache invalidation.
[ruby-core:55053] [Feature #8426] [GH-387]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42822 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-04 01:25:06 -04:00
|
|
|
{
|
2013-11-08 22:34:49 -05:00
|
|
|
return NEXT_CLASS_SERIAL();
|
* class.c, compile.c, eval.c, gc.h, insns.def, internal.h, method.h,
variable.c, vm.c, vm_core.c, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: Implement class hierarchy method cache invalidation.
[ruby-core:55053] [Feature #8426] [GH-387]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42822 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-04 01:25:06 -04:00
|
|
|
}
|
|
|
|
|
2008-06-29 13:26:16 -04:00
|
|
|
VALUE rb_cRubyVM;
|
* 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
|
|
|
VALUE rb_cThread;
|
2007-06-24 13:19:22 -04:00
|
|
|
VALUE rb_cEnv;
|
2008-06-30 23:05:58 -04:00
|
|
|
VALUE rb_mRubyVMFrozenCore;
|
* 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
|
|
|
|
2014-07-17 21:53:18 -04:00
|
|
|
#define ruby_vm_redefined_flag GET_VM()->redefined_flag
|
2009-01-15 10:31:43 -05:00
|
|
|
VALUE ruby_vm_const_missing_count = 0;
|
* 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
|
|
|
rb_thread_t *ruby_current_thread = 0;
|
|
|
|
rb_vm_t *ruby_current_vm = 0;
|
2012-08-16 07:41:24 -04:00
|
|
|
rb_event_flag_t ruby_vm_event_flags;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2009-09-18 03:29:17 -04:00
|
|
|
static void thread_free(void *ptr);
|
|
|
|
|
2009-01-15 10:31:43 -05:00
|
|
|
void
|
|
|
|
rb_vm_inc_const_missing_count(void)
|
|
|
|
{
|
|
|
|
ruby_vm_const_missing_count +=1;
|
|
|
|
}
|
|
|
|
|
2015-10-29 01:32:19 -04:00
|
|
|
VALUE rb_class_path_no_cache(VALUE _klass);
|
|
|
|
|
|
|
|
int
|
|
|
|
ruby_th_dtrace_setup(rb_thread_t *th, VALUE klass, ID id,
|
|
|
|
struct ruby_dtrace_method_hook_args *args)
|
|
|
|
{
|
|
|
|
enum ruby_value_type type;
|
|
|
|
if (!klass) {
|
|
|
|
if (!th) th = GET_THREAD();
|
|
|
|
if (!rb_thread_method_id_and_class(th, &id, &klass) || !klass)
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (RB_TYPE_P(klass, T_ICLASS)) {
|
|
|
|
klass = RBASIC(klass)->klass;
|
|
|
|
}
|
|
|
|
else if (FL_TEST(klass, FL_SINGLETON)) {
|
|
|
|
klass = rb_attr_get(klass, id__attached__);
|
|
|
|
if (NIL_P(klass)) return FALSE;
|
|
|
|
}
|
|
|
|
type = BUILTIN_TYPE(klass);
|
|
|
|
if (type == T_CLASS || type == T_ICLASS || type == T_MODULE) {
|
|
|
|
VALUE name = rb_class_path_no_cache(klass);
|
2015-10-30 21:02:26 -04:00
|
|
|
const char *classname, *filename;
|
2015-10-29 01:32:19 -04:00
|
|
|
const char *methodname = rb_id2name(id);
|
2015-10-30 21:02:26 -04:00
|
|
|
if (methodname && (filename = rb_source_loc(&args->line_no)) != 0) {
|
2015-10-29 01:32:19 -04:00
|
|
|
if (NIL_P(name) || !(classname = StringValuePtr(name)))
|
|
|
|
classname = "<unknown>";
|
|
|
|
args->classname = classname;
|
|
|
|
args->methodname = methodname;
|
|
|
|
args->filename = filename;
|
|
|
|
args->klass = klass;
|
|
|
|
args->name = name;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-12-07 23:05:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* RubyVM.stat -> Hash
|
|
|
|
* RubyVM.stat(hsh) -> hsh
|
|
|
|
* RubyVM.stat(Symbol) -> Numeric
|
|
|
|
*
|
|
|
|
* Returns a Hash containing implementation-dependent counters inside the VM.
|
|
|
|
*
|
|
|
|
* This hash includes information about method/constant cache serials:
|
|
|
|
*
|
|
|
|
* {
|
2013-12-09 05:51:02 -05:00
|
|
|
* :global_method_state=>251,
|
|
|
|
* :global_constant_state=>481,
|
2013-12-07 23:05:59 -05:00
|
|
|
* :class_serial=>9029
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* The contents of the hash are implementation specific and may be changed in
|
|
|
|
* the future.
|
|
|
|
*
|
|
|
|
* This method is only expected to work on C Ruby.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2013-12-09 04:12:23 -05:00
|
|
|
vm_stat(int argc, VALUE *argv, VALUE self)
|
2013-12-07 23:05:59 -05:00
|
|
|
{
|
2013-12-09 05:51:02 -05:00
|
|
|
static VALUE sym_global_method_state, sym_global_constant_state, sym_class_serial;
|
2013-12-07 23:05:59 -05:00
|
|
|
VALUE arg = Qnil;
|
|
|
|
VALUE hash = Qnil, key = Qnil;
|
|
|
|
|
|
|
|
if (rb_scan_args(argc, argv, "01", &arg) == 1) {
|
|
|
|
if (SYMBOL_P(arg))
|
|
|
|
key = arg;
|
|
|
|
else if (RB_TYPE_P(arg, T_HASH))
|
|
|
|
hash = arg;
|
|
|
|
else
|
|
|
|
rb_raise(rb_eTypeError, "non-hash or symbol given");
|
2014-02-27 02:10:14 -05:00
|
|
|
}
|
|
|
|
else if (NIL_P(arg)) {
|
2013-12-07 23:05:59 -05:00
|
|
|
hash = rb_hash_new();
|
|
|
|
}
|
|
|
|
|
2013-12-09 05:51:02 -05:00
|
|
|
if (sym_global_method_state == 0) {
|
2013-12-07 23:05:59 -05:00
|
|
|
#define S(s) sym_##s = ID2SYM(rb_intern_const(#s))
|
2013-12-09 05:51:02 -05:00
|
|
|
S(global_method_state);
|
|
|
|
S(global_constant_state);
|
2013-12-07 23:05:59 -05:00
|
|
|
S(class_serial);
|
|
|
|
#undef S
|
|
|
|
}
|
|
|
|
|
|
|
|
#define SET(name, attr) \
|
|
|
|
if (key == sym_##name) \
|
2013-12-08 18:07:43 -05:00
|
|
|
return SERIALT2NUM(attr); \
|
2013-12-07 23:05:59 -05:00
|
|
|
else if (hash != Qnil) \
|
2013-12-08 18:07:43 -05:00
|
|
|
rb_hash_aset(hash, sym_##name, SERIALT2NUM(attr));
|
2013-12-07 23:05:59 -05:00
|
|
|
|
2013-12-09 05:51:02 -05:00
|
|
|
SET(global_method_state, ruby_vm_global_method_state);
|
|
|
|
SET(global_constant_state, ruby_vm_global_constant_state);
|
2013-12-07 23:05:59 -05:00
|
|
|
SET(class_serial, ruby_vm_class_serial);
|
|
|
|
#undef SET
|
|
|
|
|
2014-03-30 22:34:40 -04:00
|
|
|
if (!NIL_P(key)) { /* matched key should return above */
|
|
|
|
rb_raise(rb_eArgError, "unknown key: %"PRIsVALUE, rb_sym2str(key));
|
|
|
|
}
|
2013-12-07 23:05:59 -05:00
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2007-06-24 13:19:22 -04:00
|
|
|
/* control stack frame */
|
2007-06-24 22:44:20 -04: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
|
|
|
static void
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_top_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2015-07-21 18:52:59 -04:00
|
|
|
if (iseq->body->type != ISEQ_TYPE_TOP) {
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_raise(rb_eTypeError, "Not a toplevel InstructionSequence");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for return */
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH, th->top_self,
|
|
|
|
VM_BLOCK_HANDLER_NONE,
|
2015-06-02 00:20:30 -04:00
|
|
|
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
2016-07-28 07:02:30 -04:00
|
|
|
iseq->body->iseq_encoded, th->cfp->sp, iseq->body->local_table_size, iseq->body->stack_max);
|
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
|
|
|
static void
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, const struct rb_block *base_block)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2012-08-02 07:08:44 -04:00
|
|
|
vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL | VM_FRAME_FLAG_FINISH,
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_block_self(base_block), VM_GUARDED_PREV_EP(vm_block_ep(base_block)),
|
2015-06-02 00:20:30 -04:00
|
|
|
(VALUE)cref, /* cref or me */
|
2015-07-21 18:52:59 -04:00
|
|
|
iseq->body->iseq_encoded,
|
2016-07-28 07:02:30 -04:00
|
|
|
th->cfp->sp, iseq->body->local_table_size, iseq->body->stack_max);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2008-12-26 20:15:56 -05:00
|
|
|
static void
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_main_stack(rb_thread_t *th, const rb_iseq_t *iseq)
|
2008-12-26 20:15:56 -05:00
|
|
|
{
|
|
|
|
VALUE toplevel_binding = rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING"));
|
|
|
|
rb_binding_t *bind;
|
|
|
|
|
|
|
|
GetBindingPtr(toplevel_binding, bind);
|
2015-07-21 18:52:59 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_set_eval_stack(th, iseq, 0, &bind->block);
|
2008-12-26 20:15:56 -05:00
|
|
|
|
|
|
|
/* save binding */
|
2016-07-28 07:02:30 -04:00
|
|
|
if (bind && iseq->body->local_table_size > 0) {
|
|
|
|
vm_bind_update_env(bind, vm_make_env_object(th, th->cfp));
|
2008-12-26 20:15:56 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-05 01:04:59 -05:00
|
|
|
rb_control_frame_t *
|
2014-12-16 22:08:20 -05:00
|
|
|
rb_vm_get_binding_creatable_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
2013-02-05 01:04:59 -05:00
|
|
|
{
|
|
|
|
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
|
|
|
if (cfp->iseq) {
|
|
|
|
return (rb_control_frame_t *)cfp;
|
|
|
|
}
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-07-01 13:11:35 -04:00
|
|
|
rb_control_frame_t *
|
2014-12-16 22:08:20 -05:00
|
|
|
rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
{
|
|
|
|
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
|
|
|
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2012-11-29 02:05:27 -05:00
|
|
|
return (rb_control_frame_t *)cfp;
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
}
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-01-18 22:03:09 -05:00
|
|
|
static rb_control_frame_t *
|
2014-12-16 22:08:20 -05:00
|
|
|
vm_get_ruby_level_caller_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
|
2008-05-22 05:55:36 -04:00
|
|
|
{
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2014-12-16 22:08:20 -05:00
|
|
|
return (rb_control_frame_t *)cfp;
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
|
2008-05-22 05:55:36 -04:00
|
|
|
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
|
|
|
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2014-12-16 22:08:20 -05:00
|
|
|
return (rb_control_frame_t *)cfp;
|
2008-05-22 05:55:36 -04:00
|
|
|
}
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_PASSED) == FALSE) {
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
break;
|
|
|
|
}
|
2008-05-22 05:55:36 -04:00
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-01-09 05:12:59 -05:00
|
|
|
void
|
|
|
|
rb_vm_pop_cfunc_frame(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
|
|
|
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
2015-06-02 00:20:30 -04:00
|
|
|
|
2016-07-26 06:28:21 -04:00
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, cfp->self, me->called_id, me->owner, Qnil);
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, me->called_id);
|
2016-07-26 06:28:21 -04:00
|
|
|
vm_pop_frame(th, cfp, cfp->ep);
|
2014-01-09 05:12:59 -05:00
|
|
|
}
|
|
|
|
|
2014-06-19 08:43:48 -04:00
|
|
|
void
|
|
|
|
rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
/* check skipped frame */
|
|
|
|
while (th->cfp != cfp) {
|
|
|
|
#if VMDEBUG
|
|
|
|
printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
|
|
|
|
#endif
|
|
|
|
if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_CFUNC) {
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2014-06-19 08:43:48 -04:00
|
|
|
}
|
|
|
|
else { /* unlikely path */
|
|
|
|
rb_vm_pop_cfunc_frame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-09 05:12:59 -05:00
|
|
|
/* obsolete */
|
|
|
|
void
|
|
|
|
rb_frame_pop(void)
|
|
|
|
{
|
2016-04-27 01:29:49 -04:00
|
|
|
ONLY_FOR_INTERNAL_USE("rb_frame_pop()");
|
2014-01-09 05:12:59 -05:00
|
|
|
}
|
|
|
|
|
2010-12-02 06:06:32 -05:00
|
|
|
/* at exit */
|
|
|
|
|
|
|
|
void
|
|
|
|
ruby_vm_at_exit(void (*func)(rb_vm_t *))
|
|
|
|
{
|
2016-04-04 10:37:07 -04:00
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
rb_at_exit_list *nl = ALLOC(rb_at_exit_list);
|
|
|
|
nl->func = func;
|
|
|
|
nl->next = vm->at_exit;
|
|
|
|
vm->at_exit = nl;
|
2010-12-02 06:06:32 -05:00
|
|
|
}
|
|
|
|
|
2011-02-24 08:51:59 -05:00
|
|
|
static void
|
|
|
|
ruby_vm_run_at_exit_hooks(rb_vm_t *vm)
|
|
|
|
{
|
2016-04-04 10:37:07 -04:00
|
|
|
rb_at_exit_list *l = vm->at_exit;
|
2011-02-24 08:51:59 -05:00
|
|
|
|
2016-04-04 10:37:07 -04:00
|
|
|
while (l) {
|
|
|
|
rb_at_exit_list* t = l->next;
|
|
|
|
rb_vm_at_exit_func *func = l->func;
|
|
|
|
free(l);
|
|
|
|
l = t;
|
2011-02-24 08:51:59 -05:00
|
|
|
(*func)(vm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
/* Env */
|
|
|
|
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
/*
|
|
|
|
env{
|
|
|
|
env[0] // special (block or prev env)
|
|
|
|
env[1] // env object
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
* 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
|
|
|
static void
|
2008-05-22 00:28:13 -04:00
|
|
|
env_mark(void * const ptr)
|
* 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
|
|
|
{
|
2014-09-12 17:34:12 -04:00
|
|
|
const rb_env_t * const env = ptr;
|
|
|
|
|
|
|
|
/* TODO: should mark more restricted range */
|
|
|
|
RUBY_GC_INFO("env->env\n");
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ASSERT(VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ESCAPED));
|
|
|
|
|
2014-09-12 17:34:12 -04:00
|
|
|
rb_gc_mark_values((long)env->env_size, env->env);
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ENV_FLAGS_SET(env->ep, VM_ENV_FLAG_WB_REQUIRED);
|
2014-09-12 17:34:12 -04:00
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(rb_vm_env_prev_envval(env));
|
2016-07-28 07:02:30 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL((VALUE)env->iseq);
|
2007-06-24 22:44:20 -04:00
|
|
|
RUBY_MARK_LEAVE("env");
|
* 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
|
|
|
}
|
|
|
|
|
2009-06-16 18:23:53 -04:00
|
|
|
static size_t
|
2009-09-08 22:11:35 -04:00
|
|
|
env_memsize(const void *ptr)
|
2009-06-16 18:23:53 -04:00
|
|
|
{
|
2014-09-12 17:34:12 -04:00
|
|
|
const rb_env_t * const env = ptr;
|
|
|
|
size_t size = sizeof(rb_env_t);
|
2014-09-08 15:38:22 -04:00
|
|
|
|
2014-09-12 17:34:12 -04:00
|
|
|
size += (env->env_size - 1) * sizeof(VALUE);
|
|
|
|
return size;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
#if VM_CHECK_MODE > 0
|
|
|
|
static void
|
|
|
|
env_free(void *ptr)
|
|
|
|
{
|
|
|
|
if (ptr) {
|
|
|
|
rb_env_t * const env = ptr;
|
|
|
|
VM_ASSERT(VM_ENV_FLAGS(env->ep, VM_ENV_FLAG_ESCAPED));
|
|
|
|
free(env);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define env_free RUBY_TYPED_DEFAULT_FREE
|
|
|
|
#endif
|
|
|
|
|
2009-07-07 02:23:39 -04:00
|
|
|
static const rb_data_type_t env_data_type = {
|
2009-06-16 18:23:53 -04:00
|
|
|
"VM/env",
|
2016-07-28 07:02:30 -04:00
|
|
|
{env_mark, env_free, env_memsize,},
|
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
2009-06-16 18:23:53 -04:00
|
|
|
};
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
#if VM_CHECK_MODE > 0
|
|
|
|
static int
|
|
|
|
envval_p(VALUE envval)
|
|
|
|
{
|
|
|
|
if (rb_typeddata_is_kind_of(envval, &env_data_type)) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_obj_info_dump(envval);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2015-07-14 13:36:36 -04:00
|
|
|
|
2008-05-22 12:19:14 -04:00
|
|
|
static VALUE check_env_value(VALUE envval);
|
2007-06-24 22:44:20 -04:00
|
|
|
|
|
|
|
static int
|
2008-05-22 00:28:13 -04:00
|
|
|
check_env(rb_env_t * const env)
|
2007-06-24 22:44:20 -04:00
|
|
|
{
|
2011-07-31 10:11:37 -04:00
|
|
|
fprintf(stderr, "---\n");
|
2016-07-28 07:02:30 -04:00
|
|
|
fprintf(stderr, "envptr: %p\n", (void *)&env->ep[0]);
|
|
|
|
fprintf(stderr, "envval: %10p ", (void *)env->ep[1]);
|
|
|
|
dp(env->ep[1]);
|
|
|
|
fprintf(stderr, "ep: %10p\n", (void *)env->ep);
|
2015-07-14 13:36:36 -04:00
|
|
|
if (rb_vm_env_prev_envval(env)) {
|
2011-07-31 10:11:37 -04:00
|
|
|
fprintf(stderr, ">>\n");
|
2015-07-14 13:36:36 -04:00
|
|
|
check_env_value(rb_vm_env_prev_envval(env));
|
2011-07-31 10:11:37 -04:00
|
|
|
fprintf(stderr, "<<\n");
|
2007-06-24 22:44:20 -04:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
check_env_value(VALUE envval)
|
2007-06-24 22:44:20 -04:00
|
|
|
{
|
|
|
|
rb_env_t *env;
|
|
|
|
GetEnvPtr(envval, env);
|
|
|
|
|
|
|
|
if (check_env(env)) {
|
|
|
|
return envval;
|
|
|
|
}
|
2007-08-20 10:17:16 -04:00
|
|
|
rb_bug("invalid env");
|
2007-06-24 22:44:20 -04:00
|
|
|
return Qnil; /* unreachable */
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static void
|
|
|
|
vm_block_handler_escape(rb_thread_t *th, VALUE block_handler, VALUE *procvalptr)
|
2015-07-14 12:23:17 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
switch (vm_block_handler_type(block_handler)) {
|
|
|
|
case block_handler_type_ifunc:
|
|
|
|
case block_handler_type_iseq:
|
|
|
|
*procvalptr = rb_vm_make_proc(th, VM_BH_TO_CAPT_BLOCK(block_handler), rb_cProc);
|
|
|
|
return;
|
|
|
|
|
|
|
|
case block_handler_type_symbol:
|
|
|
|
case block_handler_type_proc:
|
|
|
|
*procvalptr = block_handler;
|
|
|
|
return;
|
2015-07-14 12:23:17 -04:00
|
|
|
}
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_UNREACHABLE(vm_block_handler_escape);
|
|
|
|
return;
|
2015-07-14 12:23:17 -04:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static VALUE
|
2015-07-14 12:23:17 -04:00
|
|
|
vm_make_env_each(rb_thread_t *const th, rb_control_frame_t *const cfp)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE envval, blockprocval = Qfalse;
|
|
|
|
const VALUE * const ep = cfp->ep;
|
* 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_env_t *env;
|
2016-07-28 07:02:30 -04:00
|
|
|
const VALUE *new_ep;
|
2015-07-15 01:43:07 -04:00
|
|
|
int local_size, env_size;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (VM_ENV_ESCAPED_P(ep)) {
|
|
|
|
return VM_ENV_ENVVAL(ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (!VM_ENV_LOCAL_P(ep)) {
|
|
|
|
const VALUE *prev_ep = VM_ENV_PREV_EP(ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (!VM_ENV_ESCAPED_P(prev_ep)) {
|
2015-07-14 12:23:17 -04:00
|
|
|
rb_control_frame_t *prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
|
|
|
|
while (prev_cfp->ep != prev_ep) {
|
|
|
|
prev_cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(prev_cfp);
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ASSERT(prev_cfp->ep != NULL);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2015-07-14 12:23:17 -04:00
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
vm_make_env_each(th, prev_cfp);
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_FORCE_WRITE_SPECIAL_CONST(&ep[VM_ENV_DATA_INDEX_SPECVAL], VM_GUARDED_PREV_EP(prev_cfp->ep));
|
2015-07-14 12:23:17 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE block_handler = VM_ENV_BLOCK_HANDLER(ep);
|
2015-07-14 12:23:17 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (block_handler != VM_BLOCK_HANDLER_NONE) {
|
|
|
|
vm_block_handler_escape(th, block_handler, &blockprocval);
|
|
|
|
VM_STACK_ENV_WRITE(ep, VM_ENV_DATA_INDEX_SPECVAL, blockprocval);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
2007-01-17 03:48:52 -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
|
|
|
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2016-07-28 07:02:30 -04:00
|
|
|
local_size = VM_ENV_DATA_SIZE;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
2016-07-28 07:02:30 -04:00
|
|
|
local_size = cfp->iseq->body->local_table_size + VM_ENV_DATA_SIZE;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2015-07-15 01:43:07 -04:00
|
|
|
/*
|
|
|
|
* # local variables on a stack frame (N == local_size)
|
|
|
|
* [lvar1, lvar2, ..., lvarN, SPECVAL]
|
|
|
|
* ^
|
|
|
|
* ep[0]
|
|
|
|
*
|
|
|
|
* # moved local variables
|
|
|
|
* [lvar1, lvar2, ..., lvarN, SPECVAL, Envval, BlockProcval (if needed)]
|
|
|
|
* ^ ^
|
|
|
|
* env->env[0] ep[0]
|
|
|
|
*/
|
|
|
|
|
2015-07-14 12:23:17 -04:00
|
|
|
env_size = local_size +
|
|
|
|
1 /* envval */ +
|
|
|
|
(blockprocval ? 1 : 0) /* blockprocval */;
|
2015-05-10 08:34:26 -04:00
|
|
|
envval = TypedData_Wrap_Struct(rb_cEnv, &env_data_type, 0);
|
2015-07-14 12:23:17 -04:00
|
|
|
env = xmalloc(sizeof(rb_env_t) + (env_size - 1 /* rb_env_t::env[1] */) * sizeof(VALUE));
|
|
|
|
env->env_size = env_size;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
/* setup env */
|
|
|
|
MEMCPY((VALUE *)env->env, ep - (local_size - 1 /* specval */), VALUE, local_size);
|
2015-07-15 01:43:07 -04:00
|
|
|
|
2007-08-16 03:46:11 -04:00
|
|
|
#if 0
|
2015-07-15 01:43:07 -04:00
|
|
|
for (i = 0; i < local_size; i++) {
|
* 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
|
|
|
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
/* clear value stack for GC */
|
2015-07-14 12:23:17 -04:00
|
|
|
ep[-local_size + i] = 0;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
2015-03-28 22:47:24 -04:00
|
|
|
#endif
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2014-09-12 05:22:18 -04:00
|
|
|
/* be careful not to trigger GC after this */
|
2015-05-10 08:34:26 -04:00
|
|
|
RTYPEDDATA_DATA(envval) = env;
|
2014-09-12 05:22:18 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
new_ep = &env->env[local_size - 1 /* specval */];
|
|
|
|
RB_OBJ_WRITE(envval, &new_ep[1], envval);
|
|
|
|
if (blockprocval) RB_OBJ_WRITE(envval, &new_ep[2], blockprocval);
|
|
|
|
VM_ENV_FLAGS_SET(new_ep, VM_ENV_FLAG_ESCAPED | VM_ENV_FLAG_WB_REQUIRED);
|
|
|
|
|
|
|
|
/*
|
2014-09-12 05:22:18 -04:00
|
|
|
* must happen after TypedData_Wrap_Struct to ensure penvval is markable
|
|
|
|
* in case object allocation triggers GC and clobbers penvval.
|
|
|
|
*/
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_STACK_ENV_WRITE(ep, 0, envval); /* GC mark */
|
2015-07-14 12:26:10 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
/* setup env object */
|
|
|
|
env->ep = cfp->ep = new_ep;
|
|
|
|
env->iseq = cfp->iseq;
|
2006-12-31 10:02:22 -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
|
|
|
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
|
2016-07-28 07:02:30 -04:00
|
|
|
env->iseq = NULL;
|
2012-11-02 15:14:24 -04:00
|
|
|
}
|
2015-07-14 12:23:17 -04:00
|
|
|
|
|
|
|
return envval;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
VALUE envval = vm_make_env_each(th, cfp);
|
|
|
|
|
|
|
|
if (PROCDEBUG) {
|
|
|
|
check_env_value(envval);
|
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return envval;
|
|
|
|
}
|
|
|
|
|
2015-07-14 12:23:17 -04:00
|
|
|
void
|
|
|
|
rb_vm_stack_to_heap(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
|
|
|
while ((cfp = rb_vm_get_binding_creatable_next_cfp(th, cfp)) != 0) {
|
|
|
|
vm_make_env_object(th, cfp);
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
VALUE
|
|
|
|
rb_vm_env_prev_envval(const rb_env_t *env)
|
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
const VALUE *ep = env->ep;
|
2015-07-14 13:36:36 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (VM_ENV_LOCAL_P(ep)) {
|
2015-07-14 13:36:36 -04:00
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
else {
|
2016-07-28 07:02:30 -04:00
|
|
|
return VM_ENV_ENVVAL(VM_ENV_PREV_EP(ep));
|
2015-07-14 13:36:36 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static int
|
2014-07-01 13:55:44 -04:00
|
|
|
collect_local_variables_in_iseq(const rb_iseq_t *iseq, const struct local_var_list *vars)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2015-07-24 17:44:14 -04:00
|
|
|
unsigned int i;
|
2009-09-21 04:12:12 -04:00
|
|
|
if (!iseq) return 0;
|
2015-07-21 18:52:59 -04:00
|
|
|
for (i = 0; i < iseq->body->local_table_size; i++) {
|
|
|
|
local_var_list_add(vars, iseq->body->local_table[i]);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2009-09-21 04:12:12 -04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-07-01 13:55:44 -04:00
|
|
|
static void
|
|
|
|
collect_local_variables_in_env(const rb_env_t *env, const struct local_var_list *vars)
|
2009-09-21 04:12:12 -04:00
|
|
|
{
|
2015-07-14 13:36:36 -04:00
|
|
|
VALUE prev_envval;
|
2010-05-29 14:51:39 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
while (collect_local_variables_in_iseq(env->iseq, vars), (prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
|
2015-07-14 13:36:36 -04:00
|
|
|
GetEnvPtr(prev_envval, env);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-18 19:13:44 -05:00
|
|
|
static int
|
2014-07-01 13:55:44 -04:00
|
|
|
vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *ep, const struct local_var_list *vars)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
if (VM_ENV_ESCAPED_P(ep)) {
|
* 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_env_t *env;
|
2016-07-28 07:02:30 -04:00
|
|
|
GetEnvPtr(VM_ENV_ENVVAL(ep), env);
|
2014-05-06 22:00:28 -04:00
|
|
|
collect_local_variables_in_env(env, vars);
|
2006-12-31 10:02:22 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-01 13:57:37 -04:00
|
|
|
VALUE
|
2015-07-14 13:36:36 -04:00
|
|
|
rb_vm_env_local_variables(const rb_env_t *env)
|
2014-07-01 13:57:37 -04:00
|
|
|
{
|
|
|
|
struct local_var_list vars;
|
|
|
|
local_var_list_init(&vars);
|
|
|
|
collect_local_variables_in_env(env, &vars);
|
|
|
|
return local_var_list_finish(&vars);
|
|
|
|
}
|
|
|
|
|
2015-12-08 00:27:10 -05:00
|
|
|
VALUE
|
|
|
|
rb_iseq_local_variables(const rb_iseq_t *iseq)
|
|
|
|
{
|
|
|
|
struct local_var_list vars;
|
|
|
|
local_var_list_init(&vars);
|
|
|
|
while (collect_local_variables_in_iseq(iseq, &vars)) {
|
|
|
|
iseq = iseq->body->parent_iseq;
|
|
|
|
}
|
|
|
|
return local_var_list_finish(&vars);
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* Proc */
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE
|
|
|
|
rb_proc_create_from_captured(VALUE klass,
|
|
|
|
const struct rb_captured_block *captured,
|
|
|
|
enum rb_block_type block_type,
|
|
|
|
int8_t safe_level, int8_t is_from_method, int8_t is_lambda)
|
2014-09-12 16:57:45 -04:00
|
|
|
{
|
2015-05-16 08:21:25 -04:00
|
|
|
VALUE procval = rb_proc_alloc(klass);
|
|
|
|
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
2014-09-12 16:57:45 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ASSERT(VM_EP_IN_HEAP_P(GET_THREAD(), captured->ep));
|
|
|
|
|
|
|
|
/* copy block */
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.captured.self, captured->self);
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.val, captured->code.val);
|
|
|
|
*((const VALUE **)&proc->block.as.captured.ep) = captured->ep;
|
|
|
|
RB_OBJ_WRITTEN(procval, Qundef, VM_ENV_ENVVAL(captured->ep));
|
|
|
|
|
|
|
|
vm_block_type_set(&proc->block, block_type);
|
2014-09-12 16:57:45 -04:00
|
|
|
proc->safe_level = safe_level;
|
|
|
|
proc->is_from_method = is_from_method;
|
|
|
|
proc->is_lambda = is_lambda;
|
|
|
|
|
|
|
|
return procval;
|
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_proc_create(VALUE klass, const struct rb_block *block,
|
|
|
|
int8_t safe_level, int8_t is_from_method, int8_t is_lambda)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE procval = rb_proc_alloc(klass);
|
|
|
|
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
2008-12-24 22:51:35 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_ASSERT(VM_EP_IN_HEAP_P(GET_THREAD(), vm_block_ep(block)));
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
/* copy block */
|
|
|
|
switch (vm_block_type(block)) {
|
|
|
|
case block_type_iseq:
|
|
|
|
case block_type_ifunc:
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.captured.self, block->as.captured.self);
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.val, block->as.captured.code.val);
|
|
|
|
*((const VALUE **)&proc->block.as.captured.ep) = block->as.captured.ep;
|
|
|
|
RB_OBJ_WRITTEN(procval, Qundef, VM_ENV_ENVVAL(block->as.captured.ep));
|
|
|
|
break;
|
|
|
|
case block_type_symbol:
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.symbol, block->as.symbol);
|
|
|
|
break;
|
|
|
|
case block_type_proc:
|
|
|
|
RB_OBJ_WRITE(procval, &proc->block.as.proc, block->as.proc);
|
|
|
|
break;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_block_type_set(&proc->block, block->type);
|
|
|
|
proc->safe_level = safe_level;
|
|
|
|
proc->is_from_method = is_from_method;
|
|
|
|
proc->is_lambda = is_lambda;
|
2007-06-17 13:50:56 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
return procval;
|
|
|
|
}
|
|
|
|
|
2015-07-14 13:59:03 -04:00
|
|
|
VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_vm_make_proc(rb_thread_t *th, const struct rb_captured_block *captured, VALUE klass)
|
2015-07-14 13:59:03 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
return rb_vm_make_proc_lambda(th, captured, klass, FALSE);
|
2015-07-14 13:59:03 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE
|
|
|
|
rb_vm_make_proc_lambda(rb_thread_t *th, const struct rb_captured_block *captured, VALUE klass, int8_t is_lambda)
|
|
|
|
{
|
|
|
|
VALUE procval;
|
|
|
|
|
|
|
|
if (!VM_ENV_FLAGS(captured->ep, VM_ENV_FLAG_ESCAPED)) {
|
|
|
|
rb_control_frame_t *cfp = VM_CAPTURED_BLOCK_TO_CFP(captured);
|
|
|
|
vm_make_env_object(th, cfp);
|
|
|
|
}
|
|
|
|
VM_ASSERT(VM_EP_IN_HEAP_P(th, captured->ep));
|
|
|
|
VM_ASSERT(RB_TYPE_P(captured->code.val, T_IMEMO));
|
|
|
|
|
|
|
|
procval = rb_proc_create_from_captured(klass, captured,
|
|
|
|
imemo_type(captured->code.val) == imemo_iseq ? block_type_iseq : block_type_ifunc,
|
|
|
|
(int8_t)th->safe_level, FALSE, is_lambda);
|
|
|
|
return procval;
|
|
|
|
}
|
2015-07-14 13:59:03 -04:00
|
|
|
|
2014-10-18 07:46:31 -04:00
|
|
|
/* Binding */
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_vm_make_binding(rb_thread_t *th, const rb_control_frame_t *src_cfp)
|
|
|
|
{
|
|
|
|
rb_control_frame_t *cfp = rb_vm_get_binding_creatable_next_cfp(th, src_cfp);
|
|
|
|
rb_control_frame_t *ruby_level_cfp = rb_vm_get_ruby_level_next_cfp(th, src_cfp);
|
|
|
|
VALUE bindval, envval;
|
|
|
|
rb_binding_t *bind;
|
|
|
|
|
|
|
|
if (cfp == 0 || ruby_level_cfp == 0) {
|
|
|
|
rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1) {
|
2015-07-14 12:23:17 -04:00
|
|
|
envval = vm_make_env_object(th, cfp);
|
2014-10-18 07:46:31 -04:00
|
|
|
if (cfp == ruby_level_cfp) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cfp = rb_vm_get_binding_creatable_next_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
|
|
|
|
}
|
|
|
|
|
|
|
|
bindval = rb_binding_alloc(rb_cBinding);
|
|
|
|
GetBindingPtr(bindval, bind);
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_bind_update_env(bind, envval);
|
|
|
|
bind->block.as.captured.self = cfp->self;
|
|
|
|
bind->block.as.captured.code.iseq = cfp->iseq;
|
2015-07-21 18:52:59 -04:00
|
|
|
bind->path = ruby_level_cfp->iseq->body->location.path;
|
2014-10-18 07:46:31 -04:00
|
|
|
bind->first_lineno = rb_vm_get_sourceline(ruby_level_cfp);
|
|
|
|
|
|
|
|
return bindval;
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
const VALUE *
|
2013-08-09 05:51:00 -04:00
|
|
|
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE envval;
|
|
|
|
VALUE path = bind->path;
|
|
|
|
const struct rb_block *base_block;
|
2013-08-09 05:51:00 -04:00
|
|
|
rb_env_t *env;
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
2015-07-21 18:52:59 -04:00
|
|
|
const rb_iseq_t *base_iseq, *iseq;
|
2013-08-09 05:51:00 -04:00
|
|
|
NODE *node = 0;
|
|
|
|
ID minibuf[4], *dyns = minibuf;
|
|
|
|
VALUE idtmp = 0;
|
|
|
|
|
|
|
|
if (dyncount < 0) return 0;
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
base_block = &bind->block;
|
|
|
|
base_iseq = vm_block_iseq(base_block);
|
2013-08-09 05:51:00 -04:00
|
|
|
|
|
|
|
if (dyncount >= numberof(minibuf)) dyns = ALLOCV_N(ID, idtmp, dyncount + 1);
|
|
|
|
|
|
|
|
dyns[0] = dyncount;
|
|
|
|
MEMCPY(dyns + 1, dynvars, ID, dyncount);
|
|
|
|
node = NEW_NODE(NODE_SCOPE, dyns, 0, 0);
|
|
|
|
|
2015-05-21 04:45:57 -04:00
|
|
|
if (base_iseq) {
|
2015-07-21 18:52:59 -04:00
|
|
|
iseq = rb_iseq_new(node, base_iseq->body->location.label, path, path, base_iseq, ISEQ_TYPE_EVAL);
|
2015-05-21 04:45:57 -04:00
|
|
|
}
|
|
|
|
else {
|
2016-01-26 01:23:47 -05:00
|
|
|
VALUE tempstr = rb_fstring_cstr("<temp>");
|
2015-07-21 18:52:59 -04:00
|
|
|
iseq = rb_iseq_new_top(node, tempstr, tempstr, tempstr, NULL);
|
2015-05-21 04:45:57 -04:00
|
|
|
}
|
2013-08-09 05:51:00 -04:00
|
|
|
node->u1.tbl = 0; /* reset table */
|
|
|
|
ALLOCV_END(idtmp);
|
|
|
|
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_eval_stack(th, iseq, 0, base_block);
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_bind_update_env(bind, envval = vm_make_env_object(th, th->cfp));
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2013-08-09 05:51:00 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
GetEnvPtr(envval, env);
|
2013-08-09 05:51:00 -04:00
|
|
|
return env->env;
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* C -> Ruby: block */
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2008-05-19 10:36:13 -04:00
|
|
|
static inline VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
invoke_block(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const struct rb_captured_block *captured, const rb_cref_t *cref, VALUE type, int opt_pc)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2015-10-10 16:32:07 -04:00
|
|
|
int arg_size = iseq->body->param.size;
|
|
|
|
|
|
|
|
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH, self,
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_GUARDED_PREV_EP(captured->ep),
|
2015-10-10 16:32:07 -04:00
|
|
|
(VALUE)cref, /* cref or method */
|
|
|
|
iseq->body->iseq_encoded + opt_pc,
|
2016-07-28 07:02:30 -04:00
|
|
|
th->cfp->sp + arg_size, iseq->body->local_table_size - arg_size,
|
2015-10-10 16:32:07 -04:00
|
|
|
iseq->body->stack_max);
|
|
|
|
return vm_exec(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
invoke_bmethod(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const struct rb_captured_block *captured, const rb_callable_method_entry_t *me, VALUE type, int opt_pc)
|
2015-10-10 16:32:07 -04:00
|
|
|
{
|
|
|
|
/* bmethod */
|
|
|
|
int arg_size = iseq->body->param.size;
|
|
|
|
VALUE ret;
|
|
|
|
|
|
|
|
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self,
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_GUARDED_PREV_EP(captured->ep),
|
|
|
|
(VALUE)me,
|
2015-10-10 16:32:07 -04:00
|
|
|
iseq->body->iseq_encoded + opt_pc,
|
2016-07-28 07:02:30 -04:00
|
|
|
th->cfp->sp + arg_size, iseq->body->local_table_size - arg_size,
|
2015-10-10 16:32:07 -04:00
|
|
|
iseq->body->stack_max);
|
|
|
|
|
|
|
|
RUBY_DTRACE_METHOD_ENTRY_HOOK(th, me->owner, me->called_id);
|
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, self, me->called_id, me->owner, Qnil);
|
|
|
|
ret = vm_exec(th);
|
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, self, me->called_id, me->owner, ret);
|
|
|
|
RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->owner, me->called_id);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
invoke_iseq_block_from_c(rb_thread_t *th, const struct rb_captured_block *captured,
|
|
|
|
VALUE self, int argc, const VALUE *argv, VALUE passed_block_handler,
|
|
|
|
const rb_cref_t *cref, const int splattable, int is_lambda)
|
2015-10-10 16:32:07 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
|
|
|
|
int i, opt_pc;
|
|
|
|
VALUE type = is_lambda ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
|
|
|
|
VALUE *sp = th->cfp->sp;
|
|
|
|
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
|
|
|
|
th->passed_bmethod_me = NULL;
|
2007-06-05 13:26:00 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
for (i=0; i<argc; i++) {
|
|
|
|
sp[i] = argv[i];
|
|
|
|
}
|
2007-01-15 22:06:01 -05:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
opt_pc = vm_yield_setup_args(th, iseq, argc, sp, passed_block_handler,
|
|
|
|
(type == VM_FRAME_MAGIC_LAMBDA ? (splattable ? arg_setup_lambda : arg_setup_method) : arg_setup_block));
|
2014-06-19 06:49:46 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
if (me == NULL) {
|
|
|
|
return invoke_block(th, iseq, self, captured, cref, type, opt_pc);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
2016-07-28 07:02:30 -04:00
|
|
|
return invoke_bmethod(th, iseq, self, captured, me, type, opt_pc);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static inline VALUE
|
|
|
|
invoke_block_from_c_splattable(rb_thread_t *th, VALUE block_handler,
|
|
|
|
int argc, const VALUE *argv,
|
|
|
|
VALUE passed_block_handler, const rb_cref_t *cref)
|
|
|
|
{
|
|
|
|
int is_lambda = FALSE;
|
|
|
|
again:
|
|
|
|
switch (vm_block_handler_type(block_handler)) {
|
|
|
|
case block_handler_type_iseq:
|
|
|
|
{
|
|
|
|
const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
|
|
|
|
return invoke_iseq_block_from_c(th, captured, captured->self, argc, argv, passed_block_handler, cref, TRUE, is_lambda);
|
|
|
|
}
|
|
|
|
case block_handler_type_ifunc:
|
|
|
|
return vm_yield_with_cfunc(th, VM_BH_TO_IFUNC_BLOCK(block_handler), VM_BH_TO_IFUNC_BLOCK(block_handler)->self,
|
|
|
|
argc, argv, passed_block_handler);
|
|
|
|
case block_handler_type_symbol:
|
|
|
|
return vm_yield_with_symbol(th, VM_BH_TO_SYMBOL(block_handler), argc, argv, passed_block_handler);
|
|
|
|
case block_handler_type_proc:
|
|
|
|
is_lambda = block_proc_is_lambda(VM_BH_TO_PROC(block_handler));
|
|
|
|
block_handler = vm_proc_to_block_handler(VM_BH_TO_PROC(block_handler));
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
VM_UNREACHABLE(invoke_block_from_c_splattable);
|
|
|
|
return Qundef;
|
2015-10-10 16:32:07 -04:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static inline VALUE
|
|
|
|
check_block_handler(rb_thread_t *th)
|
2007-01-15 22:06:01 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE block_handler = VM_CF_BLOCK_HANDLER(th->cfp);
|
|
|
|
VM_ASSERT(vm_block_handler_verify(block_handler));
|
|
|
|
if (UNLIKELY(block_handler == VM_BLOCK_HANDLER_NONE)) {
|
* 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);
|
2007-01-15 22:06:01 -05:00
|
|
|
}
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
return block_handler;
|
2008-05-19 10:36:13 -04:00
|
|
|
}
|
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
static VALUE
|
2015-03-08 17:22:43 -04:00
|
|
|
vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const rb_cref_t *cref)
|
2008-05-19 10:36:13 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
return invoke_block_from_c_splattable(th, check_block_handler(th), argc, argv, VM_BLOCK_HANDLER_NONE, cref);
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
}
|
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
vm_yield(rb_thread_t *th, int argc, const VALUE *argv)
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
return invoke_block_from_c_splattable(th, check_block_handler(th), argc, argv, VM_BLOCK_HANDLER_NONE, NULL);
|
2007-01-15 22:06:01 -05:00
|
|
|
}
|
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
static VALUE
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, VALUE block_handler)
|
|
|
|
{
|
|
|
|
return invoke_block_from_c_splattable(th, check_block_handler(th), argc, argv, block_handler, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline VALUE
|
|
|
|
invoke_block_from_c_unsplattable(rb_thread_t *th, const struct rb_block *block,
|
|
|
|
VALUE self, int argc, const VALUE *argv,
|
|
|
|
VALUE passed_block_handler, int is_lambda)
|
2013-11-29 03:06:19 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
again:
|
|
|
|
switch (vm_block_type(block)) {
|
|
|
|
case block_type_iseq:
|
|
|
|
return invoke_iseq_block_from_c(th, &block->as.captured, self, argc, argv, passed_block_handler, NULL, FALSE, is_lambda);
|
|
|
|
case block_type_ifunc:
|
|
|
|
return vm_yield_with_cfunc(th, &block->as.captured, self, argc, argv, passed_block_handler);
|
|
|
|
case block_type_symbol:
|
|
|
|
return vm_yield_with_symbol(th, block->as.symbol, argc, argv, passed_block_handler);
|
|
|
|
case block_type_proc:
|
|
|
|
is_lambda = block_proc_is_lambda(block->as.proc);
|
|
|
|
block = vm_proc_block(block->as.proc);
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
VM_UNREACHABLE(invoke_block_from_c_unsplattable);
|
|
|
|
return Qundef;
|
2013-11-29 03:06:19 -05:00
|
|
|
}
|
|
|
|
|
2012-08-20 07:36:34 -04:00
|
|
|
static VALUE
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
|
2016-07-28 07:02:30 -04:00
|
|
|
int argc, const VALUE *argv, VALUE passed_block_handler)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2013-05-15 12:08:48 -04:00
|
|
|
VALUE val = Qundef;
|
2006-12-31 10:02:22 -05:00
|
|
|
int state;
|
|
|
|
volatile int stored_safe = th->safe_level;
|
2007-01-05 08:52:16 -05:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
TH_PUSH_TAG(th);
|
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
2015-05-20 18:03:06 -04:00
|
|
|
th->safe_level = proc->safe_level;
|
2016-07-28 07:02:30 -04:00
|
|
|
val = invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, passed_block_handler, proc->is_lambda);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
2007-07-05 06:04:56 -04:00
|
|
|
TH_POP_TAG();
|
|
|
|
|
2015-05-20 18:03:06 -04:00
|
|
|
th->safe_level = stored_safe;
|
2007-08-18 03:48:28 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state) {
|
2016-05-04 23:22:20 -04:00
|
|
|
TH_JUMP_TAG(th, state);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2015-05-20 18:03:06 -04:00
|
|
|
static VALUE
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
vm_invoke_bmethod(rb_thread_t *th, rb_proc_t *proc, VALUE self,
|
2016-07-28 07:02:30 -04:00
|
|
|
int argc, const VALUE *argv, VALUE block_handler)
|
2015-05-20 18:03:06 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
return invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, block_handler, TRUE);
|
2015-05-20 18:03:06 -04:00
|
|
|
}
|
|
|
|
|
2012-08-20 07:36:34 -04:00
|
|
|
VALUE
|
|
|
|
rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
|
2016-07-28 07:02:30 -04:00
|
|
|
int argc, const VALUE *argv, VALUE passed_block_handler)
|
2012-08-20 07:36:34 -04:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE self = vm_block_self(&proc->block);
|
|
|
|
VM_ASSERT(vm_block_handler_verify(passed_block_handler));
|
|
|
|
|
2015-05-20 18:03:06 -04:00
|
|
|
if (proc->is_from_method) {
|
2016-07-28 07:02:30 -04:00
|
|
|
return vm_invoke_bmethod(th, proc, self, argc, argv, passed_block_handler);
|
2015-05-20 18:03:06 -04:00
|
|
|
}
|
|
|
|
else {
|
2016-07-28 07:02:30 -04:00
|
|
|
return vm_invoke_proc(th, proc, self, argc, argv, passed_block_handler);
|
2015-05-20 18:03:06 -04:00
|
|
|
}
|
2012-08-20 07:36:34 -04:00
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* special variable */
|
|
|
|
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
static rb_control_frame_t *
|
|
|
|
vm_normal_frame(rb_thread_t *th, rb_control_frame_t *cfp)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
while (cfp->pc == 0) {
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
|
|
|
|
return 0;
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
return cfp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
|
|
|
|
{
|
|
|
|
cfp = vm_normal_frame(th, cfp);
|
2012-06-10 23:14:59 -04:00
|
|
|
return lep_svar_get(th, cfp ? VM_CF_LEP(cfp) : 0, key);
|
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
|
|
|
static void
|
2008-05-22 12:19:14 -04:00
|
|
|
vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
cfp = vm_normal_frame(th, cfp);
|
2012-06-10 23:14:59 -04:00
|
|
|
lep_svar_set(th, cfp ? VM_CF_LEP(cfp) : 0, key, val);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2007-07-10 04:04:52 -04:00
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
vm_svar_get(VALUE key)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2007-07-10 04:04:52 -04:00
|
|
|
return vm_cfp_svar_get(th, th->cfp, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-05-22 12:19:14 -04:00
|
|
|
vm_svar_set(VALUE key, VALUE val)
|
2007-07-10 04:04:52 -04:00
|
|
|
{
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2007-07-10 04:04:52 -04:00
|
|
|
vm_cfp_svar_set(th, th->cfp, key, val);
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_backref_get(void)
|
|
|
|
{
|
2015-02-27 03:10:04 -05:00
|
|
|
return vm_svar_get(VM_SVAR_BACKREF);
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_backref_set(VALUE val)
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
{
|
2015-02-27 03:10:04 -05:00
|
|
|
vm_svar_set(VM_SVAR_BACKREF, val);
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_lastline_get(void)
|
|
|
|
{
|
2015-02-27 03:10:04 -05:00
|
|
|
return vm_svar_get(VM_SVAR_LASTLINE);
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_lastline_set(VALUE val)
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
{
|
2015-02-27 03:10:04 -05:00
|
|
|
vm_svar_set(VM_SVAR_LASTLINE, val);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2012-05-25 00:50:10 -04:00
|
|
|
/* misc */
|
|
|
|
|
2011-09-03 11:11:53 -04:00
|
|
|
VALUE
|
|
|
|
rb_sourcefilename(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
|
|
|
|
|
|
|
if (cfp) {
|
2015-07-21 18:52:59 -04:00
|
|
|
return cfp->iseq->body->location.path;
|
2011-09-03 11:11:53 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
const char *
|
|
|
|
rb_sourcefile(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2007-06-24 22:44:20 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
* 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_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
* 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 (cfp) {
|
2015-07-21 18:52:59 -04:00
|
|
|
return RSTRING_PTR(cfp->iseq->body->location.path);
|
* 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
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rb_sourceline(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
* 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_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
* 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 (cfp) {
|
* 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
|
|
|
return rb_vm_get_sourceline(cfp);
|
* 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
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
2007-06-24 22:44:20 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2015-10-29 01:32:57 -04:00
|
|
|
VALUE
|
|
|
|
rb_source_location(int *pline)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
|
|
|
|
|
|
|
if (cfp) {
|
|
|
|
if (pline) *pline = rb_vm_get_sourceline(cfp);
|
|
|
|
return cfp->iseq->body->location.path;
|
|
|
|
}
|
|
|
|
else {
|
2015-10-30 20:17:41 -04:00
|
|
|
if (pline) *pline = 0;
|
2015-10-29 01:32:57 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
rb_source_loc(int *pline)
|
|
|
|
{
|
|
|
|
VALUE path = rb_source_location(pline);
|
|
|
|
if (!path) return 0;
|
|
|
|
return RSTRING_PTR(path);
|
|
|
|
}
|
|
|
|
|
2015-03-08 17:22:43 -04:00
|
|
|
rb_cref_t *
|
* 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_cref(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
* 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_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
2011-07-30 22:32:48 -04:00
|
|
|
|
2015-10-29 17:45:07 -04:00
|
|
|
if (cfp == NULL) {
|
2012-08-02 07:34:19 -04:00
|
|
|
return NULL;
|
2011-07-30 22:32:48 -04:00
|
|
|
}
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
|
|
|
|
return rb_vm_get_cref(cfp->ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2015-11-19 19:17:25 -05:00
|
|
|
rb_cref_t *
|
|
|
|
rb_vm_cref_replace_with_duplicated_cref(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
|
|
|
rb_cref_t *cref = vm_cref_replace_with_duplicated_cref(cfp->ep);
|
|
|
|
return cref;
|
|
|
|
}
|
|
|
|
|
2015-03-08 17:22:43 -04:00
|
|
|
const rb_cref_t *
|
2013-12-24 09:04:31 -05:00
|
|
|
rb_vm_cref_in_context(VALUE self, VALUE cbase)
|
2013-12-24 02:28:11 -05:00
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
const rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
2015-03-08 17:22:43 -04:00
|
|
|
const rb_cref_t *cref;
|
2013-12-24 02:28:11 -05:00
|
|
|
if (cfp->self != self) return NULL;
|
2015-12-09 02:15:48 -05:00
|
|
|
if (!vm_env_cref_by_cref(cfp->ep)) return NULL;
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
cref = rb_vm_get_cref(cfp->ep);
|
2015-03-08 15:50:37 -04:00
|
|
|
if (CREF_CLASS(cref) != cbase) return NULL;
|
2013-12-24 09:04:31 -05:00
|
|
|
return cref;
|
2013-12-24 02:28:11 -05:00
|
|
|
}
|
|
|
|
|
2007-06-24 13:19:22 -04:00
|
|
|
#if 0
|
2006-12-31 10:02:22 -05:00
|
|
|
void
|
2015-03-08 17:22:43 -04:00
|
|
|
debug_cref(rb_cref_t *cref)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
while (cref) {
|
2015-03-08 15:50:37 -04:00
|
|
|
dp(CREF_CLASS(cref));
|
|
|
|
printf("%ld\n", CREF_VISI(cref));
|
|
|
|
cref = CREF_NEXT(cref);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
2007-06-24 13:19:22 -04:00
|
|
|
#endif
|
2006-12-31 10:02:22 -05:00
|
|
|
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
VALUE
|
|
|
|
rb_vm_cbase(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
* 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_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
|
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17084 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-10 17:46:43 -04:00
|
|
|
|
2011-07-30 22:32:48 -04:00
|
|
|
if (cfp == 0) {
|
|
|
|
rb_raise(rb_eRuntimeError, "Can't call on top of Fiber or Thread");
|
|
|
|
}
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
return vm_get_cbase(cfp->ep);
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* jump */
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
make_localjump_error(const char *mesg, VALUE value, int reason)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2007-07-05 06:04:56 -04:00
|
|
|
extern VALUE rb_eLocalJumpError;
|
|
|
|
VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
|
2006-12-31 10:02:22 -05:00
|
|
|
ID id;
|
* 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
|
|
|
switch (reason) {
|
* 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 TAG_BREAK:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "break");
|
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 TAG_REDO:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "redo");
|
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 TAG_RETRY:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "retry");
|
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 TAG_NEXT:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "next");
|
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 TAG_RETURN:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "return");
|
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:
|
2008-06-09 05:25:32 -04:00
|
|
|
CONST_ID(id, "noreason");
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
rb_iv_set(exc, "@exit_value", value);
|
|
|
|
rb_iv_set(exc, "@reason", ID2SYM(id));
|
|
|
|
return exc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
* 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(const char *mesg, VALUE value, int reason)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
VALUE exc = make_localjump_error(mesg, value, reason);
|
|
|
|
rb_exc_raise(exc);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
* 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_make_jump_tag_but_local_jump(int state, VALUE val)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
VALUE result = Qnil;
|
* 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
|
|
|
|
2008-05-07 04:41:16 -04:00
|
|
|
if (val == Qundef) {
|
2006-12-31 10:02:22 -05:00
|
|
|
val = GET_THREAD()->tag->retval;
|
2008-05-07 04:41:16 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
switch (state) {
|
* 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 TAG_RETURN:
|
2006-12-31 10:02:22 -05:00
|
|
|
result = make_localjump_error("unexpected return", val, state);
|
|
|
|
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 TAG_BREAK:
|
2006-12-31 10:02:22 -05:00
|
|
|
result = make_localjump_error("unexpected break", val, state);
|
|
|
|
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 TAG_NEXT:
|
2006-12-31 10:02:22 -05:00
|
|
|
result = make_localjump_error("unexpected next", val, state);
|
|
|
|
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 TAG_REDO:
|
2006-12-31 10:02:22 -05:00
|
|
|
result = make_localjump_error("unexpected redo", Qnil, state);
|
|
|
|
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 TAG_RETRY:
|
2006-12-31 10:02:22 -05:00
|
|
|
result = make_localjump_error("retry outside of rescue clause", Qnil, state);
|
|
|
|
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:
|
2006-12-31 10:02:22 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-12-18 12:04:05 -05:00
|
|
|
rb_vm_jump_tag_but_local_jump(int state)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2012-12-18 12:04:05 -05:00
|
|
|
VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
|
|
|
|
if (!NIL_P(exc)) rb_exc_raise(exc);
|
2006-12-31 10:02:22 -05:00
|
|
|
JUMP_TAG(state);
|
|
|
|
}
|
|
|
|
|
2012-01-24 00:20:48 -05:00
|
|
|
NORETURN(static void vm_iter_break(rb_thread_t *th, VALUE val));
|
2007-06-24 22:44:20 -04:00
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
static rb_control_frame_t *
|
|
|
|
next_not_local_frame(rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
while (VM_ENV_LOCAL_P(cfp->ep)) {
|
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
|
|
|
}
|
|
|
|
return cfp;
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
static void
|
2012-01-24 00:20:48 -05:00
|
|
|
vm_iter_break(rb_thread_t *th, VALUE val)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_control_frame_t *cfp = next_not_local_frame(th->cfp);
|
|
|
|
const VALUE *ep = VM_CF_PREV_EP(cfp);
|
|
|
|
const rb_control_frame_t *target_cfp = rb_vm_search_cf_from_ep(th, cfp, ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-06-12 09:01:40 -04:00
|
|
|
#if 0 /* raise LocalJumpError */
|
|
|
|
if (!target_cfp) {
|
|
|
|
rb_vm_localjump_error("unexpected break", val, TAG_BREAK);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
th->state = TAG_BREAK;
|
2015-03-11 08:49:27 -04:00
|
|
|
th->errinfo = (VALUE)THROW_DATA_NEW(val, target_cfp, TAG_BREAK);
|
2006-12-31 10:02:22 -05:00
|
|
|
TH_JUMP_TAG(th, TAG_BREAK);
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
void
|
2008-05-22 00:28:13 -04:00
|
|
|
rb_iter_break(void)
|
2007-06-24 22:44:20 -04:00
|
|
|
{
|
2012-01-24 00:20:48 -05:00
|
|
|
vm_iter_break(GET_THREAD(), Qnil);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_iter_break_value(VALUE val)
|
|
|
|
{
|
|
|
|
vm_iter_break(GET_THREAD(), val);
|
2007-06-24 22:44:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* optimization: redefine management */
|
|
|
|
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
static st_table *vm_opt_method_table = 0;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2013-03-05 07:36:45 -05:00
|
|
|
static int
|
|
|
|
vm_redefinition_check_flag(VALUE klass)
|
|
|
|
{
|
2016-05-17 02:53:48 -04:00
|
|
|
if (klass == rb_cInteger) return INTEGER_REDEFINED_OP_FLAG;
|
2013-03-05 07:36:45 -05:00
|
|
|
if (klass == rb_cFloat) return FLOAT_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cString) return STRING_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cArray) return ARRAY_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cHash) return HASH_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cSymbol) return SYMBOL_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cTime) return TIME_REDEFINED_OP_FLAG;
|
2013-09-26 03:39:48 -04:00
|
|
|
if (klass == rb_cRegexp) return REGEXP_REDEFINED_OP_FLAG;
|
2015-12-07 20:46:45 -05:00
|
|
|
if (klass == rb_cNilClass) return NIL_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cTrueClass) return TRUE_REDEFINED_OP_FLAG;
|
|
|
|
if (klass == rb_cFalseClass) return FALSE_REDEFINED_OP_FLAG;
|
2013-03-05 07:36:45 -05:00
|
|
|
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 void
|
2011-08-24 18:02:03 -04:00
|
|
|
rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
* compile.c (iseq_build_body), error.c (set_syserr, get_syserr),
(syserr_initialize), gc.c (define_final, rb_gc_copy_finalizer),
(run_final), hash.c (rb_hash_aref, rb_hash_lookup2),
(rb_hash_fetch_m, rb_hash_clear, rb_hash_aset, eql_i),
iseq.c (iseq_load, iseq_data_to_ary), marshal.c (r_symlink),
thread.c (rb_thread_local_aref),
variable.c (generic_ivar_remove, ivar_get, rb_const_get_0),
(rb_cvar_get), vm.c (rb_vm_check_redefinition_opt_method),
vm_insnhelper.c (vm_get_ev_const), vm_method.c (remove_method),
ext/iconv/iconv.c (map_charset): use st_data_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-12 10:47:23 -04:00
|
|
|
st_data_t bop;
|
2015-12-17 17:43:35 -05:00
|
|
|
if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN)) {
|
|
|
|
klass = RBASIC_CLASS(klass);
|
|
|
|
}
|
2015-06-03 07:10:16 -04:00
|
|
|
if (me->def->type == VM_METHOD_TYPE_CFUNC) {
|
2009-07-15 10:59:41 -04:00
|
|
|
if (st_lookup(vm_opt_method_table, (st_data_t)me, &bop)) {
|
2013-03-05 07:36:45 -05:00
|
|
|
int flag = vm_redefinition_check_flag(klass);
|
2011-08-24 18:02:03 -04:00
|
|
|
|
|
|
|
ruby_vm_redefined_flag[bop] |= flag;
|
2009-07-15 10:59:41 -04:00
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-12 04:43:55 -04:00
|
|
|
static enum rb_id_table_iterator_result
|
|
|
|
check_redefined_method(ID mid, VALUE value, void *data)
|
2013-03-05 07:36:45 -05:00
|
|
|
{
|
|
|
|
VALUE klass = (VALUE)data;
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
const rb_method_entry_t *me = (rb_method_entry_t *)value;
|
|
|
|
const rb_method_entry_t *newme = rb_method_entry(klass, mid);
|
|
|
|
|
|
|
|
if (newme != me) rb_vm_check_redefinition_opt_method(me, me->owner);
|
2013-03-05 07:36:45 -05:00
|
|
|
|
2015-08-12 04:59:27 -04:00
|
|
|
return ID_TABLE_CONTINUE;
|
2013-03-05 07:36:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_vm_check_redefinition_by_prepend(VALUE klass)
|
|
|
|
{
|
|
|
|
if (!vm_redefinition_check_flag(klass)) return;
|
2015-08-12 04:43:55 -04:00
|
|
|
rb_id_table_foreach(RCLASS_M_TBL(RCLASS_ORIGIN(klass)), check_redefined_method, (void *)klass);
|
2013-03-05 07:36:45 -05:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
static void
|
2008-05-22 12:19:14 -04:00
|
|
|
add_opt_method(VALUE klass, ID mid, VALUE bop)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
const rb_method_entry_t *me = rb_method_entry_at(klass, mid);
|
2014-03-08 03:56:50 -05:00
|
|
|
|
2015-06-03 07:10:16 -04:00
|
|
|
if (me && me->def->type == VM_METHOD_TYPE_CFUNC) {
|
2009-07-15 10:59:41 -04:00
|
|
|
st_insert(vm_opt_method_table, (st_data_t)me, (st_data_t)bop);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
rb_bug("undefined optimized method: %s", rb_id2name(mid));
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
static void
|
|
|
|
vm_init_redefined_flag(void)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2007-07-20 03:11:35 -04:00
|
|
|
ID mid;
|
|
|
|
VALUE bop;
|
|
|
|
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
vm_opt_method_table = st_init_numtable();
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2008-10-11 23:28:49 -04:00
|
|
|
#define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
|
2007-07-20 03:11:35 -04:00
|
|
|
#define C(k) add_opt_method(rb_c##k, mid, bop)
|
2016-05-17 02:53:48 -04:00
|
|
|
OP(PLUS, PLUS), (C(Integer), C(Float), C(String), C(Array));
|
|
|
|
OP(MINUS, MINUS), (C(Integer), C(Float));
|
|
|
|
OP(MULT, MULT), (C(Integer), C(Float));
|
|
|
|
OP(DIV, DIV), (C(Integer), C(Float));
|
|
|
|
OP(MOD, MOD), (C(Integer), C(Float));
|
|
|
|
OP(Eq, EQ), (C(Integer), C(Float), C(String));
|
|
|
|
OP(Eqq, EQQ), (C(Integer), C(Float), C(Symbol), C(String),
|
2015-12-07 20:46:45 -05:00
|
|
|
C(NilClass), C(TrueClass), C(FalseClass));
|
2016-05-17 02:53:48 -04:00
|
|
|
OP(LT, LT), (C(Integer), C(Float));
|
|
|
|
OP(LE, LE), (C(Integer), C(Float));
|
|
|
|
OP(GT, GT), (C(Integer), C(Float));
|
|
|
|
OP(GE, GE), (C(Integer), C(Float));
|
2007-07-20 03:11:35 -04:00
|
|
|
OP(LTLT, LTLT), (C(String), C(Array));
|
|
|
|
OP(AREF, AREF), (C(Array), C(Hash));
|
|
|
|
OP(ASET, ASET), (C(Array), C(Hash));
|
|
|
|
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
|
2009-09-06 04:39:57 -04:00
|
|
|
OP(Size, SIZE), (C(Array), C(String), C(Hash));
|
2012-09-26 05:34:46 -04:00
|
|
|
OP(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash));
|
2016-05-17 02:53:48 -04:00
|
|
|
OP(Succ, SUCC), (C(Integer), C(String), C(Time));
|
2013-09-26 03:58:28 -04:00
|
|
|
OP(EqTilde, MATCH), (C(Regexp), C(String));
|
2013-11-09 16:17:06 -05:00
|
|
|
OP(Freeze, FREEZE), (C(String));
|
2016-03-17 08:47:31 -04:00
|
|
|
OP(Max, MAX), (C(Array));
|
|
|
|
OP(Min, MIN), (C(Array));
|
2007-07-20 03:11:35 -04:00
|
|
|
#undef C
|
|
|
|
#undef OP
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2010-01-24 08:52:32 -05:00
|
|
|
/* for vm development */
|
|
|
|
|
2010-02-17 03:05:42 -05:00
|
|
|
#if VMDEBUG
|
2010-01-24 08:52:32 -05:00
|
|
|
static const char *
|
|
|
|
vm_frametype_name(const rb_control_frame_t *cfp)
|
|
|
|
{
|
|
|
|
switch (VM_FRAME_TYPE(cfp)) {
|
|
|
|
case VM_FRAME_MAGIC_METHOD: return "method";
|
|
|
|
case VM_FRAME_MAGIC_BLOCK: return "block";
|
|
|
|
case VM_FRAME_MAGIC_CLASS: return "class";
|
|
|
|
case VM_FRAME_MAGIC_TOP: return "top";
|
|
|
|
case VM_FRAME_MAGIC_CFUNC: return "cfunc";
|
|
|
|
case VM_FRAME_MAGIC_PROC: return "proc";
|
|
|
|
case VM_FRAME_MAGIC_IFUNC: return "ifunc";
|
|
|
|
case VM_FRAME_MAGIC_EVAL: return "eval";
|
|
|
|
case VM_FRAME_MAGIC_LAMBDA: return "lambda";
|
2014-06-19 05:17:21 -04:00
|
|
|
case VM_FRAME_MAGIC_RESCUE: return "rescue";
|
2010-01-24 08:52:32 -05:00
|
|
|
default:
|
|
|
|
rb_bug("unknown frame");
|
|
|
|
}
|
|
|
|
}
|
2010-02-17 03:05:42 -05:00
|
|
|
#endif
|
2010-01-24 08:52:32 -05:00
|
|
|
|
2015-04-10 04:29:30 -04:00
|
|
|
static void
|
2015-08-27 21:20:32 -04:00
|
|
|
hook_before_rewind(rb_thread_t *th, rb_control_frame_t *cfp, int will_finish_vm_exec)
|
2015-04-10 04:29:30 -04:00
|
|
|
{
|
|
|
|
switch (VM_FRAME_TYPE(th->cfp)) {
|
|
|
|
case VM_FRAME_MAGIC_METHOD:
|
|
|
|
RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
|
|
|
|
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil);
|
|
|
|
break;
|
|
|
|
case VM_FRAME_MAGIC_BLOCK:
|
|
|
|
case VM_FRAME_MAGIC_LAMBDA:
|
|
|
|
if (VM_FRAME_TYPE_BMETHOD_P(th->cfp)) {
|
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
|
2015-08-27 21:20:32 -04:00
|
|
|
|
|
|
|
if (!will_finish_vm_exec) {
|
|
|
|
/* kick RUBY_EVENT_RETURN at invoke_block_from_c() for bmethod */
|
|
|
|
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_RETURN, th->cfp->self,
|
|
|
|
rb_vm_frame_method_entry(th->cfp)->called_id,
|
|
|
|
rb_vm_frame_method_entry(th->cfp)->owner, Qnil);
|
|
|
|
}
|
2015-04-10 04:29:30 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_B_RETURN, th->cfp->self, 0, 0, Qnil);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VM_FRAME_MAGIC_CLASS:
|
|
|
|
EXEC_EVENT_HOOK_AND_POP_FRAME(th, RUBY_EVENT_END, th->cfp->self, 0, 0, Qnil);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* evaluator body */
|
2007-04-19 06:37:08 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
/* finish
|
|
|
|
VMe (h1) finish
|
|
|
|
VM finish F1 F2
|
2007-11-23 03:34:34 -05:00
|
|
|
cfunc finish F1 F2 C1
|
2006-12-31 10:02:22 -05:00
|
|
|
rb_funcall finish F1 F2 C1
|
|
|
|
VMe finish F1 F2 C1
|
|
|
|
VM finish F1 F2 C1 F3
|
|
|
|
|
|
|
|
F1 - F3 : pushed by VM
|
|
|
|
C1 : pushed by send insn (CFUNC)
|
|
|
|
|
|
|
|
struct CONTROL_FRAME {
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
VALUE *pc; // cfp[0], program counter
|
|
|
|
VALUE *sp; // cfp[1], stack pointer
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_iseq_t *iseq; // cfp[2], iseq
|
|
|
|
VALUE self; // cfp[3], self
|
|
|
|
const VALUE *ep; // cfp[4], env pointer
|
|
|
|
const void *block_code; // cfp[5], blcok code
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
struct rb_captured_blcok {
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE self;
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep;
|
2016-07-28 07:02:30 -04:00
|
|
|
union code;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
struct METHOD_ENV {
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE param0;
|
|
|
|
...
|
|
|
|
VALUE paramN;
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE lvar1;
|
|
|
|
...
|
|
|
|
VALUE lvarM;
|
|
|
|
VALUE cref; // ep[-2]
|
|
|
|
VALUE special; // ep[-1]
|
|
|
|
VALUE flags; // ep[ 0] == lep[0]
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
struct BLOCK_ENV {
|
|
|
|
VALUE block_param0;
|
2006-12-31 10:02:22 -05:00
|
|
|
...
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE block_paramN;
|
|
|
|
VALUE block_lvar1;
|
2006-12-31 10:02:22 -05:00
|
|
|
...
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE block_lvarM;
|
|
|
|
VALUE cref; // ep[-2]
|
|
|
|
VALUE special; // ep[-1]
|
|
|
|
VALUE flags; // ep[ 0]
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
struct CLASS_ENV {
|
|
|
|
VALUE class_lvar0;
|
2006-12-31 10:02:22 -05:00
|
|
|
...
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE class_lvarN;
|
* vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
VM value stack frame of block contains cref information.
(dfp[-1] points CREF)
* compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
vm_dump.h, vm_core.h: ditto.
* include/ruby/ruby.h, gc.c: remove T_VALUES because of above
changes.
* bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-05-18 23:08:50 -04:00
|
|
|
VALUE cref;
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE prev_ep; // for frame jump
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE flags;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct C_METHOD_CONTROL_FRAME {
|
|
|
|
VALUE *pc; // 0
|
|
|
|
VALUE *sp; // stack pointer
|
2012-06-10 23:14:59 -04:00
|
|
|
rb_iseq_t *iseq; // cmi
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE self; // ?
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep; // ep == lep
|
2016-07-28 07:02:30 -04:00
|
|
|
void *code; //
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct C_BLOCK_CONTROL_FRAME {
|
|
|
|
VALUE *pc; // point only "finish" insn
|
|
|
|
VALUE *sp; // sp
|
2012-06-10 23:14:59 -04:00
|
|
|
rb_iseq_t *iseq; // ?
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE self; //
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep; // ep
|
2016-07-28 07:02:30 -04:00
|
|
|
void *code; //
|
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
|
|
|
static VALUE
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
vm_exec(rb_thread_t *th)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
|
|
|
int state;
|
2015-03-10 14:39:46 -04:00
|
|
|
VALUE result;
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE initial = 0;
|
2015-03-11 08:49:27 -04:00
|
|
|
struct vm_throw_data *err;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
TH_PUSH_TAG(th);
|
2008-05-07 04:41:16 -04:00
|
|
|
_tag.retval = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = EXEC_TAG()) == 0) {
|
|
|
|
vm_loop_start:
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
result = vm_exec_core(th, initial);
|
2006-12-31 10:02:22 -05:00
|
|
|
if ((state = th->state) != 0) {
|
2015-03-11 08:49:27 -04:00
|
|
|
err = (struct vm_throw_data *)result;
|
2006-12-31 10:02:22 -05:00
|
|
|
th->state = 0;
|
|
|
|
goto exception_handler;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2015-07-24 17:44:14 -04:00
|
|
|
unsigned int i;
|
2015-07-24 15:49:16 -04:00
|
|
|
const struct iseq_catch_table_entry *entry;
|
|
|
|
const struct iseq_catch_table *ct;
|
2006-12-31 10:02:22 -05:00
|
|
|
unsigned long epc, cont_pc, cont_sp;
|
2015-07-21 18:52:59 -04:00
|
|
|
const rb_iseq_t *catch_iseq;
|
* 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;
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE type;
|
2015-03-10 14:39:46 -04:00
|
|
|
const rb_control_frame_t *escape_cfp;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-03-11 08:49:27 -04:00
|
|
|
err = (struct vm_throw_data *)th->errinfo;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
exception_handler:
|
2015-07-21 18:52:59 -04:00
|
|
|
cont_pc = cont_sp = 0;
|
|
|
|
catch_iseq = NULL;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
while (th->cfp->pc == 0 || th->cfp->iseq == 0) {
|
2010-01-24 08:52:32 -05:00
|
|
|
if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
|
2015-06-02 00:20:30 -04:00
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self,
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
rb_vm_frame_method_entry(th->cfp)->called_id,
|
|
|
|
rb_vm_frame_method_entry(th->cfp)->owner, Qnil);
|
2015-12-17 21:09:38 -05:00
|
|
|
RUBY_DTRACE_CMETHOD_RETURN_HOOK(th,
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
rb_vm_frame_method_entry(th->cfp)->owner,
|
2015-06-02 00:20:30 -04:00
|
|
|
rb_vm_frame_method_entry(th->cfp)->called_id);
|
2010-01-24 08:52:32 -05:00
|
|
|
}
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
cfp = th->cfp;
|
2015-07-21 18:52:59 -04:00
|
|
|
epc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-01-15 21:54:22 -05:00
|
|
|
escape_cfp = NULL;
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state == TAG_BREAK || state == TAG_RETURN) {
|
2015-03-10 14:39:46 -04:00
|
|
|
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-01-15 21:54:22 -05:00
|
|
|
if (cfp == escape_cfp) {
|
2006-12-31 10:02:22 -05:00
|
|
|
if (state == TAG_RETURN) {
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 06:22:34 -04:00
|
|
|
if (!VM_FRAME_TYPE_FINISH_P(cfp)) {
|
2015-03-10 14:39:46 -04:00
|
|
|
THROW_DATA_CATCH_FRAME_SET(err, cfp + 1);
|
|
|
|
THROW_DATA_STATE_SET(err, state = TAG_BREAK);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
2015-07-21 18:52:59 -04:00
|
|
|
ct = cfp->iseq->body->catch_table;
|
2014-07-14 03:06:26 -04:00
|
|
|
if (ct) for (i = 0; i < ct->size; i++) {
|
|
|
|
entry = &ct->entries[i];
|
2009-08-13 08:06:14 -04:00
|
|
|
if (entry->start < epc && entry->end >= epc) {
|
|
|
|
if (entry->type == CATCH_TYPE_ENSURE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq = entry->iseq;
|
2009-08-13 08:06:14 -04:00
|
|
|
cont_pc = entry->cont;
|
|
|
|
cont_sp = entry->sp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-21 18:52:59 -04:00
|
|
|
if (!catch_iseq) {
|
2009-08-13 08:06:14 -04:00
|
|
|
th->errinfo = Qnil;
|
2015-04-10 04:29:30 -04:00
|
|
|
result = THROW_DATA_VAL(err);
|
2015-08-27 21:20:32 -04:00
|
|
|
hook_before_rewind(th, th->cfp, TRUE);
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2009-08-13 08:06:14 -04:00
|
|
|
goto finish_vme;
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
/* through */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* TAG_BREAK */
|
|
|
|
#if OPT_STACK_CACHING
|
2015-03-10 14:39:46 -04:00
|
|
|
initial = THROW_DATA_VAL(err);
|
2006-12-31 10:02:22 -05:00
|
|
|
#else
|
2015-03-10 14:39:46 -04:00
|
|
|
*th->cfp->sp++ = THROW_DATA_VAL(err);
|
2006-12-31 10:02:22 -05:00
|
|
|
#endif
|
2010-02-10 11:46:39 -05:00
|
|
|
th->errinfo = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
goto vm_loop_start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state == TAG_RAISE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
ct = cfp->iseq->body->catch_table;
|
2014-07-14 03:06:26 -04:00
|
|
|
if (ct) for (i = 0; i < ct->size; i++) {
|
|
|
|
entry = &ct->entries[i];
|
2006-12-31 10:02:22 -05:00
|
|
|
if (entry->start < epc && entry->end >= epc) {
|
|
|
|
|
|
|
|
if (entry->type == CATCH_TYPE_RESCUE ||
|
|
|
|
entry->type == CATCH_TYPE_ENSURE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq = entry->iseq;
|
2006-12-31 10:02:22 -05:00
|
|
|
cont_pc = entry->cont;
|
|
|
|
cont_sp = entry->sp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (state == TAG_RETRY) {
|
2015-07-21 18:52:59 -04:00
|
|
|
ct = cfp->iseq->body->catch_table;
|
2014-07-14 03:06:26 -04:00
|
|
|
if (ct) for (i = 0; i < ct->size; i++) {
|
|
|
|
entry = &ct->entries[i];
|
2006-12-31 10:02:22 -05:00
|
|
|
if (entry->start < epc && entry->end >= epc) {
|
|
|
|
|
|
|
|
if (entry->type == CATCH_TYPE_ENSURE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq = entry->iseq;
|
2006-12-31 10:02:22 -05:00
|
|
|
cont_pc = entry->cont;
|
|
|
|
cont_sp = entry->sp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (entry->type == CATCH_TYPE_RETRY) {
|
2015-03-10 14:39:46 -04:00
|
|
|
const rb_control_frame_t *escape_cfp;
|
|
|
|
escape_cfp = THROW_DATA_CATCH_FRAME(err);
|
2015-01-15 21:54:22 -05:00
|
|
|
if (cfp == escape_cfp) {
|
2015-07-21 18:52:59 -04:00
|
|
|
cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
|
2010-02-10 11:46:39 -05:00
|
|
|
th->errinfo = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
goto vm_loop_start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-15 21:54:22 -05:00
|
|
|
else if (state == TAG_BREAK && !escape_cfp) {
|
2006-12-31 10:02:22 -05:00
|
|
|
type = CATCH_TYPE_BREAK;
|
|
|
|
|
|
|
|
search_restart_point:
|
2015-07-21 18:52:59 -04:00
|
|
|
ct = cfp->iseq->body->catch_table;
|
2014-07-14 03:06:26 -04:00
|
|
|
if (ct) for (i = 0; i < ct->size; i++) {
|
|
|
|
entry = &ct->entries[i];
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
if (entry->start < epc && entry->end >= epc) {
|
|
|
|
if (entry->type == CATCH_TYPE_ENSURE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq = entry->iseq;
|
2006-12-31 10:02:22 -05:00
|
|
|
cont_pc = entry->cont;
|
|
|
|
cont_sp = entry->sp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (entry->type == type) {
|
2015-07-21 18:52:59 -04:00
|
|
|
cfp->pc = cfp->iseq->body->iseq_encoded + entry->cont;
|
2012-09-28 00:05:36 -04:00
|
|
|
cfp->sp = vm_base_ptr(cfp) + entry->sp;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2008-05-24 02:29:48 -04:00
|
|
|
if (state != TAG_REDO) {
|
2006-12-31 10:02:22 -05:00
|
|
|
#if OPT_STACK_CACHING
|
2015-03-10 14:39:46 -04:00
|
|
|
initial = THROW_DATA_VAL(err);
|
2006-12-31 10:02:22 -05:00
|
|
|
#else
|
2015-03-10 14:39:46 -04:00
|
|
|
*th->cfp->sp++ = THROW_DATA_VAL(err);
|
2006-12-31 10:02:22 -05:00
|
|
|
#endif
|
|
|
|
}
|
2010-02-10 11:46:39 -05:00
|
|
|
th->errinfo = Qnil;
|
2012-01-24 00:20:48 -05:00
|
|
|
th->state = 0;
|
2006-12-31 10:02:22 -05:00
|
|
|
goto vm_loop_start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (state == TAG_REDO) {
|
|
|
|
type = CATCH_TYPE_REDO;
|
|
|
|
goto search_restart_point;
|
|
|
|
}
|
|
|
|
else if (state == TAG_NEXT) {
|
|
|
|
type = CATCH_TYPE_NEXT;
|
|
|
|
goto search_restart_point;
|
|
|
|
}
|
|
|
|
else {
|
2015-07-21 18:52:59 -04:00
|
|
|
ct = cfp->iseq->body->catch_table;
|
2014-07-14 03:06:26 -04:00
|
|
|
if (ct) for (i = 0; i < ct->size; i++) {
|
|
|
|
entry = &ct->entries[i];
|
2006-12-31 10:02:22 -05:00
|
|
|
if (entry->start < epc && entry->end >= epc) {
|
|
|
|
|
|
|
|
if (entry->type == CATCH_TYPE_ENSURE) {
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq = entry->iseq;
|
2006-12-31 10:02:22 -05:00
|
|
|
cont_pc = entry->cont;
|
|
|
|
cont_sp = entry->sp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-19 13:59:58 -04:00
|
|
|
if (catch_iseq != NULL) { /* found catch table */
|
2006-12-31 10:02:22 -05:00
|
|
|
/* enter catch scope */
|
2016-07-28 07:02:30 -04:00
|
|
|
const int arg_size = 1;
|
|
|
|
|
2015-12-08 08:58:50 -05:00
|
|
|
rb_iseq_check(catch_iseq);
|
2012-09-28 00:05:36 -04:00
|
|
|
cfp->sp = vm_base_ptr(cfp) + cont_sp;
|
2015-07-21 18:52:59 -04:00
|
|
|
cfp->pc = cfp->iseq->body->iseq_encoded + cont_pc;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
|
|
|
/* push block frame */
|
2015-03-10 14:39:46 -04:00
|
|
|
cfp->sp[0] = (VALUE)err;
|
2014-06-19 05:17:21 -04:00
|
|
|
vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_RESCUE,
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
cfp->self,
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_GUARDED_PREV_EP(cfp->ep),
|
2015-06-02 00:20:30 -04:00
|
|
|
0, /* cref or me */
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq->body->iseq_encoded,
|
2016-07-28 07:02:30 -04:00
|
|
|
cfp->sp + arg_size /* push value */,
|
|
|
|
catch_iseq->body->local_table_size - arg_size,
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq->body->stack_max);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2010-02-10 11:46:39 -05:00
|
|
|
state = 0;
|
2010-02-11 03:52:16 -05:00
|
|
|
th->state = 0;
|
2010-02-10 11:46:39 -05:00
|
|
|
th->errinfo = Qnil;
|
2006-12-31 10:02:22 -05:00
|
|
|
goto vm_loop_start;
|
|
|
|
}
|
|
|
|
else {
|
2010-01-24 08:52:32 -05:00
|
|
|
/* skip frame */
|
2015-08-27 21:20:32 -04:00
|
|
|
hook_before_rewind(th, th->cfp, FALSE);
|
2010-01-24 08:52:32 -05:00
|
|
|
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 06:22:34 -04:00
|
|
|
if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2015-03-10 14:39:46 -04:00
|
|
|
th->errinfo = (VALUE)err;
|
2014-02-05 10:32:35 -05:00
|
|
|
TH_TMPPOP_TAG();
|
2016-05-04 23:22:20 -04:00
|
|
|
TH_JUMP_TAG(th, state);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 06:22:34 -04:00
|
|
|
else {
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
* vm_core.h: remove VM_FRAME_MAGIC_FINISH (finish frame type).
Before this commit:
`finish frame' was place holder which indicates that VM loop
needs to return function.
If a C method calls a Ruby methods (a method written by Ruby),
then VM loop will be (re-)invoked. When the Ruby method returns,
then also VM loop should be escaped. `finish frame' has only
one instruction `finish', which returns VM loop function.
VM loop function executes `finish' instruction, then VM loop
function returns itself.
With such mechanism, `leave' instruction (which returns one
frame from current scope) doesn't need to check that this `leave'
should also return from VM loop function.
Strictly, one branch can be removed from `leave' instructon.
Consideration:
However, pushing the `finish frame' needs costs because
it needs several memory accesses. The number of pushing
`finish frame' is greater than I had assumed. Of course,
pushing `finish frame' consumes additional control frame.
Moreover, recent processors has good branch prediction,
with which we can ignore such trivial checking.
After this commit:
Finally, I decide to remove `finish frame' and `finish'
instruction. Some parts of VM depend on `finish frame',
so the new frame flag VM_FRAME_FLAG_FINISH is introduced.
If this frame should escape from VM function loop, then
the result of VM_FRAME_TYPE_FINISH_P(cfp) is true.
`leave' instruction checks this flag every time.
I measured performance on it. However on my environments,
it improves some benchmarks and slows some benchmarks down.
Maybe it is because of C compiler optimization parameters.
I'll re-visit here if this cause problems.
* insns.def (leave, finish): remove finish instruction.
* vm.c, vm_eval.c, vm_exec.c, vm_backtrace.c, vm_dump.c:
apply above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-06-15 06:22:34 -04:00
|
|
|
goto exception_handler;
|
|
|
|
}
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
finish_vme:
|
|
|
|
TH_POP_TAG();
|
|
|
|
return result;
|
|
|
|
}
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* misc */
|
|
|
|
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
VALUE
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_iseq_eval(const rb_iseq_t *iseq)
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
{
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
VALUE val;
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_top_stack(th, iseq);
|
2008-12-26 20:15:56 -05:00
|
|
|
val = vm_exec(th);
|
|
|
|
return val;
|
2009-01-05 04:54:47 -05:00
|
|
|
}
|
2008-12-26 20:15:56 -05:00
|
|
|
|
|
|
|
VALUE
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_iseq_eval_main(const rb_iseq_t *iseq)
|
2008-12-26 20:15:56 -05:00
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
VALUE val;
|
|
|
|
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_main_stack(th, iseq);
|
* common.mk: clean up
- remove blockinlining.$(OBJEXT) to built
- make ENCODING_H_INCLDUES variable (include/ruby/encoding.h)
- make VM_CORE_H_INCLUDES variable (vm_core.h)
- simplify rules.
- make depends rule to output depend status using gcc -MM.
* include/ruby/mvm.h, include/ruby/vm.h: rename mvm.h to vm.h.
* include/ruby.h: ditto.
* load.c: add inclusion explicitly.
* enumerator.c, object.c, parse.y, thread.c, vm_dump.c:
remove useless inclusion.
* eval_intern.h: cleanup inclusion.
* vm_core.h: rb_thread_t should be defined in this file.
* vm_evalbody.c, vm_exec.c: rename vm_evalbody.c to vm_exec.c.
* vm.h, vm_exec.h: rename vm.h to vm_exec.h.
* insnhelper.h, vm_insnhelper.h: rename insnhelper.h to vm_insnhelper.h.
* vm.c, vm_insnhelper.c, vm_insnhelper.h:
- rename vm_eval() to vm_exec_core().
- rename vm_eval_body() to vm_exec().
- cleanup include order.
* vm_method.c: fix comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-22 20:20:28 -04:00
|
|
|
val = vm_exec(th);
|
* this commit is a result of refactoring. only renaming functions,
moving definitions place, add/remove prototypes, deleting
unused variables and removing yarv.h.
This commit doesn't change any behavior of ruby/vm.
* yarv.h, common.mk: remove yarv.h (contents are moved to yarvcore.h).
* error.c, eval_intern.h: include yarvcore.h instead yarv.h
* rename some functions:
* debug.[ch]: debug_*() -> ruby_debug_*()
* iseq.c: iseq_*() -> rb_iseq_*(), ruby_iseq_disasm()
* iseq.c: node_name() -> ruby_node_name()
* vm.c: yarv_check_redefinition_opt_method() ->
rb_vm_check_redefinition_opt_method()
* some refactoring with checking -Wall.
* array.c: remove rb_ary_ptr() (unused) and remove unused
local variables.
* object.c: add a prototype of rb_mod_module_exec().
* eval_intern.h (ruby_cref): set it inline.
* eval_load.c (rb_load), yarvcore.c: yarv_load() -> rb_load_internal().
* parse.y: add a prototype of rb_parse_in_eval() (in eval.c).
* process.c: add a prototype of rb_thread_stop_timer_thread() (in thread.c).
* thread.c: remove raw_gets() function (unused) and fix some format
mismatch (format mismatchs have remained yet. this is todo).
* thread.c (rb_thread_wait_fd_rw): fix typo on label name.
* thread_pthread.ci: comment out codes with USE_THREAD_CACHE.
* vm.c (rb_svar, rb_backref_get, rb_backref_get,
rb_lastline_get, rb_lastline_set) : moved from yarvcore.c.
* vm.c (yarv_init_redefined_flag): add a prototype and rename
yarv_opt_method_table to vm_opt_method_table.
* vm.c (rb_thread_eval): moved from yarvcore.c.
* yarvcore.c: remove unused global variables and fix to use nsdr().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-06 20:25:05 -05:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2007-04-24 23:50:00 -04:00
|
|
|
int
|
2013-01-29 03:25:32 -05:00
|
|
|
rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *idp, VALUE *klassp)
|
2007-04-24 23:50:00 -04:00
|
|
|
{
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
|
2015-06-02 00:20:30 -04:00
|
|
|
|
2015-06-18 05:01:00 -04:00
|
|
|
if (me) {
|
2015-06-02 00:20:30 -04:00
|
|
|
if (idp) *idp = me->def->original_id;
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
if (klassp) *klassp = me->owner;
|
2015-06-18 05:01:00 -04:00
|
|
|
return TRUE;
|
2007-04-24 23:50:00 -04:00
|
|
|
}
|
2015-06-18 05:01:00 -04:00
|
|
|
else {
|
|
|
|
return FALSE;
|
2007-11-11 03:42:13 -05:00
|
|
|
}
|
2007-04-24 23:50:00 -04:00
|
|
|
}
|
|
|
|
|
2012-08-22 01:12:31 -04:00
|
|
|
int
|
|
|
|
rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp)
|
|
|
|
{
|
|
|
|
return rb_vm_control_frame_id_and_class(th->cfp, idp, klassp);
|
|
|
|
}
|
|
|
|
|
2007-12-25 03:49:09 -05:00
|
|
|
int
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_frame_method_id_and_class(ID *idp, VALUE *klassp)
|
2007-12-25 03:49:09 -05:00
|
|
|
{
|
|
|
|
return rb_thread_method_id_and_class(GET_THREAD(), idp, klassp);
|
|
|
|
}
|
|
|
|
|
2007-04-24 23:50:00 -04:00
|
|
|
VALUE
|
* 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_thread_current_status(const rb_thread_t *th)
|
2007-04-24 23:50:00 -04: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
|
|
|
const rb_control_frame_t *cfp = th->cfp;
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
const rb_callable_method_entry_t *me;
|
2007-04-24 23:50:00 -04:00
|
|
|
VALUE str = Qnil;
|
|
|
|
|
|
|
|
if (cfp->iseq != 0) {
|
|
|
|
if (cfp->pc != 0) {
|
2015-07-21 17:41:04 -04:00
|
|
|
const rb_iseq_t *iseq = cfp->iseq;
|
* 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
|
|
|
int line_no = rb_vm_get_sourceline(cfp);
|
2014-11-25 13:44:22 -05:00
|
|
|
str = rb_sprintf("%"PRIsVALUE":%d:in `%"PRIsVALUE"'",
|
2015-07-21 18:52:59 -04:00
|
|
|
iseq->body->location.path, line_no, iseq->body->location.label);
|
2007-04-24 23:50:00 -04:00
|
|
|
}
|
|
|
|
}
|
2015-06-02 00:20:30 -04:00
|
|
|
else if ((me = rb_vm_frame_method_entry(cfp)) && me->def->original_id) {
|
2014-11-25 13:44:22 -05:00
|
|
|
str = rb_sprintf("`%"PRIsVALUE"#%"PRIsVALUE"' (cfunc)",
|
* method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
[Bug #11278], [Bug #11279]
rb_method_entry_t data belong to modules/classes.
rb_method_entry_t::owner points defined module or class.
module M
def foo; end
end
In this case, owner is M.
rb_callable_method_entry_t data belong to only classes.
For modules, MRI creates corresponding T_ICLASS internally.
rb_callable_method_entry_t can also belong to T_ICLASS.
rb_callable_method_entry_t::defined_class points T_CLASS or
T_ICLASS.
rb_method_entry_t data for classes (not for modules) are also
rb_callable_method_entry_t data because it is completely same data.
In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
For example, there are classes C and D, and incldues M,
class C; include M; end
class D; include M; end
then, two T_ICLASS objects for C's super class and D's super class
will be created.
When C.new.foo is called, then M#foo is searcheed and
rb_callable_method_t data is used by VM to invoke M#foo.
rb_method_entry_t data is only one for M#foo.
However, rb_callable_method_entry_t data are two (and can be more).
It is proportional to the number of including (and prepending)
classes (the number of T_ICLASS which point to the module).
Now, created rb_callable_method_entry_t are collected when
the original module M was modified. We can think it is a cache.
We need to select what kind of method entry data is needed.
To operate definition, then you need to use rb_method_entry_t.
You can access them by the following functions.
* rb_method_entry(VALUE klass, ID id);
* rb_method_entry_with_refinements(VALUE klass, ID id);
* rb_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
To invoke methods, then you need to use rb_callable_method_entry_t
which you can get by the following APIs corresponding to the
above listed functions.
* rb_callable_method_entry(VALUE klass, ID id);
* rb_callable_method_entry_with_refinements(VALUE klass, ID id);
* rb_callable_method_entry_without_refinements(VALUE klass, ID id);
* rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
returns rb_callable_method_entry_t.
You can check a super class of current method by
rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
rb_callable_method_entry_t data.
We need to consider abotu this field again because it is only
active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
rb_callable_method_t has all information.
* vm_core.h: remove several fields.
* rb_control_frame_t::klass.
* rb_block_t::klass.
And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 07:24:50 -04:00
|
|
|
rb_class_path(me->owner),
|
2015-06-02 00:20:30 -04:00
|
|
|
rb_id2str(me->def->original_id));
|
2007-04-24 23:50:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
2007-06-18 04:02:30 -04:00
|
|
|
|
|
|
|
VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
2016-07-28 07:02:30 -04:00
|
|
|
VALUE block_handler, VALUE filename)
|
2007-06-18 04:02:30 -04:00
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
* 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
|
|
|
const rb_control_frame_t *reg_cfp = th->cfp;
|
2015-07-21 18:52:59 -04:00
|
|
|
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
2007-06-18 04:02:30 -04:00
|
|
|
VALUE val;
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH,
|
|
|
|
recv, block_handler,
|
2015-06-02 00:20:30 -04:00
|
|
|
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
2016-07-28 07:02:30 -04:00
|
|
|
0, reg_cfp->sp, 0, 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
|
|
|
|
2007-06-18 04:02:30 -04:00
|
|
|
val = (*func)(arg);
|
2007-06-24 16:33:04 -04:00
|
|
|
|
2016-07-26 06:28:21 -04:00
|
|
|
rb_vm_pop_frame(th);
|
2007-06-18 04:02:30 -04:00
|
|
|
return val;
|
|
|
|
}
|
* 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
|
|
|
|
|
|
|
/* vm */
|
|
|
|
|
2013-03-06 01:30:03 -05:00
|
|
|
void rb_vm_trace_mark_event_hooks(rb_hook_list_t *hooks);
|
* 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
|
|
|
|
|
|
|
void
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_vm_mark(void *ptr)
|
* 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
|
|
|
{
|
2014-07-16 06:16:34 -04:00
|
|
|
int i;
|
|
|
|
|
* 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
|
|
|
RUBY_MARK_ENTER("vm");
|
|
|
|
RUBY_GC_INFO("-------------------------------------------------\n");
|
|
|
|
if (ptr) {
|
|
|
|
rb_vm_t *vm = ptr;
|
2014-05-29 11:45:25 -04:00
|
|
|
rb_thread_t *th = 0;
|
2014-05-27 21:48:11 -04:00
|
|
|
|
|
|
|
list_for_each(&vm->living_threads, th, vmlt_node) {
|
|
|
|
rb_gc_mark(th->self);
|
|
|
|
}
|
2015-07-03 20:47:05 -04:00
|
|
|
rb_gc_mark(vm->thgroup_default);
|
|
|
|
rb_gc_mark(vm->mark_object_ary);
|
|
|
|
rb_gc_mark(vm->load_path);
|
|
|
|
rb_gc_mark(vm->load_path_snapshot);
|
2012-11-05 10:27:08 -05:00
|
|
|
RUBY_MARK_UNLESS_NULL(vm->load_path_check_cache);
|
2015-07-03 20:47:05 -04:00
|
|
|
rb_gc_mark(vm->expanded_load_path);
|
|
|
|
rb_gc_mark(vm->loaded_features);
|
|
|
|
rb_gc_mark(vm->loaded_features_snapshot);
|
|
|
|
rb_gc_mark(vm->top_self);
|
2008-07-03 08:55:12 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(vm->coverages);
|
2015-07-03 20:47:05 -04:00
|
|
|
rb_gc_mark(vm->defined_module_hash);
|
* 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
|
|
|
|
|
|
|
if (vm->loading_table) {
|
|
|
|
rb_mark_tbl(vm->loading_table);
|
|
|
|
}
|
|
|
|
|
2013-03-06 01:30:03 -05:00
|
|
|
rb_vm_trace_mark_event_hooks(&vm->event_hooks);
|
2014-07-16 06:16:34 -04:00
|
|
|
|
|
|
|
for (i = 0; i < RUBY_NSIG; i++) {
|
|
|
|
if (vm->trap_list[i].cmd)
|
|
|
|
rb_gc_mark(vm->trap_list[i].cmd);
|
|
|
|
}
|
* 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
|
|
|
}
|
|
|
|
|
|
|
|
RUBY_MARK_LEAVE("vm");
|
|
|
|
}
|
|
|
|
|
2014-09-11 06:53:48 -04:00
|
|
|
void
|
|
|
|
rb_vm_register_special_exception(enum ruby_special_exceptions sp, VALUE cls, const char *mesg)
|
|
|
|
{
|
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
VALUE exc = rb_exc_new3(cls, rb_obj_freeze(rb_str_new2(mesg)));
|
|
|
|
OBJ_TAINT(exc);
|
|
|
|
OBJ_FREEZE(exc);
|
|
|
|
((VALUE *)vm->special_exceptions)[sp] = exc;
|
|
|
|
rb_gc_register_mark_object(exc);
|
|
|
|
}
|
2013-10-11 14:27:18 -04:00
|
|
|
|
|
|
|
int
|
|
|
|
rb_vm_add_root_module(ID id, VALUE module)
|
|
|
|
{
|
|
|
|
rb_vm_t *vm = GET_VM();
|
2015-07-03 20:47:05 -04:00
|
|
|
|
|
|
|
rb_hash_aset(vm->defined_module_hash, ID2SYM(id), module);
|
|
|
|
|
2013-10-11 14:27:18 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2015-12-12 04:00:27 -05:00
|
|
|
static int
|
|
|
|
free_loading_table_entry(st_data_t key, st_data_t value, st_data_t arg)
|
|
|
|
{
|
|
|
|
xfree((char *)key);
|
|
|
|
return ST_DELETE;
|
|
|
|
}
|
|
|
|
|
2009-09-18 03:29:17 -04:00
|
|
|
int
|
2010-10-13 06:28:25 -04:00
|
|
|
ruby_vm_destruct(rb_vm_t *vm)
|
2009-06-16 18:23:53 -04:00
|
|
|
{
|
|
|
|
RUBY_FREE_ENTER("vm");
|
2014-06-02 04:17:55 -04:00
|
|
|
|
2010-10-13 06:28:25 -04:00
|
|
|
if (vm) {
|
2009-09-18 03:29:17 -04:00
|
|
|
rb_thread_t *th = vm->main_thread;
|
|
|
|
struct rb_objspace *objspace = vm->objspace;
|
|
|
|
vm->main_thread = 0;
|
|
|
|
if (th) {
|
2012-02-15 09:00:11 -05:00
|
|
|
rb_fiber_reset_root_local_storage(th->self);
|
2009-09-18 03:29:17 -04:00
|
|
|
thread_free(th);
|
|
|
|
}
|
vm*: doubly-linked list from ccan to manage vm->living_threads
A doubly-linked list for tracking living threads guarantees
constant-time insert/delete performance with no corner cases of a
hash table. I chose this ccan implementation of doubly-linked
lists over the BSD sys/queue.h implementation since:
1) insertion and removal are both branchless
2) locality is improved if a struct may be a member of multiple lists
(0002 patch in Feature 9632 will introduce a secondary list
for waiting FDs)
This also increases cache locality during iteration: improving
performance in a new IO#close benchmark with many sleeping threads
while still scanning the same number of threads.
vm_thread_close 1.762
* vm_core.h (rb_vm_t): list_head and counter for living_threads
(rb_thread_t): vmlt_node for living_threads linkage
(rb_vm_living_threads_init): new function wrapper
(rb_vm_living_threads_insert): ditto
(rb_vm_living_threads_remove): ditto
* vm.c (rb_vm_living_threads_foreach): new function wrapper
* thread.c (terminate_i, thread_start_func_2, thread_create_core,
thread_fd_close_i, thread_fd_close): update to use new APIs
* vm.c (vm_mark_each_thread_func, rb_vm_mark, ruby_vm_destruct,
vm_memsize, vm_init2, Init_VM): ditto
* vm_trace.c (clear_trace_func_i, rb_clear_trace_func): ditto
* benchmark/bm_vm_thread_close.rb: added to show improvement
* ccan/build_assert/build_assert.h: added as a dependency of list.h
* ccan/check_type/check_type.h: ditto
* ccan/container_of/container_of.h: ditto
* ccan/licenses/BSD-MIT: ditto
* ccan/licenses/CC0: ditto
* ccan/str/str.h: ditto (stripped of unused macros)
* ccan/list/list.h: ditto
* common.mk: add CCAN_LIST_INCLUDES
[ruby-core:61871][Feature 9632 (part 1)]
Apologies for the size of this commit, but I think a good
doubly-linked list will be useful for future features, too.
This may be used to add ordering to a container_of-based hash
table to preserve compatibility if required (e.g. feature 9614).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-10 19:48:51 -04:00
|
|
|
rb_vm_living_threads_init(vm);
|
2013-11-21 20:38:08 -05:00
|
|
|
ruby_vm_run_at_exit_hooks(vm);
|
2015-12-12 04:00:27 -05:00
|
|
|
if (vm->loading_table) {
|
|
|
|
st_foreach(vm->loading_table, free_loading_table_entry, 0);
|
|
|
|
st_free_table(vm->loading_table);
|
|
|
|
vm->loading_table = 0;
|
|
|
|
}
|
|
|
|
if (vm->frozen_strings) {
|
|
|
|
st_free_table(vm->frozen_strings);
|
|
|
|
vm->frozen_strings = 0;
|
|
|
|
}
|
2013-11-21 20:38:08 -05:00
|
|
|
rb_vm_gvl_destroy(vm);
|
2009-09-18 03:29:17 -04:00
|
|
|
if (objspace) {
|
|
|
|
rb_objspace_free(objspace);
|
|
|
|
}
|
2013-11-21 20:38:08 -05:00
|
|
|
/* after freeing objspace, you *can't* use ruby_xfree() */
|
|
|
|
ruby_mimfree(vm);
|
2010-12-02 22:53:21 -05:00
|
|
|
ruby_current_vm = 0;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
RUBY_FREE_LEAVE("vm");
|
2009-09-18 03:29:17 -04:00
|
|
|
return 0;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static size_t
|
2009-09-08 22:11:35 -04:00
|
|
|
vm_memsize(const void *ptr)
|
2009-06-16 18:23:53 -04:00
|
|
|
{
|
2015-12-08 19:38:32 -05:00
|
|
|
const rb_vm_t *vmobj = ptr;
|
|
|
|
size_t size = sizeof(rb_vm_t);
|
vm*: doubly-linked list from ccan to manage vm->living_threads
A doubly-linked list for tracking living threads guarantees
constant-time insert/delete performance with no corner cases of a
hash table. I chose this ccan implementation of doubly-linked
lists over the BSD sys/queue.h implementation since:
1) insertion and removal are both branchless
2) locality is improved if a struct may be a member of multiple lists
(0002 patch in Feature 9632 will introduce a secondary list
for waiting FDs)
This also increases cache locality during iteration: improving
performance in a new IO#close benchmark with many sleeping threads
while still scanning the same number of threads.
vm_thread_close 1.762
* vm_core.h (rb_vm_t): list_head and counter for living_threads
(rb_thread_t): vmlt_node for living_threads linkage
(rb_vm_living_threads_init): new function wrapper
(rb_vm_living_threads_insert): ditto
(rb_vm_living_threads_remove): ditto
* vm.c (rb_vm_living_threads_foreach): new function wrapper
* thread.c (terminate_i, thread_start_func_2, thread_create_core,
thread_fd_close_i, thread_fd_close): update to use new APIs
* vm.c (vm_mark_each_thread_func, rb_vm_mark, ruby_vm_destruct,
vm_memsize, vm_init2, Init_VM): ditto
* vm_trace.c (clear_trace_func_i, rb_clear_trace_func): ditto
* benchmark/bm_vm_thread_close.rb: added to show improvement
* ccan/build_assert/build_assert.h: added as a dependency of list.h
* ccan/check_type/check_type.h: ditto
* ccan/container_of/container_of.h: ditto
* ccan/licenses/BSD-MIT: ditto
* ccan/licenses/CC0: ditto
* ccan/str/str.h: ditto (stripped of unused macros)
* ccan/list/list.h: ditto
* common.mk: add CCAN_LIST_INCLUDES
[ruby-core:61871][Feature 9632 (part 1)]
Apologies for the size of this commit, but I think a good
doubly-linked list will be useful for future features, too.
This may be used to add ordering to a container_of-based hash
table to preserve compatibility if required (e.g. feature 9614).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-10 19:48:51 -04:00
|
|
|
|
2015-12-08 19:38:32 -05:00
|
|
|
size += vmobj->living_thread_num * sizeof(rb_thread_t);
|
vm*: doubly-linked list from ccan to manage vm->living_threads
A doubly-linked list for tracking living threads guarantees
constant-time insert/delete performance with no corner cases of a
hash table. I chose this ccan implementation of doubly-linked
lists over the BSD sys/queue.h implementation since:
1) insertion and removal are both branchless
2) locality is improved if a struct may be a member of multiple lists
(0002 patch in Feature 9632 will introduce a secondary list
for waiting FDs)
This also increases cache locality during iteration: improving
performance in a new IO#close benchmark with many sleeping threads
while still scanning the same number of threads.
vm_thread_close 1.762
* vm_core.h (rb_vm_t): list_head and counter for living_threads
(rb_thread_t): vmlt_node for living_threads linkage
(rb_vm_living_threads_init): new function wrapper
(rb_vm_living_threads_insert): ditto
(rb_vm_living_threads_remove): ditto
* vm.c (rb_vm_living_threads_foreach): new function wrapper
* thread.c (terminate_i, thread_start_func_2, thread_create_core,
thread_fd_close_i, thread_fd_close): update to use new APIs
* vm.c (vm_mark_each_thread_func, rb_vm_mark, ruby_vm_destruct,
vm_memsize, vm_init2, Init_VM): ditto
* vm_trace.c (clear_trace_func_i, rb_clear_trace_func): ditto
* benchmark/bm_vm_thread_close.rb: added to show improvement
* ccan/build_assert/build_assert.h: added as a dependency of list.h
* ccan/check_type/check_type.h: ditto
* ccan/container_of/container_of.h: ditto
* ccan/licenses/BSD-MIT: ditto
* ccan/licenses/CC0: ditto
* ccan/str/str.h: ditto (stripped of unused macros)
* ccan/list/list.h: ditto
* common.mk: add CCAN_LIST_INCLUDES
[ruby-core:61871][Feature 9632 (part 1)]
Apologies for the size of this commit, but I think a good
doubly-linked list will be useful for future features, too.
This may be used to add ordering to a container_of-based hash
table to preserve compatibility if required (e.g. feature 9614).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-10 19:48:51 -04:00
|
|
|
|
2015-12-08 19:38:32 -05:00
|
|
|
if (vmobj->defined_strings) {
|
|
|
|
size += DEFINED_EXPR * sizeof(VALUE);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
2015-12-08 19:38:32 -05:00
|
|
|
return size;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
|
2009-07-07 02:23:39 -04:00
|
|
|
static const rb_data_type_t vm_data_type = {
|
2009-06-16 18:23:53 -04:00
|
|
|
"VM",
|
2014-07-16 05:06:52 -04:00
|
|
|
{NULL, NULL, vm_memsize,},
|
2014-12-01 01:38:04 -05:00
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
2009-06-16 18:23:53 -04:00
|
|
|
};
|
|
|
|
|
2012-12-19 17:29:18 -05:00
|
|
|
|
|
|
|
static VALUE
|
|
|
|
vm_default_params(void)
|
|
|
|
{
|
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
VALUE result = rb_hash_new();
|
|
|
|
#define SET(name) rb_hash_aset(result, ID2SYM(rb_intern(#name)), SIZET2NUM(vm->default_params.name));
|
|
|
|
SET(thread_vm_stack_size);
|
|
|
|
SET(thread_machine_stack_size);
|
|
|
|
SET(fiber_vm_stack_size);
|
|
|
|
SET(fiber_machine_stack_size);
|
|
|
|
#undef SET
|
|
|
|
rb_obj_freeze(result);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t
|
|
|
|
get_param(const char *name, size_t default_value, size_t min_value)
|
|
|
|
{
|
|
|
|
const char *envval;
|
|
|
|
size_t result = default_value;
|
|
|
|
if ((envval = getenv(name)) != 0) {
|
|
|
|
long val = atol(envval);
|
|
|
|
if (val < (long)min_value) {
|
|
|
|
val = (long)min_value;
|
|
|
|
}
|
|
|
|
result = (size_t)(((val -1 + RUBY_VM_SIZE_ALIGN) / RUBY_VM_SIZE_ALIGN) * RUBY_VM_SIZE_ALIGN);
|
|
|
|
}
|
2012-12-19 20:52:50 -05:00
|
|
|
if (0) fprintf(stderr, "%s: %"PRIdSIZE"\n", name, result); /* debug print */
|
2012-12-19 17:29:18 -05:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
check_machine_stack_size(size_t *sizep)
|
|
|
|
{
|
2012-12-27 22:03:19 -05:00
|
|
|
#ifdef PTHREAD_STACK_MIN
|
2012-12-19 17:29:18 -05:00
|
|
|
size_t size = *sizep;
|
2012-12-27 22:03:19 -05:00
|
|
|
#endif
|
|
|
|
|
2012-12-19 17:29:18 -05:00
|
|
|
#ifdef PTHREAD_STACK_MIN
|
|
|
|
if (size < PTHREAD_STACK_MIN) {
|
|
|
|
*sizep = PTHREAD_STACK_MIN * 2;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vm_default_params_setup(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
vm->default_params.thread_vm_stack_size =
|
|
|
|
get_param("RUBY_THREAD_VM_STACK_SIZE",
|
|
|
|
RUBY_VM_THREAD_VM_STACK_SIZE,
|
|
|
|
RUBY_VM_THREAD_VM_STACK_SIZE_MIN);
|
|
|
|
|
|
|
|
vm->default_params.thread_machine_stack_size =
|
|
|
|
get_param("RUBY_THREAD_MACHINE_STACK_SIZE",
|
|
|
|
RUBY_VM_THREAD_MACHINE_STACK_SIZE,
|
|
|
|
RUBY_VM_THREAD_MACHINE_STACK_SIZE_MIN);
|
|
|
|
|
|
|
|
vm->default_params.fiber_vm_stack_size =
|
|
|
|
get_param("RUBY_FIBER_VM_STACK_SIZE",
|
|
|
|
RUBY_VM_FIBER_VM_STACK_SIZE,
|
|
|
|
RUBY_VM_FIBER_VM_STACK_SIZE_MIN);
|
|
|
|
|
|
|
|
vm->default_params.fiber_machine_stack_size =
|
|
|
|
get_param("RUBY_FIBER_MACHINE_STACK_SIZE",
|
|
|
|
RUBY_VM_FIBER_MACHINE_STACK_SIZE,
|
|
|
|
RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN);
|
|
|
|
|
|
|
|
/* environment dependent check */
|
|
|
|
check_machine_stack_size(&vm->default_params.thread_machine_stack_size);
|
|
|
|
check_machine_stack_size(&vm->default_params.fiber_machine_stack_size);
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
static void
|
2008-05-22 12:19:14 -04:00
|
|
|
vm_init2(rb_vm_t *vm)
|
* 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
|
|
|
{
|
|
|
|
MEMZERO(vm, rb_vm_t, 1);
|
vm*: doubly-linked list from ccan to manage vm->living_threads
A doubly-linked list for tracking living threads guarantees
constant-time insert/delete performance with no corner cases of a
hash table. I chose this ccan implementation of doubly-linked
lists over the BSD sys/queue.h implementation since:
1) insertion and removal are both branchless
2) locality is improved if a struct may be a member of multiple lists
(0002 patch in Feature 9632 will introduce a secondary list
for waiting FDs)
This also increases cache locality during iteration: improving
performance in a new IO#close benchmark with many sleeping threads
while still scanning the same number of threads.
vm_thread_close 1.762
* vm_core.h (rb_vm_t): list_head and counter for living_threads
(rb_thread_t): vmlt_node for living_threads linkage
(rb_vm_living_threads_init): new function wrapper
(rb_vm_living_threads_insert): ditto
(rb_vm_living_threads_remove): ditto
* vm.c (rb_vm_living_threads_foreach): new function wrapper
* thread.c (terminate_i, thread_start_func_2, thread_create_core,
thread_fd_close_i, thread_fd_close): update to use new APIs
* vm.c (vm_mark_each_thread_func, rb_vm_mark, ruby_vm_destruct,
vm_memsize, vm_init2, Init_VM): ditto
* vm_trace.c (clear_trace_func_i, rb_clear_trace_func): ditto
* benchmark/bm_vm_thread_close.rb: added to show improvement
* ccan/build_assert/build_assert.h: added as a dependency of list.h
* ccan/check_type/check_type.h: ditto
* ccan/container_of/container_of.h: ditto
* ccan/licenses/BSD-MIT: ditto
* ccan/licenses/CC0: ditto
* ccan/str/str.h: ditto (stripped of unused macros)
* ccan/list/list.h: ditto
* common.mk: add CCAN_LIST_INCLUDES
[ruby-core:61871][Feature 9632 (part 1)]
Apologies for the size of this commit, but I think a good
doubly-linked list will be useful for future features, too.
This may be used to add ordering to a container_of-based hash
table to preserve compatibility if required (e.g. feature 9614).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-10 19:48:51 -04:00
|
|
|
rb_vm_living_threads_init(vm);
|
2008-06-09 00:20:07 -04:00
|
|
|
vm->src_encoding_index = -1;
|
2012-12-19 17:29:18 -05:00
|
|
|
|
|
|
|
vm_default_params_setup(vm);
|
* 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
|
|
|
}
|
|
|
|
|
|
|
|
/* Thread */
|
|
|
|
|
2007-11-21 04:06:06 -05:00
|
|
|
#define USE_THREAD_DATA_RECYCLE 1
|
|
|
|
|
|
|
|
#if USE_THREAD_DATA_RECYCLE
|
|
|
|
#define RECYCLE_MAX 64
|
2008-09-04 13:58:53 -04:00
|
|
|
static VALUE *thread_recycle_stack_slot[RECYCLE_MAX];
|
|
|
|
static int thread_recycle_stack_count = 0;
|
2007-11-21 04:06:06 -05:00
|
|
|
|
|
|
|
static VALUE *
|
2009-05-17 00:15:33 -04:00
|
|
|
thread_recycle_stack(size_t size)
|
2007-11-21 04:06:06 -05:00
|
|
|
{
|
|
|
|
if (thread_recycle_stack_count) {
|
2012-12-19 17:29:18 -05:00
|
|
|
/* TODO: check stack size if stack sizes are variable */
|
2007-11-21 04:06:06 -05:00
|
|
|
return thread_recycle_stack_slot[--thread_recycle_stack_count];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return ALLOC_N(VALUE, size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define thread_recycle_stack(size) ALLOC_N(VALUE, (size))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_recycle_stack_release(VALUE *stack)
|
2007-11-21 04:06:06 -05:00
|
|
|
{
|
|
|
|
#if USE_THREAD_DATA_RECYCLE
|
|
|
|
if (thread_recycle_stack_count < RECYCLE_MAX) {
|
|
|
|
thread_recycle_stack_slot[thread_recycle_stack_count++] = stack;
|
2008-06-08 22:58:23 -04:00
|
|
|
return;
|
2007-11-21 04:06:06 -05:00
|
|
|
}
|
|
|
|
#endif
|
2008-06-08 22:58:23 -04:00
|
|
|
ruby_xfree(stack);
|
2007-11-21 04:06:06 -05:00
|
|
|
}
|
|
|
|
|
2014-10-15 18:35:08 -04:00
|
|
|
void rb_fiber_mark_self(rb_fiber_t *fib);
|
|
|
|
|
* 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
|
|
|
void
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_mark(void *ptr)
|
* 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
|
|
|
{
|
2015-07-15 04:29:22 -04:00
|
|
|
rb_thread_t *th = ptr;
|
* 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
|
|
|
RUBY_MARK_ENTER("thread");
|
2015-07-15 04:29:22 -04:00
|
|
|
|
|
|
|
if (th->stack) {
|
|
|
|
VALUE *p = th->stack;
|
|
|
|
VALUE *sp = th->cfp->sp;
|
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
|
|
|
rb_control_frame_t *limit_cfp = (void *)(th->stack + th->stack_size);
|
|
|
|
|
|
|
|
rb_gc_mark_values((long)(sp - p), p);
|
|
|
|
|
|
|
|
while (cfp != limit_cfp) {
|
2016-07-28 07:02:30 -04:00
|
|
|
#if VM_CHECK_MODE > 0
|
|
|
|
const VALUE *ep = cfp->ep;
|
|
|
|
VM_ASSERT(!!VM_ENV_FLAGS(ep, VM_ENV_FLAG_ESCAPED) == vm_ep_in_heap_p_(th, ep));
|
|
|
|
#endif
|
2015-07-15 04:29:22 -04:00
|
|
|
rb_gc_mark(cfp->self);
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_gc_mark((VALUE)cfp->iseq);
|
2016-07-28 07:02:30 -04:00
|
|
|
rb_gc_mark((VALUE)cfp->block_code);
|
|
|
|
|
2015-07-15 04:29:22 -04:00
|
|
|
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
* 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
|
|
|
}
|
2015-07-15 04:29:22 -04:00
|
|
|
}
|
* 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
|
|
|
|
2015-07-15 04:29:22 -04:00
|
|
|
/* mark ruby objects */
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->first_proc);
|
|
|
|
if (th->first_proc) RUBY_MARK_UNLESS_NULL(th->first_args);
|
|
|
|
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->thgroup);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->value);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->errinfo);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->pending_interrupt_queue);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->pending_interrupt_mask_stack);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->root_svar);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->top_self);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->top_wrapper);
|
|
|
|
rb_fiber_mark_self(th->fiber);
|
|
|
|
rb_fiber_mark_self(th->root_fiber);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->stat_insn_usage);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->last_status);
|
* 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
|
|
|
|
2015-07-15 04:29:22 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(th->locking_mutex);
|
2015-06-13 07:17:04 -04:00
|
|
|
|
2015-07-15 04:29:22 -04:00
|
|
|
rb_mark_tbl(th->local_storage);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->local_storage_recursive_hash);
|
|
|
|
RUBY_MARK_UNLESS_NULL(th->local_storage_recursive_hash_for_trace);
|
|
|
|
|
|
|
|
if (GET_THREAD() != th && th->machine.stack_start && th->machine.stack_end) {
|
|
|
|
rb_gc_mark_machine_stack(th);
|
|
|
|
rb_gc_mark_locations((VALUE *)&th->machine.regs,
|
|
|
|
(VALUE *)(&th->machine.regs) +
|
|
|
|
sizeof(th->machine.regs) / sizeof(VALUE));
|
* 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
|
|
|
}
|
|
|
|
|
2015-07-15 04:29:22 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(th->name);
|
|
|
|
|
|
|
|
rb_vm_trace_mark_event_hooks(&th->event_hooks);
|
|
|
|
|
* 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
|
|
|
RUBY_MARK_LEAVE("thread");
|
|
|
|
}
|
|
|
|
|
2009-06-16 18:23:53 -04:00
|
|
|
static void
|
|
|
|
thread_free(void *ptr)
|
|
|
|
{
|
|
|
|
rb_thread_t *th;
|
|
|
|
RUBY_FREE_ENTER("thread");
|
|
|
|
|
|
|
|
if (ptr) {
|
|
|
|
th = ptr;
|
|
|
|
|
|
|
|
if (!th->root_fiber) {
|
|
|
|
RUBY_FREE_UNLESS_NULL(th->stack);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (th->locking_mutex != Qfalse) {
|
2010-10-13 10:07:22 -04:00
|
|
|
rb_bug("thread_free: locking_mutex must be NULL (%p:%p)", (void *)th, (void *)th->locking_mutex);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
if (th->keeping_mutexes != NULL) {
|
2010-06-17 21:44:52 -04:00
|
|
|
rb_bug("thread_free: keeping_mutexes must be NULL (%p:%p)", (void *)th, (void *)th->keeping_mutexes);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (th->local_storage) {
|
|
|
|
st_free_table(th->local_storage);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (th->vm && th->vm->main_thread == th) {
|
|
|
|
RUBY_GC_INFO("main thread\n");
|
|
|
|
}
|
|
|
|
else {
|
2010-07-05 11:57:20 -04:00
|
|
|
#ifdef USE_SIGALTSTACK
|
|
|
|
if (th->altstack) {
|
2011-08-02 09:08:45 -04:00
|
|
|
free(th->altstack);
|
2010-07-05 11:57:20 -04:00
|
|
|
}
|
|
|
|
#endif
|
2012-01-09 22:49:10 -05:00
|
|
|
ruby_xfree(ptr);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
2011-01-12 05:35:36 -05:00
|
|
|
if (ruby_current_thread == th)
|
|
|
|
ruby_current_thread = NULL;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
RUBY_FREE_LEAVE("thread");
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t
|
2009-09-08 22:11:35 -04:00
|
|
|
thread_memsize(const void *ptr)
|
2009-06-16 18:23:53 -04:00
|
|
|
{
|
2015-12-08 19:38:32 -05:00
|
|
|
const rb_thread_t *th = ptr;
|
|
|
|
size_t size = sizeof(rb_thread_t);
|
2009-06-16 18:23:53 -04:00
|
|
|
|
2015-12-08 19:38:32 -05:00
|
|
|
if (!th->root_fiber) {
|
|
|
|
size += th->stack_size * sizeof(VALUE);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
2015-12-08 19:38:32 -05:00
|
|
|
if (th->local_storage) {
|
|
|
|
size += st_memsize(th->local_storage);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
2015-12-08 19:38:32 -05:00
|
|
|
return size;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
|
2011-08-16 05:56:56 -04:00
|
|
|
#define thread_data_type ruby_threadptr_data_type
|
|
|
|
const rb_data_type_t ruby_threadptr_data_type = {
|
2009-06-16 18:23:53 -04:00
|
|
|
"VM/thread",
|
2010-07-18 03:31:54 -04:00
|
|
|
{
|
|
|
|
rb_thread_mark,
|
|
|
|
thread_free,
|
|
|
|
thread_memsize,
|
|
|
|
},
|
2014-12-01 01:38:04 -05:00
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
2009-06-16 18:23:53 -04:00
|
|
|
};
|
|
|
|
|
2011-06-09 10:45:56 -04:00
|
|
|
VALUE
|
|
|
|
rb_obj_is_thread(VALUE obj)
|
|
|
|
{
|
|
|
|
if (rb_typeddata_is_kind_of(obj, &thread_data_type)) {
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
thread_alloc(VALUE klass)
|
* 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
|
|
|
{
|
2014-09-12 17:34:25 -04:00
|
|
|
VALUE obj;
|
* 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
|
|
|
rb_thread_t *th;
|
2009-07-07 16:28:27 -04:00
|
|
|
obj = TypedData_Make_Struct(klass, rb_thread_t, &thread_data_type, th);
|
2014-09-04 17:05:31 -04:00
|
|
|
|
* 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
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-02-12 00:42:17 -05:00
|
|
|
th_init(rb_thread_t *th, VALUE self)
|
* 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
|
|
|
{
|
2008-06-13 22:59:19 -04:00
|
|
|
th->self = self;
|
|
|
|
|
* 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
|
|
|
/* allocate thread stack */
|
2011-07-29 21:57:06 -04:00
|
|
|
#ifdef USE_SIGALTSTACK
|
2011-08-02 09:08:45 -04:00
|
|
|
/* altstack of main thread is reallocated in another place */
|
2012-12-15 09:20:12 -05:00
|
|
|
th->altstack = malloc(rb_sigaltstack_size());
|
2011-07-29 21:57:06 -04:00
|
|
|
#endif
|
2012-12-19 17:29:18 -05:00
|
|
|
/* th->stack_size is word number.
|
|
|
|
* th->vm->default_params.thread_vm_stack_size is byte size.
|
|
|
|
*/
|
|
|
|
th->stack_size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
|
2007-11-21 04:06:06 -05:00
|
|
|
th->stack = thread_recycle_stack(th->stack_size);
|
* 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
|
|
|
|
|
|
|
th->cfp = (void *)(th->stack + th->stack_size);
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH /* dummy frame */,
|
|
|
|
Qnil /* dummy self */, VM_BLOCK_HANDLER_NONE /* dummy block ptr */,
|
2015-06-02 00:20:30 -04:00
|
|
|
0 /* dummy cref/me */,
|
2016-07-28 07:02:30 -04:00
|
|
|
0 /* dummy pc */, th->stack, 0, 0);
|
* 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
|
|
|
|
|
|
|
th->status = THREAD_RUNNABLE;
|
|
|
|
th->errinfo = Qnil;
|
2008-07-09 23:10:00 -04:00
|
|
|
th->last_status = Qnil;
|
2011-02-12 00:42:17 -05:00
|
|
|
th->waiting_fd = -1;
|
2015-06-02 00:20:30 -04:00
|
|
|
th->root_svar = Qfalse;
|
2014-11-26 20:56:38 -05:00
|
|
|
th->local_storage_recursive_hash = Qnil;
|
2014-12-10 14:35:07 -05:00
|
|
|
th->local_storage_recursive_hash_for_trace = Qnil;
|
2014-06-11 04:38:09 -04:00
|
|
|
#ifdef NON_SCALAR_THREAD_ID
|
|
|
|
th->thread_id_string[0] = '\0';
|
|
|
|
#endif
|
2012-08-07 07:13:57 -04:00
|
|
|
|
|
|
|
#if OPT_CALL_THREADED_CODE
|
|
|
|
th->retval = Qundef;
|
|
|
|
#endif
|
2015-06-13 04:39:30 -04:00
|
|
|
th->name = Qnil;
|
* 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
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
ruby_thread_init(VALUE self)
|
* 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
|
|
|
{
|
|
|
|
rb_thread_t *th;
|
|
|
|
rb_vm_t *vm = GET_THREAD()->vm;
|
|
|
|
GetThreadPtr(self, th);
|
|
|
|
|
2012-12-19 17:29:18 -05:00
|
|
|
th->vm = vm;
|
2008-06-13 22:59:19 -04:00
|
|
|
th_init(th, self);
|
2013-05-02 03:55:50 -04:00
|
|
|
rb_ivar_set(self, rb_intern("locals"), rb_hash_new());
|
* 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
|
|
|
|
|
|
|
th->top_wrapper = 0;
|
|
|
|
th->top_self = rb_vm_top_self();
|
2015-06-02 00:20:30 -04:00
|
|
|
th->root_svar = Qfalse;
|
* 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
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_thread_alloc(VALUE klass)
|
* 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
|
|
|
{
|
|
|
|
VALUE self = thread_alloc(klass);
|
|
|
|
ruby_thread_init(self);
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2008-08-12 05:59:06 -04:00
|
|
|
static void
|
2015-11-13 13:01:59 -05:00
|
|
|
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, int is_singleton)
|
2008-08-12 05:59:06 -04:00
|
|
|
{
|
2015-11-13 12:38:12 -05:00
|
|
|
VALUE klass;
|
|
|
|
rb_method_visibility_t visi;
|
2015-11-13 13:01:59 -05:00
|
|
|
rb_cref_t *cref = rb_vm_cref();
|
2008-08-12 05:59:06 -04:00
|
|
|
|
2015-11-13 12:38:12 -05:00
|
|
|
if (!is_singleton) {
|
2015-11-13 13:01:59 -05:00
|
|
|
klass = CREF_CLASS(cref);
|
2015-11-13 12:38:12 -05:00
|
|
|
visi = rb_scope_visibility_get();
|
2008-08-12 05:59:06 -04:00
|
|
|
}
|
2015-11-13 12:38:12 -05:00
|
|
|
else { /* singleton */
|
2012-10-27 15:47:58 -04:00
|
|
|
klass = rb_singleton_class(obj); /* class and frozen checked in this API */
|
2015-06-02 21:39:16 -04:00
|
|
|
visi = METHOD_VISI_PUBLIC;
|
2008-08-12 05:59:06 -04:00
|
|
|
}
|
|
|
|
|
2015-11-13 12:38:12 -05:00
|
|
|
if (NIL_P(klass)) {
|
|
|
|
rb_raise(rb_eTypeError, "no class/module to add method");
|
|
|
|
}
|
|
|
|
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
|
2008-08-12 05:59:06 -04:00
|
|
|
|
2015-11-13 12:38:12 -05:00
|
|
|
if (!is_singleton && rb_scope_module_func_check()) {
|
* class.c, compile.c, eval.c, gc.h, insns.def, internal.h, method.h,
variable.c, vm.c, vm_core.c, vm_insnhelper.c, vm_insnhelper.h,
vm_method.c: Implement class hierarchy method cache invalidation.
[ruby-core:55053] [Feature #8426] [GH-387]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42822 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-04 01:25:06 -04:00
|
|
|
klass = rb_singleton_class(klass);
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, METHOD_VISI_PUBLIC);
|
2008-08-12 05:59:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-13 00:49:37 -04:00
|
|
|
#define REWIND_CFP(expr) do { \
|
|
|
|
rb_thread_t *th__ = GET_THREAD(); \
|
2015-07-16 01:34:27 -04:00
|
|
|
VALUE *const curr_sp = (th__->cfp++)->sp; \
|
|
|
|
VALUE *const saved_sp = th__->cfp->sp; \
|
|
|
|
th__->cfp->sp = curr_sp; \
|
|
|
|
expr; \
|
|
|
|
(th__->cfp--)->sp = saved_sp; \
|
2008-08-13 00:49:37 -04:00
|
|
|
} while (0)
|
|
|
|
|
2008-06-30 23:05:58 -04:00
|
|
|
static VALUE
|
2015-11-13 13:01:59 -05:00
|
|
|
m_core_define_method(VALUE self, VALUE sym, VALUE iseqval)
|
2008-06-30 23:05:58 -04:00
|
|
|
{
|
2008-08-13 00:49:37 -04:00
|
|
|
REWIND_CFP({
|
2015-11-13 13:01:59 -05:00
|
|
|
vm_define_method(GET_THREAD(), Qnil, SYM2ID(sym), iseqval, FALSE);
|
2008-08-13 00:49:37 -04:00
|
|
|
});
|
2013-08-02 10:58:11 -04:00
|
|
|
return sym;
|
2008-06-30 23:05:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
m_core_define_singleton_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval)
|
|
|
|
{
|
2008-08-13 00:49:37 -04:00
|
|
|
REWIND_CFP({
|
2015-11-13 13:01:59 -05:00
|
|
|
vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, TRUE);
|
2008-08-13 00:49:37 -04:00
|
|
|
});
|
2013-08-02 10:58:11 -04:00
|
|
|
return sym;
|
2008-06-30 23:05:58 -04:00
|
|
|
}
|
|
|
|
|
2008-07-01 08:19:00 -04:00
|
|
|
static VALUE
|
2008-08-13 00:49:37 -04:00
|
|
|
m_core_set_method_alias(VALUE self, VALUE cbase, VALUE sym1, VALUE sym2)
|
2008-07-01 08:19:00 -04:00
|
|
|
{
|
2008-08-13 00:49:37 -04:00
|
|
|
REWIND_CFP({
|
|
|
|
rb_alias(cbase, SYM2ID(sym1), SYM2ID(sym2));
|
|
|
|
});
|
|
|
|
return Qnil;
|
|
|
|
}
|
2008-07-01 08:19:00 -04:00
|
|
|
|
2008-08-13 00:49:37 -04:00
|
|
|
static VALUE
|
|
|
|
m_core_set_variable_alias(VALUE self, VALUE sym1, VALUE sym2)
|
|
|
|
{
|
|
|
|
REWIND_CFP({
|
|
|
|
rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
|
|
|
|
});
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
m_core_undef_method(VALUE self, VALUE cbase, VALUE sym)
|
|
|
|
{
|
|
|
|
REWIND_CFP({
|
|
|
|
rb_undef(cbase, SYM2ID(sym));
|
* 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(self);
|
2008-08-13 00:49:37 -04:00
|
|
|
});
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2013-08-22 02:50:42 -04:00
|
|
|
m_core_set_postexe(VALUE self)
|
2008-08-13 00:49:37 -04:00
|
|
|
{
|
2013-08-22 02:50:42 -04:00
|
|
|
rb_set_end_proc(rb_call_end_proc, rb_block_proc());
|
2008-07-01 08:19:00 -04:00
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2014-05-21 02:11:25 -04:00
|
|
|
static VALUE core_hash_merge_ary(VALUE hash, VALUE ary);
|
|
|
|
static VALUE core_hash_from_ary(VALUE ary);
|
|
|
|
static VALUE core_hash_merge_kwd(int argc, VALUE *argv);
|
2014-03-24 11:28:30 -04:00
|
|
|
|
2014-03-24 11:28:31 -04:00
|
|
|
static VALUE
|
|
|
|
core_hash_merge(VALUE hash, long argc, const VALUE *argv)
|
|
|
|
{
|
|
|
|
long i;
|
|
|
|
|
2015-06-10 19:42:01 -04:00
|
|
|
VM_ASSERT(argc % 2 == 0);
|
2014-03-24 11:28:31 -04:00
|
|
|
for (i=0; i<argc; i+=2) {
|
|
|
|
rb_hash_aset(hash, argv[i], argv[i+1]);
|
|
|
|
}
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2012-04-11 21:33:34 -04:00
|
|
|
static VALUE
|
|
|
|
m_core_hash_from_ary(VALUE self, VALUE ary)
|
2014-05-21 02:11:25 -04:00
|
|
|
{
|
|
|
|
VALUE hash;
|
|
|
|
REWIND_CFP(hash = core_hash_from_ary(ary));
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
core_hash_from_ary(VALUE ary)
|
2012-04-11 21:33:34 -04:00
|
|
|
{
|
|
|
|
VALUE hash = rb_hash_new();
|
|
|
|
|
2015-10-29 01:32:57 -04:00
|
|
|
RUBY_DTRACE_CREATE_HOOK(HASH, RARRAY_LEN(ary));
|
2014-05-21 02:11:25 -04:00
|
|
|
return core_hash_merge_ary(hash, ary);
|
2012-04-11 21:33:34 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
m_core_hash_merge_ary(VALUE self, VALUE hash, VALUE ary)
|
2014-05-21 02:11:25 -04:00
|
|
|
{
|
|
|
|
REWIND_CFP(core_hash_merge_ary(hash, ary));
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
core_hash_merge_ary(VALUE hash, VALUE ary)
|
2012-04-11 21:33:34 -04:00
|
|
|
{
|
2014-03-24 11:28:31 -04:00
|
|
|
core_hash_merge(hash, RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
|
2012-04-11 21:33:34 -04:00
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
m_core_hash_merge_ptr(int argc, VALUE *argv, VALUE recv)
|
|
|
|
{
|
|
|
|
VALUE hash = argv[0];
|
2015-07-16 01:34:27 -04:00
|
|
|
|
|
|
|
REWIND_CFP(core_hash_merge(hash, argc-1, argv+1));
|
2012-04-11 21:33:34 -04:00
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2012-04-28 17:12:05 -04:00
|
|
|
static int
|
|
|
|
kwmerge_i(VALUE key, VALUE value, VALUE hash)
|
|
|
|
{
|
2016-07-23 09:43:44 -04:00
|
|
|
Check_Type(key, T_SYMBOL);
|
2014-10-11 00:46:56 -04:00
|
|
|
rb_hash_aset(hash, key, value);
|
2012-04-28 17:12:05 -04:00
|
|
|
return ST_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2013-10-12 23:16:54 -04:00
|
|
|
static int
|
|
|
|
kwcheck_i(VALUE key, VALUE value, VALUE hash)
|
|
|
|
{
|
2016-07-23 09:43:44 -04:00
|
|
|
Check_Type(key, T_SYMBOL);
|
2013-10-12 23:16:54 -04:00
|
|
|
return ST_CONTINUE;
|
|
|
|
}
|
|
|
|
|
2012-04-28 17:12:05 -04:00
|
|
|
static VALUE
|
2013-10-12 23:16:54 -04:00
|
|
|
m_core_hash_merge_kwd(int argc, VALUE *argv, VALUE recv)
|
2014-05-21 02:11:25 -04:00
|
|
|
{
|
|
|
|
VALUE hash;
|
|
|
|
REWIND_CFP(hash = core_hash_merge_kwd(argc, argv));
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
core_hash_merge_kwd(int argc, VALUE *argv)
|
2012-04-28 17:12:05 -04:00
|
|
|
{
|
2013-10-12 23:16:54 -04:00
|
|
|
VALUE hash, kw;
|
|
|
|
rb_check_arity(argc, 1, 2);
|
|
|
|
hash = argv[0];
|
|
|
|
kw = argv[argc-1];
|
2012-04-28 17:12:05 -04:00
|
|
|
kw = rb_convert_type(kw, T_HASH, "Hash", "to_hash");
|
2014-06-03 15:08:40 -04:00
|
|
|
if (argc < 2) hash = kw;
|
2013-10-12 23:16:54 -04:00
|
|
|
rb_hash_foreach(kw, argc < 2 ? kwcheck_i : kwmerge_i, hash);
|
2012-04-28 17:12:05 -04:00
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
extern VALUE *rb_gc_stack_start;
|
2007-12-14 23:09:24 -05:00
|
|
|
extern size_t rb_gc_stack_maxsize;
|
* 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
|
|
|
#ifdef __ia64
|
|
|
|
extern VALUE *rb_gc_register_stack_start;
|
|
|
|
#endif
|
|
|
|
|
2008-05-22 00:28:13 -04:00
|
|
|
/* debug functions */
|
|
|
|
|
2009-09-07 18:32:31 -04:00
|
|
|
/* :nodoc: */
|
* 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
|
|
|
static VALUE
|
|
|
|
sdr(void)
|
|
|
|
{
|
2014-05-24 23:46:55 -04:00
|
|
|
rb_vm_bugreport(NULL);
|
* 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
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2009-09-07 18:32:31 -04:00
|
|
|
/* :nodoc: */
|
* 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
|
|
|
static VALUE
|
|
|
|
nsdr(void)
|
|
|
|
{
|
|
|
|
VALUE ary = rb_ary_new();
|
|
|
|
#if HAVE_BACKTRACE
|
|
|
|
#include <execinfo.h>
|
|
|
|
#define MAX_NATIVE_TRACE 1024
|
|
|
|
static void *trace[MAX_NATIVE_TRACE];
|
2014-01-14 16:49:45 -05:00
|
|
|
int n = (int)backtrace(trace, MAX_NATIVE_TRACE);
|
* 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
|
|
|
char **syms = backtrace_symbols(trace, n);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (syms == 0) {
|
|
|
|
rb_memerror();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<n; i++) {
|
|
|
|
rb_ary_push(ary, rb_str_new2(syms[i]));
|
|
|
|
}
|
* array.c, bignum.c, cont.c, dir.c, dln.c, encoding.c, enumerator.c,
enumerator.c (enumerator_allocate), eval_jump.c, file.c, hash.c,
io.c, load.c, pack.c, proc.c, random.c, re.c, ruby.c, st.c,
string.c, thread.c, thread_pthread.c, time.c, util.c, variable.c,
vm.c, gc.c:
allocated memory objects by xmalloc (ruby_xmalloc) should be
freed by xfree (ruby_xfree).
* ext/curses/curses.c, ext/dbm/dbm.c, ext/digest/digest.c,
ext/gdbm/gdbm.c, ext/json/ext/parser/parser.c,
ext/json/ext/parser/unicode.c, ext/openssl/ossl_cipher.c,
ext/openssl/ossl_hmac.c, ext/openssl/ossl_pkey_ec.c,
ext/sdbm/init.c, ext/strscan/strscan.c, ext/zlib/zlib.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@17017 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-06-08 06:01:40 -04:00
|
|
|
free(syms); /* OK */
|
* 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
|
|
|
#endif
|
|
|
|
return ary;
|
|
|
|
}
|
|
|
|
|
2012-10-04 08:31:05 -04:00
|
|
|
#if VM_COLLECT_USAGE_DETAILS
|
|
|
|
static VALUE usage_analysis_insn_stop(VALUE self);
|
|
|
|
static VALUE usage_analysis_operand_stop(VALUE self);
|
|
|
|
static VALUE usage_analysis_register_stop(VALUE self);
|
|
|
|
#endif
|
|
|
|
|
* 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
|
|
|
void
|
|
|
|
Init_VM(void)
|
|
|
|
{
|
|
|
|
VALUE opts;
|
2008-08-14 01:14:01 -04:00
|
|
|
VALUE klass;
|
|
|
|
VALUE fcore;
|
* 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
|
|
|
|
2012-01-02 03:28:05 -05:00
|
|
|
/* ::RubyVM */
|
2008-06-29 13:26:16 -04:00
|
|
|
rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
|
|
|
|
rb_undef_alloc_func(rb_cRubyVM);
|
2009-12-21 05:12:21 -05:00
|
|
|
rb_undef_method(CLASS_OF(rb_cRubyVM), "new");
|
2013-12-09 04:12:23 -05:00
|
|
|
rb_define_singleton_method(rb_cRubyVM, "stat", vm_stat, -1);
|
* 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
|
|
|
|
2012-01-02 03:28:05 -05:00
|
|
|
/* FrozenCore (hidden) */
|
2008-08-15 02:30:43 -04:00
|
|
|
fcore = rb_class_new(rb_cBasicObject);
|
2008-08-14 01:14:01 -04:00
|
|
|
RBASIC(fcore)->flags = T_ICLASS;
|
|
|
|
klass = rb_singleton_class(fcore);
|
|
|
|
rb_define_method_id(klass, id_core_set_method_alias, m_core_set_method_alias, 3);
|
|
|
|
rb_define_method_id(klass, id_core_set_variable_alias, m_core_set_variable_alias, 2);
|
|
|
|
rb_define_method_id(klass, id_core_undef_method, m_core_undef_method, 2);
|
2015-11-13 13:01:59 -05:00
|
|
|
rb_define_method_id(klass, id_core_define_method, m_core_define_method, 2);
|
2008-08-14 01:14:01 -04:00
|
|
|
rb_define_method_id(klass, id_core_define_singleton_method, m_core_define_singleton_method, 3);
|
2013-08-22 02:50:42 -04:00
|
|
|
rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 0);
|
2012-04-11 21:33:34 -04:00
|
|
|
rb_define_method_id(klass, id_core_hash_from_ary, m_core_hash_from_ary, 1);
|
|
|
|
rb_define_method_id(klass, id_core_hash_merge_ary, m_core_hash_merge_ary, 2);
|
|
|
|
rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1);
|
2013-10-12 23:16:54 -04:00
|
|
|
rb_define_method_id(klass, id_core_hash_merge_kwd, m_core_hash_merge_kwd, -1);
|
2013-04-30 22:38:44 -04:00
|
|
|
rb_define_method_id(klass, idProc, rb_block_proc, 0);
|
|
|
|
rb_define_method_id(klass, idLambda, rb_block_lambda, 0);
|
2008-08-14 01:14:01 -04:00
|
|
|
rb_obj_freeze(fcore);
|
2013-10-09 22:11:37 -04:00
|
|
|
RBASIC_CLEAR_CLASS(klass);
|
|
|
|
rb_obj_freeze(klass);
|
* gc.c, include/ruby/ruby.h: rename rb_register_mark_object()
to rb_gc_register_mark_object().
* eval.c, vm.c: initialize vm->mark_object_ary at
Init_top_self().
* bignum.c, complex.c, encoding.c, ext/win32ole/win32ole.c,
io.c, load.c, marshal.c, rational.c, ruby.c, vm.c:
use rb_gc_register_mark_object() instead of
rb_global_variable() or rb_gc_register_address().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19365 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-15 10:59:14 -04:00
|
|
|
rb_gc_register_mark_object(fcore);
|
2008-08-14 01:14:01 -04:00
|
|
|
rb_mRubyVMFrozenCore = fcore;
|
2008-06-30 23:05:58 -04:00
|
|
|
|
2012-01-02 03:28:05 -05:00
|
|
|
/* ::RubyVM::Env */
|
2008-06-29 13:26:16 -04:00
|
|
|
rb_cEnv = rb_define_class_under(rb_cRubyVM, "Env", rb_cObject);
|
* 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
|
|
|
rb_undef_alloc_func(rb_cEnv);
|
2009-12-21 05:12:21 -05:00
|
|
|
rb_undef_method(CLASS_OF(rb_cEnv), "new");
|
* 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
|
|
|
|
2013-02-26 23:02:06 -05:00
|
|
|
/*
|
|
|
|
* Document-class: Thread
|
|
|
|
*
|
|
|
|
* Threads are the Ruby implementation for a concurrent programming model.
|
|
|
|
*
|
|
|
|
* Programs that require multiple threads of execution are a perfect
|
|
|
|
* candidate for Ruby's Thread class.
|
|
|
|
*
|
|
|
|
* For example, we can create a new thread separate from the main thread's
|
|
|
|
* execution using ::new.
|
|
|
|
*
|
|
|
|
* thr = Thread.new { puts "Whats the big deal" }
|
|
|
|
*
|
|
|
|
* Then we are able to pause the execution of the main thread and allow
|
|
|
|
* our new thread to finish, using #join:
|
|
|
|
*
|
|
|
|
* thr.join #=> "Whats the big deal"
|
|
|
|
*
|
|
|
|
* If we don't call +thr.join+ before the main thread terminates, then all
|
|
|
|
* other threads including +thr+ will be killed.
|
|
|
|
*
|
|
|
|
* Alternatively, you can use an array for handling multiple threads at
|
|
|
|
* once, like in the following example:
|
|
|
|
*
|
|
|
|
* threads = []
|
|
|
|
* threads << Thread.new { puts "Whats the big deal" }
|
|
|
|
* threads << Thread.new { 3.times { puts "Threads are fun!" } }
|
|
|
|
*
|
|
|
|
* After creating a few threads we wait for them all to finish
|
|
|
|
* consecutively.
|
|
|
|
*
|
|
|
|
* threads.each { |thr| thr.join }
|
|
|
|
*
|
|
|
|
* === Thread initialization
|
|
|
|
*
|
|
|
|
* In order to create new threads, Ruby provides ::new, ::start, and
|
|
|
|
* ::fork. A block must be provided with each of these methods, otherwise
|
|
|
|
* a ThreadError will be raised.
|
|
|
|
*
|
|
|
|
* When subclassing the Thread class, the +initialize+ method of your
|
|
|
|
* subclass will be ignored by ::start and ::fork. Otherwise, be sure to
|
|
|
|
* call super in your +initialize+ method.
|
|
|
|
*
|
|
|
|
* === Thread termination
|
|
|
|
*
|
|
|
|
* For terminating threads, Ruby provides a variety of ways to do this.
|
|
|
|
*
|
|
|
|
* The class method ::kill, is meant to exit a given thread:
|
|
|
|
*
|
|
|
|
* thr = Thread.new { ... }
|
|
|
|
* Thread.kill(thr) # sends exit() to thr
|
|
|
|
*
|
2013-02-27 05:54:11 -05:00
|
|
|
* Alternatively, you can use the instance method #exit, or any of its
|
2013-02-26 23:02:06 -05:00
|
|
|
* aliases #kill or #terminate.
|
|
|
|
*
|
|
|
|
* thr.exit
|
|
|
|
*
|
|
|
|
* === Thread status
|
|
|
|
*
|
|
|
|
* Ruby provides a few instance methods for querying the state of a given
|
2013-02-27 05:54:11 -05:00
|
|
|
* thread. To get a string with the current thread's state use #status
|
2013-02-26 23:02:06 -05:00
|
|
|
*
|
|
|
|
* thr = Thread.new { sleep }
|
|
|
|
* thr.status # => "sleep"
|
|
|
|
* thr.exit
|
2013-02-27 12:43:25 -05:00
|
|
|
* thr.status # => false
|
2013-02-26 23:02:06 -05:00
|
|
|
*
|
|
|
|
* You can also use #alive? to tell if the thread is running or sleeping,
|
|
|
|
* and #stop? if the thread is dead or sleeping.
|
|
|
|
*
|
|
|
|
* === Thread variables and scope
|
|
|
|
*
|
|
|
|
* Since threads are created with blocks, the same rules apply to other
|
|
|
|
* Ruby blocks for variable scope. Any local variables created within this
|
|
|
|
* block are accessible to only this thread.
|
|
|
|
*
|
|
|
|
* ==== Fiber-local vs. Thread-local
|
|
|
|
*
|
2013-02-27 05:54:11 -05:00
|
|
|
* Each fiber has its own bucket for Thread#[] storage. When you set a
|
2013-02-26 23:02:06 -05:00
|
|
|
* new fiber-local it is only accessible within this Fiber. To illustrate:
|
|
|
|
*
|
|
|
|
* Thread.new {
|
|
|
|
* Thread.current[:foo] = "bar"
|
|
|
|
* Fiber.new {
|
|
|
|
* p Thread.current[:foo] # => nil
|
|
|
|
* }.resume
|
|
|
|
* }.join
|
|
|
|
*
|
2013-02-26 23:22:08 -05:00
|
|
|
* This example uses #[] for getting and #[]= for setting fiber-locals,
|
2013-02-26 23:02:06 -05:00
|
|
|
* you can also use #keys to list the fiber-locals for a given
|
|
|
|
* thread and #key? to check if a fiber-local exists.
|
|
|
|
*
|
|
|
|
* When it comes to thread-locals, they are accessible within the entire
|
|
|
|
* scope of the thread. Given the following example:
|
|
|
|
*
|
|
|
|
* Thread.new{
|
|
|
|
* Thread.current.thread_variable_set(:foo, 1)
|
|
|
|
* p Thread.current.thread_variable_get(:foo) # => 1
|
|
|
|
* Fiber.new{
|
|
|
|
* Thread.current.thread_variable_set(:foo, 2)
|
|
|
|
* p Thread.current.thread_variable_get(:foo) # => 2
|
|
|
|
* }.resume
|
|
|
|
* p Thread.current.thread_variable_get(:foo) # => 2
|
|
|
|
* }.join
|
|
|
|
*
|
|
|
|
* You can see that the thread-local +:foo+ carried over into the fiber
|
|
|
|
* and was changed to +2+ by the end of the thread.
|
|
|
|
*
|
|
|
|
* This example makes use of #thread_variable_set to create new
|
|
|
|
* thread-locals, and #thread_variable_get to reference them.
|
|
|
|
*
|
|
|
|
* There is also #thread_variables to list all thread-locals, and
|
|
|
|
* #thread_variable? to check if a given thread-local exists.
|
|
|
|
*
|
|
|
|
* === Exception handling
|
|
|
|
*
|
|
|
|
* Any thread can raise an exception using the #raise instance method,
|
|
|
|
* which operates similarly to Kernel#raise.
|
|
|
|
*
|
|
|
|
* However, it's important to note that an exception that occurs in any
|
|
|
|
* thread except the main thread depends on #abort_on_exception. This
|
|
|
|
* option is +false+ by default, meaning that any unhandled exception will
|
|
|
|
* cause the thread to terminate silently when waited on by either #join
|
|
|
|
* or #value. You can change this default by either #abort_on_exception=
|
|
|
|
* +true+ or setting $DEBUG to +true+.
|
|
|
|
*
|
|
|
|
* With the addition of the class method ::handle_interrupt, you can now
|
|
|
|
* handle exceptions asynchronously with threads.
|
|
|
|
*
|
|
|
|
* === Scheduling
|
|
|
|
*
|
|
|
|
* Ruby provides a few ways to support scheduling threads in your program.
|
|
|
|
*
|
|
|
|
* The first way is by using the class method ::stop, to put the current
|
|
|
|
* running thread to sleep and schedule the execution of another thread.
|
|
|
|
*
|
|
|
|
* Once a thread is asleep, you can use the instance method #wakeup to
|
|
|
|
* mark your thread as eligible for scheduling.
|
|
|
|
*
|
|
|
|
* You can also try ::pass, which attempts to pass execution to another
|
|
|
|
* thread but is dependent on the OS whether a running thread will switch
|
2013-02-27 05:54:11 -05:00
|
|
|
* or not. The same goes for #priority, which lets you hint to the thread
|
2013-02-26 23:02:06 -05:00
|
|
|
* scheduler which threads you want to take precedence when passing
|
|
|
|
* execution. This method is also dependent on the OS and may be ignored
|
|
|
|
* on some platforms.
|
|
|
|
*
|
|
|
|
*/
|
* 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
|
|
|
rb_cThread = rb_define_class("Thread", rb_cObject);
|
|
|
|
rb_undef_alloc_func(rb_cThread);
|
|
|
|
|
2012-10-04 08:31:05 -04:00
|
|
|
#if VM_COLLECT_USAGE_DETAILS
|
2012-01-02 03:28:05 -05:00
|
|
|
/* ::RubyVM::USAGE_ANALYSIS_* */
|
2013-06-01 23:12:04 -04:00
|
|
|
#define define_usage_analysis_hash(name) /* shut up rdoc -C */ \
|
2016-04-04 03:42:51 -04:00
|
|
|
rb_define_const(rb_cRubyVM, "USAGE_ANALYSIS_" #name, rb_hash_new())
|
|
|
|
define_usage_analysis_hash(INSN);
|
|
|
|
define_usage_analysis_hash(REGS);
|
|
|
|
define_usage_analysis_hash(INSN_BIGRAM);
|
2012-10-04 08:31:05 -04:00
|
|
|
|
|
|
|
rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_INSN_STOP", usage_analysis_insn_stop, 0);
|
|
|
|
rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_OPERAND_STOP", usage_analysis_operand_stop, 0);
|
|
|
|
rb_define_singleton_method(rb_cRubyVM, "USAGE_ANALYSIS_REGISTER_STOP", usage_analysis_register_stop, 0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ::RubyVM::OPTS, which shows vm build options */
|
2008-06-29 13:26:16 -04:00
|
|
|
rb_define_const(rb_cRubyVM, "OPTS", opts = rb_ary_new());
|
* 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
|
|
|
|
|
|
|
#if OPT_DIRECT_THREADED_CODE
|
|
|
|
rb_ary_push(opts, rb_str_new2("direct threaded code"));
|
|
|
|
#elif OPT_TOKEN_THREADED_CODE
|
|
|
|
rb_ary_push(opts, rb_str_new2("token threaded code"));
|
|
|
|
#elif OPT_CALL_THREADED_CODE
|
|
|
|
rb_ary_push(opts, rb_str_new2("call threaded code"));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if OPT_STACK_CACHING
|
|
|
|
rb_ary_push(opts, rb_str_new2("stack caching"));
|
|
|
|
#endif
|
|
|
|
#if OPT_OPERANDS_UNIFICATION
|
2014-01-04 03:22:46 -05:00
|
|
|
rb_ary_push(opts, rb_str_new2("operands unification"));
|
* 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
|
|
|
#endif
|
|
|
|
#if OPT_INSTRUCTIONS_UNIFICATION
|
|
|
|
rb_ary_push(opts, rb_str_new2("instructions unification"));
|
|
|
|
#endif
|
|
|
|
#if OPT_INLINE_METHOD_CACHE
|
|
|
|
rb_ary_push(opts, rb_str_new2("inline method cache"));
|
|
|
|
#endif
|
|
|
|
#if OPT_BLOCKINLINING
|
|
|
|
rb_ary_push(opts, rb_str_new2("block inlining"));
|
|
|
|
#endif
|
|
|
|
|
2012-01-02 03:28:05 -05:00
|
|
|
/* ::RubyVM::INSTRUCTION_NAMES */
|
2009-01-18 20:06:56 -05:00
|
|
|
rb_define_const(rb_cRubyVM, "INSTRUCTION_NAMES", rb_insns_name_array());
|
* 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
|
|
|
|
2012-12-19 17:29:18 -05:00
|
|
|
/* ::RubyVM::DEFAULT_PARAMS
|
|
|
|
* This constant variable shows VM's default parameters.
|
2013-05-18 23:10:21 -04:00
|
|
|
* Note that changing these values does not affect VM execution.
|
2012-12-19 17:29:18 -05:00
|
|
|
* Specification is not stable and you should not depend on this value.
|
|
|
|
* Of course, this constant is MRI specific.
|
|
|
|
*/
|
|
|
|
rb_define_const(rb_cRubyVM, "DEFAULT_PARAMS", vm_default_params());
|
|
|
|
|
2012-01-02 03:28:05 -05:00
|
|
|
/* debug functions ::RubyVM::SDR(), ::RubyVM::NSDR() */
|
2008-05-22 06:01:32 -04:00
|
|
|
#if VMDEBUG
|
2008-06-29 13:26:16 -04:00
|
|
|
rb_define_singleton_method(rb_cRubyVM, "SDR", sdr, 0);
|
|
|
|
rb_define_singleton_method(rb_cRubyVM, "NSDR", nsdr, 0);
|
2008-06-01 15:55:25 -04:00
|
|
|
#else
|
|
|
|
(void)sdr;
|
|
|
|
(void)nsdr;
|
2008-05-22 06:01:32 -04:00
|
|
|
#endif
|
* 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
|
|
|
|
|
|
|
/* VM bootstrap: phase 2 */
|
|
|
|
{
|
|
|
|
rb_vm_t *vm = ruby_current_vm;
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
2016-01-26 01:23:47 -05:00
|
|
|
VALUE filename = rb_fstring_cstr("<main>");
|
2015-07-21 18:52:59 -04:00
|
|
|
const rb_iseq_t *iseq = rb_iseq_new(0, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
* 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
|
|
|
volatile VALUE th_self;
|
|
|
|
|
|
|
|
/* create vm object */
|
2009-07-07 16:28:27 -04:00
|
|
|
vm->self = TypedData_Wrap_Struct(rb_cRubyVM, &vm_data_type, vm);
|
* 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
|
|
|
|
|
|
|
/* create main thread */
|
2009-07-07 16:28:27 -04:00
|
|
|
th_self = th->self = TypedData_Wrap_Struct(rb_cThread, &thread_data_type, th);
|
2012-10-29 13:22:36 -04:00
|
|
|
rb_iv_set(th_self, "locals", rb_hash_new());
|
* 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
|
|
|
vm->main_thread = th;
|
|
|
|
vm->running_thread = th;
|
|
|
|
th->vm = vm;
|
|
|
|
th->top_wrapper = 0;
|
|
|
|
th->top_self = rb_vm_top_self();
|
|
|
|
rb_thread_set_current(th);
|
|
|
|
|
vm*: doubly-linked list from ccan to manage vm->living_threads
A doubly-linked list for tracking living threads guarantees
constant-time insert/delete performance with no corner cases of a
hash table. I chose this ccan implementation of doubly-linked
lists over the BSD sys/queue.h implementation since:
1) insertion and removal are both branchless
2) locality is improved if a struct may be a member of multiple lists
(0002 patch in Feature 9632 will introduce a secondary list
for waiting FDs)
This also increases cache locality during iteration: improving
performance in a new IO#close benchmark with many sleeping threads
while still scanning the same number of threads.
vm_thread_close 1.762
* vm_core.h (rb_vm_t): list_head and counter for living_threads
(rb_thread_t): vmlt_node for living_threads linkage
(rb_vm_living_threads_init): new function wrapper
(rb_vm_living_threads_insert): ditto
(rb_vm_living_threads_remove): ditto
* vm.c (rb_vm_living_threads_foreach): new function wrapper
* thread.c (terminate_i, thread_start_func_2, thread_create_core,
thread_fd_close_i, thread_fd_close): update to use new APIs
* vm.c (vm_mark_each_thread_func, rb_vm_mark, ruby_vm_destruct,
vm_memsize, vm_init2, Init_VM): ditto
* vm_trace.c (clear_trace_func_i, rb_clear_trace_func): ditto
* benchmark/bm_vm_thread_close.rb: added to show improvement
* ccan/build_assert/build_assert.h: added as a dependency of list.h
* ccan/check_type/check_type.h: ditto
* ccan/container_of/container_of.h: ditto
* ccan/licenses/BSD-MIT: ditto
* ccan/licenses/CC0: ditto
* ccan/str/str.h: ditto (stripped of unused macros)
* ccan/list/list.h: ditto
* common.mk: add CCAN_LIST_INCLUDES
[ruby-core:61871][Feature 9632 (part 1)]
Apologies for the size of this commit, but I think a good
doubly-linked list will be useful for future features, too.
This may be used to add ordering to a container_of-based hash
table to preserve compatibility if required (e.g. feature 9614).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-10 19:48:51 -04:00
|
|
|
rb_vm_living_threads_insert(vm, th);
|
2007-12-24 16:18:47 -05:00
|
|
|
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_gc_register_mark_object((VALUE)iseq);
|
2007-12-24 16:18:47 -05:00
|
|
|
th->cfp->iseq = iseq;
|
2015-07-21 18:52:59 -04:00
|
|
|
th->cfp->pc = iseq->body->iseq_encoded;
|
2008-12-26 20:15:56 -05:00
|
|
|
th->cfp->self = th->top_self;
|
|
|
|
|
2016-07-28 07:02:30 -04:00
|
|
|
VM_STACK_ENV_WRITE(th->cfp->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE));
|
* fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
When calling ISEQ type method, push CREF information onto method
frame, SVAR located place. Before this fix, SVAR is simply nil.
After this patch, CREF (or NULL == Qfalse for not iseq methods)
is stored at the method invocation.
When SVAR is requierd, then put NODE_IF onto SVAR location,
and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 07:24:58 -05:00
|
|
|
|
2011-06-28 23:09:34 -04:00
|
|
|
/*
|
|
|
|
* The Binding of the top level scope
|
|
|
|
*/
|
2008-12-26 20:15:56 -05:00
|
|
|
rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new());
|
* 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
|
|
|
}
|
|
|
|
vm_init_redefined_flag();
|
2012-06-02 11:23:37 -04:00
|
|
|
|
2012-06-15 08:01:41 -04:00
|
|
|
/* vm_backtrace.c */
|
2012-06-02 11:23:37 -04:00
|
|
|
Init_vm_backtrace();
|
* vm_core.h, vm_insnhelper.c, vm_eval.c (OPT_CALL_CFUNC_WITHOUT_FRAME):
add a new otpimization and its macro `OPT_CALL_CFUNC_WITHOUT_FRAME'.
This optimization makes all cfunc method calls `frameless', which
is fster than ordinal cfunc method call.
If `frame' is needed (for example, it calls another method with
`rb_funcall()'), then build a frame. In other words, this
optimization delays frame building.
However, to delay the frame building, we need additional overheads:
(1) Store the last call information.
(2) Check the delayed frame buidling before the frame is needed.
(3) Overhead to build a delayed frame.
rb_thread_t::passed_ci is storage of delayed cfunc call information.
(1) is lightweight because it is only 1 assignment to `passed_ci'.
To achieve (2), we modify GET_THREAD() to check `passed_ci' every
time. It causes 10% overhead on my envrionment.
This optimization only works for cfunc methods which do not need
their `frame'.
After evaluation on my environment, this optimization does not
effective every time. Because of this evaluation results, this
optimization is disabled at default.
* vm_insnhelper.c, vm.c: add VM_PROFILE* macros to measure behaviour
of VM internals. I will extend this feature.
* vm_method.c, method.h: change parameters of the `invoker' function.
Receive `func' pointer as the first parameter.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37293 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-10-23 00:22:31 -04:00
|
|
|
VM_PROFILE_ATEXIT();
|
* 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
|
|
|
}
|
|
|
|
|
2009-05-17 01:02:58 -04:00
|
|
|
void
|
|
|
|
rb_vm_set_progname(VALUE filename)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_VM()->main_thread;
|
|
|
|
rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size);
|
|
|
|
--cfp;
|
2015-07-21 18:52:59 -04:00
|
|
|
RB_OBJ_WRITE(cfp->iseq, &cfp->iseq->body->location.path, filename);
|
2009-05-17 01:02:58 -04:00
|
|
|
}
|
|
|
|
|
2015-08-09 01:15:57 -04:00
|
|
|
extern const struct st_hash_type rb_fstring_hash_type;
|
|
|
|
|
* 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
|
|
|
void
|
|
|
|
Init_BareVM(void)
|
|
|
|
{
|
|
|
|
/* VM bootstrap: phase 1 */
|
2012-01-09 22:49:10 -05:00
|
|
|
rb_vm_t * vm = ruby_mimmalloc(sizeof(*vm));
|
|
|
|
rb_thread_t * th = ruby_mimmalloc(sizeof(*th));
|
2008-08-01 08:30:25 -04:00
|
|
|
if (!vm || !th) {
|
|
|
|
fprintf(stderr, "[FATAL] failed to allocate memory\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2007-11-21 04:06:06 -05:00
|
|
|
MEMZERO(th, rb_thread_t, 1);
|
2007-12-24 15:27:10 -05:00
|
|
|
rb_thread_set_current_raw(th);
|
|
|
|
|
* 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
|
|
|
vm_init2(vm);
|
2008-04-26 23:20:35 -04:00
|
|
|
vm->objspace = rb_objspace_alloc();
|
* 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
|
|
|
ruby_current_vm = vm;
|
|
|
|
|
2010-06-05 19:26:43 -04:00
|
|
|
Init_native_thread();
|
* 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
|
|
|
th->vm = vm;
|
2012-12-19 17:29:18 -05:00
|
|
|
th_init(th, 0);
|
2008-06-13 22:59:19 -04:00
|
|
|
ruby_thread_init_stack(th);
|
2014-05-04 09:04:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Init_vm_objects(void)
|
|
|
|
{
|
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
|
2013-10-13 07:59:27 -04:00
|
|
|
vm->defined_module_hash = rb_hash_new();
|
2014-05-04 09:04:37 -04:00
|
|
|
|
|
|
|
/* initialize mark object array, hash */
|
2014-07-06 00:42:35 -04:00
|
|
|
vm->mark_object_ary = rb_ary_tmp_new(128);
|
2015-06-03 03:21:37 -04:00
|
|
|
vm->loading_table = st_init_strtable();
|
2015-08-09 01:15:57 -04:00
|
|
|
vm->frozen_strings = st_init_table_with_size(&rb_fstring_hash_type, 1000);
|
* 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
|
|
|
}
|
|
|
|
|
|
|
|
/* top self */
|
|
|
|
|
|
|
|
static VALUE
|
2008-05-22 12:19:14 -04:00
|
|
|
main_to_s(VALUE obj)
|
* 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
|
|
|
{
|
|
|
|
return rb_str_new2("main");
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
2008-05-22 00:28:13 -04:00
|
|
|
rb_vm_top_self(void)
|
* 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
|
|
|
{
|
|
|
|
return GET_VM()->top_self;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2008-05-22 00:28:13 -04:00
|
|
|
Init_top_self(void)
|
* 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
|
|
|
{
|
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
|
|
|
|
vm->top_self = rb_obj_alloc(rb_cObject);
|
|
|
|
rb_define_singleton_method(rb_vm_top_self(), "to_s", main_to_s, 0);
|
2012-08-15 07:50:01 -04:00
|
|
|
rb_define_alias(rb_singleton_class(rb_vm_top_self()), "inspect", "to_s");
|
* 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
|
|
|
}
|
2008-06-09 01:18:03 -04:00
|
|
|
|
2015-12-04 16:08:47 -05:00
|
|
|
static VALUE *
|
2008-06-09 01:18:03 -04:00
|
|
|
ruby_vm_verbose_ptr(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
return &vm->verbose;
|
|
|
|
}
|
|
|
|
|
2015-12-04 16:08:47 -05:00
|
|
|
static VALUE *
|
2008-06-09 01:18:03 -04:00
|
|
|
ruby_vm_debug_ptr(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
return &vm->debug;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE *
|
|
|
|
rb_ruby_verbose_ptr(void)
|
|
|
|
{
|
|
|
|
return ruby_vm_verbose_ptr(GET_VM());
|
|
|
|
}
|
|
|
|
|
2008-06-13 22:59:19 -04:00
|
|
|
VALUE *
|
|
|
|
rb_ruby_debug_ptr(void)
|
2008-06-09 01:18:03 -04:00
|
|
|
{
|
|
|
|
return ruby_vm_debug_ptr(GET_VM());
|
|
|
|
}
|
2012-10-04 08:31:05 -04:00
|
|
|
|
* 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
|
|
|
/* iseq.c */
|
2015-07-21 18:52:59 -04:00
|
|
|
VALUE rb_insn_operand_intern(const rb_iseq_t *iseq,
|
2013-03-06 01:30:03 -05:00
|
|
|
VALUE insn, int op_no, VALUE op,
|
|
|
|
int len, size_t pos, VALUE *pnop, VALUE child);
|
* 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
|
|
|
|
2015-08-09 01:15:57 -04:00
|
|
|
st_table *
|
|
|
|
rb_vm_fstring_table(void)
|
|
|
|
{
|
|
|
|
return GET_VM()->frozen_strings;
|
|
|
|
}
|
|
|
|
|
2012-10-04 08:31:05 -04:00
|
|
|
#if VM_COLLECT_USAGE_DETAILS
|
|
|
|
|
2013-12-07 19:41:01 -05:00
|
|
|
#define HASH_ASET(h, k, v) rb_hash_aset((h), (st_data_t)(k), (st_data_t)(v))
|
2012-10-04 08:48:35 -04:00
|
|
|
|
2012-10-04 08:31:05 -04:00
|
|
|
/* uh = {
|
|
|
|
* insn(Fixnum) => ihash(Hash)
|
|
|
|
* }
|
|
|
|
* ihash = {
|
|
|
|
* -1(Fixnum) => count, # insn usage
|
|
|
|
* 0(Fixnum) => ophash, # operand usage
|
|
|
|
* }
|
|
|
|
* ophash = {
|
|
|
|
* val(interned string) => count(Fixnum)
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
vm_analysis_insn(int insn)
|
|
|
|
{
|
|
|
|
ID usage_hash;
|
|
|
|
ID bigram_hash;
|
|
|
|
static int prev_insn = -1;
|
|
|
|
|
|
|
|
VALUE uh;
|
|
|
|
VALUE ihash;
|
|
|
|
VALUE cv;
|
|
|
|
|
|
|
|
CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN");
|
|
|
|
CONST_ID(bigram_hash, "USAGE_ANALYSIS_INSN_BIGRAM");
|
|
|
|
uh = rb_const_get(rb_cRubyVM, usage_hash);
|
|
|
|
if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) {
|
|
|
|
ihash = rb_hash_new();
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(uh, INT2FIX(insn), ihash);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
if ((cv = rb_hash_aref(ihash, INT2FIX(-1))) == Qnil) {
|
|
|
|
cv = INT2FIX(0);
|
|
|
|
}
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(ihash, INT2FIX(-1), INT2FIX(FIX2INT(cv) + 1));
|
2012-10-04 08:31:05 -04:00
|
|
|
|
|
|
|
/* calc bigram */
|
|
|
|
if (prev_insn != -1) {
|
|
|
|
VALUE bi;
|
|
|
|
VALUE ary[2];
|
|
|
|
VALUE cv;
|
|
|
|
|
|
|
|
ary[0] = INT2FIX(prev_insn);
|
|
|
|
ary[1] = INT2FIX(insn);
|
|
|
|
bi = rb_ary_new4(2, &ary[0]);
|
|
|
|
|
|
|
|
uh = rb_const_get(rb_cRubyVM, bigram_hash);
|
|
|
|
if ((cv = rb_hash_aref(uh, bi)) == Qnil) {
|
|
|
|
cv = INT2FIX(0);
|
|
|
|
}
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(uh, bi, INT2FIX(FIX2INT(cv) + 1));
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
prev_insn = insn;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vm_analysis_operand(int insn, int n, VALUE op)
|
|
|
|
{
|
|
|
|
ID usage_hash;
|
|
|
|
|
|
|
|
VALUE uh;
|
|
|
|
VALUE ihash;
|
|
|
|
VALUE ophash;
|
|
|
|
VALUE valstr;
|
|
|
|
VALUE cv;
|
|
|
|
|
|
|
|
CONST_ID(usage_hash, "USAGE_ANALYSIS_INSN");
|
|
|
|
|
|
|
|
uh = rb_const_get(rb_cRubyVM, usage_hash);
|
|
|
|
if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) {
|
|
|
|
ihash = rb_hash_new();
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(uh, INT2FIX(insn), ihash);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
if ((ophash = rb_hash_aref(ihash, INT2FIX(n))) == Qnil) {
|
|
|
|
ophash = rb_hash_new();
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(ihash, INT2FIX(n), ophash);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
/* intern */
|
2013-03-06 01:30:03 -05:00
|
|
|
valstr = rb_insn_operand_intern(GET_THREAD()->cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
2012-10-04 08:31:05 -04:00
|
|
|
|
|
|
|
/* set count */
|
|
|
|
if ((cv = rb_hash_aref(ophash, valstr)) == Qnil) {
|
|
|
|
cv = INT2FIX(0);
|
|
|
|
}
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(ophash, valstr, INT2FIX(FIX2INT(cv) + 1));
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
vm_analysis_register(int reg, int isset)
|
|
|
|
{
|
|
|
|
ID usage_hash;
|
|
|
|
VALUE uh;
|
|
|
|
VALUE valstr;
|
|
|
|
static const char regstrs[][5] = {
|
|
|
|
"pc", /* 0 */
|
|
|
|
"sp", /* 1 */
|
|
|
|
"ep", /* 2 */
|
|
|
|
"cfp", /* 3 */
|
|
|
|
"self", /* 4 */
|
|
|
|
"iseq", /* 5 */
|
|
|
|
};
|
|
|
|
static const char getsetstr[][4] = {
|
|
|
|
"get",
|
|
|
|
"set",
|
|
|
|
};
|
|
|
|
static VALUE syms[sizeof(regstrs) / sizeof(regstrs[0])][2];
|
|
|
|
|
|
|
|
VALUE cv;
|
|
|
|
|
|
|
|
CONST_ID(usage_hash, "USAGE_ANALYSIS_REGS");
|
|
|
|
if (syms[0] == 0) {
|
|
|
|
char buff[0x10];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < (int)(sizeof(regstrs) / sizeof(regstrs[0])); i++) {
|
|
|
|
int j;
|
|
|
|
for (j = 0; j < 2; j++) {
|
|
|
|
snprintf(buff, 0x10, "%d %s %-4s", i, getsetstr[j], regstrs[i]);
|
|
|
|
syms[i][j] = ID2SYM(rb_intern(buff));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
valstr = syms[reg][isset];
|
|
|
|
|
|
|
|
uh = rb_const_get(rb_cRubyVM, usage_hash);
|
|
|
|
if ((cv = rb_hash_aref(uh, valstr)) == Qnil) {
|
|
|
|
cv = INT2FIX(0);
|
|
|
|
}
|
2012-10-04 08:48:35 -04:00
|
|
|
HASH_ASET(uh, valstr, INT2FIX(FIX2INT(cv) + 1));
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
|
2012-10-04 08:48:35 -04:00
|
|
|
#undef HASH_ASET
|
|
|
|
|
2012-10-04 08:31:05 -04:00
|
|
|
void (*ruby_vm_collect_usage_func_insn)(int insn) = vm_analysis_insn;
|
|
|
|
void (*ruby_vm_collect_usage_func_operand)(int insn, int n, VALUE op) = vm_analysis_operand;
|
|
|
|
void (*ruby_vm_collect_usage_func_register)(int reg, int isset) = vm_analysis_register;
|
|
|
|
|
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
usage_analysis_insn_stop(VALUE self)
|
|
|
|
{
|
|
|
|
ruby_vm_collect_usage_func_insn = 0;
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
usage_analysis_operand_stop(VALUE self)
|
|
|
|
{
|
|
|
|
ruby_vm_collect_usage_func_operand = 0;
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
usage_analysis_register_stop(VALUE self)
|
|
|
|
{
|
|
|
|
ruby_vm_collect_usage_func_register = 0;
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
* 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
|
|
|
#else
|
|
|
|
|
|
|
|
void (*ruby_vm_collect_usage_func_insn)(int insn) = NULL;
|
|
|
|
void (*ruby_vm_collect_usage_func_operand)(int insn, int n, VALUE op) = NULL;
|
|
|
|
void (*ruby_vm_collect_usage_func_register)(int reg, int isset) = NULL;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2012-11-22 02:23:40 -05:00
|
|
|
#if VM_COLLECT_USAGE_DETAILS
|
2012-10-04 08:31:05 -04:00
|
|
|
/* @param insn instruction number */
|
|
|
|
static void
|
|
|
|
vm_collect_usage_insn(int insn)
|
|
|
|
{
|
* 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
|
|
|
if (RUBY_DTRACE_INSN_ENABLED()) {
|
|
|
|
RUBY_DTRACE_INSN(rb_insns_name(insn));
|
|
|
|
}
|
2012-10-04 08:31:05 -04:00
|
|
|
if (ruby_vm_collect_usage_func_insn)
|
2012-11-16 12:02:35 -05:00
|
|
|
(*ruby_vm_collect_usage_func_insn)(insn);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* @param insn instruction number
|
|
|
|
* @param n n-th operand
|
|
|
|
* @param op operand value
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
vm_collect_usage_operand(int insn, int n, VALUE op)
|
|
|
|
{
|
* 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
|
|
|
if (RUBY_DTRACE_INSN_OPERAND_ENABLED()) {
|
|
|
|
VALUE valstr;
|
|
|
|
|
2013-03-06 01:30:03 -05:00
|
|
|
valstr = rb_insn_operand_intern(GET_THREAD()->cfp->iseq, insn, n, op, 0, 0, 0, 0);
|
* 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_INSN_OPERAND(RSTRING_PTR(valstr), rb_insns_name(insn));
|
2012-11-16 12:02:37 -05:00
|
|
|
RB_GC_GUARD(valstr);
|
* 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-10-04 08:31:05 -04:00
|
|
|
if (ruby_vm_collect_usage_func_operand)
|
2012-11-16 12:02:35 -05:00
|
|
|
(*ruby_vm_collect_usage_func_operand)(insn, n, op);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* @param reg register id. see code of vm_analysis_register() */
|
2014-10-11 21:39:53 -04:00
|
|
|
/* @param isset 0: read, 1: write */
|
2012-10-04 08:31:05 -04:00
|
|
|
static void
|
|
|
|
vm_collect_usage_register(int reg, int isset)
|
|
|
|
{
|
|
|
|
if (ruby_vm_collect_usage_func_register)
|
2012-11-16 12:02:35 -05:00
|
|
|
(*ruby_vm_collect_usage_func_register)(reg, isset);
|
2012-10-04 08:31:05 -04:00
|
|
|
}
|
|
|
|
#endif
|
2015-10-23 13:53:35 -04:00
|
|
|
|
|
|
|
#include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
|