yarv-diff:119
From: ko1 atdot.net
Date: 5 Oct 2005 12:25:41 -0000
Subject: [yarv-diff:119] r275 - trunk
Author: ko1
Date: 2005-10-05 21:25:40 +0900 (Wed, 05 Oct 2005)
New Revision: 275
Modified:
trunk/ChangeLog
trunk/compile.c
trunk/compile.h
trunk/error.c
trunk/eval.c
trunk/eval_error.h
trunk/eval_jump.h
trunk/eval_load.c
trunk/eval_thread.c
trunk/ruby.h
trunk/test.rb
trunk/thread.c
trunk/thread_pthread.h
trunk/thread_win32.h
trunk/vm.c
trunk/vm.h
trunk/vm_dump.c
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* eva.c, eval_thread.c, ruby.h, eval_error.h, eval_jump.h,
eval_load.c, thread.c, error.c, compile.h : remove ruby_errinfo
* thread_win32.h, thread_pthread.h : set stack size to 4KB
* vm.c : fix making env routine
* vm_dump.c, vm.h : support frame type "EVAL" and fix magic number
* yarvcore.c : fix some mark/free routine
* yarvcore.h :
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/ChangeLog 2005-10-05 12:25:40 UTC (rev 275)
@@ -5,6 +5,22 @@
#
+2005-10-05(Wed) 21:20:13 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eva.c, eval_thread.c, ruby.h, eval_error.h, eval_jump.h,
+ eval_load.c, thread.c, error.c, compile.h : remove ruby_errinfo
+
+ * thread_win32.h, thread_pthread.h : set stack size to 4KB
+
+ * vm.c : fix making env routine
+
+ * vm_dump.c, vm.h : support frame type "EVAL" and fix magic number
+
+ * yarvcore.c : fix some mark/free routine
+
+ * yarvcore.h :
+
+
2005-10-05(Wed) 09:08:11 +0900 Koichi Sasada <ko1 atdot.net>
* eval.c, eval_intern.h, vm.c, eval_jump.h, yarvcore.h :
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/compile.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -3313,7 +3313,8 @@
if(!poped){
idx = get_dyna_var_idx(self, node->nd_vid, &lv, &ls);
if(idx < 0){
- COMPILE_ERROR(("unknown dvar"));
+ int *a = 0;
+ rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
}
ADD_INSN2(ret, nd_line(node), getdynamic, I2F(ls - idx), I2F(lv));
}
Modified: trunk/compile.h
===================================================================
--- trunk/compile.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/compile.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -174,12 +174,12 @@
/* error */
#define COMPILE_ERROR(strs) \
{ \
- VALUE tmp = ruby_errinfo; \
+ VALUE tmp = GET_THREAD()->errinfo; \
if(CPDEBUG)rb_bug strs; \
- ruby_errinfo = iseqobj->compile_data->err_info; \
+ GET_THREAD()->errinfo = iseqobj->compile_data->err_info; \
rb_compile_error strs; \
- iseqobj->compile_data->err_info = ruby_errinfo; \
- ruby_errinfo = tmp; \
+ iseqobj->compile_data->err_info = GET_THREAD()->errinfo; \
+ GET_THREAD()->errinfo = tmp; \
ret = 0; \
break; \
}
Modified: trunk/error.c
===================================================================
--- trunk/error.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/error.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -1467,21 +1467,21 @@
eNOERROR = set_syserr(0, "NOERROR");
}
+#include "yarv.h"
+
static void
err_append(const char *s)
{
- extern VALUE ruby_errinfo;
-
if (ruby_in_eval) {
- if (NIL_P(ruby_errinfo)) {
- ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s);
+ if (NIL_P(GET_THREAD()->errinfo)) {
+ GET_THREAD()->errinfo = rb_exc_new2(rb_eSyntaxError, s);
}
else {
- VALUE str = rb_obj_as_string(ruby_errinfo);
+ VALUE str = rb_obj_as_string(GET_THREAD()->errinfo);
rb_str_cat2(str, "\n");
rb_str_cat2(str, s);
- ruby_errinfo = rb_exc_new3(rb_eSyntaxError, str);
+ GET_THREAD()->errinfo = rb_exc_new3(rb_eSyntaxError, str);
}
}
else {
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -39,8 +39,6 @@
static ID added, singleton_added;
static ID __id__, __send__, respond_to;
-VALUE ruby_errinfo = Qnil;
-
VALUE rb_eLocalJumpError;
VALUE rb_eSysStackError;
@@ -210,7 +208,7 @@
ruby_finalize_1()
{
signal(SIGINT, SIG_DFL);
- ruby_errinfo = 0;
+ GET_THREAD()->errinfo = 0;
rb_gc_call_finalizer_at_exit();
trace_func = 0;
tracing = 0;
@@ -228,14 +226,14 @@
int ex;
{
int state;
- volatile VALUE err = ruby_errinfo;
+ volatile VALUE err = GET_THREAD()->errinfo;
ruby_safe_level = 0;
Init_stack((void*)&state);
PUSH_THREAD_TAG();
if ((state = EXEC_TAG()) == 0) {
ruby_finalize_0();
- if (ruby_errinfo) err = ruby_errinfo;
+ if (GET_THREAD()->errinfo) err = GET_THREAD()->errinfo;
rb_thread_cleanup();
rb_thread_wait_other_threads();
}
@@ -245,7 +243,7 @@
else if (ex == 0) {
ex = state;
}
- ruby_errinfo = err;
+ GET_THREAD()->errinfo = err;
ex = error_handle(ex);
ruby_finalize_1();
POP_THREAD_TAG();
@@ -885,10 +883,10 @@
VALUE at;
if (thread_set_raised()) {
- ruby_errinfo = exception_error;
+ GET_THREAD()->errinfo = exception_error;
JUMP_TAG(TAG_FATAL);
}
- if (NIL_P(mesg)) mesg = ruby_errinfo;
+ if (NIL_P(mesg)) mesg = GET_THREAD()->errinfo;
if (NIL_P(mesg)) {
mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
}
@@ -902,25 +900,25 @@
}
}
if (!NIL_P(mesg)) {
- ruby_errinfo = mesg;
+ GET_THREAD()->errinfo = mesg;
}
- if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
- && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
- VALUE e = ruby_errinfo;
+ if (RTEST(ruby_debug) && !NIL_P(GET_THREAD()->errinfo)
+ && !rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
+ VALUE e = GET_THREAD()->errinfo;
int status;
PUSH_TAG(PROT_NONE);
if ((status = EXEC_TAG()) == 0) {
e = rb_obj_as_string(e);
warn_printf("Exception `%s' at %s:%d - %s\n",
- rb_obj_classname(ruby_errinfo),
+ rb_obj_classname(GET_THREAD()->errinfo),
ruby_sourcefile, ruby_sourceline,
RSTRING(e)->ptr);
}
POP_TAG();
- if (status == TAG_FATAL && ruby_errinfo == exception_error) {
- ruby_errinfo = mesg;
+ if (status == TAG_FATAL && GET_THREAD()->errinfo == exception_error) {
+ GET_THREAD()->errinfo = mesg;
}
else if (status) {
thread_reset_raised();
@@ -1286,7 +1284,7 @@
{
int state;
volatile VALUE result;
- volatile VALUE e_info = ruby_errinfo;
+ volatile VALUE e_info = GET_THREAD()->errinfo;
va_list args;
PUSH_TAG(PROT_NONE);
@@ -1300,7 +1298,7 @@
va_init_list(args, data2);
while (eclass = va_arg(args, VALUE)) {
- if (rb_obj_is_kind_of(ruby_errinfo, eclass)) {
+ if (rb_obj_is_kind_of(GET_THREAD()->errinfo, eclass)) {
handle = Qtrue;
break;
}
@@ -1311,12 +1309,12 @@
if (r_proc) {
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
- result = (*r_proc)(data2, ruby_errinfo);
+ result = (*r_proc)(data2, GET_THREAD()->errinfo);
}
POP_TAG();
if (state == TAG_RETRY) {
state = 0;
- ruby_errinfo = Qnil;
+ GET_THREAD()->errinfo = Qnil;
goto retry_entry;
}
}
@@ -1325,7 +1323,7 @@
state = 0;
}
if (state == 0) {
- ruby_errinfo = e_info;
+ GET_THREAD()->errinfo = e_info;
}
}
}
@@ -1872,8 +1870,8 @@
if (strcmp(file, "(eval)") == 0) {
VALUE mesg, errat;
- errat = get_backtrace(ruby_errinfo);
- mesg = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
+ errat = get_backtrace(GET_THREAD()->errinfo);
+ mesg = rb_attr_get(GET_THREAD()->errinfo, rb_intern("mesg"));
if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
rb_str_update(mesg, 0, 0, rb_str_new2(": "));
@@ -1882,7 +1880,7 @@
RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
}
}
- rb_exc_raise(ruby_errinfo);
+ rb_exc_raise(GET_THREAD()->errinfo);
}
JUMP_TAG(state);
}
@@ -2521,7 +2519,7 @@
errat_getter(id)
ID id;
{
- return get_backtrace(ruby_errinfo);
+ return get_backtrace(GET_THREAD()->errinfo);
}
static void
@@ -2530,10 +2528,10 @@
ID id;
VALUE *var;
{
- if (NIL_P(ruby_errinfo)) {
+ if (NIL_P(GET_THREAD()->errinfo)) {
rb_raise(rb_eArgError, "$! not set");
}
- set_backtrace(ruby_errinfo, val);
+ set_backtrace(GET_THREAD()->errinfo, val);
}
/*
@@ -2549,6 +2547,9 @@
* local_variables #=> ["fred", "i"]
*/
+int
+th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary);
+
static VALUE
rb_f_local_variables()
{
@@ -2559,16 +2560,26 @@
while(1){
if(cfp->iseq){
- for(i= (cfp->lfp == cfp->dfp); i<cfp->iseq->local_size; i++){
+ int start = 0;
+ if(cfp->lfp == cfp->dfp){
+ start = 1;
+ }
+ for(i= start; i<cfp->iseq->local_size; i++){
rb_ary_push(ary, rb_str_new2(rb_id2name(cfp->iseq->local_tbl[i])));
}
}
if(cfp->lfp != cfp->dfp){
/* block */
VALUE *dfp = GC_GUARDED_PTR_REF(cfp->dfp[0]);
- while(cfp->dfp != dfp){
- cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
+
+ if(th_collect_local_variables_in_heap(th, dfp, ary)){
+ break;
}
+ else{
+ while(cfp->dfp != dfp){
+ cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
+ }
+ }
}
else{
break;
@@ -2649,7 +2660,9 @@
rb_global_variable((VALUE*)&ruby_eval_tree);
rb_define_virtual_variable("$@", errat_getter, errat_setter);
+ /*
rb_define_hooked_variable("$!", &ruby_errinfo, 0, errinfo_setter);
+ */
rb_define_global_function("eval", rb_f_eval, -1);
rb_define_global_function("iterator?", rb_f_block_given_p, 0);
@@ -2728,9 +2741,12 @@
(iseq = th->base_block->iseq)){
while(iseq->type == ISEQ_TYPE_BLOCK ||
iseq->type == ISEQ_TYPE_RESCUE||
- iseq->type == ISEQ_TYPE_ENSURE){
+ iseq->type == ISEQ_TYPE_ENSURE||
+ iseq->type == ISEQ_TYPE_EVAL){
int i;
- for(i=0; iseq->local_size; i++){
+ // printf("local size: %d\n", iseq->local_size);
+ for(i=0; i<iseq->local_size; i++){
+ // printf("id (%4d): %s\n", i, rb_id2name(iseq->local_tbl[i]));
if(iseq->local_tbl[i] == id){
return Qtrue;
}
Modified: trunk/eval_error.h
===================================================================
--- trunk/eval_error.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_error.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -77,11 +77,11 @@
char *einfo;
long elen;
- if (NIL_P(ruby_errinfo)) return;
+ if (NIL_P(GET_THREAD()->errinfo)) return;
PUSH_TAG(PROT_NONE);
if (EXEC_TAG() == 0) {
- errat = get_backtrace(ruby_errinfo);
+ errat = get_backtrace(GET_THREAD()->errinfo);
}
else {
errat = Qnil;
@@ -106,9 +106,9 @@
}
}
- eclass = CLASS_OF(ruby_errinfo);
+ eclass = CLASS_OF(GET_THREAD()->errinfo);
if (EXEC_TAG() == 0) {
- e = rb_funcall(ruby_errinfo, rb_intern("message"), 0, 0);
+ e = rb_funcall(GET_THREAD()->errinfo, rb_intern("message"), 0, 0);
StringValue(e);
einfo = RSTRING(e)->ptr;
elen = RSTRING(e)->len;
@@ -237,8 +237,8 @@
break;
case TAG_RAISE:
case TAG_FATAL:
- if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
- status = sysexit_status(ruby_errinfo);
+ if (rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
+ status = sysexit_status(GET_THREAD()->errinfo);
}
else {
error_print();
Modified: trunk/eval_jump.h
===================================================================
--- trunk/eval_jump.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_jump.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -250,7 +250,7 @@
{
rb_secure(4);
if (argc == 0) {
- if (!NIL_P(ruby_errinfo)) {
+ if (!NIL_P(GET_THREAD()->errinfo)) {
error_print();
}
rb_exit(EXIT_FAILURE);
Modified: trunk/eval_load.c
===================================================================
--- trunk/eval_load.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_load.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -129,7 +129,7 @@
}
fname = tmp;
- ruby_errinfo = Qnil; /* ensure */
+ GET_THREAD()->errinfo = Qnil; /* ensure */
if (!wrap) {
rb_secure(4); /* should alter global state */
}
@@ -149,15 +149,15 @@
if (ruby_nerrs > 0) {
ruby_nerrs = 0;
- rb_exc_raise(ruby_errinfo);
+ rb_exc_raise(GET_THREAD()->errinfo);
}
if (state){
jump_tag_but_local_jump(state, Qundef);
}
- if (!NIL_P(ruby_errinfo)){
+ if (!NIL_P(GET_THREAD()->errinfo)){
/* exception during load */
- rb_exc_raise(ruby_errinfo);
+ rb_exc_raise(GET_THREAD()->errinfo);
}
}
@@ -336,7 +336,7 @@
int safe;
{
VALUE result = Qnil;
- volatile VALUE errinfo = ruby_errinfo;
+ volatile VALUE errinfo = GET_THREAD()->errinfo;
int state;
struct {
NODE *node;
@@ -404,7 +404,7 @@
if (NIL_P(result)) {
load_failed(fname);
}
- ruby_errinfo = errinfo;
+ GET_THREAD()->errinfo = errinfo;
return result;
}
Modified: trunk/eval_thread.c
===================================================================
--- trunk/eval_thread.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/eval_thread.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -482,7 +482,7 @@
th->flags &= THREAD_FLAGS_MASK;
//th->tag = prot_tag;
// th->tracing = tracing;
- th->errinfo = ruby_errinfo;
+ th->errinfo = GET_THREAD()->errinfo;
th->last_status = rb_last_status;
tval = rb_lastline_get();
rb_lastline_set(th->last_line);
@@ -551,7 +551,7 @@
rb_trap_immediate = 0; /* inhibit interrupts from here */
// prot_tag = th->tag;
// tracing = th->tracing;
- ruby_errinfo = th->errinfo;
+ GET_THREAD()->errinfo = th->errinfo;
rb_last_status = th->last_status;
ruby_safe_level = th->safe;
@@ -1491,14 +1491,14 @@
int state;
enum yarv_thread_status status;
{
- if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
+ if (state && status != THREAD_TO_KILL && !NIL_P(GET_THREAD()->errinfo)) {
th->flags |= THREAD_RAISED;
if (state == TAG_FATAL) {
/* fatal error within this thread, need to stop whole script */
- main_thread->errinfo = ruby_errinfo;
+ main_thread->errinfo = GET_THREAD()->errinfo;
rb_thread_cleanup();
}
- else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
+ else if (rb_obj_is_kind_of(GET_THREAD()->errinfo, rb_eSystemExit)) {
if (th->safe >= 4) {
char buf[32];
@@ -1507,15 +1507,15 @@
}
else {
/* delegate exception to main_thread */
- rb_thread_main_jump(ruby_errinfo, RESTORE_RAISE);
+ rb_thread_main_jump(GET_THREAD()->errinfo, RESTORE_RAISE);
}
}
else if (th->safe < 4 && (ruby_thread_abort || th->abort || RTEST(ruby_debug))) {
/* exit on main_thread */
- rb_thread_main_jump(ruby_errinfo, RESTORE_EXIT);
+ rb_thread_main_jump(GET_THREAD()->errinfo, RESTORE_EXIT);
}
else {
- th->errinfo = ruby_errinfo;
+ th->errinfo = GET_THREAD()->errinfo;
}
}
rb_thread_schedule();
Modified: trunk/ruby.h
===================================================================
--- trunk/ruby.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/ruby.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -652,7 +652,6 @@
RUBY_EXTERN VALUE rb_eLoadError;
RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
-RUBY_EXTERN VALUE ruby_errinfo;
static inline VALUE
#if defined(HAVE_PROTOTYPES)
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/test.rb 2005-10-05 12:25:40 UTC (rev 275)
@@ -1,4 +1,50 @@
+a = 0
+def m b
+ eval('a+=1', b)
+ eval('p a', b)
+ eval('b = 0', b)
+ p b
+ p local_variables
+end
+m binding
+
+__END__
+x = :x
+def m
+ m1 = :m1
+ m2 = :m2
+ eval('a=1; b=2; c=3; eval("d=4; e=5; f=6; binding")')
+end
+
+eval('p local_variables;p [a,b,c,d,e,f]', m)
+
+__END__
+b = nil
+eval("b=binding; 1", b)
+eval("b=binding; a = 1", b)
+eval("b=binding; p local_variables", b)
+__END__
+b = binding
+loop{
+ print "> "
+ ans = eval("b=binding; #{gets}", b)
+ puts "ans: #{ans}"
+}
+__END__
+
+ts = []
+10000.times{|i|
+ p i
+ ts << Thread.new{
+ }
+}
+__END__
+Thread.new{
+ raise
+}.join
+
+__END__
i=0
def m
end
Modified: trunk/thread.c
===================================================================
--- trunk/thread.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -100,9 +100,10 @@
TH_PUSH_TAG(th);
if((state = EXEC_TAG()) == 0){
th->value = th_invoke_proc(th, proc, RARRAY(args)->len, RARRAY(args)->ptr);
+ th->errinfo = Qnil;
}
else{
-
+ th->value = Qnil;
}
TH_POP_TAG();
th->status = THREAD_KILLED;
@@ -137,62 +138,75 @@
static VALUE
yarv_thread_join(int argc, VALUE *argv, VALUE self)
{
+ yarv_thread_t *cur_th = GET_THREAD();
yarv_thread_t *th;
int err;
+
GetThreadVal(self, th);
+ cur_th->wait_thread_value = self;
- if(th->status == THREAD_KILLED){
- return self;
- }
-
+again:
if(argc == 0){
thread_debug("yarv_thread_join(0)\n");
-
+
GVL_UNLOCK_BEGIN();
{
err = native_thread_join(th->thread_id, 0);
}
GVL_UNLOCK_END();
+ if(errno == EINTR){
+ goto again;
+ }
+
switch(err){
case EDEADLK:
+ cur_th->wait_thread_value = Qnil;
rb_raise(rb_eThreadError, "can't join current thread (cause dead lock)");
}
}
else if(argc == 1){
double limit = timeofday();
struct timeval interval;
-
+
interval = rb_time_interval(argv[0]);
limit += interval.tv_sec;
limit += interval.tv_usec * 1e-6;
-
+
while(1){
GVL_UNLOCK_BEGIN();
{
sleep_for_polling();
}
GVL_UNLOCK_END();
-
+
if(th->status == THREAD_KILLED){
break;
}
if(timeofday() > limit){
/* timeout */
- return Qnil;
+ cur_th->wait_thread_value = Qnil;
+ return self;
}
}
}
else{
+ cur_th->wait_thread_value = Qnil;
rb_raise(rb_eArgError, "wrong number of arguments");
}
- return Qnil;
+
+ cur_th->wait_thread_value = Qnil;
+ if(th->errinfo != Qnil){
+ rb_exc_raise(th->errinfo);
+ }
+ return self;
}
static VALUE
yarv_thread_value(VALUE self)
{
yarv_thread_t *th;
+
yarv_thread_join(0, 0, self);
GetThreadVal(self, th);
return th->value;
Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread_pthread.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -60,7 +60,7 @@
native_thread_crteate(yarv_thread_t *th)
{
pthread_attr_t attr;
- size_t stack_size = 16 * 1024;
+ size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
int err;
thread_debug("create: %p, stack size: %d\n", th, stack_size);
Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/thread_win32.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -179,7 +179,7 @@
static int
native_thread_crteate(yarv_thread_t *th)
{
- size_t stack_size = 16 * 1024;
+ size_t stack_size = 4 * 1024 - sizeof(int); /* 4KB */
if((th->thread_id = (HANDLE)_beginthreadex(0, /* security */
stack_size,
thread_start_func_1,
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -139,12 +139,15 @@
/* for return */
th_set_finish_env(th);
th_set_env(th, iseq,
- FRAME_MAGIC_BLOCK, block->self, GC_GUARDED_PTR(block->dfp),
+ FRAME_MAGIC_EVAL, block->self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded, th->cfp->sp, block->lfp,
iseq->local_size, 0, 0);
return 0;
}
+static int
+check_env(yarv_env_t *env);
+
static VALUE
th_make_env_each(yarv_thread_t *th, yarv_control_frame_t *cfp,
VALUE *envptr, VALUE *endptr)
@@ -155,18 +158,29 @@
int i, local_size;
if(ENV_IN_HEAP_P(envptr)){
+ printf("ENV_IN_HEAP!\n");
return ENV_VAL(envptr);
}
-
if(envptr != endptr){
VALUE *penvptr = GC_GUARDED_PTR_REF(*envptr);
yarv_control_frame_t *pcfp = cfp;
- while(pcfp->dfp != penvptr){
- pcfp++;
+ if(ENV_IN_HEAP_P(penvptr)){
+ penvval = ENV_VAL(penvptr);
}
- penvval = th_make_env_each(th, pcfp, penvptr, endptr);
- cfp->lfp = pcfp->lfp;
- *envptr = GC_GUARDED_PTR(pcfp->dfp);
+ else{
+ while(pcfp->dfp != penvptr){
+ // printf("pcfp: %p (%p)\n", pcfp->dfp, penvptr);
+ pcfp++;
+ if(pcfp->dfp == 0){
+ SDR();
+ printf("[BUG] orz\n");
+ exit(0);
+ }
+ }
+ penvval = th_make_env_each(th, pcfp, penvptr, endptr);
+ cfp->lfp = pcfp->lfp;
+ *envptr = GC_GUARDED_PTR(pcfp->dfp);
+ }
}
/* allocate env */
@@ -208,13 +222,81 @@
env->block.lfp = cfp->lfp;
env->block.dfp = cfp->dfp;
env->block.iseq = cfp->iseq;
+
return envval;
}
+static VALUE
+check_env_value(VALUE envval);
+
+static int
+check_env(yarv_env_t *env){
+ printf("---\n");
+ printf("envptr: %p\n", &env->block.dfp[0]);
+ printf("orphan: %p\n", env->block.dfp[1]);
+ printf("inheap: %p\n", env->block.dfp[2]);
+ printf("envval: %10p ", env->block.dfp[3]); dp(env->block.dfp[3]);
+ printf("penvv : %10p ", env->block.dfp[4]); dp(env->block.dfp[4]);
+ printf("lfp: %10p\n", env->block.lfp);
+ printf("dfp: %10p\n", env->block.dfp);
+ if(env->block.dfp[4]){
+ printf(">>\n");
+ check_env_value(env->block.dfp[4]);
+ printf("<<\n");
+ }
+ return 1;
+}
+
+static VALUE
+check_env_value(VALUE envval){
+ yarv_env_t *env;
+ GetEnvVal(envval, env);
+
+ if(check_env(env)){
+ return envval;
+ }
+ rb_bug("invalid env\n");
+ return Qnil; /* unreachable */
+}
+
+static int
+collect_local_variables_in_env(yarv_env_t *env, VALUE ary){
+ int i;
+ if(env->block.lfp == env->block.dfp){
+ return 0;
+ }
+ for(i = 0; i<env->block.iseq->local_size; i++){
+ rb_ary_push(ary, rb_str_new2(rb_id2name(env->block.iseq->local_tbl[i])));
+ }
+ if(env->prev_envval){
+ GetEnvVal(env->prev_envval, env);
+ collect_local_variables_in_env(env, ary);
+ }
+ return 0;
+}
+
+int
+th_collect_local_variables_in_heap(yarv_thread_t *th, VALUE *dfp, VALUE ary)
+{
+ if(ENV_IN_HEAP_P(dfp)){
+ yarv_env_t *env;
+ GetEnvVal(ENV_VAL(dfp), env);
+ collect_local_variables_in_env(env, ary);
+ return 1;
+ }
+ else{
+ return 0;
+ }
+}
+
+
VALUE
th_make_env_object(yarv_thread_t *th, yarv_control_frame_t *cfp)
{
- return th_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
+ VALUE envval;
+ envval = th_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
+ /* check_env_value(envval); */
+ return envval;
}
static VALUE
@@ -1026,7 +1108,7 @@
VALUE *escape_dfp;
VALUE type;
- err = ruby_errinfo;
+ err = th->errinfo;
if(state == TAG_RAISE){
rb_ivar_set(err, idThrowState, state);
}
@@ -1057,7 +1139,7 @@
#else
*th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
#endif
- ruby_errinfo = Qnil;
+ th->errinfo = Qnil;
goto vm_loop_start;
}
}
@@ -1097,7 +1179,7 @@
if(cfp->dfp == escape_dfp){
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
- ruby_errinfo = Qnil;
+ th->errinfo = Qnil;
goto vm_loop_start;
}
}
@@ -1131,7 +1213,7 @@
*th->cfp->sp++ = (GET_THROWOBJ_VAL(err));
#endif
}
- ruby_errinfo = Qnil;
+ th->errinfo = Qnil;
goto vm_loop_start;
}
}
@@ -1181,7 +1263,7 @@
catch_iseq->local_size - 1, 0, 0);
state = 0;
- ruby_errinfo = Qnil;
+ th->errinfo = Qnil;
goto vm_loop_start;
}
else{
@@ -1196,7 +1278,7 @@
}
else{
th->cfp++;
- ruby_errinfo = err;
+ th->errinfo = err;
TH_POP_TAG2();
JUMP_TAG(state);
}
Modified: trunk/vm.h
===================================================================
--- trunk/vm.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -226,19 +226,19 @@
#define ENV_IN_HEAP(env) ((env)[2] = Qundef)
#define ORPHAN_ENV(env) ((env)[1] = Qundef)
-#define FRAME_MAGIC_METHOD 0xfaffffa1
-#define FRAME_MAGIC_BLOCK 0xfaffffa2
-#define FRAME_MAGIC_CLASS 0xfaffffa3
-#define FRAME_MAGIC_TOP 0xfaffffa4
-#define FRAME_MAGIC_FINISH 0xfaffffa5
-#define FRAME_MAGIC_CFUNC 0xfaffffa6
-#define FRAME_MAGIC_PROC 0xfaffffa7
-#define FRAME_MAGIC_IFUNC 0xfaffffa8
+#define FRAME_MAGIC_METHOD 0xfaffff11
+#define FRAME_MAGIC_BLOCK 0xfaffff21
+#define FRAME_MAGIC_CLASS 0xfaffff31
+#define FRAME_MAGIC_TOP 0xfaffff41
+#define FRAME_MAGIC_FINISH 0xfaffff51
+#define FRAME_MAGIC_CFUNC 0xfaffff61
+#define FRAME_MAGIC_PROC 0xfaffff71
+#define FRAME_MAGIC_IFUNC 0xfaffff81
+#define FRAME_MAGIC_EVAL 0xfaffff91
-
#define CHECK_FRAME_MAGIC(magic) \
{ \
- if((magic & 0xfffffff0) != 0xfaffffa0){ \
+ if((magic & 0xffffff00) != 0xfaffff00){ \
rb_bug("YARV Stack frame error: %08x", magic); \
} \
}
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/vm_dump.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -33,6 +33,7 @@
case FRAME_MAGIC_CFUNC: magic = "CFUNC"; break;
case FRAME_MAGIC_PROC: magic = "PROC"; break;
case FRAME_MAGIC_IFUNC: magic = "IFUNC"; break;
+ case FRAME_MAGIC_EVAL: magic = "EVAL"; break;
case 0: magic = "------"; break;
default: magic = "(none)"; break;
}
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/yarvcore.c 2005-10-05 12:25:40 UTC (rev 275)
@@ -251,7 +251,7 @@
if(ruby_nerrs > 0){
ruby_nerrs = 0;
- rb_exc_raise(ruby_errinfo);
+ rb_exc_raise(GET_THREAD()->errinfo);
}
return (VALUE)node;
@@ -608,12 +608,15 @@
}
/* mark ruby objects */
- MARK_UNLESS_NULL(th->vm_value);
MARK_UNLESS_NULL(th->klass_nest_stack);
+
MARK_UNLESS_NULL(th->first_proc);
MARK_UNLESS_NULL(th->first_args);
- MARK_UNLESS_NULL(th->stat_insn_usage);
+ MARK_UNLESS_NULL(th->wait_thread_value);
+ MARK_UNLESS_NULL(th->value);
+ MARK_UNLESS_NULL(th->errinfo);
+
rb_mark_tbl(th->local_storage);
if(GET_THREAD() != th &&
@@ -622,6 +625,8 @@
yarv_machine_stack_mark(th);
}
}
+
+ MARK_UNLESS_NULL(th->stat_insn_usage);
MARK_REPORT("<- thread", 0);
}
@@ -631,12 +636,13 @@
obj = Data_Make_Struct(klass, yarv_thread_t,
thread_mark, thread_free, th);
- MEMZERO(th, yarv_thread_t, 1);
return obj;
}
static void
th_init2(yarv_thread_t *th){
+ MEMZERO(th, yarv_thread_t, 1);
+
/* allocate thread stack */
th->stack = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
th->stack_size = YARV_THREAD_STACK_SIZE;
@@ -650,8 +656,9 @@
th->cfp->dfp = th->stack;
th->cfp->self = Qnil;
th->cfp->magic = 0;
-
+
th->status = THREAD_RUNNABLE;
+ th->errinfo = Qnil;
}
static void
th_init(yarv_thread_t *th)
@@ -664,15 +671,12 @@
thread_init(VALUE self)
{
yarv_thread_t *th;
- yarv_vm_t *vm;
- VALUE vmval = GET_VM()->self;
+ yarv_vm_t *vm = GET_VM();
GetThreadVal(self, th);
- GetVMVal(vmval, vm);
th_init(th);
th->self = self;
- th->vm_value = vmval;
th->vm = vm;
return self;
}
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-10-05 00:11:35 UTC (rev 274)
+++ trunk/yarvcore.h 2005-10-05 12:25:40 UTC (rev 275)
@@ -330,7 +330,6 @@
typedef struct yarv_thread{
VALUE self;
- VALUE vm_value;
yarv_vm_t *vm;
/* execution information */
@@ -359,11 +358,11 @@
yarv_thread_id_t thread_id;
enum yarv_thread_status status;
struct yarv_tag *tag;
+
VALUE value;
- VALUE exception;
+ VALUE errinfo;
+ VALUE wait_thread_value;
- struct yarv_thread *join_thread;
-
VALUE first_proc;
VALUE first_args;
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml