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
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
2015-10-29 17:16:19 -04:00
|
|
|
#ifndef VM_CHECK_MODE
|
* 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
|
|
|
#define VM_CHECK_MODE 0
|
2015-10-29 17:16:19 -04:00
|
|
|
#endif
|
* 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
|
|
|
|
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
|
|
|
|
2015-09-29 03:37:40 -04:00
|
|
|
VALUE rb_str_append_literal(VALUE str, VALUE str2);
|
|
|
|
|
2012-06-10 23:14:59 -04:00
|
|
|
static inline VALUE *
|
|
|
|
VM_EP_LEP(VALUE *ep)
|
|
|
|
{
|
2013-04-29 04:44:16 -04:00
|
|
|
while (!VM_EP_LEP_P(ep)) {
|
2012-06-10 23:14:59 -04:00
|
|
|
ep = VM_EP_PREV_EP(ep);
|
|
|
|
}
|
2013-04-29 04:44:16 -04:00
|
|
|
return ep;
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
|
|
|
|
2015-01-15 21:54:22 -05:00
|
|
|
static inline rb_control_frame_t *
|
|
|
|
rb_vm_search_cf_from_ep(const rb_thread_t * const th, rb_control_frame_t *cfp, const VALUE * const ep)
|
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *
|
|
|
|
rb_vm_ep_local_ep(VALUE *ep)
|
|
|
|
{
|
|
|
|
return VM_EP_LEP(ep);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline 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
|
|
|
{
|
2015-01-15 21:54:25 -05:00
|
|
|
return VM_EP_PREV_EP(cfp->ep);
|
2012-06-10 23:14:59 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline rb_block_t *
|
2015-01-16 03:21:49 -05:00
|
|
|
VM_CF_BLOCK_PTR(const rb_control_frame_t * const cfp)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
|
|
|
VALUE *ep = VM_CF_LEP(cfp);
|
|
|
|
return VM_EP_BLOCK_PTR(ep);
|
|
|
|
}
|
|
|
|
|
|
|
|
rb_block_t *
|
2015-01-16 03:21:49 -05:00
|
|
|
rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp)
|
2012-06-10 23:14:59 -04:00
|
|
|
{
|
|
|
|
return VM_CF_BLOCK_PTR(cfp);
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
rb_cref_t *cref;
|
|
|
|
|
|
|
|
/* 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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
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,
|
2015-05-20 18:03:06 -04:00
|
|
|
int argc, const VALUE *argv, const rb_block_t *blockptr);
|
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,
|
2012-08-20 07:36:34 -04:00
|
|
|
int argc, const VALUE *argv, const rb_block_t *blockptr);
|
|
|
|
|
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"
|
2007-12-20 04:29:46 -05: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.h"
|
|
|
|
#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 */
|
* 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_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH, th->top_self,
|
* 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_ENVVAL_BLOCK_PTR(0),
|
2015-06-02 00:20:30 -04:00
|
|
|
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
2015-07-21 18:52:59 -04:00
|
|
|
iseq->body->iseq_encoded, th->cfp->sp, iseq->body->local_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
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_cref_t *cref, rb_block_t *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,
|
* 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
|
|
|
base_block->self, VM_ENVVAL_PREV_EP_PTR(base_block->ep),
|
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,
|
|
|
|
th->cfp->sp, iseq->body->local_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;
|
|
|
|
rb_env_t *env;
|
|
|
|
|
|
|
|
GetBindingPtr(toplevel_binding, bind);
|
|
|
|
GetEnvPtr(bind->env, env);
|
2015-07-21 18:52:59 -04:00
|
|
|
|
|
|
|
vm_set_eval_stack(th, iseq, 0, &env->block);
|
2008-12-26 20:15:56 -05:00
|
|
|
|
|
|
|
/* save binding */
|
2015-07-21 18:52:59 -04:00
|
|
|
if (bind && iseq->body->local_size > 0) {
|
2015-07-14 12:23:17 -04:00
|
|
|
bind->env = 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
|
|
|
|
|
|
|
if ((cfp->flag & VM_FRAME_FLAG_PASSED) == 0) {
|
|
|
|
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();
|
* 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(th->cfp);
|
2015-06-02 00:20:30 -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
|
|
|
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->owner, Qnil);
|
|
|
|
RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, me->called_id);
|
2014-01-09 05:12:59 -05:00
|
|
|
vm_pop_frame(th);
|
|
|
|
}
|
|
|
|
|
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) {
|
|
|
|
vm_pop_frame(th);
|
|
|
|
}
|
|
|
|
else { /* unlikely path */
|
|
|
|
rb_vm_pop_cfunc_frame();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-09 05:12:59 -05:00
|
|
|
/* obsolete */
|
|
|
|
void
|
|
|
|
rb_frame_pop(void)
|
|
|
|
{
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
vm_pop_frame(th);
|
|
|
|
}
|
|
|
|
|
2010-12-02 06:06:32 -05:00
|
|
|
/* at exit */
|
|
|
|
|
|
|
|
void
|
|
|
|
ruby_vm_at_exit(void (*func)(rb_vm_t *))
|
|
|
|
{
|
|
|
|
rb_ary_push((VALUE)&GET_VM()->at_exit, (VALUE)func);
|
|
|
|
}
|
|
|
|
|
2011-02-24 08:51:59 -05:00
|
|
|
static void
|
|
|
|
ruby_vm_run_at_exit_hooks(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
VALUE hook = (VALUE)&vm->at_exit;
|
|
|
|
|
|
|
|
while (RARRAY_LEN(hook) > 0) {
|
|
|
|
typedef void rb_vm_at_exit_func(rb_vm_t*);
|
|
|
|
rb_vm_at_exit_func *func = (rb_vm_at_exit_func*)rb_ary_pop(hook);
|
|
|
|
(*func)(vm);
|
|
|
|
}
|
|
|
|
rb_ary_free(hook);
|
|
|
|
}
|
|
|
|
|
* 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");
|
|
|
|
rb_gc_mark_values((long)env->env_size, env->env);
|
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(rb_vm_env_prev_envval(env));
|
2014-09-12 17:34:12 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL(env->block.self);
|
|
|
|
RUBY_MARK_UNLESS_NULL(env->block.proc);
|
2015-10-15 00:44:58 -04:00
|
|
|
RUBY_MARK_UNLESS_NULL((VALUE)env->block.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
|
|
|
}
|
|
|
|
|
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",
|
2014-09-12 17:34:12 -04:00
|
|
|
{env_mark, RUBY_TYPED_DEFAULT_FREE, env_memsize,},
|
2014-12-01 01:38:04 -05:00
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
2009-06-16 18:23:53 -04:00
|
|
|
};
|
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
#define VM_EP_IN_HEAP_P(th, ep) (!((th)->stack <= (ep) && (ep) < ((th)->stack + (th)->stack_size)))
|
|
|
|
#define VM_ENV_EP_ENVVAL(ep) ((ep)[1])
|
|
|
|
|
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");
|
2012-06-10 23:14:59 -04:00
|
|
|
fprintf(stderr, "envptr: %p\n", (void *)&env->block.ep[0]);
|
|
|
|
fprintf(stderr, "envval: %10p ", (void *)env->block.ep[1]);
|
|
|
|
dp(env->block.ep[1]);
|
|
|
|
fprintf(stderr, "ep: %10p\n", (void *)env->block.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
|
|
|
|
2015-07-14 12:23:17 -04:00
|
|
|
/* return Qfalse if proc was already created */
|
|
|
|
static VALUE
|
|
|
|
vm_make_proc_from_block(rb_thread_t *th, rb_block_t *block)
|
|
|
|
{
|
|
|
|
if (!block->proc) {
|
|
|
|
block->proc = rb_vm_make_proc(th, block, rb_cProc);
|
|
|
|
return block->proc;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2015-07-14 13:36:36 -04:00
|
|
|
VALUE envval, blockprocval = 0;
|
2015-07-14 12:23:17 -04:00
|
|
|
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;
|
2015-07-14 12:23:17 -04:00
|
|
|
VALUE *new_ep;
|
2015-07-15 01:43:07 -04:00
|
|
|
int local_size, env_size;
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
if (VM_EP_IN_HEAP_P(th, ep)) {
|
|
|
|
return VM_ENV_EP_ENVVAL(ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
|
2015-07-14 12:23:17 -04:00
|
|
|
if (!VM_EP_LEP_P(ep)) {
|
|
|
|
VALUE *prev_ep = VM_EP_PREV_EP(ep);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
if (!VM_EP_IN_HEAP_P(th, 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);
|
|
|
|
if (VM_CHECK_MODE > 0 && prev_cfp->ep == 0) rb_bug("invalid ep");
|
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);
|
2015-07-14 12:23:17 -04:00
|
|
|
*ep = VM_ENVVAL_PREV_EP_PTR(prev_cfp->ep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_block_t *block = VM_EP_BLOCK_PTR(ep);
|
|
|
|
|
|
|
|
if (block && (blockprocval = vm_make_proc_from_block(th, block)) != Qfalse) {
|
|
|
|
rb_proc_t *p;
|
|
|
|
GetProcPtr(blockprocval, p);
|
|
|
|
*ep = VM_ENVVAL_BLOCK_PTR(&p->block);
|
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)) {
|
2015-07-15 01:43:07 -04:00
|
|
|
local_size = 1 /* cref/me */;
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
2015-07-21 18:52:59 -04:00
|
|
|
local_size = cfp->iseq->body->local_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 /* specval */ +
|
|
|
|
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
|
|
|
|
2015-07-15 01:43:07 -04:00
|
|
|
MEMCPY(env->env, ep - local_size, VALUE, local_size + 1 /* specval */);
|
|
|
|
|
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
|
|
|
|
|
|
|
/*
|
|
|
|
* must happen after TypedData_Wrap_Struct to ensure penvval is markable
|
|
|
|
* in case object allocation triggers GC and clobbers penvval.
|
|
|
|
*/
|
2015-07-14 12:23:17 -04:00
|
|
|
*ep = envval; /* GC mark */
|
2015-07-14 13:36:36 -04:00
|
|
|
|
2015-07-15 01:43:07 -04:00
|
|
|
new_ep = &env->env[local_size];
|
2015-07-14 12:23:17 -04:00
|
|
|
new_ep[1] = envval;
|
|
|
|
if (blockprocval) new_ep[2] = blockprocval;
|
2015-07-14 12:26:10 -04:00
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
/* as Binding */
|
|
|
|
env->block.self = cfp->self;
|
2015-07-14 12:23:17 -04:00
|
|
|
env->block.ep = cfp->ep = new_ep;
|
2006-12-31 10:02:22 -05:00
|
|
|
env->block.iseq = cfp->iseq;
|
2014-09-12 05:22:18 -04:00
|
|
|
env->block.proc = 0;
|
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)) {
|
2006-12-31 10:02:22 -05:00
|
|
|
/* TODO */
|
|
|
|
env->block.iseq = 0;
|
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)
|
|
|
|
{
|
|
|
|
const VALUE *ep = env->block.ep;
|
|
|
|
|
|
|
|
if (VM_EP_LEP_P(ep)) {
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return VM_ENV_EP_ENVVAL(VM_EP_PREV_EP(ep));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2015-07-14 13:36:36 -04:00
|
|
|
while (collect_local_variables_in_iseq(env->block.iseq, vars), (prev_envval = rb_vm_env_prev_envval(env)) != Qfalse) {
|
|
|
|
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
|
|
|
{
|
2015-07-14 13:36:36 -04:00
|
|
|
if (VM_EP_IN_HEAP_P(th, 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;
|
2015-07-14 13:36:36 -04:00
|
|
|
GetEnvPtr(VM_ENV_EP_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);
|
|
|
|
}
|
|
|
|
|
2007-06-24 22:44:20 -04:00
|
|
|
/* Proc */
|
|
|
|
|
2014-09-12 16:57:45 -04:00
|
|
|
static inline VALUE
|
2015-05-16 08:21:25 -04:00
|
|
|
rb_proc_create(VALUE klass, const rb_block_t *block,
|
2015-07-15 01:43:07 -04:00
|
|
|
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
|
|
|
|
|
|
|
proc->block = *block;
|
2015-05-16 08:21:25 -04:00
|
|
|
proc->block.proc = procval;
|
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
|
* 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_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass)
|
2014-11-13 04:10:40 -05:00
|
|
|
{
|
|
|
|
return rb_vm_make_proc_lambda(th, block, klass, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_vm_make_proc_lambda(rb_thread_t *th, const rb_block_t *block, VALUE klass, int8_t is_lambda)
|
2006-12-31 10:02:22 -05:00
|
|
|
{
|
2015-07-15 01:43:07 -04:00
|
|
|
VALUE procval;
|
2008-12-24 07:56:58 -05:00
|
|
|
rb_control_frame_t *cfp = RUBY_VM_GET_CFP_FROM_BLOCK_PTR(block);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2008-12-24 22:51:35 -05:00
|
|
|
if (block->proc) {
|
* 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_bug("rb_vm_make_proc: Proc value is already created.");
|
2008-12-24 22:51:35 -05:00
|
|
|
}
|
|
|
|
|
2015-07-15 01:43:07 -04:00
|
|
|
vm_make_env_object(th, cfp);
|
|
|
|
procval = rb_proc_create(klass, block, (int8_t)th->safe_level, 0, is_lambda);
|
2006-12-31 10:02:22 -05:00
|
|
|
|
2007-06-24 13:19:22 -04:00
|
|
|
if (VMDEBUG) {
|
2012-06-10 23:14:59 -04:00
|
|
|
if (th->stack < block->ep && block->ep < th->stack + th->stack_size) {
|
|
|
|
rb_bug("invalid ptr: block->ep");
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
rb_vm_proc_envval(const rb_proc_t *proc)
|
|
|
|
{
|
|
|
|
VALUE envval = VM_ENV_EP_ENVVAL(proc->block.ep);
|
|
|
|
return envval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
bind->env = envval;
|
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;
|
|
|
|
}
|
|
|
|
|
2013-08-09 05:51:00 -04:00
|
|
|
VALUE *
|
|
|
|
rb_binding_add_dynavars(rb_binding_t *bind, int dyncount, const ID *dynvars)
|
|
|
|
{
|
2015-07-21 18:52:59 -04:00
|
|
|
VALUE envval = bind->env, path = bind->path;
|
2013-08-09 05:51:00 -04:00
|
|
|
rb_env_t *env;
|
|
|
|
rb_block_t *base_block;
|
|
|
|
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;
|
|
|
|
|
|
|
|
GetEnvPtr(envval, env);
|
|
|
|
|
|
|
|
base_block = &env->block;
|
|
|
|
base_iseq = base_block->iseq;
|
|
|
|
|
|
|
|
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 {
|
|
|
|
VALUE tempstr = rb_str_new2("<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);
|
2015-07-14 12:23:17 -04:00
|
|
|
bind->env = vm_make_env_object(th, th->cfp);
|
2013-08-09 05:51:00 -04:00
|
|
|
vm_pop_frame(th);
|
|
|
|
GetEnvPtr(bind->env, env);
|
|
|
|
|
|
|
|
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
|
2015-10-10 16:32:07 -04:00
|
|
|
invoke_block(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const rb_block_t *block, const rb_cref_t *cref, int 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,
|
|
|
|
VM_ENVVAL_PREV_EP_PTR(block->ep),
|
|
|
|
(VALUE)cref, /* cref or method */
|
|
|
|
iseq->body->iseq_encoded + opt_pc,
|
|
|
|
th->cfp->sp + arg_size, iseq->body->local_size - arg_size,
|
|
|
|
iseq->body->stack_max);
|
|
|
|
|
|
|
|
return vm_exec(th);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
invoke_bmethod(rb_thread_t *th, const rb_iseq_t *iseq, VALUE self, const rb_block_t *block, int type, int opt_pc)
|
|
|
|
{
|
|
|
|
/* bmethod */
|
|
|
|
int arg_size = iseq->body->param.size;
|
|
|
|
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
|
|
|
|
VALUE ret;
|
|
|
|
|
|
|
|
th->passed_bmethod_me = NULL;
|
|
|
|
|
|
|
|
vm_push_frame(th, iseq, type | VM_FRAME_FLAG_FINISH | VM_FRAME_FLAG_BMETHOD, self,
|
|
|
|
VM_ENVVAL_PREV_EP_PTR(block->ep),
|
|
|
|
(VALUE)me, /* cref or method (TODO: can we ignore cref?) */
|
|
|
|
iseq->body->iseq_encoded + opt_pc,
|
|
|
|
th->cfp->sp + arg_size, iseq->body->local_size - arg_size,
|
|
|
|
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
|
|
|
|
invoke_block_from_c_0(rb_thread_t *th, const rb_block_t *block,
|
|
|
|
VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr,
|
|
|
|
const rb_cref_t *cref, const int splattable)
|
|
|
|
{
|
2015-10-15 23:21:10 -04:00
|
|
|
if (UNLIKELY(!RTEST(block->iseq))) {
|
2009-10-26 16:58:25 -04:00
|
|
|
return Qnil;
|
2014-06-19 06:49:46 -04:00
|
|
|
}
|
2015-10-10 16:32:07 -04:00
|
|
|
else if (LIKELY(RUBY_VM_NORMAL_ISEQ_P(block->iseq))) {
|
* 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_iseq_t *iseq = block->iseq;
|
2015-10-10 16:32:07 -04:00
|
|
|
int i, opt_pc;
|
2014-06-19 06:49:46 -04:00
|
|
|
int type = block_proc_is_lambda(block->proc) ? VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
|
2015-10-10 16:32:07 -04:00
|
|
|
VALUE *sp = th->cfp->sp;
|
2007-06-05 13:26:00 -04:00
|
|
|
|
2007-01-15 22:06:01 -05:00
|
|
|
for (i=0; i<argc; i++) {
|
2015-10-10 16:32:07 -04:00
|
|
|
sp[i] = argv[i];
|
2007-01-15 22:06:01 -05:00
|
|
|
}
|
2007-06-05 13:26:00 -04:00
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
opt_pc = vm_yield_setup_args(th, iseq, argc, sp, blockptr,
|
* rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-02 13:02:55 -05:00
|
|
|
(type == VM_FRAME_MAGIC_LAMBDA ? (splattable ? arg_setup_lambda : arg_setup_method) : arg_setup_block));
|
2007-01-15 22:06:01 -05:00
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
if (th->passed_bmethod_me == NULL) {
|
|
|
|
return invoke_block(th, iseq, self, block, cref, type, opt_pc);
|
2014-04-30 05:08:10 -04:00
|
|
|
}
|
|
|
|
else {
|
2015-10-10 16:32:07 -04:00
|
|
|
return invoke_bmethod(th, iseq, self, block, type, opt_pc);
|
2014-06-19 06:49:46 -04:00
|
|
|
}
|
|
|
|
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
else {
|
* 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
|
|
|
return vm_yield_with_cfunc(th, block, self, argc, argv, blockptr);
|
2006-12-31 10:02:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
static VALUE
|
|
|
|
invoke_block_from_c_splattable(rb_thread_t *th, const rb_block_t *block,
|
|
|
|
VALUE self, int argc, const VALUE *argv,
|
|
|
|
const rb_block_t *blockptr, const rb_cref_t *cref)
|
|
|
|
{
|
|
|
|
return invoke_block_from_c_0(th, block, self, argc, argv, blockptr, cref, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
invoke_block_from_c_unsplattable(rb_thread_t *th, const rb_block_t *block,
|
|
|
|
VALUE self, int argc, const VALUE *argv,
|
|
|
|
const rb_block_t *blockptr, const rb_cref_t *cref)
|
|
|
|
{
|
|
|
|
return invoke_block_from_c_0(th, block, self, argc, argv, blockptr, cref, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* 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 inline const rb_block_t *
|
2008-05-22 12:19:14 -04:00
|
|
|
check_block(rb_thread_t *th)
|
2007-01-15 22:06:01 -05:00
|
|
|
{
|
2012-06-10 23:14:59 -04:00
|
|
|
const rb_block_t *blockptr = VM_CF_BLOCK_PTR(th->cfp);
|
2007-01-15 22:06:01 -05:00
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
if (UNLIKELY(blockptr == 0)) {
|
* 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
|
|
|
}
|
|
|
|
|
2008-05-19 10:36:13 -04:00
|
|
|
return blockptr;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
* 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_block_t *blockptr = check_block(th);
|
2015-10-10 16:32:07 -04:00
|
|
|
return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, NULL, 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
|
|
|
{
|
* 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_block_t *blockptr = check_block(th);
|
2015-10-10 16:32:07 -04:00
|
|
|
return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, NULL, NULL);
|
2007-01-15 22:06:01 -05:00
|
|
|
}
|
|
|
|
|
2015-10-10 16:32:07 -04:00
|
|
|
static VALUE
|
2013-11-29 03:06:19 -05:00
|
|
|
vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, const rb_block_t *blockargptr)
|
|
|
|
{
|
|
|
|
const rb_block_t *blockptr = check_block(th);
|
2015-10-10 16:32:07 -04:00
|
|
|
return invoke_block_from_c_splattable(th, blockptr, blockptr->self, argc, argv, blockargptr, NULL);
|
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,
|
2012-08-20 07:36:34 -04:00
|
|
|
int argc, const VALUE *argv, const rb_block_t *blockptr)
|
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;
|
2015-10-10 16:32:07 -04:00
|
|
|
val = invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, blockptr, NULL);
|
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) {
|
|
|
|
JUMP_TAG(state);
|
|
|
|
}
|
|
|
|
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,
|
2015-05-20 18:03:06 -04:00
|
|
|
int argc, const VALUE *argv, const rb_block_t *blockptr)
|
|
|
|
{
|
2015-10-10 16:32:07 -04:00
|
|
|
return invoke_block_from_c_unsplattable(th, &proc->block, self, argc, argv, blockptr, NULL);
|
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,
|
|
|
|
int argc, const VALUE *argv, const rb_block_t *blockptr)
|
|
|
|
{
|
2015-05-20 18:03:06 -04:00
|
|
|
VALUE self = proc->block.self;
|
|
|
|
if (proc->is_from_method) {
|
* 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
|
|
|
return vm_invoke_bmethod(th, proc, self, argc, argv, blockptr);
|
2015-05-20 18:03:06 -04:00
|
|
|
}
|
|
|
|
else {
|
* 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
|
|
|
return vm_invoke_proc(th, proc, self, argc, argv, blockptr);
|
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;
|
* 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
|
|
|
|
|
|
|
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
|
|
|
{
|
2008-05-22 12:19:14 -04:00
|
|
|
rb_control_frame_t *cfp = th->cfp;
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep = VM_CF_PREV_EP(cfp);
|
2015-01-15 21:54:22 -05:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
if (klass == rb_cFixnum) return FIXNUM_REDEFINED_OP_FLAG;
|
|
|
|
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_cBignum) return BIGNUM_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;
|
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-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)
|
|
|
|
OP(PLUS, PLUS), (C(Fixnum), C(Float), C(String), C(Array));
|
2012-08-23 03:22:40 -04:00
|
|
|
OP(MINUS, MINUS), (C(Fixnum), C(Float));
|
2007-07-20 03:11:35 -04:00
|
|
|
OP(MULT, MULT), (C(Fixnum), C(Float));
|
|
|
|
OP(DIV, DIV), (C(Fixnum), C(Float));
|
|
|
|
OP(MOD, MOD), (C(Fixnum), C(Float));
|
|
|
|
OP(Eq, EQ), (C(Fixnum), C(Float), C(String));
|
2009-08-12 01:55:06 -04:00
|
|
|
OP(Eqq, EQQ), (C(Fixnum), C(Bignum), C(Float), C(Symbol), C(String));
|
2012-08-23 03:22:40 -04:00
|
|
|
OP(LT, LT), (C(Fixnum), C(Float));
|
|
|
|
OP(LE, LE), (C(Fixnum), C(Float));
|
|
|
|
OP(GT, GT), (C(Fixnum), C(Float));
|
|
|
|
OP(GE, GE), (C(Fixnum), 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));
|
2007-07-20 03:11:35 -04:00
|
|
|
OP(Succ, SUCC), (C(Fixnum), 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));
|
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
|
|
|
|
VALUE *bp; // cfp[2], base pointer
|
|
|
|
rb_iseq_t *iseq; // cfp[3], iseq
|
|
|
|
VALUE flag; // cfp[4], magic
|
|
|
|
VALUE self; // cfp[5], self
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep; // cfp[6], env pointer
|
|
|
|
rb_iseq_t * block_iseq; // cfp[7], block iseq
|
|
|
|
VALUE proc; // cfp[8], always 0
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BLOCK {
|
|
|
|
VALUE self;
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *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_iseq_t *block_iseq;
|
* 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 proc;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct METHOD_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
|
|
|
rb_control_frame_t frame;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct METHOD_FRAME {
|
|
|
|
VALUE arg0;
|
|
|
|
...
|
|
|
|
VALUE argM;
|
|
|
|
VALUE param0;
|
|
|
|
...
|
|
|
|
VALUE paramN;
|
* 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 special; // lep [1]
|
|
|
|
struct block_object *block_ptr | 0x01; // lep [0]
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BLOCK_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
|
|
|
rb_control_frame_t frame;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct BLOCK_FRAME {
|
|
|
|
VALUE arg0;
|
|
|
|
...
|
|
|
|
VALUE argM;
|
|
|
|
VALUE param0;
|
|
|
|
...
|
|
|
|
VALUE paramN;
|
* 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_ptr | 0x01); // ep[0]
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CLASS_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
|
|
|
rb_control_frame_t frame;
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CLASS_FRAME {
|
|
|
|
VALUE param0;
|
|
|
|
...
|
|
|
|
VALUE paramN;
|
* 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
|
2006-12-31 10:02:22 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
struct C_METHOD_CONTROL_FRAME {
|
|
|
|
VALUE *pc; // 0
|
|
|
|
VALUE *sp; // stack pointer
|
|
|
|
VALUE *bp; // base pointer (used in exception)
|
2012-06-10 23:14:59 -04:00
|
|
|
rb_iseq_t *iseq; // cmi
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE magic; // C_METHOD_FRAME
|
|
|
|
VALUE self; // ?
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep; // ep == lep
|
|
|
|
rb_iseq_t * block_iseq; //
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE proc; // always 0
|
|
|
|
};
|
|
|
|
|
|
|
|
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; // ?
|
2006-12-31 10:02:22 -05:00
|
|
|
VALUE magic; // C_METHOD_FRAME
|
|
|
|
VALUE self; // needed?
|
2012-06-10 23:14:59 -04:00
|
|
|
VALUE *ep; // 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_iseq_t * block_iseq; // 0
|
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);
|
|
|
|
RUBY_DTRACE_METHOD_RETURN_HOOK(th,
|
|
|
|
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
|
|
|
}
|
|
|
|
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
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);
|
* 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
|
|
|
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 */
|
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,
|
2012-08-02 07:08:44 -04:00
|
|
|
VM_ENVVAL_PREV_EP_PTR(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,
|
2012-08-02 07:08:44 -04:00
|
|
|
cfp->sp + 1 /* push value */,
|
2015-07-21 18:52:59 -04:00
|
|
|
catch_iseq->body->local_size - 1,
|
|
|
|
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)) {
|
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
|
|
|
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();
|
2006-12-31 10:02:22 -05:00
|
|
|
JUMP_TAG(state);
|
|
|
|
}
|
* 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 {
|
|
|
|
th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
|
|
|
|
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,
|
2010-06-17 10:32:20 -04:00
|
|
|
const rb_block_t *blockptr, 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;
|
|
|
|
|
2015-07-21 18:52:59 -04:00
|
|
|
vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP | VM_FRAME_FLAG_FINISH,
|
* 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
|
|
|
recv, VM_ENVVAL_BLOCK_PTR(blockptr),
|
2015-06-02 00:20:30 -04:00
|
|
|
(VALUE)vm_cref_new_toplevel(th), /* cref or me */
|
|
|
|
0, reg_cfp->sp, 1, 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
|
|
|
|
* vm.c: some refactoring.
* rename th_* to vm_*.
* remove unused variables functions.
* add prototypes.
* blockinlining.c, compile.c, cont.c, eval.c, eval_intern.h,
eval_jump.h, eval_load.c, inits.c, insns.def, iseq.c, parse.y,
proc.c, process.c, signal.c, thread.c, vm.c, vm_dump.c,
vm_evalbody.ci, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-06-24 11:42:41 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
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
|
|
|
{
|
|
|
|
if (ptr) {
|
2009-09-08 22:11:35 -04:00
|
|
|
const rb_vm_t *vmobj = ptr;
|
2012-09-24 04:36:53 -04:00
|
|
|
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
|
|
|
|
|
|
|
size += vmobj->living_thread_num * sizeof(rb_thread_t);
|
|
|
|
|
2012-09-24 04:36:53 -04:00
|
|
|
if (vmobj->defined_strings) {
|
|
|
|
size += DEFINED_EXPR * sizeof(VALUE);
|
|
|
|
}
|
|
|
|
return size;
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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;
|
2010-12-02 06:06:32 -05:00
|
|
|
vm->at_exit.basic.flags = (T_ARRAY | RARRAY_EMBED_FLAG) & ~RARRAY_EMBED_LEN_MASK; /* len set 0 */
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 06:49:11 -04:00
|
|
|
rb_obj_hide((VALUE)&vm->at_exit);
|
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) {
|
|
|
|
rb_gc_mark(cfp->proc);
|
|
|
|
rb_gc_mark(cfp->self);
|
2015-07-21 18:52:59 -04:00
|
|
|
rb_gc_mark((VALUE)cfp->iseq);
|
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
|
|
|
{
|
|
|
|
if (ptr) {
|
2009-09-08 22:11:35 -04:00
|
|
|
const rb_thread_t *th = ptr;
|
2009-06-16 18:23:53 -04:00
|
|
|
size_t size = sizeof(rb_thread_t);
|
|
|
|
|
|
|
|
if (!th->root_fiber) {
|
|
|
|
size += th->stack_size * sizeof(VALUE);
|
|
|
|
}
|
|
|
|
if (th->local_storage) {
|
2011-06-11 01:21:30 -04:00
|
|
|
size += st_memsize(th->local_storage);
|
2009-06-16 18:23:53 -04:00
|
|
|
}
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
2015-06-02 00:20:30 -04:00
|
|
|
vm_push_frame(th, 0 /* dummy iseq */, VM_FRAME_MAGIC_DUMMY | VM_FRAME_FLAG_FINISH /* dummy frame */,
|
* 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
|
|
|
Qnil /* dummy self */, VM_ENVVAL_BLOCK_PTR(0) /* dummy block ptr */,
|
2015-06-02 00:20:30 -04:00
|
|
|
0 /* dummy cref/me */,
|
|
|
|
0 /* dummy pc */, th->stack, 1, 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)
|
|
|
|
{
|
|
|
|
if (!SYMBOL_P(key)) 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)
|
|
|
|
{
|
|
|
|
if (!SYMBOL_P(key)) Check_Type(key, T_SYMBOL);
|
|
|
|
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 */ \
|
|
|
|
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();
|
2008-12-26 20:15:56 -05:00
|
|
|
VALUE filename = rb_str_new2("<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;
|
|
|
|
|
2015-11-13 15:02:19 -05:00
|
|
|
th->cfp->ep[-1] = (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
|
|
|
|
|
|
|
VALUE *
|
|
|
|
ruby_vm_verbose_ptr(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
return &vm->verbose;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE *
|
|
|
|
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 */
|