diff options
Diffstat (limited to 'yarvcore.c')
-rw-r--r-- | yarvcore.c | 464 |
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); |