summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog49
-rw-r--r--array.c9
-rw-r--r--blockinlining.c25
-rw-r--r--common.mk37
-rw-r--r--compile.c97
-rw-r--r--compile.h10
-rw-r--r--cont.c2
-rw-r--r--debug.c2
-rw-r--r--error.c6
-rw-r--r--eval.c29
-rw-r--r--eval_intern.h5
-rw-r--r--eval_load.c10
-rw-r--r--ext/probeprofiler/probeprofiler.c2
-rw-r--r--gc.c4
-rw-r--r--id.c68
-rw-r--r--id.h53
-rw-r--r--inits.c4
-rw-r--r--insnhelper.ci3
-rw-r--r--insnhelper.h5
-rw-r--r--insns.def2
-rw-r--r--iseq.c72
-rw-r--r--numeric.c5
-rw-r--r--object.c13
-rw-r--r--proc.c12
-rw-r--r--process.c2
-rw-r--r--signal.c2
-rw-r--r--template/insns.inc.tmpl2
-rw-r--r--thread.c20
-rw-r--r--thread_pthread.ci2
-rw-r--r--vm.c433
-rw-r--r--vm.h20
-rw-r--r--vm_core.h (renamed from yarvcore.h)104
-rw-r--r--vm_dump.c36
-rw-r--r--vm_evalbody.ci4
-rw-r--r--yarvcore.c582
35 files changed, 800 insertions, 931 deletions
diff --git a/ChangeLog b/ChangeLog
index f058a7b..a45a4c1 100644
--- a/ChangeLog
+++ b/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]
diff --git a/array.c b/array.c
index 6d469cb..2dcb2b4 100644
--- a/array.c
+++ b/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;
}
diff --git a/blockinlining.c b/blockinlining.c
index 4f491c1..35a9d61 100644
--- a/blockinlining.c
+++ b/blockinlining.c
@@ -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];
diff --git a/common.mk b/common.mk
index 1f77bf6..de84d52 100644
--- a/common.mk
+++ b/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
diff --git a/compile.c b/compile.c
index a2cef37..3ef895b 100644
--- a/compile.c
+++ b/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;
diff --git a/compile.h b/compile.h
index e298008..e40517e 100644
--- a/compile.h
+++ b/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
diff --git a/cont.c b/cont.c
index 914eed4..2924810 100644
--- a/cont.c
+++ b/cont.c
@@ -11,7 +11,7 @@
**********************************************************************/
#include "ruby/ruby.h"
-#include "yarvcore.h"
+#include "vm_core.h"
#include "gc.h"
#include "eval_intern.h"
diff --git a/debug.c b/debug.c
index cd1b80f..b5a014e 100644
--- a/debug.c
+++ b/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)
diff --git a/error.c b/error.c
index 4bdc028..f12c890 100644
--- a/error.c
+++ b/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",
diff --git a/eval.c b/eval.c
index 1f02286..53b4ab2 100644
--- a/eval.c
+++ b/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);
diff --git a/eval_intern.h b/eval_intern.h
index 0328186..7b89ed3 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -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())
diff --git a/eval_load.c b/eval_load.c
index 3974513..d0cd5e2 100644
--- a/eval_load.c
+++ b/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);
diff --git a/ext/probeprofiler/probeprofiler.c b/ext/probeprofiler/probeprofiler.c
index cff7930..473844c 100644
--- a/ext/probeprofiler/probeprofiler.c
+++ b/ext/probeprofiler/probeprofiler.c
@@ -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);
diff --git a/gc.c b/gc.c
index d596d10..b4240c0 100644
--- a/gc.c
+++ b/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);
diff --git a/id.c b/id.c
new file mode 100644
index 0000000..4685390
--- /dev/null
+++ b/id.c
@@ -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!");
+}
diff --git a/id.h b/id.h
new file mode 100644
index 0000000..32f4e27
--- /dev/null
+++ b/id.h
@@ -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;
+
+
diff --git a/inits.c b/inits.c
index 3ace504..302f1c6 100644
--- a/inits.c
+++ b/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();
diff --git a/insnhelper.ci b/insnhelper.ci
index c3c44cb..e77a144 100644
--- a/insnhelper.ci
+++ b/insnhelper.ci
@@ -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));
}
diff --git a/insnhelper.h b/insnhelper.h
index 8ae9599..f8439f7 100644
--- a/insnhelper.h
+++ b/insnhelper.h
@@ -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)
diff --git a/insns.def b/insns.def
index 9116430..5e0f49b 100644
--- a/insns.def
+++ b/insns.def
@@ -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);
}
/**
diff --git a/iseq.c b/iseq.c
index 55ff995..c50a6d4 100644
--- a/iseq.c
+++ b/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;
}
-static VALUE
-iseq_s_compile(int argc, VALUE *argv, VALUE self)
+VALUE
+rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE line, VALUE opt)
{
- VALUE str, file = Qnil, line = INT2FIX(1), opt = Qnil;
- NODE *node;
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);
+}
- rb_scan_args(argc, argv, "13", &str, &file, &line, &opt);
+static VALUE
+iseq_s_compile(int argc, VALUE *argv, VALUE self)
+{
+ 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);
diff --git a/numeric.c b/numeric.c
index c331030..cd2b4af 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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;
diff --git a/object.c b/object.c
index 6264b16..bcff31e 100644
--- a/object.c
+++ b/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);
diff --git a/proc.c b/proc.c
index 1628f68..d5c0ce4 100644
--- a/proc.c
+++ b/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;
@@ -70,12 +70,6 @@ proc_alloc(VALUE klass)
}
VALUE
-rb_proc_alloc(void)
-{
- return proc_alloc(rb_cProc);
-}
-
-VALUE
rb_obj_is_proc(VALUE proc)
{
if (TYPE(proc) == T_DATA &&
@@ -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);
diff --git a/process.c b/process.c
index 5dff222..0ff54d0 100644
--- a/process.c
+++ b/process.c
@@ -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>
diff --git a/signal.c b/signal.c
index 44c2d2d..772e5ec 100644
--- a/signal.c
+++ b/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>
diff --git a/template/insns.inc.tmpl b/template/insns.inc.tmpl
index 05af3e8..770210e 100644
--- a/template/insns.inc.tmpl
+++ b/template/insns.inc.tmpl
@@ -17,5 +17,5 @@ enum{
<%= insns %>
};
-#define YARV_MAX_INSTRUCTION_SIZE <%= @insns.size %>
+#define VM_INSTRUCTION_SIZE <%= @insns.size %>
diff --git a/thread.c b/thread.c
index bf17dc8..c38130f 100644
--- a/thread.c
+++ b/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);
diff --git a/thread_pthread.ci b/thread_pthread.ci
index cd5e05b..d624e98 100644
--- a/thread_pthread.ci
+++ b/thread_pthread.ci
@@ -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);
}
diff --git a/vm.c b/vm.c
index 0aae865..80e470f 100644
--- a/vm.c
+++ b/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);
+}
diff --git a/vm.h b/vm.h
index de8365b..c496e59 100644
--- a/vm.h
+++ b/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 */
diff --git a/yarvcore.h b/vm_core.h
index d0ce781..568b7b3 100644
--- a/yarvcore.h
+++ b/vm_core.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 */
diff --git a/vm_dump.c b/vm_dump.c
index c72b4e1..0f782e6 100644
--- a/vm_dump.c
+++ b/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;
diff --git a/vm_evalbody.ci b/vm_evalbody.ci
index f9dd39f..3ac3fa5 100644
--- a/vm_evalbody.ci
+++ b/vm_evalbody.ci
@@ -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;
}
diff --git a/yarvcore.c b/yarvcore.c
deleted file mode 100644
index 194ca1a..0000000
--- a/yarvcore.c
+++ /dev/null
@@ -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);
-}
-