aboutsummaryrefslogtreecommitdiffstats
path: root/yarvcore.c
diff options
context:
space:
mode:
Diffstat (limited to 'yarvcore.c')
-rw-r--r--yarvcore.c464
1 files changed, 26 insertions, 438 deletions
diff --git a/yarvcore.c b/yarvcore.c
index 899ffb65e3..543dffd6da 100644
--- a/yarvcore.c
+++ b/yarvcore.c
@@ -17,14 +17,8 @@
#include "yarv.h"
#include "gc.h"
-VALUE mYarvCore;
-VALUE cYarvISeq;
-VALUE cYarvVM;
VALUE cYarvThread;
-VALUE mYarvInsns;
-VALUE cYarvEnv;
-VALUE cYarvProc;
-VALUE cYarvBinding;
+VALUE rb_cVM;
VALUE symIFUNC;
VALUE symCFUNC;
@@ -453,7 +447,6 @@ yarv_thread_alloc(VALUE klass)
VALUE th_eval_body(yarv_thread_t *th);
void th_set_top_stack(yarv_thread_t *, VALUE iseq);
-VALUE rb_f_binding(VALUE);
VALUE
yarv_th_eval(yarv_thread_t *th, VALUE iseqval)
@@ -464,375 +457,19 @@ yarv_th_eval(yarv_thread_t *th, VALUE iseqval)
th_set_top_stack(th, iseqval);
if (!rb_const_defined(rb_cObject, rb_intern("TOPLEVEL_BINDING"))) {
- rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(Qnil));
+ rb_define_global_const("TOPLEVEL_BINDING", rb_binding_new());
}
val = th_eval_body(th);
tmp = iseqval; /* prohibit tail call optimization */
return val;
}
-
-/***************/
-/* YarvEnv */
-/***************/
-
-static void
-env_free(void *ptr)
-{
- yarv_env_t *env;
- FREE_REPORT_ENTER("env");
- if (ptr) {
- env = ptr;
- FREE_UNLESS_NULL(env->env);
- ruby_xfree(ptr);
- }
- FREE_REPORT_LEAVE("env");
-}
-
-static void
-env_mark(void *ptr)
-{
- yarv_env_t *env;
- MARK_REPORT_ENTER("env");
- if (ptr) {
- env = ptr;
- if (env->env) {
- /* TODO: should mark more restricted range */
- GC_INFO("env->env\n");
- rb_gc_mark_locations(env->env, env->env + env->env_size);
- }
- GC_INFO("env->prev_envval\n");
- MARK_UNLESS_NULL(env->prev_envval);
-
- if (env->block.iseq) {
- //printf("env->block.iseq <%p, %d>\n",
- // env->block.iseq, BUILTIN_TYPE(env->block.iseq));
- if (BUILTIN_TYPE(env->block.iseq) == T_NODE) {
- MARK_UNLESS_NULL((VALUE)env->block.iseq);
- }
- else {
- MARK_UNLESS_NULL(env->block.iseq->self);
- }
- }
- }
- MARK_REPORT_LEAVE("env");
-}
-
-VALUE
-yarv_env_alloc(VALUE klass)
-{
- VALUE obj;
- yarv_env_t *env;
- obj = Data_Make_Struct(klass, yarv_env_t, env_mark, env_free, env);
- env->env = 0;
- env->prev_envval = 0;
- env->block.iseq = 0;
- return obj;
-}
-
-
-/***************/
-/* YarvProc */
-/***************/
-
-static void
-proc_free(void *ptr)
-{
- FREE_REPORT_ENTER("proc");
- if (ptr) {
- ruby_xfree(ptr);
- }
- FREE_REPORT_LEAVE("proc");
-}
-
-static void
-proc_mark(void *ptr)
-{
- yarv_proc_t *proc;
- MARK_REPORT_ENTER("proc");
- if (ptr) {
- proc = ptr;
- MARK_UNLESS_NULL(proc->envval);
- MARK_UNLESS_NULL(proc->blockprocval);
- MARK_UNLESS_NULL((VALUE)proc->special_cref_stack);
- if (proc->block.iseq && YARV_IFUNC_P(proc->block.iseq)) {
- MARK_UNLESS_NULL((VALUE)(proc->block.iseq));
- }
- }
- MARK_REPORT_LEAVE("proc");
-}
-
-static VALUE
-proc_alloc(VALUE klass)
-{
- VALUE obj;
- yarv_proc_t *proc;
- obj = Data_Make_Struct(klass, yarv_proc_t, proc_mark, proc_free, proc);
- MEMZERO(proc, yarv_proc_t, 1);
- return obj;
-}
-
-VALUE
-yarv_proc_alloc(VALUE klass)
-{
- return proc_alloc(cYarvProc);
-}
-
-static VALUE
-proc_call(int argc, VALUE *argv, VALUE procval)
-{
- yarv_proc_t *proc;
- GetProcPtr(procval, proc);
- return th_invoke_proc(GET_THREAD(), proc, proc->block.self, argc, argv);
-}
-
-static VALUE
-proc_yield(int argc, VALUE *argv, VALUE procval)
-{
- yarv_proc_t *proc;
- GetProcPtr(procval, proc);
- return th_invoke_proc(GET_THREAD(), proc, proc->block.self, argc, argv);
-}
-
-static VALUE
-proc_to_proc(VALUE self)
-{
- return self;
-}
-
-VALUE
-yarv_obj_is_proc(VALUE proc)
-{
- if (TYPE(proc) == T_DATA &&
- RDATA(proc)->dfree == (RUBY_DATA_FUNC) proc_free) {
- return Qtrue;
- }
- else {
- return Qfalse;
- }
-}
-
-static VALUE
-proc_arity(VALUE self)
-{
- yarv_proc_t *proc;
- yarv_iseq_t *iseq;
- GetProcPtr(self, proc);
- iseq = proc->block.iseq;
- if (iseq && BUILTIN_TYPE(iseq) != T_NODE) {
- if (iseq->arg_rest == 0 && iseq->arg_opts == 0) {
- return INT2FIX(iseq->argc);
- }
- else {
- return INT2FIX(-iseq->argc - 1);
- }
- }
- else {
- return INT2FIX(-1);
- }
-}
-
-int
-rb_proc_arity(VALUE proc)
-{
- return FIX2INT(proc_arity(proc));
-}
-
-static VALUE
-proc_eq(VALUE self, VALUE other)
-{
- if (self == other) {
- return Qtrue;
- }
- else {
- if (TYPE(other) == T_DATA &&
- RBASIC(other)->klass == cYarvProc &&
- CLASS_OF(self) == CLASS_OF(other)) {
- yarv_proc_t *p1, *p2;
- GetProcPtr(self, p1);
- GetProcPtr(other, p2);
- if (p1->block.iseq == p2->block.iseq && p1->envval == p2->envval) {
- return Qtrue;
- }
- }
- }
- return Qfalse;
-}
-
-static VALUE
-proc_hash(VALUE self)
-{
- int hash;
- yarv_proc_t *proc;
- GetProcPtr(self, proc);
- hash = (long)proc->block.iseq;
- hash ^= (long)proc->envval;
- hash ^= (long)proc->block.lfp >> 16;
- return INT2FIX(hash);
-}
-
-static VALUE
-proc_to_s(VALUE self)
-{
- VALUE str = 0;
- yarv_proc_t *proc;
- char *cname = rb_obj_classname(self);
- yarv_iseq_t *iseq;
-
- GetProcPtr(self, proc);
- iseq = proc->block.iseq;
-
- if (YARV_NORMAL_ISEQ_P(iseq)) {
- int line_no = 0;
-
- if (iseq->insn_info_tbl) {
- line_no = iseq->insn_info_tbl[0].line_no;
- }
- str = rb_sprintf("#<%s:%lx@%s:%d>", cname, self,
- RSTRING_PTR(iseq->file_name),
- line_no);
- }
- else {
- str = rb_sprintf("#<%s:%p>", cname, proc->block.iseq);
- }
-
- if (OBJ_TAINTED(self)) {
- OBJ_TAINT(str);
- }
- return str;
-}
-
-static VALUE
-proc_dup(VALUE self)
-{
- VALUE procval = proc_alloc(cYarvProc);
- yarv_proc_t *src, *dst;
- GetProcPtr(self, src);
- GetProcPtr(procval, dst);
-
- dst->block = src->block;
- dst->envval = src->envval;
- dst->safe_level = dst->safe_level;
- dst->special_cref_stack = src->special_cref_stack;
-
- return procval;
-}
-
-VALUE yarv_proc_dup(VALUE self)
-{
- return proc_dup(self);
-}
-static VALUE
-proc_clone(VALUE self)
-{
- VALUE procval = proc_dup(self);
- CLONESETUP(procval, self);
- return procval;
-}
-
-
-/***************/
-/* YarvBinding */
-/***************/
-
-static void
-binding_free(void *ptr)
-{
- yarv_binding_t *bind;
- FREE_REPORT_ENTER("binding");
- if (ptr) {
- bind = ptr;
- ruby_xfree(ptr);
- }
- FREE_REPORT_LEAVE("binding");
-}
-
-static void
-binding_mark(void *ptr)
-{
- yarv_binding_t *bind;
- MARK_REPORT_ENTER("binding");
- if (ptr) {
- bind = ptr;
- MARK_UNLESS_NULL(bind->env);
- MARK_UNLESS_NULL((VALUE)bind->cref_stack);
- }
- MARK_REPORT_LEAVE("binding");
-}
-
-static VALUE
-binding_alloc(VALUE klass)
-{
- VALUE obj;
- yarv_binding_t *bind;
- obj = Data_Make_Struct(klass, yarv_binding_t,
- binding_mark, binding_free, bind);
- MEMZERO(bind, yarv_binding_t, 1);
- return obj;
-}
-
-VALUE
-yarv_binding_alloc(VALUE klass)
-{
- return binding_alloc(klass);
-}
-
-static VALUE
-binding_dup(VALUE self)
-{
- VALUE bindval = binding_alloc(cYarvBinding);
- yarv_binding_t *src, *dst;
- GetBindingPtr(self, src);
- GetBindingPtr(bindval, dst);
- dst->env = src->env;
- dst->cref_stack = src->cref_stack;
- return bindval;
-}
-
-static VALUE
-binding_clone(VALUE self)
-{
- VALUE bindval = binding_dup(self);
- CLONESETUP(bindval, self);
- return bindval;
-}
-
-
/********************************************************************/
-static VALUE
-yarv_once()
-{
- return rb_yield(Qnil);
-}
-
-static VALUE
-yarv_segv()
-{
- volatile int *a = 0;
- *a = 0;
- return Qnil;
-}
-
-static VALUE
-proc_func(VALUE v)
-{
- dp(v);
-}
-
-static VALUE
-cfunc(void)
-{
- return rb_proc_new(proc_func, INT2FIX(12345));
-}
-
-// VALUE yarv_Hash_each();
VALUE insns_name_array(void);
VALUE Init_yarvthread(void);
extern VALUE *rb_gc_stack_start;
-VALUE rb_proc_s_new(VALUE klass);
-
VALUE
sdr(void)
{
@@ -897,79 +534,41 @@ char *yarv_options = ""
void Init_ISeq(void);
void
-Init_yarvcore(void)
+Init_vm(void)
{
- /* declare YARVCore module */
- mYarvCore = rb_define_module("YARVCore");
- rb_define_const(mYarvCore, "OPTS", rb_str_new2(yarv_options));
-
Init_ISeq();
-
- /* YARVCore::USAGE_ANALISYS_* */
- rb_define_const(mYarvCore, "USAGE_ANALISYS_INSN", rb_hash_new());
- rb_define_const(mYarvCore, "USAGE_ANALISYS_REGS", rb_hash_new());
- rb_define_const(mYarvCore, "USAGE_ANALISYS_INSN_BIGRAM", rb_hash_new());
- /* YARVCore::InsnNameArray */
- rb_define_const(mYarvCore, "InsnNameArray", insns_name_array());
+ /* ::VM */
+ rb_cVM = rb_define_class("VM", rb_cObject);
+ rb_undef_alloc_func(rb_cVM);
+
+ /* ::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));
- rb_define_singleton_method(mYarvCore, "eval", yarvcore_eval, 3);
+ /* ::VM::InsnNameArray */
+ rb_define_const(rb_cVM, "InsnNameArray", insns_name_array());
- /* declare YARVCore::VM */
- cYarvVM = rb_define_class_under(mYarvCore, "VM", rb_cObject);
- rb_undef_alloc_func(cYarvVM);
+ /* ::VM::eval() */
+ rb_define_singleton_method(rb_cVM, "eval", yarvcore_eval, 3);
- /* declare YARVCore::VM::Thread */
- cYarvThread = rb_define_class_under(cYarvVM, "Thread", rb_cObject);
+ /* ::VM::Thread */
+ cYarvThread = rb_define_class_under(rb_cVM, "Thread", rb_cObject);
rb_define_global_const("Thread", cYarvThread);
rb_undef_alloc_func(cYarvThread);
rb_define_method(cYarvThread, "initialize", thread_init, 0);
- /* declare YARVCore::VM::Env */
- cYarvEnv = rb_define_class_under(cYarvVM, "Env", rb_cObject);
- rb_undef_alloc_func(cYarvEnv);
-
- /* declare YARVCore::VM::Proc */
- rb_cProc = cYarvProc = rb_define_class_under(cYarvVM, "Proc", rb_cObject);
- rb_const_set(rb_cObject, rb_intern("Proc"), cYarvProc);
- rb_undef_alloc_func(cYarvProc);
- rb_define_singleton_method(cYarvProc, "new", rb_proc_s_new, 0);
- rb_define_method(cYarvProc, "call", proc_call, -1);
- rb_define_method(cYarvProc, "[]", proc_call, -1);
- rb_define_method(cYarvProc, "yield", proc_yield, -1);
- rb_define_method(cYarvProc, "to_proc", proc_to_proc, 0);
- rb_define_method(cYarvProc, "arity", proc_arity, 0);
- rb_define_method(cYarvProc, "clone", proc_clone, 0);
- rb_define_method(cYarvProc, "dup", proc_dup, 0);
- rb_define_method(cYarvProc, "==", proc_eq, 1);
- rb_define_method(cYarvProc, "eql?", proc_eq, 1);
- rb_define_method(cYarvProc, "hash", proc_hash, 0);
- rb_define_method(cYarvProc, "to_s", proc_to_s, 0);
-
- /* declare YARVCore::VM::Binding */
- cYarvBinding = rb_define_class_under(cYarvVM, "Binding", rb_cObject);
- rb_const_set(rb_cObject, rb_intern("Binding"), cYarvBinding);
- rb_undef_alloc_func(cYarvBinding);
- rb_undef_method(CLASS_OF(cYarvBinding), "new");
- rb_define_method(cYarvBinding, "clone", binding_clone, 0);
- rb_define_method(cYarvBinding, "dup", binding_dup, 0);
- rb_define_global_function("binding", rb_f_binding, 0);
-
- /* misc */
-
-
- /* YARV test functions */
-
- rb_define_global_function("once", yarv_once, 0);
- rb_define_global_function("segv", yarv_segv, 0);
- rb_define_global_function("cfunc", cfunc, 0);
- rb_define_global_function("SDR", sdr, 0);
- rb_define_global_function("NSDR", nsdr, 0);
+ /* debug functions */
+ rb_define_singleton_method(rb_cVM, "SDR", sdr, 0);
+ rb_define_singleton_method(rb_cVM, "NSDR", sdr, 0);
+ /* Symbols */
symIFUNC = ID2SYM(rb_intern("<IFUNC>"));
symCFUNC = ID2SYM(rb_intern("<CFUNC>"));
- /* for optimize */
+ /* IDs */
idPLUS = rb_intern("+");
idMINUS = rb_intern("-");
idMULT = rb_intern("*");
@@ -1014,10 +613,10 @@ Init_yarvcore(void)
#if TEST_AOT_COMPILE
Init_compiled();
#endif
- // make vm
+ /* VM bootstrap: phase 1 */
{
/* create vm object */
- VALUE vmval = vm_alloc(cYarvVM);
+ VALUE vmval = vm_alloc(rb_cVM);
VALUE thval;
yarv_vm_t *vm;
@@ -1053,21 +652,10 @@ Init_yarvcore(void)
yarv_init_redefined_flag();
}
-static void
-test(void)
-{
- int i;
- int *p;
- printf("!test!\n");
- for (i = 0; i < 1000000; i++) {
- p = ALLOC(int);
- }
-}
-
void
Init_yarv(void)
{
- /* initialize main thread */
+ /* VM bootstrap: phase 1 */
yarv_vm_t *vm = ALLOC(yarv_vm_t);
yarv_thread_t *th = ALLOC(yarv_thread_t);