From 40517ecac82e4b406227bd30fd89d05c2e90bc87 Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 29 Nov 1999 06:33:02 +0000 Subject: 19991129 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@572 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 18 ++++++++++++++++++ ToDo | 1 + eval.c | 34 ++++++++++++++++++++++++++-------- gc.c | 3 ++- lib/pstore.rb | 1 + sample/freq.rb | 5 ++--- variable.c | 12 +++++++++++- 7 files changed, 61 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7f62c45fdb..c574386026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +Mon Nov 29 15:28:52 1999 Yukihiro Matsumoto + + * variable.c (rb_path2class): evaluated value from path should be + module or class. + +Fri Nov 26 18:12:49 1999 Yukihiro Matsumoto + + * eval.c (rb_exec_end_proc): should remove only end_procs defined + within load wrapper. + + * eval.c (rb_load): save and restore ruby_wrapper around loading. + + * eval.c (rb_mark_end_proc): mark end procs registered by END{} or + at_exit{}. + + * eval.c (rb_set_end_proc): should not call rb_global_variable() + on heap address; it crashed mod_ruby. + Mon Nov 22 14:07:24 1999 Koji Arai * ruby.c (proc_options): variable e_script should be visited by diff --git a/ToDo b/ToDo index c762f3c988..6ccbd17381 100644 --- a/ToDo +++ b/ToDo @@ -25,6 +25,7 @@ Hacking Interpreter - use eban's fnmatch - RUBYOPT environment variable - alias $defout $> +* remove end_proc registered out of require only * non-blocking open (e.g. for named pipe) for thread * avoid blocking with gethostbyname/gethostbyaddr * objectify interpreters diff --git a/eval.c b/eval.c index c4d2afcea1..f1a5a8dabd 100644 --- a/eval.c +++ b/eval.c @@ -4682,6 +4682,7 @@ rb_load(fname, wrap) int state; char *file; volatile ID last_func; + volatile VALUE wrapper = 0; VALUE self = ruby_top_self; TMP_PROTECT; @@ -4698,9 +4699,11 @@ rb_load(fname, wrap) PUSH_VARS(); PUSH_CLASS(); + wrapper = ruby_wrapper; if (!wrap) { rb_secure(4); /* should alter global state */ ruby_class = rb_cObject; + ruby_wrapper = 0; } else { /* load in anonymous module as toplevel */ @@ -4747,7 +4750,7 @@ rb_load(fname, wrap) POP_FRAME(); POP_CLASS(); POP_VARS(); - ruby_wrapper = 0; + ruby_wrapper = wrapper; if (ruby_nerrs > 0) { ruby_nerrs = 0; rb_exc_raise(ruby_errinfo); @@ -5220,7 +5223,8 @@ struct end_proc_data { VALUE data; struct end_proc_data *next; }; -static struct end_proc_data *end_proc_data; + +static struct end_proc_data *end_procs, *ephemeral_end_procs; void rb_set_end_proc(func, data) @@ -5228,18 +5232,27 @@ rb_set_end_proc(func, data) VALUE data; { struct end_proc_data *link = ALLOC(struct end_proc_data); + struct end_proc_data **list; - link->next = end_proc_data; + if (ruby_wrapper) list = &ephemeral_end_procs; + else list = &end_procs; + link->next = *list; link->func = func; link->data = data; - end_proc_data = link; + *list = link; } void rb_mark_end_proc() { - struct end_proc_data *link = end_proc_data; + struct end_proc_data *link; + link = end_procs; + while (link) { + rb_gc_mark(link->data); + link = link->next; + } + link = ephemeral_end_procs; while (link) { rb_gc_mark(link->data); link = link->next; @@ -5279,9 +5292,14 @@ rb_exec_end_proc() struct end_proc_data *link; int status; - while (end_proc_data) { - link = end_proc_data; - end_proc_data = link->next; + link = end_procs; + while (link) { + rb_protect((VALUE(*)())link->func, link->data, &status); + link = link->next; + } + while (ephemeral_end_procs) { + link = ephemeral_end_procs; + ephemeral_end_procs = link->next; rb_protect((VALUE(*)())link->func, link->data, &status); free(link); } diff --git a/gc.c b/gc.c index 7b9873ad21..0398b6b946 100644 --- a/gc.c +++ b/gc.c @@ -896,7 +896,8 @@ rb_gc() alloca(0); # define STACK_END (&stack_end) #else -# define STACK_END alloca(1) + VALUE *stack_end = alloca(1); +# define STACK_END (stack_end) #endif alloc_objects = 0; diff --git a/lib/pstore.rb b/lib/pstore.rb index 566de8d8f9..9ea9ab3660 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -107,6 +107,7 @@ class PStore Marshal::dump(@table, file) rescue File::rename backup, @filename if File::exist?(backup) + raise end end @abort = false diff --git a/sample/freq.rb b/sample/freq.rb index 4e0206c114..362753f71f 100644 --- a/sample/freq.rb +++ b/sample/freq.rb @@ -1,9 +1,8 @@ # word occurrence listing # usege: ruby freq.rb file.. freq = Hash.new(0) -while gets - while sub!(/\w+/, '') - word = $& +while line = gets() + line.scan(/\w+/) do |word| freq[word] += 1 end end diff --git a/variable.c b/variable.c index 41f935dff8..b29ce55cce 100644 --- a/variable.c +++ b/variable.c @@ -195,10 +195,20 @@ VALUE rb_path2class(path) const char *path; { + VALUE c; + if (path[0] == '#') { rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path); } - return rb_eval_string(path); + c = rb_eval_string(path); + switch (TYPE(c)) { + case T_MODULE: + case T_CLASS: + break; + default: + rb_raise(rb_eTypeError, "class path %s does not point class", path); + } + return c; } void -- cgit v1.2.3