* some refactoring around yarvcore and proc.

* eval_proc.c: renamed to proc.c.
* common.mk: ditto.
* yarvcore.h, yarvcore.c: rename or remove some global variables
  removed: mYarvCore, mYarvInsns
  renamed: cYarvISeq -> rb_cISeq,
           cYarvProc -> rb_cProc, cYarvBinding -> rb_cBinding
  ::YarvCore module is removed and ::YarvCore::VM class becomes ::VM.
  And change/remove some functions which added with YARV.
* compile.c: ditto.
* eval.c: ditto.
* iseq.c: ditto.
* vm.c: ditto.
* inits.c: rename Init_yarvcore to Init_vm.
* yarvcore.c, proc.c: move some functions and initialization
  from yarvcore.c to proc.c.
* intern.h, proc.c: add global function rb_binding_new(void).



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11541 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2007-01-17 08:48:52 +00:00
Родитель ca46eab090
Коммит dbee678630
12 изменённых файлов: 1649 добавлений и 1685 удалений

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

@ -1,3 +1,33 @@
Wed Jan 17 17:31:28 2007 Koichi Sasada <ko1@atdot.net>
* some refactoring around yarvcore and proc.
* eval_proc.c: renamed to proc.c.
* common.mk: ditto.
* yarvcore.h, yarvcore.c: rename or remove some global variables
removed: mYarvCore, mYarvInsns
renamed: cYarvISeq -> rb_cISeq,
cYarvProc -> rb_cProc, cYarvBinding -> rb_cBinding
::YarvCore module is removed and ::YarvCore::VM class becomes ::VM.
And change/remove some functions which added with YARV.
* compile.c: ditto.
* eval.c: ditto.
* iseq.c: ditto.
* vm.c: ditto.
* inits.c: rename Init_yarvcore to Init_vm.
* yarvcore.c, proc.c: move some functions and initialization
from yarvcore.c to proc.c.
* intern.h, proc.c: add global function rb_binding_new(void).
Tue Jan 16 17:49:29 2007 Koichi Sasada <ko1@atdot.net>
* vm.c (eval_search_super_klass): rename to search_super_klass() and

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

@ -31,7 +31,7 @@ OBJS = array.$(OBJEXT) \
euc_jp.$(OBJEXT) \
eval.$(OBJEXT) \
eval_load.$(OBJEXT) \
eval_proc.$(OBJEXT) \
proc.$(OBJEXT) \
eval_thread.$(OBJEXT) \
file.$(OBJEXT) \
gc.$(OBJEXT) \
@ -408,7 +408,7 @@ eval_thread.$(OBJEXT): {$(VPATH)}eval_thread.c {$(VPATH)}eval_intern.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
{$(VPATH)}node.h {$(VPATH)}util.h \
{$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
eval_proc.$(OBJEXT): {$(VPATH)}eval_proc.c {$(VPATH)}eval_intern.h \
proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \
{$(VPATH)}ruby.h config.h {$(VPATH)}yarvcore.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
{$(VPATH)}node.h {$(VPATH)}util.h \

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

@ -4829,7 +4829,7 @@ iseq_build_body(yarv_iseq_t *iseq, LINK_ANCHOR *anchor,
argv[j] =
iseq_load(0, op, iseq->self, Qnil);
}
else if (CLASS_OF(op) == cYarvISeq) {
else if (CLASS_OF(op) == rb_cISeq) {
argv[j] = op;
}
else {

7
eval.c
Просмотреть файл

@ -18,7 +18,7 @@ VALUE rb_cProc;
VALUE rb_cBinding;
VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
VALUE rb_f_binding(VALUE);
VALUE rb_binding_new();
VALUE rb_f_block_given_p(void);
@ -660,7 +660,7 @@ call_trace_func(rb_event_t event, NODE *node, VALUE self, ID id, VALUE klass)
srcfile,
INT2FIX(ruby_sourceline),
id ? ID2SYM(id) : Qnil,
self ? rb_f_binding(self) : Qnil,
self ? rb_binding_new() : Qnil,
klass ? klass : Qnil), Qundef, 0);
}
if (raised)
@ -1934,7 +1934,8 @@ eval(VALUE self, VALUE src, VALUE scope, char *file, int line)
VALUE iseqval;
if (scope != Qnil) {
if (CLASS_OF(scope) == cYarvBinding) {
if (CLASS_OF(scope) == rb_cBinding) {
GetBindingPtr(scope, bind);
envval = bind->env;
stored_cref_stack = bind->cref_stack;

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

@ -46,8 +46,8 @@ void Init_Struct _((void));
void Init_Time _((void));
void Init_var_tables _((void));
void Init_version _((void));
void Init_yarvcore _((void));
void Init_jump _((void));
void Init_vm _((void));
void
@ -86,6 +86,6 @@ rb_call_inits()
Init_GC();
Init_marshal();
Init_Enumerator();
Init_yarvcore();
Init_vm();
Init_version();
}

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

@ -246,6 +246,7 @@ VALUE rb_f_lambda(void);
VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE);
VALUE rb_proc_call(VALUE, VALUE);
int rb_proc_arity(VALUE);
VALUE rb_binding_new(void);
VALUE rb_obj_method(VALUE, VALUE);
VALUE rb_method_call(int, VALUE*, VALUE);
int rb_mod_method_arity(VALUE, ID);

30
iseq.c
Просмотреть файл

@ -20,6 +20,8 @@
// #define MARK_FREE_DEBUG 1
#include "gc.h"
VALUE rb_cISeq;
static void
compile_data_free(struct iseq_compile_data *compile_data)
{
@ -262,7 +264,7 @@ yarv_iseq_new_with_bopt_and_opt(NODE *node, VALUE name, VALUE file_name,
const yarv_compile_option_t *option)
{
yarv_iseq_t *iseq;
VALUE self = iseq_alloc(cYarvISeq);
VALUE self = iseq_alloc(rb_cISeq);
GetISeqPtr(self, iseq);
iseq->self = self;
@ -300,7 +302,7 @@ VALUE iseq_build_from_ary(yarv_iseq_t *iseq, VALUE line,
VALUE
iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt)
{
VALUE iseqval = iseq_alloc(cYarvISeq);
VALUE iseqval = iseq_alloc(rb_cISeq);
VALUE magic, version1, version2, format_type, misc;
VALUE name, filename, line;
@ -569,7 +571,7 @@ insn_operand_intern(yarv_iseq_t *iseq,
op = ID2SYM(op);
case TS_VALUE: /* VALUE */
ret = rb_inspect(op);
if (CLASS_OF(op) == cYarvISeq) {
if (CLASS_OF(op) == rb_cISeq) {
rb_ary_push(child, op);
}
break;
@ -1328,18 +1330,18 @@ void
Init_ISeq(void)
{
/* declare YARVCore::InstructionSequence */
cYarvISeq = rb_define_class_under(mYarvCore, "InstructionSequence", rb_cObject);
rb_define_alloc_func(cYarvISeq, iseq_alloc);
rb_define_method(cYarvISeq, "inspect", iseq_inspect, 0);
rb_define_method(cYarvISeq, "disasm", iseq_disasm, 0);
rb_define_method(cYarvISeq, "to_a", iseq_to_a, 0);
rb_define_method(cYarvISeq, "eval", iseq_eval, 0);
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);
rb_define_method(rb_cISeq, "disasm", iseq_disasm, 0);
rb_define_method(rb_cISeq, "to_a", iseq_to_a, 0);
rb_define_method(rb_cISeq, "eval", iseq_eval, 0);
rb_define_singleton_method(cYarvISeq, "load", iseq_s_load, -1);
rb_define_singleton_method(cYarvISeq, "compile", iseq_s_compile, -1);
rb_define_singleton_method(cYarvISeq, "new", iseq_s_compile, -1);
rb_define_singleton_method(cYarvISeq, "compile_file", iseq_s_compile_file, -1);
rb_define_singleton_method(cYarvISeq, "compile_option=",
rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1);
rb_define_singleton_method(rb_cISeq, "compile", iseq_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "new", iseq_s_compile, -1);
rb_define_singleton_method(rb_cISeq, "compile_file", iseq_s_compile_file, -1);
rb_define_singleton_method(rb_cISeq, "compile_option=",
iseq_s_compile_option_set, 1);
}

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

@ -1,8 +1,17 @@
/*
Proc, Method, Binding from eval.c
*/
/**********************************************************************
proc.c - Proc, Bindng, Env
$Author: ko1 $
$Date: $
created at: Wed Jan 17 12:13:14 2007
Copyright (C) 2004-2007 Koichi Sasada
**********************************************************************/
#include "eval_intern.h"
#include "gc.h"
struct METHOD {
VALUE klass, rklass;
@ -13,18 +22,225 @@ struct METHOD {
VALUE rb_cUnboundMethod;
VALUE rb_cMethod;
VALUE rb_cBinding;
VALUE rb_cProc;
VALUE rb_cEnv;
static VALUE bmcall(VALUE, VALUE);
static int method_arity(VALUE);
static VALUE rb_obj_is_method(VALUE m);
/*
* MISSING: documentation
*/
/* Env */
/*
* MISSING: documentation
*/
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) {
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(void)
{
VALUE obj;
yarv_env_t *env;
obj = Data_Make_Struct(rb_cEnv, yarv_env_t, env_mark, env_free, env);
env->env = 0;
env->prev_envval = 0;
env->block.iseq = 0;
return obj;
}
/* Proc */
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(void)
{
proc_alloc(rb_cProc);
}
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_dup(VALUE self)
{
VALUE procval = proc_alloc(rb_cProc);
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;
}
/* Binding */
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;
}
static VALUE
binding_dup(VALUE self)
{
VALUE bindval = binding_alloc(rb_cBinding);
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;
}
VALUE
rb_binding_new(void)
{
yarv_thread_t *th = GET_THREAD();
yarv_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
VALUE bindval = binding_alloc(rb_cBinding);
yarv_binding_t *bind;
GetBindingPtr(bindval, bind);
bind->env = th_make_env_object(th, cfp);
bind->cref_stack = ruby_cref();
return bindval;
}
/*
* call-seq:
@ -42,20 +258,10 @@ static VALUE rb_obj_is_method(VALUE m);
* eval("param", b) #=> "hello"
*/
VALUE yarv_binding_alloc(VALUE klass);
VALUE
static VALUE
rb_f_binding(VALUE self)
{
yarv_thread_t *th = GET_THREAD();
yarv_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp);
VALUE bindval = yarv_binding_alloc(cYarvBinding);
yarv_binding_t *bind;
GetBindingPtr(bindval, bind);
bind->env = th_make_env_object(th, cfp);
bind->cref_stack = ruby_cref();
return bindval;
return rb_binding_new();
}
/*
@ -89,7 +295,7 @@ bind_eval(int argc, VALUE *argv, VALUE bind)
#define SAFE_LEVEL_MAX PROC_TMASK
static VALUE
proc_alloc(VALUE klass, int is_lambda)
proc_new(VALUE klass, int is_lambda)
{
VALUE procval = Qnil;
yarv_thread_t *th = GET_THREAD();
@ -144,10 +350,10 @@ proc_alloc(VALUE klass, int is_lambda)
* proc.call #=> "hello"
*/
VALUE
static VALUE
rb_proc_s_new(VALUE klass)
{
return proc_alloc(klass, Qfalse);
return proc_new(klass, Qfalse);
}
/*
@ -160,20 +366,20 @@ rb_proc_s_new(VALUE klass)
VALUE
rb_block_proc(void)
{
return proc_alloc(rb_cProc, Qfalse);
return proc_new(rb_cProc, Qfalse);
}
VALUE
rb_block_lambda(void)
{
return proc_alloc(rb_cProc, Qtrue);
return proc_new(rb_cProc, Qtrue);
}
VALUE
rb_f_lambda(void)
{
rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead");
return proc_alloc(rb_cProc, Qtrue);
return rb_block_lambda();
}
/*
@ -187,7 +393,7 @@ rb_f_lambda(void)
static VALUE
proc_lambda(void)
{
return proc_alloc(rb_cProc, Qtrue);
return rb_block_lambda();
}
VALUE
@ -235,6 +441,22 @@ proc_invoke(VALUE self, VALUE args, VALUE alt_self, VALUE alt_klass)
* from prog.rb:5
*/
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);
}
VALUE
rb_proc_call(VALUE proc, VALUE args)
{
@ -261,6 +483,32 @@ rb_proc_call(VALUE proc, VALUE args)
* Proc.new {|a,*b|}.arity #=> -2
*/
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));
}
/*
* call-seq:
* prc == other_proc => true or false
@ -269,6 +517,26 @@ rb_proc_call(VALUE proc, VALUE args)
* <i>other_proc</i>, or if they are both procs with the same body.
*/
static VALUE
proc_eq(VALUE self, VALUE other)
{
if (self == other) {
return Qtrue;
}
else {
if (TYPE(other) == T_DATA &&
RBASIC(other)->klass == rb_cProc &&
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;
}
/*
* call-seq:
@ -277,6 +545,17 @@ rb_proc_call(VALUE proc, VALUE args)
* Return hash value corresponding to proc body.
*/
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);
}
/*
* call-seq:
@ -286,6 +565,37 @@ rb_proc_call(VALUE proc, VALUE args)
* an indication of where the proc was defined.
*/
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;
}
/*
* call-seq:
* prc.to_proc -> prc
@ -295,6 +605,12 @@ rb_proc_call(VALUE proc, VALUE args)
* themselves.
*/
static VALUE
proc_to_proc(VALUE self)
{
return self;
}
/*
* call-seq:
* prc.binding => binding
@ -1116,10 +1432,40 @@ localjump_reason(VALUE exc)
void
Init_Proc()
{
/* Env */
rb_cVM = rb_define_class("VM", rb_cObject); /* TODO: should be moved to suitable place */
rb_cEnv = rb_define_class_under(rb_cVM, "Env", rb_cObject);
rb_undef_alloc_func(rb_cEnv);
/* Proc */
rb_cProc = rb_define_class("Proc", rb_cObject);
rb_undef_alloc_func(rb_cProc);
rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, 0);
rb_define_method(rb_cProc, "call", proc_call, -1);
rb_define_method(rb_cProc, "[]", proc_call, -1);
rb_define_method(rb_cProc, "yield", proc_yield, -1);
rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
rb_define_method(rb_cProc, "clone", proc_clone, 0);
rb_define_method(rb_cProc, "dup", proc_dup, 0);
rb_define_method(rb_cProc, "==", proc_eq, 1);
rb_define_method(rb_cProc, "eql?", proc_eq, 1);
rb_define_method(rb_cProc, "hash", proc_hash, 0);
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
/* Binding */
rb_cBinding = rb_define_class("Binding", rb_cObject);
rb_undef_alloc_func(rb_cBinding);
rb_undef_method(CLASS_OF(rb_cBinding), "new");
rb_define_method(rb_cBinding, "clone", binding_clone, 0);
rb_define_method(rb_cBinding, "dup", binding_dup, 0);
rb_define_global_function("binding", rb_f_binding, 0);
rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
/* Exceptions */
exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
rb_register_mark_object(exception_error);
@ -1128,9 +1474,11 @@ Init_Proc()
OBJ_TAINT(sysstack_error);
rb_register_mark_object(sysstack_error);
/* utility functions */
rb_define_global_function("proc", rb_block_proc, 0);
rb_define_global_function("lambda", proc_lambda, 0);
/* Method */
rb_cMethod = rb_define_class("Method", rb_cObject);
rb_undef_alloc_func(rb_cMethod);
rb_undef_method(CLASS_OF(rb_cMethod), "new");
@ -1147,6 +1495,7 @@ Init_Proc()
rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
/* UnboundMethod */
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
rb_undef_alloc_func(rb_cUnboundMethod);
rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new");
@ -1159,10 +1508,10 @@ Init_Proc()
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
/* Module#*_method */
rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
rb_define_private_method(rb_cModule, "define_method",
rb_mod_define_method, -1);
}
/*
@ -1205,3 +1554,4 @@ Init_Binding()
{
}

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

@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
#define RUBY_RELEASE_DATE "2007-01-16"
#define RUBY_RELEASE_DATE "2007-01-17"
#define RUBY_VERSION_CODE 190
#define RUBY_RELEASE_CODE 20070116
#define RUBY_RELEASE_CODE 20070117
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2007
#define RUBY_RELEASE_MONTH 1
#define RUBY_RELEASE_DAY 16
#define RUBY_RELEASE_DAY 17
RUBY_EXTERN const char ruby_version[];
RUBY_EXTERN const char ruby_release_date[];

8
vm.c
Просмотреть файл

@ -180,7 +180,6 @@ th_set_eval_stack(yarv_thread_t *th, VALUE iseqval)
}
static int check_env(yarv_env_t *env);
VALUE yarv_env_alloc(VALUE klass);
static VALUE
th_make_env_each(yarv_thread_t *th, yarv_control_frame_t *cfp,
@ -216,10 +215,9 @@ th_make_env_each(yarv_thread_t *th, yarv_control_frame_t *cfp,
*envptr = GC_GUARDED_PTR(pcfp->dfp);
}
}
//SDR2(cfp);
//fprintf(stderr, "lfp: %p, cfp: %p, endptr: %p\n", cfp->lfp, cfp->dfp, endptr);
/* allocate env */
envval = yarv_env_alloc(cYarvEnv);
envval = yarv_env_alloc();
GetEnvPtr(envval, env);
if (!YARV_NORMAL_ISEQ_P(cfp->iseq)) {
@ -402,7 +400,7 @@ th_make_proc(yarv_thread_t *th, yarv_control_frame_t *cfp,
if (PROCDEBUG) {
check_env_value(envval);
}
procval = yarv_proc_alloc(cYarvProc);
procval = yarv_proc_alloc();
GetProcPtr(procval, proc);
proc->blockprocval = blockprocval;
proc->block.self = block->self;

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

@ -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());
/* ::VM */
rb_cVM = rb_define_class("VM", rb_cObject);
rb_undef_alloc_func(rb_cVM);
/* YARVCore::InsnNameArray */
rb_define_const(mYarvCore, "InsnNameArray", insns_name_array());
/* ::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);

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

@ -100,14 +100,10 @@
/* classes and modules */
extern VALUE mYarvCore;
extern VALUE cYarvISeq;
extern VALUE cYarvVM;
extern VALUE cYarvThread;
extern VALUE mYarvInsns;
extern VALUE cYarvEnv;
extern VALUE cYarvProc;
extern VALUE cYarvBinding;
extern VALUE rb_cISeq;
extern VALUE rb_cVM;
extern VALUE symIFUNC;
extern VALUE symCFUNC;
@ -601,10 +597,8 @@ typedef VALUE CDHASH;
/* VM related object allocate functions */
/* TODO: should be static functions */
VALUE yarv_thread_alloc(VALUE klass);
VALUE yarv_env_alloc(VALUE klass);
VALUE yarv_proc_alloc(VALUE klass);
VALUE yarv_binding_alloc(VALUE klass);
VALUE yarv_env_alloc(void);
VALUE yarv_proc_alloc(void);
/* for debug */
extern void vm_stack_dump_raw(yarv_thread_t *, yarv_control_frame_t *);