зеркало из https://github.com/github/ruby.git
* 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
This commit is contained in:
Родитель
2e601474e7
Коммит
6b6bf4dd48
49
ChangeLog
49
ChangeLog
|
@ -1,3 +1,52 @@
|
|||
Thu Jul 12 12:58:21 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* 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.
|
||||
|
||||
Thu Jul 12 12:24:29 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* insns.def (opt_succ): fixed typo. [ruby-dev:31189]
|
||||
|
|
9
array.c
9
array.c
|
@ -1136,20 +1136,11 @@ each_i(VALUE ary)
|
|||
* a -- b -- c --
|
||||
*/
|
||||
|
||||
VALUE yarv_invoke_Array_each_special_block(VALUE ary);
|
||||
|
||||
VALUE
|
||||
rb_ary_each(VALUE ary)
|
||||
{
|
||||
VALUE val;
|
||||
|
||||
RETURN_ENUMERATOR(ary, 0, 0);
|
||||
|
||||
val = yarv_invoke_Array_each_special_block(ary);
|
||||
if(val != Qundef){
|
||||
return val;
|
||||
}
|
||||
|
||||
ITERATE(each_i, ary);
|
||||
return ary;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,10 @@
|
|||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/node.h"
|
||||
#include "yarvcore.h"
|
||||
|
||||
VALUE yarv_new_iseqval(VALUE node, VALUE name, VALUE file,
|
||||
VALUE parent, VALUE type, VALUE block_opt, VALUE opt);
|
||||
#include "vm_core.h"
|
||||
|
||||
static VALUE
|
||||
yarv_iseq_special_block(rb_iseq_t *iseq, void *builder)
|
||||
iseq_special_block(rb_iseq_t *iseq, void *builder)
|
||||
{
|
||||
#if OPT_BLOCKINLINING
|
||||
VALUE parent = Qfalse;
|
||||
|
@ -181,14 +178,14 @@ build_Integer_times_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
|
|||
}
|
||||
|
||||
VALUE
|
||||
yarv_invoke_Integer_times_special_block(VALUE num)
|
||||
invoke_Integer_times_special_block(VALUE num)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
|
||||
|
||||
if (orig_block && BUILTIN_TYPE(orig_block->iseq) != T_NODE) {
|
||||
VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq,
|
||||
build_Integer_times_node);
|
||||
VALUE tsiseqval = iseq_special_block(orig_block->iseq,
|
||||
build_Integer_times_node);
|
||||
rb_iseq_t *tsiseq;
|
||||
VALUE argv[2], val;
|
||||
|
||||
|
@ -297,8 +294,8 @@ build_Range_each_node_LT(rb_iseq_t *iseq, NODE * node, NODE * lnode,
|
|||
}
|
||||
|
||||
VALUE
|
||||
yarv_invoke_Range_each_special_block(VALUE range,
|
||||
VALUE beg, VALUE end, int excl)
|
||||
invoke_Range_each_special_block(VALUE range,
|
||||
VALUE beg, VALUE end, int excl)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
|
||||
|
@ -306,7 +303,7 @@ yarv_invoke_Range_each_special_block(VALUE range,
|
|||
if (BUILTIN_TYPE(orig_block->iseq) != T_NODE) {
|
||||
void *builder =
|
||||
excl ? build_Range_each_node_LT : build_Range_each_node_LE;
|
||||
VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq, builder);
|
||||
VALUE tsiseqval = iseq_special_block(orig_block->iseq, builder);
|
||||
rb_iseq_t *tsiseq;
|
||||
VALUE argv[2];
|
||||
|
||||
|
@ -429,14 +426,14 @@ build_Array_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
|
|||
}
|
||||
|
||||
VALUE
|
||||
yarv_invoke_Array_each_special_block(VALUE ary)
|
||||
invoke_Array_each_special_block(VALUE ary)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
rb_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
|
||||
|
||||
if (BUILTIN_TYPE(orig_block->iseq) != T_NODE) {
|
||||
VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq,
|
||||
build_Array_each_node);
|
||||
VALUE tsiseqval = iseq_special_block(orig_block->iseq,
|
||||
build_Array_each_node);
|
||||
rb_iseq_t *tsiseq;
|
||||
VALUE argv[2];
|
||||
|
||||
|
|
37
common.mk
37
common.mk
|
@ -73,9 +73,9 @@ OBJS = array.$(OBJEXT) \
|
|||
iseq.$(OBJEXT) \
|
||||
vm.$(OBJEXT) \
|
||||
vm_dump.$(OBJEXT) \
|
||||
yarvcore.$(OBJEXT) \
|
||||
thread.$(OBJEXT) \
|
||||
cont.$(OBJEXT) \
|
||||
id.$(OBJEXT) \
|
||||
$(MISSING)
|
||||
|
||||
SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \
|
||||
|
@ -404,13 +404,13 @@ enumerator.$(OBJEXT): {$(VPATH)}enumerator.c {$(VPATH)}ruby.h {$(VPATH)}config.h
|
|||
error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}st.h {$(VPATH)}vm_opts.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}yarvcore.h {$(VPATH)}node.h {$(VPATH)}debug.h \
|
||||
{$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}node.h {$(VPATH)}debug.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
euc_jp.$(OBJEXT): {$(VPATH)}euc_jp.c {$(VPATH)}regenc.h \
|
||||
{$(VPATH)}oniguruma.h {$(VPATH)}config.h
|
||||
eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_error.ci {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}eval_method.ci {$(VPATH)}eval_safe.ci {$(VPATH)}eval_jump.ci \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}yarvcore.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}vm_core.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}debug.h \
|
||||
|
@ -418,7 +418,7 @@ eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_error.ci {$(VPATH)}eval_intern.h
|
|||
eval_load.$(OBJEXT): {$(VPATH)}eval_load.c {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}yarvcore.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}vm_core.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}debug.h \
|
||||
{$(VPATH)}vm_opts.h {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
file.$(OBJEXT): {$(VPATH)}file.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
|
@ -429,7 +429,7 @@ gc.$(OBJEXT): {$(VPATH)}gc.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
|||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}node.h \
|
||||
{$(VPATH)}re.h {$(VPATH)}regex.h {$(VPATH)}oniguruma.h \
|
||||
{$(VPATH)}yarvcore.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
hash.$(OBJEXT): {$(VPATH)}hash.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
|
@ -461,7 +461,7 @@ parse.$(OBJEXT): {$(VPATH)}parse.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
|||
prec.$(OBJEXT): {$(VPATH)}prec.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h
|
||||
proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}yarvcore.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}vm_core.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}gc.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}dln.h \
|
||||
|
@ -469,7 +469,7 @@ proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \
|
|||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
process.$(OBJEXT): {$(VPATH)}process.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}yarvcore.h
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}vm_core.h {$(VPATH)}id.h
|
||||
random.$(OBJEXT): {$(VPATH)}random.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h
|
||||
range.$(OBJEXT): {$(VPATH)}range.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
|
@ -506,7 +506,7 @@ ruby.$(OBJEXT): {$(VPATH)}ruby.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
|||
{$(VPATH)}dln.h {$(VPATH)}node.h {$(VPATH)}util.h
|
||||
signal.$(OBJEXT): {$(VPATH)}signal.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}yarvcore.h {$(VPATH)}node.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}node.h \
|
||||
{$(VPATH)}debug.h {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
sjis.$(OBJEXT): {$(VPATH)}sjis.c {$(VPATH)}regenc.h \
|
||||
|
@ -524,12 +524,12 @@ struct.$(OBJEXT): {$(VPATH)}struct.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
|||
thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}thread_win32.h {$(VPATH)}thread_pthread.h \
|
||||
{$(VPATH)}thread_win32.ci {$(VPATH)}thread_pthread.ci \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}yarvcore.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}dln.h
|
||||
cont.$(OBJEXT): {$(VPATH)}cont.c {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}yarvcore.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}st.h {$(VPATH)}dln.h
|
||||
|
@ -549,19 +549,19 @@ version.$(OBJEXT): {$(VPATH)}version.c {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
|||
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}version.h
|
||||
|
||||
compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}yarvcore.h \
|
||||
compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}vm_core.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}compile.h {$(VPATH)}debug.h {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
|
||||
{$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}insns_info.inc {$(VPATH)}optinsn.inc \
|
||||
{$(VPATH)}opt_sc.inc {$(VPATH)}optunifs.inc {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}yarvcore.h {$(VPATH)}debug.h \
|
||||
iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}debug.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}defines.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}gc.h {$(VPATH)}vm_opts.h {$(VPATH)}config.h {$(VPATH)}node.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}insns_info.inc
|
||||
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}yarvcore.h \
|
||||
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}vm_core.h {$(VPATH)}id.h \
|
||||
{$(VPATH)}debug.h {$(VPATH)}ruby.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}dln.h \
|
||||
{$(VPATH)}insnhelper.h {$(VPATH)}insnhelper.ci {$(VPATH)}vm_evalbody.ci \
|
||||
|
@ -569,25 +569,20 @@ vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}yarvcore.h \
|
|||
{$(VPATH)}vm_opts.h {$(VPATH)}eval_intern.h \
|
||||
{$(VPATH)}defines.h {$(VPATH)}missing.h {$(VPATH)}intern.h \
|
||||
{$(VPATH)}gc.h {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c {$(VPATH)}yarvcore.h {$(VPATH)}vm.h \
|
||||
vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}vm.h \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h {$(VPATH)}missing.h \
|
||||
{$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}debug.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}vm_opts.h {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
yarvcore.$(OBJEXT): {$(VPATH)}yarvcore.c {$(VPATH)}yarvcore.h \
|
||||
{$(VPATH)}debug.h {$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h \
|
||||
{$(VPATH)}missing.h {$(VPATH)}intern.h {$(VPATH)}st.h \
|
||||
{$(VPATH)}signal.h {$(VPATH)}node.h {$(VPATH)}gc.h {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
debug.$(OBJEXT): {$(VPATH)}debug.h {$(VPATH)}ruby.h {$(VPATH)}defines.h \
|
||||
{$(VPATH)}missing.h {$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}st.h
|
||||
blockinlining.$(OBJEXT): {$(VPATH)}blockinlining.c \
|
||||
{$(VPATH)}ruby.h {$(VPATH)}defines.h \
|
||||
{$(VPATH)}missing.h {$(VPATH)}intern.h {$(VPATH)}st.h {$(VPATH)}config.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}yarvcore.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}node.h {$(VPATH)}vm_core.h {$(VPATH)}id.h {$(VPATH)}signal.h \
|
||||
{$(VPATH)}debug.h {$(VPATH)}vm_opts.h \
|
||||
{$(VPATH)}thread_$(THREAD_MODEL).h
|
||||
|
||||
id.$(OBJEXT): {$(VPATH)}id.c {$(VPATH)}ruby.h
|
||||
|
||||
MATZRUBY = $(MATZRUBYDIR)ruby
|
||||
|
||||
|
|
97
compile.c
97
compile.c
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************
|
||||
|
||||
compile.c - ruby node tree -> yarv instruction sequence
|
||||
compile.c - ruby node tree -> VM instruction sequence
|
||||
|
||||
$Author$
|
||||
$Date$
|
||||
|
@ -13,12 +13,11 @@
|
|||
#include "ruby/ruby.h"
|
||||
#include "ruby/node.h"
|
||||
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
#include "compile.h"
|
||||
#include "insns.inc"
|
||||
#include "insns_info.inc"
|
||||
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
#include <stdarg.h>
|
||||
#define va_init_list(a,b) va_start(a,b)
|
||||
|
@ -27,8 +26,12 @@
|
|||
#define va_init_list(a,b) va_start(a)
|
||||
#endif
|
||||
|
||||
/* iseq.c */
|
||||
VALUE iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt);
|
||||
|
||||
/* vm.c */
|
||||
VALUE vm_eval(void *);
|
||||
|
||||
/* types */
|
||||
|
||||
#define ISEQ_ELEMENT_NONE INT2FIX(0x00)
|
||||
|
@ -77,6 +80,10 @@ struct iseq_compile_data_ensure_node_stack {
|
|||
struct ensure_range *erange;
|
||||
};
|
||||
|
||||
#include "optinsn.inc"
|
||||
#if OPT_INSTRUCTIONS_UNIFICATION
|
||||
#include "optunifs.inc"
|
||||
#endif
|
||||
|
||||
/* for debug */
|
||||
#if CPDEBUG > 0
|
||||
|
@ -92,24 +99,22 @@ static int calc_sp_depth(int depth, INSN *iobj);
|
|||
|
||||
static void ADD_ELEM(LINK_ANCHOR *anchor, LINK_ELEMENT *elem);
|
||||
|
||||
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no,
|
||||
int insn_id, int argc, ...);
|
||||
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, int insn_id, int argc, ...);
|
||||
static LABEL *new_label_body(rb_iseq_t *iseq, int line);
|
||||
|
||||
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
|
||||
NODE * n, int);
|
||||
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * n, int);
|
||||
static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
|
||||
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
static int set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
static int set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
|
||||
static int set_exception_table(rb_iseq_t *iseq);
|
||||
static int set_local_table(rb_iseq_t *iseq, ID *tbl);
|
||||
static int set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * node);
|
||||
static int set_exception_tbl(rb_iseq_t *iseq);
|
||||
static int set_optargs_table(rb_iseq_t *iseq);
|
||||
static int iseq_set_local_table(rb_iseq_t *iseq, ID *tbl);
|
||||
static int iseq_set_exception_local_table(rb_iseq_t *iseq);
|
||||
static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * node);
|
||||
|
||||
static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
|
||||
static int iseq_set_exception_table(rb_iseq_t *iseq);
|
||||
static int iseq_set_optargs_table(rb_iseq_t *iseq);
|
||||
|
||||
static int
|
||||
iseq_add_mark_object(rb_iseq_t *iseq, VALUE v)
|
||||
|
@ -129,15 +134,8 @@ iseq_add_mark_object_compile_time(rb_iseq_t *iseq, VALUE v)
|
|||
return COMPILE_OK;
|
||||
}
|
||||
|
||||
|
||||
#include "optinsn.inc"
|
||||
|
||||
#if OPT_INSTRUCTIONS_UNIFICATION
|
||||
#include "optunifs.inc"
|
||||
#endif
|
||||
|
||||
VALUE
|
||||
rb_iseq_compile(VALUE self, NODE *node)
|
||||
iseq_compile(VALUE self, NODE *node)
|
||||
{
|
||||
DECL_ANCHOR(ret);
|
||||
rb_iseq_t *iseq;
|
||||
|
@ -148,8 +146,8 @@ rb_iseq_compile(VALUE self, NODE *node)
|
|||
}
|
||||
else if (nd_type(node) == NODE_SCOPE) {
|
||||
/* iseq type of top, method, class, block */
|
||||
set_local_table(iseq, node->nd_tbl);
|
||||
set_arguments(iseq, ret, node->nd_args);
|
||||
iseq_set_local_table(iseq, node->nd_tbl);
|
||||
iseq_set_arguments(iseq, ret, node->nd_args);
|
||||
|
||||
switch (iseq->type) {
|
||||
case ISEQ_TYPE_BLOCK: {
|
||||
|
@ -195,11 +193,11 @@ rb_iseq_compile(VALUE self, NODE *node)
|
|||
__FILE__, __LINE__);
|
||||
break;
|
||||
case ISEQ_TYPE_RESCUE:
|
||||
set_exception_tbl(iseq);
|
||||
iseq_set_exception_local_table(iseq);
|
||||
COMPILE(ret, "rescue", node);
|
||||
break;
|
||||
case ISEQ_TYPE_ENSURE:
|
||||
set_exception_tbl(iseq);
|
||||
iseq_set_exception_local_table(iseq);
|
||||
COMPILE_POPED(ret, "ensure", node);
|
||||
break;
|
||||
case ISEQ_TYPE_DEFINED_GUARD:
|
||||
|
@ -221,8 +219,6 @@ rb_iseq_compile(VALUE self, NODE *node)
|
|||
return iseq_setup(iseq, ret);
|
||||
}
|
||||
|
||||
VALUE vm_eval(void *);
|
||||
|
||||
int
|
||||
iseq_translate_threaded_code(rb_iseq_t *iseq)
|
||||
{
|
||||
|
@ -678,22 +674,22 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
}
|
||||
|
||||
if (iseq->compile_data->option->stack_caching) {
|
||||
debugs("[compile step 3.3 (set_sequence_stackcaching)]\n");
|
||||
set_sequence_stackcaching(iseq, anchor);
|
||||
debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
|
||||
iseq_set_sequence_stackcaching(iseq, anchor);
|
||||
if (CPDEBUG > 5)
|
||||
dump_disasm_list(FIRST_ELEMENT(anchor));
|
||||
}
|
||||
|
||||
debugs("[compile step 4.1 (set_sequence)]\n");
|
||||
set_sequence(iseq, anchor);
|
||||
debugs("[compile step 4.1 (iseq_set_sequence)]\n");
|
||||
iseq_set_sequence(iseq, anchor);
|
||||
if (CPDEBUG > 5)
|
||||
dump_disasm_list(FIRST_ELEMENT(anchor));
|
||||
|
||||
debugs("[compile step 4.2 (set_exception_table)]\n");
|
||||
set_exception_table(iseq);
|
||||
debugs("[compile step 4.2 (iseq_set_exception_table)]\n");
|
||||
iseq_set_exception_table(iseq);
|
||||
|
||||
debugs("[compile step 4.3 (set_optargs_table)] \n");
|
||||
set_optargs_table(iseq);
|
||||
iseq_set_optargs_table(iseq);
|
||||
|
||||
debugs("[compile step 5 (iseq_translate_threaded_code)] \n");
|
||||
iseq_translate_threaded_code(iseq);
|
||||
|
@ -708,15 +704,8 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
VALUE
|
||||
iseq_assemble_setup(VALUE self, VALUE args, VALUE locals, VALUE insn_ary)
|
||||
{
|
||||
/* unsupported */
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
int
|
||||
set_exception_tbl(rb_iseq_t *iseq)
|
||||
static int
|
||||
iseq_set_exception_local_table(rb_iseq_t *iseq)
|
||||
{
|
||||
static ID id_dollar_bang;
|
||||
|
||||
|
@ -778,9 +767,9 @@ get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
|
|||
}
|
||||
|
||||
static int
|
||||
set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
||||
iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
||||
{
|
||||
debugs("set_arguments: %s\n", node_args ? "" : "0");
|
||||
debugs("iseq_set_arguments: %s\n", node_args ? "" : "0");
|
||||
|
||||
if (node_args) {
|
||||
NODE *node_aux = node_args->nd_next;
|
||||
|
@ -791,7 +780,7 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
NODE *node_init = 0;
|
||||
|
||||
if (nd_type(node_args) != NODE_ARGS) {
|
||||
rb_bug("set_arguments: NODE_ARGS is expected, but %s",
|
||||
rb_bug("iseq_set_arguments: NODE_ARGS is expected, but %s",
|
||||
ruby_node_name(nd_type(node_args)));
|
||||
}
|
||||
|
||||
|
@ -925,7 +914,7 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
}
|
||||
|
||||
static int
|
||||
set_local_table(rb_iseq_t *iseq, ID *tbl)
|
||||
iseq_set_local_table(rb_iseq_t *iseq, ID *tbl)
|
||||
{
|
||||
int size;
|
||||
|
||||
|
@ -950,7 +939,7 @@ set_local_table(rb_iseq_t *iseq, ID *tbl)
|
|||
iseq->local_size += 1 /* svar */;
|
||||
}
|
||||
|
||||
debugs("set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
|
||||
debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
|
||||
return COMPILE_OK;
|
||||
}
|
||||
|
||||
|
@ -958,7 +947,7 @@ set_local_table(rb_iseq_t *iseq, ID *tbl)
|
|||
ruby insn object array -> raw instruction sequence
|
||||
*/
|
||||
static int
|
||||
set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||
iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||
{
|
||||
LABEL *lobj;
|
||||
INSN *iobj;
|
||||
|
@ -1177,7 +1166,7 @@ label_get_sp(LABEL *lobj)
|
|||
}
|
||||
|
||||
static int
|
||||
set_exception_table(rb_iseq_t *iseq)
|
||||
iseq_set_exception_table(rb_iseq_t *iseq)
|
||||
{
|
||||
VALUE *tptr, *ptr;
|
||||
int tlen, i;
|
||||
|
@ -1235,7 +1224,7 @@ set_exception_table(rb_iseq_t *iseq)
|
|||
* expr2
|
||||
*/
|
||||
static int
|
||||
set_optargs_table(rb_iseq_t *iseq)
|
||||
iseq_set_optargs_table(rb_iseq_t *iseq)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1664,7 +1653,7 @@ label_set_sc_state(LABEL *lobj, int state)
|
|||
#endif
|
||||
|
||||
static int
|
||||
set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||
iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
||||
{
|
||||
#if OPT_STACK_CACHING
|
||||
LINK_ELEMENT *list;
|
||||
|
|
10
compile.h
10
compile.h
|
@ -13,12 +13,6 @@
|
|||
#ifndef RUBY_COMPILE_H
|
||||
#define RUBY_COMPILE_H
|
||||
|
||||
|
||||
#if YARVDEBUG > CPDEBUG
|
||||
#undef CPDEBUG
|
||||
#define CPDEBUG YARVDEBUG
|
||||
#endif
|
||||
|
||||
/* */
|
||||
/**
|
||||
* debug function(macro) interface depend on CPDEBUG
|
||||
|
@ -32,6 +26,10 @@
|
|||
* 10: show every AST array
|
||||
*/
|
||||
|
||||
#ifndef CPDEBUG
|
||||
#define CPDEBUG 0
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#undef CPDEBUG
|
||||
#define CPDEBUG 2
|
||||
|
|
2
cont.c
2
cont.c
|
@ -11,7 +11,7 @@
|
|||
**********************************************************************/
|
||||
|
||||
#include "ruby/ruby.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
#include "gc.h"
|
||||
#include "eval_intern.h"
|
||||
|
||||
|
|
2
debug.c
2
debug.c
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "ruby/ruby.h"
|
||||
#include "debug.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
|
||||
void
|
||||
ruby_debug_print_indent(int level, int debug_level, int indent_level)
|
||||
|
|
6
error.c
6
error.c
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/st.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -197,7 +197,7 @@ rb_warn_m(VALUE self, VALUE mesg)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
void yarv_bug(void);
|
||||
void rb_vm_bugreport(void);
|
||||
|
||||
static void
|
||||
report_bug(const char *file, int line, const char *fmt, va_list args)
|
||||
|
@ -208,7 +208,7 @@ report_bug(const char *file, int line, const char *fmt, va_list args)
|
|||
|
||||
if (fwrite(buf, 1, len, out) == len ||
|
||||
fwrite(buf, 1, len, (out = stdout)) == len) {
|
||||
yarv_bug();
|
||||
rb_vm_bugreport();
|
||||
fputs("[BUG] ", out);
|
||||
vfprintf(out, fmt, args);
|
||||
fprintf(out, "\nruby %s (%s) [%s]\n\n",
|
||||
|
|
29
eval.c
29
eval.c
|
@ -32,8 +32,6 @@ VALUE rb_eSysStackError;
|
|||
VALUE exception_error;
|
||||
VALUE sysstack_error;
|
||||
|
||||
extern VALUE ruby_top_self;
|
||||
|
||||
static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
|
||||
|
||||
static inline VALUE rb_yield_0(int argc, VALUE *argv);
|
||||
|
@ -63,7 +61,7 @@ void rb_call_inits _((void));
|
|||
void Init_stack _((VALUE *));
|
||||
void Init_heap _((void));
|
||||
void Init_ext _((void));
|
||||
void Init_yarv(void);
|
||||
void Init_BareVM(void);
|
||||
|
||||
void
|
||||
ruby_init(void)
|
||||
|
@ -82,7 +80,7 @@ ruby_init(void)
|
|||
#endif
|
||||
|
||||
Init_stack((void *)&state);
|
||||
Init_yarv();
|
||||
Init_BareVM();
|
||||
Init_heap();
|
||||
|
||||
PUSH_TAG();
|
||||
|
@ -214,7 +212,7 @@ ruby_cleanup(int ex)
|
|||
}
|
||||
|
||||
int
|
||||
ruby_exec_node(void *n)
|
||||
ruby_exec_node(void *n, char *file)
|
||||
{
|
||||
int state;
|
||||
VALUE val;
|
||||
|
@ -226,8 +224,10 @@ ruby_exec_node(void *n)
|
|||
PUSH_TAG();
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
SAVE_ROOT_JMPBUF(th, {
|
||||
VALUE iseq = rb_iseq_new(n, rb_str_new2("<main>"),
|
||||
rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP);
|
||||
th->base_block = 0;
|
||||
val = yarvcore_eval_parsed(node, rb_str_new2(node->nd_file));
|
||||
val = rb_iseq_eval(iseq);
|
||||
});
|
||||
}
|
||||
POP_TAG();
|
||||
|
@ -243,17 +243,18 @@ ruby_stop(int ex)
|
|||
int
|
||||
ruby_run_node(void *n)
|
||||
{
|
||||
NODE *node = (NODE *)n;
|
||||
if (!n) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
Init_stack((void *)&n);
|
||||
return ruby_cleanup(ruby_exec_node(n));
|
||||
return ruby_cleanup(ruby_exec_node(node, node->nd_file));
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_eval_string(const char *str)
|
||||
{
|
||||
return eval(ruby_top_self, rb_str_new2(str), Qnil, "(eval)", 1);
|
||||
return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -272,7 +273,7 @@ rb_eval_string_wrap(const char *str, int *state)
|
|||
VALUE val;
|
||||
|
||||
th->top_wrapper = rb_module_new();
|
||||
th->top_self = rb_obj_clone(ruby_top_self);
|
||||
th->top_self = rb_obj_clone(rb_vm_top_self());
|
||||
rb_extend_object(th->top_self, th->top_wrapper);
|
||||
|
||||
val = rb_eval_string_protect(str, &status);
|
||||
|
@ -318,7 +319,7 @@ rb_eval_cmd(VALUE cmd, VALUE arg, int level)
|
|||
|
||||
PUSH_TAG();
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
val = eval(ruby_top_self, cmd, Qnil, 0, 0);
|
||||
val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0);
|
||||
}
|
||||
POP_TAG();
|
||||
|
||||
|
@ -1679,7 +1680,7 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
|
|||
|
||||
/* make eval iseq */
|
||||
th->parse_in_eval++;
|
||||
iseqval = vm_compile(th, src, rb_str_new2(file), INT2FIX(line));
|
||||
iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
|
||||
th->parse_in_eval--;
|
||||
rb_vm_set_eval_stack(th, iseqval);
|
||||
th->base_block = 0;
|
||||
|
@ -2710,9 +2711,9 @@ Init_eval(void)
|
|||
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
|
||||
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, -1);
|
||||
|
||||
rb_define_singleton_method(ruby_top_self, "include", top_include, -1);
|
||||
rb_define_singleton_method(ruby_top_self, "public", top_public, -1);
|
||||
rb_define_singleton_method(ruby_top_self, "private", top_private, -1);
|
||||
rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
|
||||
rb_define_singleton_method(rb_vm_top_self(), "public", top_public, -1);
|
||||
rb_define_singleton_method(rb_vm_top_self(), "private", top_private, -1);
|
||||
|
||||
rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "ruby/node.h"
|
||||
#include "ruby/util.h"
|
||||
#include "ruby/signal.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
|
@ -195,8 +195,6 @@ NORETURN(void print_undef _((VALUE, ID)));
|
|||
NORETURN(void vm_localjump_error(const char *, VALUE, int));
|
||||
NORETURN(void vm_jump_tag_but_local_jump(int, VALUE));
|
||||
|
||||
VALUE vm_compile(rb_thread_t *th, VALUE str, VALUE file, VALUE line);
|
||||
|
||||
NODE *vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp);
|
||||
NODE *vm_cref_push(rb_thread_t *th, VALUE, int);
|
||||
NODE *vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack);
|
||||
|
@ -228,6 +226,7 @@ void rb_vm_check_redefinition_opt_method(NODE *node);
|
|||
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename);
|
||||
void rb_thread_terminate_all(void);
|
||||
void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq);
|
||||
VALUE rb_vm_top_self();
|
||||
|
||||
#define ruby_cbase() vm_get_cbase(GET_THREAD())
|
||||
|
||||
|
|
10
eval_load.c
10
eval_load.c
|
@ -4,8 +4,6 @@
|
|||
|
||||
#include "eval_intern.h"
|
||||
|
||||
extern VALUE ruby_top_self;
|
||||
|
||||
VALUE ruby_dln_librefs;
|
||||
|
||||
#define IS_SOEXT(e) (strcmp(e, ".so") == 0 || strcmp(e, ".o") == 0)
|
||||
|
@ -157,7 +155,7 @@ rb_load(VALUE fname, int wrap)
|
|||
}
|
||||
else {
|
||||
/* load in anonymous module as toplevel */
|
||||
th->top_self = rb_obj_clone(ruby_top_self);
|
||||
th->top_self = rb_obj_clone(rb_vm_top_self());
|
||||
th->top_wrapper = rb_module_new();
|
||||
rb_extend_object(th->top_self, th->top_wrapper);
|
||||
}
|
||||
|
@ -175,7 +173,7 @@ rb_load(VALUE fname, int wrap)
|
|||
loaded = Qtrue;
|
||||
iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
|
||||
fname, Qfalse, ISEQ_TYPE_TOP);
|
||||
rb_thread_eval(th, iseq);
|
||||
rb_iseq_eval(iseq);
|
||||
}
|
||||
POP_TAG();
|
||||
|
||||
|
@ -435,7 +433,7 @@ rb_require_safe(VALUE fname, int safe)
|
|||
break;
|
||||
|
||||
case 's':
|
||||
handle = (long)rb_vm_call_cfunc(ruby_top_self, load_ext,
|
||||
handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
|
||||
path, 0, path);
|
||||
rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
|
||||
break;
|
||||
|
@ -482,7 +480,7 @@ void
|
|||
ruby_init_ext(const char *name, void (*init)(void))
|
||||
{
|
||||
if (load_lock(name)) {
|
||||
rb_vm_call_cfunc(ruby_top_self, init_ext_call, (VALUE)init,
|
||||
rb_vm_call_cfunc(rb_vm_top_self(), init_ext_call, (VALUE)init,
|
||||
0, rb_str_new2(name));
|
||||
rb_provide(name);
|
||||
load_unlock(name);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <ruby/ruby.h>
|
||||
#include <yarvcore.h>
|
||||
#include <vm_core.h>
|
||||
|
||||
VALUE rb_thread_current_status(rb_thread_t *);
|
||||
void rb_add_event_hook(rb_event_hook_func_t, rb_event_flag_t, VALUE);
|
||||
|
|
4
gc.c
4
gc.c
|
@ -17,7 +17,7 @@
|
|||
#include "ruby/st.h"
|
||||
#include "ruby/node.h"
|
||||
#include "ruby/re.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
#include "gc.h"
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
@ -1455,7 +1455,7 @@ garbage_collect(void)
|
|||
}
|
||||
|
||||
void
|
||||
yarv_machine_stack_mark(rb_thread_t *th)
|
||||
rb_gc_mark_machine_stack(rb_thread_t *th)
|
||||
{
|
||||
#if STACK_GROW_DIRECTION < 0
|
||||
rb_gc_mark_locations(th->machine_stack_end, th->machine_stack_start);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/**********************************************************************
|
||||
|
||||
id.c -
|
||||
|
||||
$Author$
|
||||
$Date$
|
||||
created at: Thu Jul 12 04:37:51 2007
|
||||
|
||||
Copyright (C) 2004-2006 Koichi Sasada
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "ruby/ruby.h"
|
||||
|
||||
#define extern
|
||||
#include "id.h"
|
||||
#undef extern
|
||||
|
||||
void
|
||||
Init_id(void)
|
||||
{
|
||||
/* Symbols */
|
||||
symIFUNC = ID2SYM(rb_intern("<IFUNC>"));
|
||||
symCFUNC = ID2SYM(rb_intern("<CFUNC>"));
|
||||
|
||||
/* IDs */
|
||||
idPLUS = rb_intern("+");
|
||||
idMINUS = rb_intern("-");
|
||||
idMULT = rb_intern("*");
|
||||
idDIV = rb_intern("/");
|
||||
idMOD = rb_intern("%");
|
||||
idLT = rb_intern("<");
|
||||
idLTLT = rb_intern("<<");
|
||||
idLE = rb_intern("<=");
|
||||
idGT = rb_intern(">");
|
||||
idGE = rb_intern(">=");
|
||||
idEq = rb_intern("==");
|
||||
idEqq = rb_intern("===");
|
||||
idBackquote = rb_intern("`");
|
||||
idEqTilde = rb_intern("=~");
|
||||
|
||||
idAREF = rb_intern("[]");
|
||||
idASET = rb_intern("[]=");
|
||||
|
||||
idEach = rb_intern("each");
|
||||
idTimes = rb_intern("times");
|
||||
idLength = rb_intern("length");
|
||||
idLambda = rb_intern("lambda");
|
||||
idIntern = rb_intern("intern");
|
||||
idGets = rb_intern("gets");
|
||||
idSucc = rb_intern("succ");
|
||||
idEnd = rb_intern("end");
|
||||
idRangeEachLT = rb_intern("Range#each#LT");
|
||||
idRangeEachLE = rb_intern("Range#each#LE");
|
||||
idArrayEach = rb_intern("Array#each");
|
||||
idMethodMissing = rb_intern("method_missing");
|
||||
|
||||
idThrowState = rb_intern("#__ThrowState__");
|
||||
|
||||
idBitblt = rb_intern("bitblt");
|
||||
idAnswer = rb_intern("the_answer_to_life_the_universe_and_everything");
|
||||
|
||||
idSend = rb_intern("send");
|
||||
id__send__ = rb_intern("__send__");
|
||||
id__send = rb_intern("__send");
|
||||
idFuncall = rb_intern("funcall");
|
||||
id__send_bang = rb_intern("__send!");
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/**********************************************************************
|
||||
|
||||
id.h -
|
||||
|
||||
$Author: ko1 $
|
||||
$Date: $
|
||||
created at: Thu Jul 12 04:38:07 2007
|
||||
|
||||
Copyright (C) 2007 Koichi Sasada
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
extern VALUE symIFUNC;
|
||||
extern VALUE symCFUNC;
|
||||
|
||||
extern ID idPLUS;
|
||||
extern ID idMINUS;
|
||||
extern ID idMULT;
|
||||
extern ID idDIV;
|
||||
extern ID idMOD;
|
||||
extern ID idLT;
|
||||
extern ID idLTLT;
|
||||
extern ID idLE;
|
||||
extern ID idGT;
|
||||
extern ID idGE;
|
||||
extern ID idEq;
|
||||
extern ID idEqq;
|
||||
extern ID idBackquote;
|
||||
extern ID idEqTilde;
|
||||
extern ID idThrowState;
|
||||
extern ID idAREF;
|
||||
extern ID idASET;
|
||||
extern ID idIntern;
|
||||
extern ID idMethodMissing;
|
||||
extern ID idLength;
|
||||
extern ID idGets;
|
||||
extern ID idSucc;
|
||||
extern ID idEach;
|
||||
extern ID idLambda;
|
||||
extern ID idRangeEachLT;
|
||||
extern ID idRangeEachLE;
|
||||
extern ID idArrayEach;
|
||||
extern ID idTimes;
|
||||
extern ID idEnd;
|
||||
extern ID idBitblt;
|
||||
extern ID idAnswer;
|
||||
extern ID idSend;
|
||||
extern ID id__send__;
|
||||
extern ID id__send;
|
||||
extern ID idFuncall;
|
||||
extern ID id__send_bang;
|
||||
|
||||
|
4
inits.c
4
inits.c
|
@ -35,6 +35,7 @@ void Init_Object(void);
|
|||
void Init_pack(void);
|
||||
void Init_Precision(void);
|
||||
void Init_sym(void);
|
||||
void Init_id(void);
|
||||
void Init_process(void);
|
||||
void Init_Random(void);
|
||||
void Init_Range(void);
|
||||
|
@ -49,13 +50,16 @@ void Init_ISeq(void);
|
|||
void Init_VM(void);
|
||||
void Init_Thread(void);
|
||||
void Init_Cont(void);
|
||||
void Init_top_self(void);
|
||||
|
||||
void
|
||||
rb_call_inits()
|
||||
{
|
||||
Init_sym();
|
||||
Init_id();
|
||||
Init_var_tables();
|
||||
Init_Object();
|
||||
Init_top_self();
|
||||
Init_Comparable();
|
||||
Init_Enumerable();
|
||||
Init_Precision();
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
**********************************************************************/
|
||||
|
||||
/* finish iseq array */
|
||||
|
||||
#include "insns.inc"
|
||||
|
||||
/* control stack frame */
|
||||
|
@ -1005,7 +1004,7 @@ vm_search_super_klass(VALUE klass, VALUE recv)
|
|||
}
|
||||
|
||||
static void
|
||||
call_yarv_end_proc(VALUE data)
|
||||
call_end_proc(VALUE data)
|
||||
{
|
||||
rb_proc_call(data, rb_ary_new2(0));
|
||||
}
|
||||
|
|
|
@ -69,9 +69,6 @@
|
|||
#define GET_DFP() (USAGE_ANALYSIS_REGISTER_HELPER(4, 0, REG_DFP))
|
||||
#define SET_DFP(x) (REG_DFP = (USAGE_ANALYSIS_REGISTER_HELPER(4, 1, (x))))
|
||||
|
||||
#define GET_CONTINUATION_FRAME_PTR(cfp) \
|
||||
((struct continuation_frame *)((cfp) + CC_DIFF_WC()))
|
||||
|
||||
/* SP */
|
||||
#define GET_SP() (USAGE_ANALYSIS_REGISTER_HELPER(1, 0, REG_SP))
|
||||
#define SET_SP(x) (REG_SP = (USAGE_ANALYSIS_REGISTER_HELPER(1, 1, (x))))
|
||||
|
@ -84,13 +81,11 @@
|
|||
|
||||
/* instruction sequence C struct */
|
||||
#define GET_ISEQ() (GET_CFP()->iseq)
|
||||
#define CLEAR_ENV(env) (GET_ENV_CTRL(env)->is_orphan = Qundef)
|
||||
|
||||
/**********************************************************/
|
||||
/* deal with variables */
|
||||
/**********************************************************/
|
||||
|
||||
#define GET_CURRENT_DYNAMIC(idx) (*(GET_DFP() -(idx)))
|
||||
#define GET_PREV_DFP(dfp) ((VALUE *)((dfp)[0] & ~0x03))
|
||||
|
||||
#define GET_GLOBAL(entry) rb_gvar_get((struct global_entry*)entry)
|
||||
|
|
|
@ -979,7 +979,7 @@ postexe
|
|||
blockptr->proc = 0;
|
||||
|
||||
proc = vm_make_proc(th, GET_CFP(), blockptr);
|
||||
rb_set_end_proc(call_yarv_end_proc, proc);
|
||||
rb_set_end_proc(call_end_proc, proc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
72
iseq.c
72
iseq.c
|
@ -13,12 +13,16 @@
|
|||
#include "ruby/ruby.h"
|
||||
#include "ruby/node.h"
|
||||
|
||||
#include "yarvcore.h"
|
||||
/* #define MARK_FREE_DEBUG 1 */
|
||||
#include "gc.h"
|
||||
#include "vm_core.h"
|
||||
|
||||
#include "insns.inc"
|
||||
#include "insns_info.inc"
|
||||
|
||||
/* #define MARK_FREE_DEBUG 1 */
|
||||
#include "gc.h"
|
||||
/* compile.c */
|
||||
void iseq_compile(VALUE self, NODE *node);
|
||||
int iseq_translate_threaded_code(rb_iseq_t *iseq);
|
||||
|
||||
VALUE rb_cISeq;
|
||||
|
||||
|
@ -289,7 +293,7 @@ rb_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE filename,
|
|||
iseq->self = self;
|
||||
|
||||
prepare_iseq_build(iseq, name, filename, parent, type, bopt, option);
|
||||
rb_iseq_compile(self, node);
|
||||
iseq_compile(self, node);
|
||||
cleanup_iseq_build(iseq);
|
||||
return self;
|
||||
}
|
||||
|
@ -418,22 +422,41 @@ compile_string(VALUE str, VALUE file, VALUE line)
|
|||
return node;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt)
|
||||
{
|
||||
rb_compile_option_t option;
|
||||
NODE *node = compile_string(src, file, line);
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
make_compile_option(&option, opt);
|
||||
|
||||
if (th->base_block) {
|
||||
return rb_iseq_new_with_opt(node, th->base_block->iseq->name,
|
||||
file, th->base_block->iseq->self,
|
||||
ISEQ_TYPE_EVAL, &option);
|
||||
}
|
||||
else {
|
||||
return rb_iseq_new_with_opt(node, rb_str_new2("<compiled>"), file, Qfalse,
|
||||
ISEQ_TYPE_TOP, &option);
|
||||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_iseq_compile(VALUE src, VALUE file, VALUE line)
|
||||
{
|
||||
return rb_iseq_compile_with_option(src, file, line, Qnil);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
iseq_s_compile(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE str, file = Qnil, line = INT2FIX(1), opt = Qnil;
|
||||
NODE *node;
|
||||
rb_compile_option_t option;
|
||||
|
||||
rb_scan_args(argc, argv, "13", &str, &file, &line, &opt);
|
||||
VALUE src, file = Qnil, line = INT2FIX(1), opt = Qnil;
|
||||
|
||||
rb_scan_args(argc, argv, "13", &src, &file, &line, &opt);
|
||||
file = file == Qnil ? rb_str_new2("<compiled>") : file;
|
||||
line = line == Qnil ? INT2FIX(1) : line;
|
||||
|
||||
node = compile_string(str, file, line);
|
||||
make_compile_option(&option, opt);
|
||||
return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file, Qfalse,
|
||||
ISEQ_TYPE_TOP, &option);
|
||||
return rb_iseq_compile_with_option(src, file, line, opt);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -481,7 +504,7 @@ iseq_check(VALUE val)
|
|||
static VALUE
|
||||
iseq_eval(VALUE self)
|
||||
{
|
||||
return rb_thread_eval(GET_THREAD(), self);
|
||||
return rb_iseq_eval(self);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -1066,15 +1089,6 @@ end
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
debug_node(NODE *node)
|
||||
{
|
||||
printf("node type: %d\n", nd_type(node));
|
||||
printf("node name: %s\n", ruby_node_name(nd_type(node)));
|
||||
printf("node filename: %s\n", node->nd_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DECL_SYMBOL(name) \
|
||||
static VALUE sym_##name
|
||||
|
||||
|
@ -1121,7 +1135,7 @@ cdhash_each(VALUE key, VALUE value, VALUE ary)
|
|||
VALUE
|
||||
iseq_data_to_ary(rb_iseq_t *iseq)
|
||||
{
|
||||
int i, pos, line = 0, insn_pos = 0;
|
||||
int i, pos, line = 0;
|
||||
VALUE *seq;
|
||||
|
||||
VALUE val = rb_ary_new();
|
||||
|
@ -1133,7 +1147,7 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
|||
VALUE exception = rb_ary_new(); /* [[....]] */
|
||||
VALUE misc = rb_hash_new();
|
||||
|
||||
static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
|
||||
static VALUE insn_syms[VM_INSTRUCTION_SIZE];
|
||||
struct st_table *labels_table = st_init_numtable();
|
||||
|
||||
DECL_SYMBOL(top);
|
||||
|
@ -1146,7 +1160,7 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
|||
|
||||
if (sym_top == 0) {
|
||||
int i;
|
||||
for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
|
||||
for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
|
||||
insn_syms[i] = ID2SYM(rb_intern(insn_name(i)));
|
||||
}
|
||||
INIT_SYMBOL(top);
|
||||
|
@ -1341,7 +1355,7 @@ iseq_data_to_ary(rb_iseq_t *iseq)
|
|||
* :name, :filename, :type, :locals, :args,
|
||||
* :catch_table, :bytecode]
|
||||
*/
|
||||
rb_ary_push(val, rb_str_new2("YARVInstructionSimpledataFormat"));
|
||||
rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat"));
|
||||
rb_ary_push(val, INT2FIX(1));
|
||||
rb_ary_push(val, INT2FIX(1));
|
||||
rb_ary_push(val, INT2FIX(1));
|
||||
|
@ -1363,7 +1377,7 @@ insn_make_insn_table(void)
|
|||
int i;
|
||||
table = st_init_numtable();
|
||||
|
||||
for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
|
||||
for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
|
||||
st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);
|
||||
}
|
||||
|
||||
|
@ -1428,7 +1442,7 @@ rb_iseq_build_for_ruby2cext(
|
|||
void
|
||||
Init_ISeq(void)
|
||||
{
|
||||
/* declare YARVCore::InstructionSequence */
|
||||
/* declare ::VM::InstructionSequence */
|
||||
rb_cISeq = rb_define_class_under(rb_cVM, "InstructionSequence", rb_cObject);
|
||||
rb_define_alloc_func(rb_cISeq, iseq_alloc);
|
||||
rb_define_method(rb_cISeq, "inspect", iseq_inspect, 0);
|
||||
|
|
|
@ -2867,17 +2867,12 @@ int_downto(VALUE from, VALUE to)
|
|||
* 0 1 2 3 4
|
||||
*/
|
||||
|
||||
VALUE yarv_invoke_Integer_times_special_block(VALUE);
|
||||
|
||||
static VALUE
|
||||
int_dotimes(VALUE num)
|
||||
{
|
||||
VALUE val;
|
||||
|
||||
RETURN_ENUMERATOR(num, 0, 0);
|
||||
if((val = yarv_invoke_Integer_times_special_block(num)) != Qundef){
|
||||
return val;
|
||||
}
|
||||
|
||||
if (FIXNUM_P(num)) {
|
||||
long i, end;
|
||||
|
|
13
object.c
13
object.c
|
@ -792,13 +792,6 @@ nil_plus(VALUE x, VALUE y)
|
|||
}
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
main_to_s(VALUE obj)
|
||||
{
|
||||
return rb_str_new2("main");
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Document-class: TrueClass
|
||||
*
|
||||
|
@ -2206,8 +2199,6 @@ boot_defclass(const char *name, VALUE super)
|
|||
return obj;
|
||||
}
|
||||
|
||||
VALUE ruby_top_self;
|
||||
|
||||
/*
|
||||
* Document-class: Class
|
||||
*
|
||||
|
@ -2442,10 +2433,6 @@ Init_Object(void)
|
|||
rb_cData = rb_define_class("Data", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cData);
|
||||
|
||||
rb_global_variable(&ruby_top_self);
|
||||
ruby_top_self = rb_obj_alloc(rb_cObject);
|
||||
rb_define_singleton_method(ruby_top_self, "to_s", main_to_s, 0);
|
||||
|
||||
rb_cTrueClass = rb_define_class("TrueClass", rb_cObject);
|
||||
rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0);
|
||||
rb_define_method(rb_cTrueClass, "&", true_and, 1);
|
||||
|
|
12
proc.c
12
proc.c
|
@ -59,8 +59,8 @@ proc_mark(void *ptr)
|
|||
RUBY_MARK_LEAVE("proc");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
proc_alloc(VALUE klass)
|
||||
VALUE
|
||||
rb_proc_alloc(VALUE klass)
|
||||
{
|
||||
VALUE obj;
|
||||
rb_proc_t *proc;
|
||||
|
@ -69,12 +69,6 @@ proc_alloc(VALUE klass)
|
|||
return obj;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_proc_alloc(void)
|
||||
{
|
||||
return proc_alloc(rb_cProc);
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_obj_is_proc(VALUE proc)
|
||||
{
|
||||
|
@ -90,7 +84,7 @@ rb_obj_is_proc(VALUE proc)
|
|||
static VALUE
|
||||
proc_dup(VALUE self)
|
||||
{
|
||||
VALUE procval = proc_alloc(rb_cProc);
|
||||
VALUE procval = rb_proc_alloc(rb_cProc);
|
||||
rb_proc_t *src, *dst;
|
||||
GetProcPtr(self, src);
|
||||
GetProcPtr(procval, dst);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/signal.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
|
2
signal.c
2
signal.c
|
@ -15,7 +15,7 @@
|
|||
#include "ruby/ruby.h"
|
||||
#include "ruby/signal.h"
|
||||
#include "ruby/node.h"
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -17,5 +17,5 @@ enum{
|
|||
<%= insns %>
|
||||
};
|
||||
|
||||
#define YARV_MAX_INSTRUCTION_SIZE <%= @insns.size %>
|
||||
#define VM_INSTRUCTION_SIZE <%= @insns.size %>
|
||||
|
||||
|
|
20
thread.c
20
thread.c
|
@ -389,7 +389,7 @@ thread_join(rb_thread_t *target_th, double delay)
|
|||
rb_thread_t *th = GET_THREAD();
|
||||
double now, limit = timeofday() + delay;
|
||||
|
||||
thread_debug("thread_join (thid: %p)\n", (void*)target_th->thread_id);
|
||||
thread_debug("thread_join (thid: %p)\n", (void *)target_th->thread_id);
|
||||
|
||||
if (target_th->status != THREAD_KILLED) {
|
||||
th->join_list_next = target_th->join_list_head;
|
||||
|
@ -404,17 +404,17 @@ thread_join(rb_thread_t *target_th, double delay)
|
|||
now = timeofday();
|
||||
if (now > limit) {
|
||||
thread_debug("thread_join: timeout (thid: %p)\n",
|
||||
(void*)target_th->thread_id);
|
||||
(void *)target_th->thread_id);
|
||||
return Qnil;
|
||||
}
|
||||
sleep_wait_for_interrupt(th, limit - now);
|
||||
}
|
||||
thread_debug("thread_join: interrupted (thid: %p)\n",
|
||||
(void*)target_th->thread_id);
|
||||
(void *)target_th->thread_id);
|
||||
}
|
||||
|
||||
thread_debug("thread_join: success (thid: %p)\n",
|
||||
(void*)target_th->thread_id);
|
||||
(void *)target_th->thread_id);
|
||||
|
||||
if (target_th->errinfo != Qnil) {
|
||||
VALUE err = target_th->errinfo;
|
||||
|
@ -2349,7 +2349,7 @@ thlist_signal(rb_thread_list_t **list, unsigned int maxth)
|
|||
int woken = 0;
|
||||
rb_thread_list_t *q;
|
||||
|
||||
while ((q = *list) != 0) {
|
||||
while ((q = *list) != NULL) {
|
||||
rb_thread_t *th = q->th;
|
||||
|
||||
*list = q->next;
|
||||
|
@ -2922,10 +2922,12 @@ Init_Thread(void)
|
|||
rb_define_method(rb_cMutex, "lock", rb_mutex_lock, 0);
|
||||
rb_define_method(rb_cMutex, "unlock", rb_mutex_unlock, 0);
|
||||
rb_define_method(rb_cMutex, "sleep", mutex_sleep, -1);
|
||||
yarvcore_eval(Qnil, rb_str_new2(
|
||||
"class Mutex;"
|
||||
" def synchronize; self.lock; yield; ensure; self.unlock; end;"
|
||||
"end;"), rb_str_new2("<preload>"), INT2FIX(1));
|
||||
|
||||
rb_iseq_eval(rb_iseq_compile(
|
||||
rb_str_new2("class Mutex;"
|
||||
" def synchronize; self.lock; yield; ensure; self.unlock; end;"
|
||||
"end;"),
|
||||
rb_str_new2(__FILE__), INT2FIX(__LINE__)));
|
||||
|
||||
recursive_key = rb_intern("__recursive_key__");
|
||||
rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
|
||||
|
|
|
@ -301,7 +301,7 @@ ubf_pthread_cond_signal(rb_thread_t *th)
|
|||
static void
|
||||
ubf_select_each(rb_thread_t *th)
|
||||
{
|
||||
thread_debug("ubf_select_each (%p)\n", (void*)th->thread_id);
|
||||
thread_debug("ubf_select_each (%p)\n", (void *)th->thread_id);
|
||||
if (th) {
|
||||
pthread_kill(th->thread_id, SIGVTALRM);
|
||||
}
|
||||
|
|
433
vm.c
433
vm.c
|
@ -21,29 +21,26 @@
|
|||
#define BUFSIZE 0x100
|
||||
#define PROCDEBUG 0
|
||||
|
||||
VALUE rb_cVM;
|
||||
VALUE rb_cThread;
|
||||
VALUE rb_cEnv;
|
||||
|
||||
VALUE ruby_vm_global_state_version = 1;
|
||||
rb_thread_t *ruby_current_thread = 0;
|
||||
rb_vm_t *ruby_current_vm = 0;
|
||||
|
||||
void vm_analysis_operand(int insn, int n, VALUE op);
|
||||
void vm_analysis_register(int reg, int isset);
|
||||
void vm_analysis_insn(int insn);
|
||||
|
||||
VALUE vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
|
||||
VALUE self, int argc, VALUE *argv);
|
||||
|
||||
VALUE vm_eval_body(rb_thread_t *th);
|
||||
|
||||
static NODE *lfp_get_special_cref(VALUE *lfp);
|
||||
static NODE *lfp_set_special_cref(VALUE *lfp, NODE * cref);
|
||||
|
||||
static inline int block_proc_is_lambda(VALUE procval);
|
||||
|
||||
#if OPT_STACK_CACHING
|
||||
static VALUE yarv_finish_insn_seq[1] = { BIN(finish_SC_ax_ax) };
|
||||
static VALUE finish_insn_seq[1] = { BIN(finish_SC_ax_ax) };
|
||||
#elif OPT_CALL_THREADED_CODE
|
||||
static VALUE const yarv_finish_insn_seq[1] = { 0 };
|
||||
static VALUE const finish_insn_seq[1] = { 0 };
|
||||
#else
|
||||
static VALUE yarv_finish_insn_seq[1] = { BIN(finish) };
|
||||
static VALUE finish_insn_seq[1] = { BIN(finish) };
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -60,7 +57,7 @@ rb_vm_set_finish_env(rb_thread_t *th)
|
|||
vm_push_frame(th, 0, FRAME_MAGIC_FINISH,
|
||||
Qnil, th->cfp->lfp[0], 0,
|
||||
th->cfp->sp, 0, 1);
|
||||
th->cfp->pc = (VALUE *)&yarv_finish_insn_seq[0];
|
||||
th->cfp->pc = (VALUE *)&finish_insn_seq[0];
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
|
@ -379,7 +376,7 @@ vm_make_proc(rb_thread_t *th,
|
|||
if (PROCDEBUG) {
|
||||
check_env_value(envval);
|
||||
}
|
||||
procval = rb_proc_alloc();
|
||||
procval = rb_proc_alloc(rb_cProc);
|
||||
GetProcPtr(procval, proc);
|
||||
proc->blockprocval = blockprocval;
|
||||
proc->block.self = block->self;
|
||||
|
@ -1009,8 +1006,8 @@ add_opt_method(VALUE klass, ID mid, VALUE bop)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
yarv_init_redefined_flag(void)
|
||||
static void
|
||||
vm_init_redefined_flag(void)
|
||||
{
|
||||
const VALUE register_info[] = {
|
||||
idPLUS, BOP_PLUS, rb_cFixnum, rb_cFloat, rb_cString, rb_cArray, 0,
|
||||
|
@ -1202,7 +1199,7 @@ vm_eval_body(rb_thread_t *th)
|
|||
|
||||
if (cfp->dfp == escape_dfp) {
|
||||
if (state == TAG_RETURN) {
|
||||
if ((cfp + 1)->pc != &yarv_finish_insn_seq[0]) {
|
||||
if ((cfp + 1)->pc != &finish_insn_seq[0]) {
|
||||
SET_THROWOBJ_CATCH_POINT(err, (VALUE)(cfp + 1)->dfp);
|
||||
SET_THROWOBJ_STATE(err, state = TAG_BREAK);
|
||||
}
|
||||
|
@ -1344,7 +1341,7 @@ vm_eval_body(rb_thread_t *th)
|
|||
}
|
||||
else {
|
||||
th->cfp++;
|
||||
if (th->cfp->pc != &yarv_finish_insn_seq[0]) {
|
||||
if (th->cfp->pc != &finish_insn_seq[0]) {
|
||||
goto exception_handler;
|
||||
}
|
||||
else {
|
||||
|
@ -1363,8 +1360,9 @@ vm_eval_body(rb_thread_t *th)
|
|||
/* misc */
|
||||
|
||||
VALUE
|
||||
rb_thread_eval(rb_thread_t *th, VALUE iseqval)
|
||||
rb_iseq_eval(VALUE iseqval)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE val;
|
||||
volatile VALUE tmp;
|
||||
|
||||
|
@ -1439,3 +1437,402 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockp
|
|||
vm_pop_frame(th);
|
||||
return val;
|
||||
}
|
||||
|
||||
/* vm */
|
||||
|
||||
static void
|
||||
vm_free(void *ptr)
|
||||
{
|
||||
RUBY_FREE_ENTER("vm");
|
||||
if (ptr) {
|
||||
rb_vm_t *vmobj = ptr;
|
||||
|
||||
st_free_table(vmobj->living_threads);
|
||||
/* TODO: MultiVM Instance */
|
||||
/* VM object should not be cleaned by GC */
|
||||
/* ruby_xfree(ptr); */
|
||||
/* ruby_current_vm = 0; */
|
||||
}
|
||||
RUBY_FREE_LEAVE("vm");
|
||||
}
|
||||
|
||||
static int
|
||||
vm_mark_each_thread_func(st_data_t key, st_data_t value, st_data_t dummy)
|
||||
{
|
||||
VALUE thval = (VALUE)key;
|
||||
rb_gc_mark(thval);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
mark_event_hooks(rb_event_hook_t *hook)
|
||||
{
|
||||
while (hook) {
|
||||
rb_gc_mark(hook->data);
|
||||
hook = hook->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_vm_mark(void *ptr)
|
||||
{
|
||||
RUBY_MARK_ENTER("vm");
|
||||
RUBY_GC_INFO("-------------------------------------------------\n");
|
||||
if (ptr) {
|
||||
rb_vm_t *vm = ptr;
|
||||
if (vm->living_threads) {
|
||||
st_foreach(vm->living_threads, vm_mark_each_thread_func, 0);
|
||||
}
|
||||
RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
|
||||
RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
|
||||
RUBY_MARK_UNLESS_NULL(vm->last_status);
|
||||
RUBY_MARK_UNLESS_NULL(vm->loaded_features);
|
||||
RUBY_MARK_UNLESS_NULL(vm->top_self);
|
||||
|
||||
if (vm->loading_table) {
|
||||
rb_mark_tbl(vm->loading_table);
|
||||
}
|
||||
|
||||
mark_event_hooks(vm->event_hooks);
|
||||
}
|
||||
|
||||
RUBY_MARK_LEAVE("vm");
|
||||
}
|
||||
|
||||
static void
|
||||
vm_init2(rb_vm_t *vm)
|
||||
{
|
||||
MEMZERO(vm, rb_vm_t, 1);
|
||||
}
|
||||
|
||||
/* Thread */
|
||||
|
||||
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->local_storage) {
|
||||
st_free_table(th->local_storage);
|
||||
}
|
||||
|
||||
#if USE_VALUE_CACHE
|
||||
{
|
||||
VALUE *ptr = th->value_cache_ptr;
|
||||
while (*ptr) {
|
||||
VALUE v = *ptr;
|
||||
RBASIC(v)->flags = 0;
|
||||
RBASIC(v)->klass = 0;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (th->vm->main_thread == th) {
|
||||
RUBY_GC_INFO("main thread\n");
|
||||
}
|
||||
else {
|
||||
ruby_xfree(ptr);
|
||||
}
|
||||
}
|
||||
RUBY_FREE_LEAVE("thread");
|
||||
}
|
||||
|
||||
void rb_gc_mark_machine_stack(rb_thread_t *th);
|
||||
|
||||
void
|
||||
rb_thread_mark(void *ptr)
|
||||
{
|
||||
rb_thread_t *th = NULL;
|
||||
RUBY_MARK_ENTER("thread");
|
||||
if (ptr) {
|
||||
th = ptr;
|
||||
if (th->stack) {
|
||||
VALUE *p = th->stack;
|
||||
VALUE *sp = th->cfp->sp + th->mark_stack_len;
|
||||
rb_control_frame_t *cfp = th->cfp;
|
||||
rb_control_frame_t *limit_cfp =
|
||||
(void *)(th->stack + th->stack_size);
|
||||
|
||||
while (p < sp) {
|
||||
rb_gc_mark(*p++);
|
||||
}
|
||||
while (cfp != limit_cfp) {
|
||||
rb_gc_mark(cfp->proc);
|
||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
}
|
||||
}
|
||||
|
||||
/* mark ruby objects */
|
||||
RUBY_MARK_UNLESS_NULL(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->thrown_errinfo);
|
||||
RUBY_MARK_UNLESS_NULL(th->local_svar);
|
||||
RUBY_MARK_UNLESS_NULL(th->top_self);
|
||||
RUBY_MARK_UNLESS_NULL(th->top_wrapper);
|
||||
RUBY_MARK_UNLESS_NULL(th->fiber);
|
||||
RUBY_MARK_UNLESS_NULL(th->root_fiber);
|
||||
|
||||
rb_mark_tbl(th->local_storage);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
mark_event_hooks(th->event_hooks);
|
||||
}
|
||||
|
||||
RUBY_MARK_UNLESS_NULL(th->stat_insn_usage);
|
||||
RUBY_MARK_LEAVE("thread");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
thread_alloc(VALUE klass)
|
||||
{
|
||||
VALUE volatile obj;
|
||||
rb_thread_t *th;
|
||||
obj = Data_Make_Struct(klass, rb_thread_t,
|
||||
rb_thread_mark, thread_free, th);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
th_init2(rb_thread_t *th)
|
||||
{
|
||||
MEMZERO(th, rb_thread_t, 1);
|
||||
|
||||
/* allocate thread stack */
|
||||
th->stack_size = RUBY_VM_THREAD_STACK_SIZE;
|
||||
th->stack = ALLOC_N(VALUE, th->stack_size);
|
||||
|
||||
th->cfp = (void *)(th->stack + th->stack_size);
|
||||
th->cfp--;
|
||||
|
||||
th->cfp->pc = 0;
|
||||
th->cfp->sp = th->stack + 1;
|
||||
th->cfp->bp = 0;
|
||||
th->cfp->lfp = th->stack;
|
||||
*th->cfp->lfp = 0;
|
||||
th->cfp->dfp = th->stack;
|
||||
th->cfp->self = Qnil;
|
||||
th->cfp->flag = 0;
|
||||
th->cfp->iseq = 0;
|
||||
th->cfp->proc = 0;
|
||||
th->cfp->block_iseq = 0;
|
||||
|
||||
th->status = THREAD_RUNNABLE;
|
||||
th->errinfo = Qnil;
|
||||
|
||||
#if USE_VALUE_CACHE
|
||||
th->value_cache_ptr = &th->value_cache[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
th_init(rb_thread_t *th)
|
||||
{
|
||||
th_init2(th);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ruby_thread_init(VALUE self)
|
||||
{
|
||||
rb_thread_t *th;
|
||||
rb_vm_t *vm = GET_THREAD()->vm;
|
||||
GetThreadPtr(self, th);
|
||||
|
||||
th_init(th);
|
||||
th->self = self;
|
||||
th->vm = vm;
|
||||
|
||||
th->top_wrapper = 0;
|
||||
th->top_self = rb_vm_top_self();
|
||||
return self;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_thread_alloc(VALUE klass)
|
||||
{
|
||||
VALUE self = thread_alloc(klass);
|
||||
ruby_thread_init(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
VALUE insns_name_array(void);
|
||||
extern VALUE *rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
extern VALUE *rb_gc_register_stack_start;
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
sdr(void)
|
||||
{
|
||||
rb_vm_bugreport();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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];
|
||||
int n = backtrace(trace, MAX_NATIVE_TRACE);
|
||||
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]));
|
||||
}
|
||||
free(syms);
|
||||
#endif
|
||||
return ary;
|
||||
}
|
||||
|
||||
void
|
||||
Init_VM(void)
|
||||
{
|
||||
VALUE opts;
|
||||
|
||||
/* ::VM */
|
||||
rb_cVM = rb_define_class("VM", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cVM);
|
||||
|
||||
/* Env */
|
||||
rb_cEnv = rb_define_class_under(rb_cVM, "Env", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cEnv);
|
||||
|
||||
/* ::Thread */
|
||||
rb_cThread = rb_define_class("Thread", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cThread);
|
||||
rb_define_method(rb_cThread, "initialize", ruby_thread_init, 0);
|
||||
|
||||
/* ::VM::USAGE_ANALISYS_* */
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_INSN", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_REGS", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_INSN_BIGRAM", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "OPTS", opts = rb_ary_new());
|
||||
|
||||
#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_BASIC_OPERATIONS
|
||||
rb_ary_push(opts, rb_str_new2("optimize basic operation"));
|
||||
#endif
|
||||
|
||||
#if OPT_STACK_CACHING
|
||||
rb_ary_push(opts, rb_str_new2("stack caching"));
|
||||
#endif
|
||||
#if OPT_OPERANDS_UNIFICATION
|
||||
rb_ary_push(opts, rb_str_new2("operands unification]"));
|
||||
#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
|
||||
|
||||
/* ::VM::InsnNameArray */
|
||||
rb_define_const(rb_cVM, "INSTRUCTION_NAMES", insns_name_array());
|
||||
|
||||
/* debug functions ::VM::SDR(), ::VM::NSDR() */
|
||||
rb_define_singleton_method(rb_cVM, "SDR", sdr, 0);
|
||||
rb_define_singleton_method(rb_cVM, "NSDR", nsdr, 0);
|
||||
|
||||
/* VM bootstrap: phase 2 */
|
||||
{
|
||||
rb_vm_t *vm = ruby_current_vm;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE th_self;
|
||||
|
||||
/* create vm object */
|
||||
vm->self = Data_Wrap_Struct(rb_cVM, rb_vm_mark, vm_free, vm);
|
||||
|
||||
/* create main thread */
|
||||
th_self = th->self = Data_Wrap_Struct(rb_cThread, rb_thread_mark,
|
||||
thread_free, th);
|
||||
|
||||
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->living_threads = st_init_numtable();
|
||||
st_insert(vm->living_threads, th_self, (st_data_t) th->thread_id);
|
||||
}
|
||||
vm_init_redefined_flag();
|
||||
}
|
||||
|
||||
void
|
||||
Init_BareVM(void)
|
||||
{
|
||||
/* VM bootstrap: phase 1 */
|
||||
rb_vm_t *vm = ALLOC(rb_vm_t);
|
||||
rb_thread_t *th = ALLOC(rb_thread_t);
|
||||
|
||||
vm_init2(vm);
|
||||
ruby_current_vm = vm;
|
||||
|
||||
th_init2(th);
|
||||
th->vm = vm;
|
||||
th->machine_stack_start = rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_start = rb_gc_register_stack_start;
|
||||
#endif
|
||||
rb_thread_set_current_raw(th);
|
||||
}
|
||||
|
||||
/* top self */
|
||||
|
||||
static VALUE
|
||||
main_to_s(VALUE obj)
|
||||
{
|
||||
return rb_str_new2("main");
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_vm_top_self()
|
||||
{
|
||||
return GET_VM()->top_self;
|
||||
}
|
||||
|
||||
void
|
||||
Init_top_self()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
20
vm.h
20
vm.h
|
@ -10,13 +10,8 @@
|
|||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _VM_H_INCLUDED_
|
||||
#define _VM_H_INCLUDED_
|
||||
|
||||
#if YARVDEBUG > VMDEBUG
|
||||
#undef VMDEBUG
|
||||
#define VMDEBUG YARVDEBUG
|
||||
#endif
|
||||
#ifndef RUBY_VM_H
|
||||
#define RUBY_VM_H
|
||||
|
||||
typedef long OFFSET;
|
||||
typedef unsigned long rb_num_t;
|
||||
|
@ -42,6 +37,11 @@ extern VALUE ruby_vm_redefined_flag;
|
|||
* 10: gc check
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VMDEBUG
|
||||
#define VMDEBUG 0
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#undef VMDEBUG
|
||||
#define VMDEBUG 3
|
||||
|
@ -52,9 +52,9 @@ extern VALUE ruby_vm_redefined_flag;
|
|||
#define USAGE_ANALYSIS_OPERAND(insn, n, op) vm_analysis_operand(insn, n, (VALUE)op)
|
||||
#define USAGE_ANALYSIS_REGISTER(reg, s) vm_analysis_register(reg, s)
|
||||
#else
|
||||
#define USAGE_ANALYSIS_INSN(insn) /* none */
|
||||
#define USAGE_ANALYSIS_INSN(insn) /* none */
|
||||
#define USAGE_ANALYSIS_OPERAND(insn, n, op) /* none */
|
||||
#define USAGE_ANALYSIS_REGISTER(reg, s) /* none */
|
||||
#define USAGE_ANALYSIS_REGISTER(reg, s) /* none */
|
||||
#endif
|
||||
|
||||
#ifdef __GCC__
|
||||
|
@ -298,4 +298,4 @@ while (0)
|
|||
#define BOP_GT 0x2000
|
||||
#define BOP_GE 0x4000
|
||||
|
||||
#endif /* _VM_H_INCLUDED_ */
|
||||
#endif /* RUBY_VM_H */
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
/**********************************************************************
|
||||
|
||||
yarvcore.h -
|
||||
vm_core.h -
|
||||
|
||||
$Author$
|
||||
$Date$
|
||||
created at: 04/01/01 19:41:38 JST
|
||||
|
||||
Copyright (C) 2004-2006 Koichi Sasada
|
||||
Copyright (C) 2004-2007 Koichi Sasada
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _YARVCORE_H_INCLUDED_
|
||||
#define _YARVCORE_H_INCLUDED_
|
||||
#ifndef RUBY_CORE_H
|
||||
#define RUBY_CORE_H
|
||||
|
||||
#define RUBY_VM_THREAD_MODEL 2
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "vm_opts.h"
|
||||
#include "id.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "thread_win32.h"
|
||||
|
@ -77,7 +78,6 @@
|
|||
#if OPT_STACK_CACHING
|
||||
#undef OPT_STACK_CACHING
|
||||
#endif /* OPT_STACK_CACHING */
|
||||
#define YARV_AOT_COMPILED 1
|
||||
#endif /* OPT_CALL_THREADED_CODE */
|
||||
|
||||
/* likely */
|
||||
|
@ -89,62 +89,6 @@
|
|||
#define UNLIKELY(x) (x)
|
||||
#endif /* __GNUC__ >= 3 */
|
||||
|
||||
#define YARVDEBUG 0
|
||||
#define CPDEBUG 0
|
||||
#define VMDEBUG 0
|
||||
#define GCDEBUG 0
|
||||
|
||||
|
||||
/* classes and modules */
|
||||
|
||||
extern VALUE symIFUNC;
|
||||
extern VALUE symCFUNC;
|
||||
|
||||
/* special id */
|
||||
extern ID idPLUS;
|
||||
extern ID idMINUS;
|
||||
extern ID idMULT;
|
||||
extern ID idDIV;
|
||||
extern ID idMOD;
|
||||
extern ID idLT;
|
||||
extern ID idLTLT;
|
||||
extern ID idLE;
|
||||
extern ID idGT;
|
||||
extern ID idGE;
|
||||
extern ID idEq;
|
||||
extern ID idEqq;
|
||||
extern ID idBackquote;
|
||||
extern ID idEqTilde;
|
||||
extern ID idThrowState;
|
||||
extern ID idAREF;
|
||||
extern ID idASET;
|
||||
extern ID idIntern;
|
||||
extern ID idMethodMissing;
|
||||
extern ID idLength;
|
||||
extern ID idGets;
|
||||
extern ID idSucc;
|
||||
extern ID idEach;
|
||||
extern ID idLambda;
|
||||
extern ID idRangeEachLT;
|
||||
extern ID idRangeEachLE;
|
||||
extern ID idArrayEach;
|
||||
extern ID idTimes;
|
||||
extern ID idEnd;
|
||||
extern ID idBitblt;
|
||||
extern ID idAnswer;
|
||||
extern ID idSvarPlaceholder;
|
||||
extern ID idSend;
|
||||
extern ID id__send__;
|
||||
extern ID id__send;
|
||||
extern ID idFuncall;
|
||||
extern ID id__send_bang;
|
||||
|
||||
|
||||
struct iseq_insn_info_entry {
|
||||
unsigned short position;
|
||||
unsigned short line_no;
|
||||
};
|
||||
|
||||
#define ISEQ_TYPE_TOP INT2FIX(1)
|
||||
#define ISEQ_TYPE_METHOD INT2FIX(2)
|
||||
#define ISEQ_TYPE_BLOCK INT2FIX(3)
|
||||
|
@ -161,6 +105,11 @@ struct iseq_insn_info_entry {
|
|||
#define CATCH_TYPE_REDO INT2FIX(5)
|
||||
#define CATCH_TYPE_NEXT INT2FIX(6)
|
||||
|
||||
struct iseq_insn_info_entry {
|
||||
unsigned short position;
|
||||
unsigned short line_no;
|
||||
};
|
||||
|
||||
struct iseq_catch_table_entry {
|
||||
VALUE type;
|
||||
VALUE iseq;
|
||||
|
@ -349,7 +298,6 @@ typedef struct rb_event_hook_struct {
|
|||
struct rb_event_hook_struct *next;
|
||||
} rb_event_hook_t;
|
||||
|
||||
|
||||
#define GetVMPtr(obj, ptr) \
|
||||
GetCoreDataFromValue(obj, rb_vm_t, ptr)
|
||||
|
||||
|
@ -372,6 +320,7 @@ typedef struct rb_vm_struct {
|
|||
VALUE mark_object_ary;
|
||||
|
||||
/* load */
|
||||
VALUE top_self;
|
||||
VALUE loaded_features;
|
||||
struct st_table *loading_table;
|
||||
|
||||
|
@ -528,24 +477,19 @@ struct rb_thread_struct
|
|||
int abort_on_exception;
|
||||
};
|
||||
|
||||
/** node -> yarv instruction sequence object */
|
||||
VALUE rb_iseq_compile(VALUE self, NODE *node);
|
||||
/* iseq.c */
|
||||
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE);
|
||||
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);
|
||||
VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*);
|
||||
|
||||
/** disassemble instruction sequence */
|
||||
VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
|
||||
VALUE ruby_iseq_disasm(VALUE self);
|
||||
VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos,
|
||||
rb_iseq_t *iseq, VALUE child);
|
||||
VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos, rb_iseq_t *iseq, VALUE child);
|
||||
const char *ruby_node_name(int node);
|
||||
|
||||
|
||||
/* each thread has this size stack : 2MB */
|
||||
/* each thread has this size stack : 128KB */
|
||||
#define RUBY_VM_THREAD_STACK_SIZE (128 * 1024)
|
||||
|
||||
|
||||
/* from ruby 1.9 variable.c */
|
||||
struct global_entry {
|
||||
struct global_variable *var;
|
||||
ID id;
|
||||
|
@ -639,7 +583,6 @@ typedef rb_control_frame_t *
|
|||
#define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
|
||||
((rb_control_frame_t *)((VALUE *)(b) - 5))
|
||||
|
||||
|
||||
/* defined? */
|
||||
#define DEFINED_IVAR INT2FIX(1)
|
||||
#define DEFINED_IVAR2 INT2FIX(2)
|
||||
|
@ -652,22 +595,21 @@ typedef rb_control_frame_t *
|
|||
#define DEFINED_ZSUPER INT2FIX(9)
|
||||
#define DEFINED_FUNC INT2FIX(10)
|
||||
|
||||
|
||||
/* VM related object allocate functions */
|
||||
/* TODO: should be static functions */
|
||||
VALUE rb_thread_alloc(VALUE klass);
|
||||
VALUE rb_proc_alloc(void);
|
||||
VALUE rb_proc_alloc(VALUE klass);
|
||||
|
||||
/* for debug */
|
||||
extern void vm_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
|
||||
#define SDR() vm_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp)
|
||||
#define SDR2(cfp) vm_stack_dump_raw(GET_THREAD(), (cfp))
|
||||
void yarv_bug(void);
|
||||
void rb_vm_bugreport(void);
|
||||
|
||||
|
||||
/* functions about thread/vm execution */
|
||||
|
||||
VALUE rb_thread_eval(rb_thread_t *th, VALUE iseqval);
|
||||
VALUE rb_iseq_eval(VALUE iseqval);
|
||||
void rb_enable_interrupt(void);
|
||||
void rb_disable_interrupt(void);
|
||||
int rb_thread_method_id_and_klass(rb_thread_t *th, ID *idp, VALUE *klassp);
|
||||
|
@ -679,15 +621,11 @@ VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
|
|||
VALUE vm_backtrace(rb_thread_t *, int);
|
||||
|
||||
VALUE vm_yield(rb_thread_t *th, int argc, VALUE *argv);
|
||||
VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv,
|
||||
VALUE id, ID oid, int argc, const VALUE *argv,
|
||||
NODE * body, int nosuper);
|
||||
VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID oid,
|
||||
int argc, const VALUE *argv, NODE *body, int nosuper);
|
||||
|
||||
int vm_get_sourceline(rb_control_frame_t *);
|
||||
|
||||
VALUE yarvcore_eval_parsed(NODE *node, VALUE file);
|
||||
VALUE yarvcore_eval(VALUE self, VALUE str, VALUE file, VALUE line);
|
||||
|
||||
RUBY_EXTERN VALUE sysstack_error;
|
||||
|
||||
/* for thread */
|
||||
|
@ -748,4 +686,4 @@ exec_event_hooks(rb_event_hook_t *hook, rb_event_flag_t flag, VALUE self, ID id,
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* _YARVCORE_H_INCLUDED_ */
|
||||
#endif /* RUBY_CORE_H */
|
36
vm_dump.c
36
vm_dump.c
|
@ -13,7 +13,7 @@
|
|||
#include "ruby/ruby.h"
|
||||
#include "ruby/node.h"
|
||||
|
||||
#include "yarvcore.h"
|
||||
#include "vm_core.h"
|
||||
#include "vm.h"
|
||||
|
||||
#define MAX_POSBUF 128
|
||||
|
@ -114,7 +114,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
line = -1;
|
||||
}
|
||||
|
||||
fprintf(stderr, "c:%04ld ",
|
||||
fprintf(stderr, "c:%04d ",
|
||||
(rb_control_frame_t *)(th->stack + th->stack_size) - cfp);
|
||||
if (pc == -1) {
|
||||
fprintf(stderr, "p:---- ");
|
||||
|
@ -123,8 +123,8 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
fprintf(stderr, "p:%04d ", pc);
|
||||
}
|
||||
fprintf(stderr, "s:%04d b:%04d ", cfp->sp - th->stack, bp);
|
||||
fprintf(stderr, lfp_in_heap == ' ' ? "l:%06d " : "l:%06p ", lfp % 10000);
|
||||
fprintf(stderr, dfp_in_heap == ' ' ? "d:%06d " : "d:%06p ", dfp % 10000);
|
||||
fprintf(stderr, lfp_in_heap == ' ' ? "l:%06d " : "l:%06x ", lfp % 10000);
|
||||
fprintf(stderr, dfp_in_heap == ' ' ? "d:%06d " : "d:%06x ", dfp % 10000);
|
||||
fprintf(stderr, "%-6s ", magic);
|
||||
if (line) {
|
||||
fprintf(stderr, "%s", posbuf);
|
||||
|
@ -235,7 +235,7 @@ stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
VALUE *lfp = cfp->lfp;
|
||||
VALUE *dfp = cfp->dfp;
|
||||
|
||||
int argc, local_size;
|
||||
int argc = 0, local_size;
|
||||
const char *name;
|
||||
rb_iseq_t *iseq = cfp->iseq;
|
||||
|
||||
|
@ -300,7 +300,7 @@ stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||
else {
|
||||
rstr = rb_inspect(*ptr);
|
||||
}
|
||||
fprintf(stderr, " stack %2d: %8s (%ld)\n", i, StringValueCStr(rstr),
|
||||
fprintf(stderr, " stack %2d: %8s (%d)\n", i, StringValueCStr(rstr),
|
||||
ptr - th->stack);
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +337,7 @@ debug_print_register(rb_thread_t *th)
|
|||
dfp = -1;
|
||||
|
||||
cfpi = ((rb_control_frame_t *)(th->stack + th->stack_size)) - cfp;
|
||||
fprintf(stderr, " [PC] %04d, [SP] %04ld, [LFP] %04d, [DFP] %04d, [CFP] %04d\n",
|
||||
fprintf(stderr, " [PC] %04d, [SP] %04d, [LFP] %04d, [DFP] %04d, [CFP] %04d\n",
|
||||
pc, cfp->sp - th->stack, lfp, dfp, cfpi);
|
||||
}
|
||||
|
||||
|
@ -424,13 +424,11 @@ vm_analysis_insn(int insn)
|
|||
VALUE ihash;
|
||||
VALUE cv;
|
||||
|
||||
SET_YARV_STOP();
|
||||
|
||||
if (usage_hash == 0) {
|
||||
usage_hash = rb_intern("USAGE_ANALISYS_INSN");
|
||||
bigram_hash = rb_intern("USAGE_ANALISYS_INSN_BIGRAM");
|
||||
}
|
||||
uh = rb_const_get(mYarvCore, usage_hash);
|
||||
uh = rb_const_get(rb_cVM, usage_hash);
|
||||
if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) {
|
||||
ihash = rb_hash_new();
|
||||
rb_hash_aset(uh, INT2FIX(insn), ihash);
|
||||
|
@ -450,15 +448,13 @@ vm_analysis_insn(int insn)
|
|||
ary[1] = INT2FIX(insn);
|
||||
bi = rb_ary_new4(2, &ary[0]);
|
||||
|
||||
uh = rb_const_get(mYarvCore, bigram_hash);
|
||||
uh = rb_const_get(rb_cVM, bigram_hash);
|
||||
if ((cv = rb_hash_aref(uh, bi)) == Qnil) {
|
||||
cv = INT2FIX(0);
|
||||
}
|
||||
rb_hash_aset(uh, bi, INT2FIX(FIX2INT(cv) + 1));
|
||||
}
|
||||
prev_insn = insn;
|
||||
|
||||
SET_YARV_START();
|
||||
}
|
||||
|
||||
/* from disasm.c */
|
||||
|
@ -476,13 +472,11 @@ vm_analysis_operand(int insn, int n, VALUE op)
|
|||
VALUE valstr;
|
||||
VALUE cv;
|
||||
|
||||
SET_YARV_STOP();
|
||||
|
||||
if (usage_hash == 0) {
|
||||
usage_hash = rb_intern("USAGE_ANALISYS_INSN");
|
||||
}
|
||||
|
||||
uh = rb_const_get(mYarvCore, usage_hash);
|
||||
uh = rb_const_get(rb_cVM, usage_hash);
|
||||
if ((ihash = rb_hash_aref(uh, INT2FIX(insn))) == Qnil) {
|
||||
ihash = rb_hash_new();
|
||||
rb_hash_aset(uh, INT2FIX(insn), ihash);
|
||||
|
@ -499,8 +493,6 @@ vm_analysis_operand(int insn, int n, VALUE op)
|
|||
cv = INT2FIX(0);
|
||||
}
|
||||
rb_hash_aset(ophash, valstr, INT2FIX(FIX2INT(cv) + 1));
|
||||
|
||||
SET_YARV_START();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -527,8 +519,6 @@ vm_analysis_register(int reg, int isset)
|
|||
|
||||
VALUE cv;
|
||||
|
||||
SET_YARV_STOP();
|
||||
|
||||
if (usage_hash == 0) {
|
||||
char buff[0x10];
|
||||
int i;
|
||||
|
@ -546,13 +536,11 @@ vm_analysis_register(int reg, int isset)
|
|||
}
|
||||
valstr = syms[reg][isset];
|
||||
|
||||
uh = rb_const_get(mYarvCore, usage_hash);
|
||||
uh = rb_const_get(rb_cVM, usage_hash);
|
||||
if ((cv = rb_hash_aref(uh, valstr)) == Qnil) {
|
||||
cv = INT2FIX(0);
|
||||
}
|
||||
rb_hash_aset(uh, valstr, INT2FIX(FIX2INT(cv) + 1));
|
||||
|
||||
SET_YARV_START();
|
||||
}
|
||||
|
||||
|
||||
|
@ -575,7 +563,7 @@ thread_dump_state(VALUE self)
|
|||
}
|
||||
|
||||
void
|
||||
yarv_bug(void)
|
||||
rb_vm_bugreport(void)
|
||||
{
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE bt;
|
||||
|
|
|
@ -80,9 +80,9 @@ vm_eval(rb_thread_t *th, VALUE initial)
|
|||
#include "vmtc.inc"
|
||||
if (th == 0) {
|
||||
#if OPT_STACK_CACHING
|
||||
yarv_finish_insn_seq[0] = (VALUE)&&LABEL (finish_SC_ax_ax);
|
||||
finish_insn_seq[0] = (VALUE)&&LABEL (finish_SC_ax_ax);
|
||||
#else
|
||||
yarv_finish_insn_seq[0] = (VALUE)&&LABEL (finish);
|
||||
finish_insn_seq[0] = (VALUE)&&LABEL (finish);
|
||||
#endif
|
||||
return (VALUE)insns_address_table;
|
||||
}
|
||||
|
|
582
yarvcore.c
582
yarvcore.c
|
@ -1,582 +0,0 @@
|
|||
/**********************************************************************
|
||||
|
||||
yarvcore.h -
|
||||
|
||||
$Author$
|
||||
$Date$
|
||||
created at: 04/01/01 01:17:22 JST
|
||||
|
||||
Copyright (C) 2004-2006 Koichi Sasada
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/node.h"
|
||||
#include "yarvcore.h"
|
||||
#include "gc.h"
|
||||
|
||||
|
||||
VALUE rb_cVM;
|
||||
VALUE rb_cThread;
|
||||
|
||||
VALUE symIFUNC;
|
||||
VALUE symCFUNC;
|
||||
|
||||
ID idPLUS;
|
||||
ID idMINUS;
|
||||
ID idMULT;
|
||||
ID idDIV;
|
||||
ID idMOD;
|
||||
ID idLT;
|
||||
ID idLTLT;
|
||||
ID idLE;
|
||||
ID idGT;
|
||||
ID idGE;
|
||||
ID idEq;
|
||||
ID idEqq;
|
||||
ID idBackquote;
|
||||
ID idEqTilde;
|
||||
ID idThrowState;
|
||||
ID idAREF;
|
||||
ID idASET;
|
||||
ID idIntern;
|
||||
ID idMethodMissing;
|
||||
ID idLength;
|
||||
ID idLambda;
|
||||
ID idGets;
|
||||
ID idSucc;
|
||||
ID idEach;
|
||||
ID idRangeEachLT;
|
||||
ID idRangeEachLE;
|
||||
ID idArrayEach;
|
||||
ID idTimes;
|
||||
ID idEnd;
|
||||
ID idBitblt;
|
||||
ID idAnswer;
|
||||
ID idSvarPlaceholder;
|
||||
ID idSend;
|
||||
ID id__send__;
|
||||
ID id__send;
|
||||
ID idFuncall;
|
||||
ID id__send_bang;
|
||||
|
||||
/* from Ruby 1.9 eval.c */
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
#include <stdarg.h>
|
||||
#define va_init_list(a,b) va_start(a,b)
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#define va_init_list(a,b) va_start(a)
|
||||
#endif
|
||||
|
||||
/************/
|
||||
/* YARVCore */
|
||||
/************/
|
||||
|
||||
rb_thread_t *ruby_current_thread = 0;
|
||||
rb_vm_t *ruby_current_vm = 0;
|
||||
|
||||
static NODE *
|
||||
compile_string(VALUE str, VALUE file, VALUE line)
|
||||
{
|
||||
VALUE parser = rb_parser_new();
|
||||
NODE *node;
|
||||
|
||||
node = rb_parser_compile_string(parser, StringValueCStr(file),
|
||||
str, NUM2INT(line));
|
||||
|
||||
if (!node) {
|
||||
rb_exc_raise(GET_THREAD()->errinfo); /* TODO: check err */
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
yarvcore_eval_iseq(VALUE iseq)
|
||||
{
|
||||
return rb_thread_eval(GET_THREAD(), iseq);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
vm_compile_from_node(rb_thread_t *th, NODE * node, VALUE file)
|
||||
{
|
||||
VALUE iseq;
|
||||
if (th->base_block) {
|
||||
iseq = rb_iseq_new(node,
|
||||
th->base_block->iseq->name,
|
||||
file,
|
||||
th->base_block->iseq->self,
|
||||
ISEQ_TYPE_EVAL);
|
||||
}
|
||||
else {
|
||||
iseq = rb_iseq_new(node, rb_str_new2("<main>"), file,
|
||||
Qfalse, ISEQ_TYPE_TOP);
|
||||
}
|
||||
return iseq;
|
||||
}
|
||||
|
||||
VALUE
|
||||
vm_compile(rb_thread_t *th, VALUE str, VALUE file, VALUE line)
|
||||
{
|
||||
NODE *node = (NODE *) compile_string(str, file, line);
|
||||
return vm_compile_from_node(th, (NODE *) node, file);
|
||||
}
|
||||
|
||||
VALUE
|
||||
yarvcore_eval_parsed(NODE *node, VALUE file)
|
||||
{
|
||||
VALUE iseq = vm_compile_from_node(GET_THREAD(), node, file);
|
||||
return yarvcore_eval_iseq(iseq);
|
||||
}
|
||||
|
||||
VALUE
|
||||
yarvcore_eval(VALUE self, VALUE str, VALUE file, VALUE line)
|
||||
{
|
||||
NODE *node;
|
||||
node = compile_string(str, file, line);
|
||||
return yarvcore_eval_parsed(node, file);
|
||||
}
|
||||
|
||||
/******/
|
||||
/* VM */
|
||||
/******/
|
||||
|
||||
void native_thread_cleanup(void *);
|
||||
|
||||
static void
|
||||
vm_free(void *ptr)
|
||||
{
|
||||
RUBY_FREE_ENTER("vm");
|
||||
if (ptr) {
|
||||
rb_vm_t *vmobj = ptr;
|
||||
|
||||
st_free_table(vmobj->living_threads);
|
||||
/* TODO: MultiVM Instance */
|
||||
/* VM object should not be cleaned by GC */
|
||||
/* ruby_xfree(ptr); */
|
||||
/* ruby_current_vm = 0; */
|
||||
}
|
||||
RUBY_FREE_LEAVE("vm");
|
||||
}
|
||||
|
||||
static int
|
||||
vm_mark_each_thread_func(st_data_t key, st_data_t value, st_data_t dummy)
|
||||
{
|
||||
VALUE thval = (VALUE)key;
|
||||
rb_gc_mark(thval);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
mark_event_hooks(rb_event_hook_t *hook)
|
||||
{
|
||||
while (hook) {
|
||||
rb_gc_mark(hook->data);
|
||||
hook = hook->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vm_mark(void *ptr)
|
||||
{
|
||||
RUBY_MARK_ENTER("vm");
|
||||
RUBY_GC_INFO("-------------------------------------------------\n");
|
||||
if (ptr) {
|
||||
rb_vm_t *vm = ptr;
|
||||
if (vm->living_threads) {
|
||||
st_foreach(vm->living_threads, vm_mark_each_thread_func, 0);
|
||||
}
|
||||
RUBY_MARK_UNLESS_NULL(vm->thgroup_default);
|
||||
RUBY_MARK_UNLESS_NULL(vm->mark_object_ary);
|
||||
RUBY_MARK_UNLESS_NULL(vm->last_status);
|
||||
RUBY_MARK_UNLESS_NULL(vm->loaded_features);
|
||||
|
||||
if (vm->loading_table) {
|
||||
rb_mark_tbl(vm->loading_table);
|
||||
}
|
||||
|
||||
mark_event_hooks(vm->event_hooks);
|
||||
}
|
||||
|
||||
RUBY_MARK_LEAVE("vm");
|
||||
}
|
||||
|
||||
void
|
||||
rb_vm_mark(void *ptr)
|
||||
{
|
||||
vm_mark(ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
vm_init2(rb_vm_t *vm)
|
||||
{
|
||||
MEMZERO(vm, rb_vm_t, 1);
|
||||
}
|
||||
|
||||
/**********/
|
||||
/* Thread */
|
||||
/**********/
|
||||
|
||||
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->local_storage) {
|
||||
st_free_table(th->local_storage);
|
||||
}
|
||||
|
||||
#if USE_VALUE_CACHE
|
||||
{
|
||||
VALUE *ptr = th->value_cache_ptr;
|
||||
while (*ptr) {
|
||||
VALUE v = *ptr;
|
||||
RBASIC(v)->flags = 0;
|
||||
RBASIC(v)->klass = 0;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (th->vm->main_thread == th) {
|
||||
RUBY_GC_INFO("main thread\n");
|
||||
}
|
||||
else {
|
||||
ruby_xfree(ptr);
|
||||
}
|
||||
}
|
||||
RUBY_FREE_LEAVE("thread");
|
||||
}
|
||||
|
||||
void yarv_machine_stack_mark(rb_thread_t *th);
|
||||
|
||||
void
|
||||
rb_thread_mark(void *ptr)
|
||||
{
|
||||
rb_thread_t *th = NULL;
|
||||
RUBY_MARK_ENTER("thread");
|
||||
if (ptr) {
|
||||
th = ptr;
|
||||
if (th->stack) {
|
||||
VALUE *p = th->stack;
|
||||
VALUE *sp = th->cfp->sp + th->mark_stack_len;
|
||||
rb_control_frame_t *cfp = th->cfp;
|
||||
rb_control_frame_t *limit_cfp =
|
||||
(void *)(th->stack + th->stack_size);
|
||||
|
||||
while (p < sp) {
|
||||
rb_gc_mark(*p++);
|
||||
}
|
||||
while (cfp != limit_cfp) {
|
||||
rb_gc_mark(cfp->proc);
|
||||
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
|
||||
}
|
||||
}
|
||||
|
||||
/* mark ruby objects */
|
||||
RUBY_MARK_UNLESS_NULL(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->thrown_errinfo);
|
||||
RUBY_MARK_UNLESS_NULL(th->local_svar);
|
||||
RUBY_MARK_UNLESS_NULL(th->top_self);
|
||||
RUBY_MARK_UNLESS_NULL(th->top_wrapper);
|
||||
RUBY_MARK_UNLESS_NULL(th->fiber);
|
||||
RUBY_MARK_UNLESS_NULL(th->root_fiber);
|
||||
|
||||
rb_mark_tbl(th->local_storage);
|
||||
|
||||
if (GET_THREAD() != th && th->machine_stack_start && th->machine_stack_end) {
|
||||
yarv_machine_stack_mark(th);
|
||||
rb_gc_mark_locations((VALUE *)&th->machine_regs,
|
||||
(VALUE *)(&th->machine_regs) +
|
||||
sizeof(th->machine_regs) / sizeof(VALUE));
|
||||
}
|
||||
|
||||
mark_event_hooks(th->event_hooks);
|
||||
}
|
||||
|
||||
RUBY_MARK_UNLESS_NULL(th->stat_insn_usage);
|
||||
RUBY_MARK_LEAVE("thread");
|
||||
}
|
||||
|
||||
static VALUE
|
||||
thread_alloc(VALUE klass)
|
||||
{
|
||||
VALUE volatile obj;
|
||||
rb_thread_t *th;
|
||||
obj = Data_Make_Struct(klass, rb_thread_t,
|
||||
rb_thread_mark, thread_free, th);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
th_init2(rb_thread_t *th)
|
||||
{
|
||||
MEMZERO(th, rb_thread_t, 1);
|
||||
|
||||
/* allocate thread stack */
|
||||
th->stack_size = RUBY_VM_THREAD_STACK_SIZE;
|
||||
th->stack = ALLOC_N(VALUE, th->stack_size);
|
||||
|
||||
th->cfp = (void *)(th->stack + th->stack_size);
|
||||
th->cfp--;
|
||||
|
||||
th->cfp->pc = 0;
|
||||
th->cfp->sp = th->stack + 1;
|
||||
th->cfp->bp = 0;
|
||||
th->cfp->lfp = th->stack;
|
||||
*th->cfp->lfp = 0;
|
||||
th->cfp->dfp = th->stack;
|
||||
th->cfp->self = Qnil;
|
||||
th->cfp->flag = 0;
|
||||
th->cfp->iseq = 0;
|
||||
th->cfp->proc = 0;
|
||||
th->cfp->block_iseq = 0;
|
||||
|
||||
th->status = THREAD_RUNNABLE;
|
||||
th->errinfo = Qnil;
|
||||
|
||||
#if USE_VALUE_CACHE
|
||||
th->value_cache_ptr = &th->value_cache[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
th_init(rb_thread_t *th)
|
||||
{
|
||||
th_init2(th);
|
||||
}
|
||||
|
||||
extern VALUE ruby_top_self;
|
||||
|
||||
static VALUE
|
||||
ruby_thread_init(VALUE self)
|
||||
{
|
||||
rb_thread_t *th;
|
||||
rb_vm_t *vm = GET_THREAD()->vm;
|
||||
GetThreadPtr(self, th);
|
||||
|
||||
th_init(th);
|
||||
th->self = self;
|
||||
th->vm = vm;
|
||||
|
||||
th->top_wrapper = 0;
|
||||
th->top_self = ruby_top_self;
|
||||
return self;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_thread_alloc(VALUE klass)
|
||||
{
|
||||
VALUE self = thread_alloc(klass);
|
||||
ruby_thread_init(self);
|
||||
return self;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
VALUE insns_name_array(void);
|
||||
extern VALUE *rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
extern VALUE *rb_gc_register_stack_start;
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
sdr(void)
|
||||
{
|
||||
yarv_bug();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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];
|
||||
int n = backtrace(trace, MAX_NATIVE_TRACE);
|
||||
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]));
|
||||
}
|
||||
free(syms);
|
||||
#endif
|
||||
return ary;
|
||||
}
|
||||
|
||||
static char *yarv_options = ""
|
||||
#if OPT_DIRECT_THREADED_CODE
|
||||
"[direct threaded code] "
|
||||
#elif OPT_TOKEN_THREADED_CODE
|
||||
"[token threaded code] "
|
||||
#elif OPT_CALL_THREADED_CODE
|
||||
"[call threaded code] "
|
||||
#endif
|
||||
|
||||
#if OPT_BASIC_OPERATIONS
|
||||
"[optimize basic operation] "
|
||||
#endif
|
||||
#if OPT_STACK_CACHING
|
||||
"[stack caching] "
|
||||
#endif
|
||||
#if OPT_OPERANDS_UNIFICATION
|
||||
"[operands unification] "
|
||||
#endif
|
||||
#if OPT_INSTRUCTIONS_UNIFICATION
|
||||
"[instructions unification] "
|
||||
#endif
|
||||
#if OPT_INLINE_METHOD_CACHE
|
||||
"[inline method cache] "
|
||||
#endif
|
||||
#if OPT_BLOCKINLINING
|
||||
"[block inlining] "
|
||||
#endif
|
||||
;
|
||||
|
||||
void yarv_init_redefined_flag(void);
|
||||
|
||||
void
|
||||
Init_VM(void)
|
||||
{
|
||||
/* ::VM */
|
||||
rb_cVM = rb_define_class("VM", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cVM);
|
||||
|
||||
/* Env */
|
||||
rb_cEnv = rb_define_class_under(rb_cVM, "Env", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cEnv);
|
||||
|
||||
/* ::Thread */
|
||||
rb_cThread = rb_define_class("Thread", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cThread);
|
||||
rb_define_method(rb_cThread, "initialize", ruby_thread_init, 0);
|
||||
|
||||
/* ::VM::USAGE_ANALISYS_* */
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_INSN", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_REGS", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "USAGE_ANALISYS_INSN_BIGRAM", rb_hash_new());
|
||||
rb_define_const(rb_cVM, "OPTS", rb_str_new2(yarv_options));
|
||||
|
||||
/* ::VM::InsnNameArray */
|
||||
rb_define_const(rb_cVM, "InsnNameArray", insns_name_array());
|
||||
|
||||
/* ::VM::eval() */
|
||||
rb_define_singleton_method(rb_cVM, "eval", yarvcore_eval, 3);
|
||||
|
||||
/* debug functions ::VM::SDR(), ::VM::NSDR() */
|
||||
rb_define_singleton_method(rb_cVM, "SDR", sdr, 0);
|
||||
rb_define_singleton_method(rb_cVM, "NSDR", nsdr, 0);
|
||||
|
||||
/* Symbols */
|
||||
symIFUNC = ID2SYM(rb_intern("<IFUNC>"));
|
||||
symCFUNC = ID2SYM(rb_intern("<CFUNC>"));
|
||||
|
||||
/* IDs */
|
||||
idPLUS = rb_intern("+");
|
||||
idMINUS = rb_intern("-");
|
||||
idMULT = rb_intern("*");
|
||||
idDIV = rb_intern("/");
|
||||
idMOD = rb_intern("%");
|
||||
idLT = rb_intern("<");
|
||||
idLTLT = rb_intern("<<");
|
||||
idLE = rb_intern("<=");
|
||||
idGT = rb_intern(">");
|
||||
idGE = rb_intern(">=");
|
||||
idEq = rb_intern("==");
|
||||
idEqq = rb_intern("===");
|
||||
idBackquote = rb_intern("`");
|
||||
idEqTilde = rb_intern("=~");
|
||||
|
||||
idAREF = rb_intern("[]");
|
||||
idASET = rb_intern("[]=");
|
||||
|
||||
idEach = rb_intern("each");
|
||||
idTimes = rb_intern("times");
|
||||
idLength = rb_intern("length");
|
||||
idLambda = rb_intern("lambda");
|
||||
idIntern = rb_intern("intern");
|
||||
idGets = rb_intern("gets");
|
||||
idSucc = rb_intern("succ");
|
||||
idEnd = rb_intern("end");
|
||||
idRangeEachLT = rb_intern("Range#each#LT");
|
||||
idRangeEachLE = rb_intern("Range#each#LE");
|
||||
idArrayEach = rb_intern("Array#each");
|
||||
idMethodMissing = rb_intern("method_missing");
|
||||
|
||||
idThrowState = rb_intern("#__ThrowState__");
|
||||
|
||||
idBitblt = rb_intern("bitblt");
|
||||
idAnswer = rb_intern("the_answer_to_life_the_universe_and_everything");
|
||||
idSvarPlaceholder = rb_intern("#svar");
|
||||
|
||||
idSend = rb_intern("send");
|
||||
id__send__ = rb_intern("__send__");
|
||||
id__send = rb_intern("__send");
|
||||
idFuncall = rb_intern("funcall");
|
||||
id__send_bang = rb_intern("__send!");
|
||||
|
||||
/* VM bootstrap: phase 2 */
|
||||
{
|
||||
rb_vm_t *vm = ruby_current_vm;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
volatile VALUE th_self;
|
||||
|
||||
/* create vm object */
|
||||
vm->self = Data_Wrap_Struct(rb_cVM, vm_mark, vm_free, vm);
|
||||
|
||||
/* create main thread */
|
||||
th_self = th->self = Data_Wrap_Struct(rb_cThread, rb_thread_mark,
|
||||
thread_free, th);
|
||||
|
||||
vm->main_thread = th;
|
||||
vm->running_thread = th;
|
||||
th->vm = vm;
|
||||
th->top_wrapper = 0;
|
||||
th->top_self = ruby_top_self;
|
||||
rb_thread_set_current(th);
|
||||
|
||||
vm->living_threads = st_init_numtable();
|
||||
st_insert(vm->living_threads, th_self, (st_data_t) th->thread_id);
|
||||
}
|
||||
yarv_init_redefined_flag();
|
||||
}
|
||||
|
||||
void
|
||||
Init_yarv(void)
|
||||
{
|
||||
/* VM bootstrap: phase 1 */
|
||||
rb_vm_t *vm = ALLOC(rb_vm_t);
|
||||
rb_thread_t *th = ALLOC(rb_thread_t);
|
||||
|
||||
vm_init2(vm);
|
||||
ruby_current_vm = vm;
|
||||
|
||||
th_init2(th);
|
||||
th->vm = vm;
|
||||
th->machine_stack_start = rb_gc_stack_start;
|
||||
#ifdef __ia64
|
||||
th->machine_register_stack_start = rb_gc_register_stack_start;
|
||||
#endif
|
||||
rb_thread_set_current_raw(th);
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче