* 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:
ko1 2007-07-12 04:25:46 +00:00
Родитель 2e601474e7
Коммит 6b6bf4dd48
35 изменённых файлов: 800 добавлений и 931 удалений

Просмотреть файл

@ -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]

Просмотреть файл

@ -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];

Просмотреть файл

@ -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

Просмотреть файл

@ -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;

Просмотреть файл

@ -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
Просмотреть файл

@ -11,7 +11,7 @@
**********************************************************************/
#include "ruby/ruby.h"
#include "yarvcore.h"
#include "vm_core.h"
#include "gc.h"
#include "eval_intern.h"

Просмотреть файл

@ -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)

Просмотреть файл

@ -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
Просмотреть файл

@ -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())

Просмотреть файл

@ -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
Просмотреть файл

@ -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);

68
id.c Normal file
Просмотреть файл

@ -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!");
}

53
id.h Normal file
Просмотреть файл

@ -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;

Просмотреть файл

@ -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
Просмотреть файл

@ -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;

Просмотреть файл

@ -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
Просмотреть файл

@ -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>

Просмотреть файл

@ -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 %>

Просмотреть файл

@ -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
Просмотреть файл

@ -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
Просмотреть файл

@ -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 */

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);
}