зеркало из https://github.com/github/ruby.git
* 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:
Родитель
ca46eab090
Коммит
dbee678630
30
ChangeLog
30
ChangeLog
|
@ -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
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;
|
||||
|
|
4
inits.c
4
inits.c
|
@ -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();
|
||||
}
|
||||
|
|
1
intern.h
1
intern.h
|
@ -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
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
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;
|
||||
|
|
462
yarvcore.c
462
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());
|
||||
/* ::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);
|
||||
|
||||
|
|
14
yarvcore.h
14
yarvcore.h
|
@ -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 *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче