diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | eval.c | 57 | ||||
-rw-r--r-- | gc.c | 8 | ||||
-rw-r--r-- | inits.c | 6 | ||||
-rw-r--r-- | lib/cgi-lib.rb | 4 | ||||
-rw-r--r-- | lib/thread.rb | 58 | ||||
-rw-r--r-- | parse.y | 22 | ||||
-rw-r--r-- | sample/ruby-mode.el | 2 |
8 files changed, 131 insertions, 44 deletions
@@ -1,5 +1,23 @@ +Wed Feb 25 15:50:07 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * eval.c (mod_module_eval): clear the_scope's PRIVATE flag before + calling eval(). + + * eval.c (rb_eval): needed to keep prot_tag->retval before + evaluating the ensure clause. + Tue Feb 24 11:16:32 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + * parse.y (yylex): reserved words can be appear as method names at + right after 'def' and `.'(dot), like foo.next. + + * eval.c (return_check): checks for return out of thread (formaly + done in return_value). + + * eval.c (POP_TAG): copy retval to outer level. + + * eval.c (return_value): just set retval, no check, no unwinding. + * parse.y (nextc): line continuation by backslash at end of line. * regex.c (re_compile_pattern): forgot to clear pending_exact on @@ -451,6 +451,8 @@ static struct tag { } #define POP_TAG() \ + if (_tag.prev) \ + _tag.prev->retval = _tag.retval;\ prot_tag = _tag.prev; \ } @@ -1394,7 +1396,9 @@ call_trace_func(event, file, line, self, id) if (state) JUMP_TAG(state); } -static void return_value _((VALUE val)); +static void return_check _((void)); +#define return_value(v) prot_tag->retval = (v) + static VALUE rb_eval(self, node) VALUE self; @@ -1695,7 +1699,12 @@ rb_eval(self, node) result = rb_eval(self, node->nd_head); } POP_TAG(); - rb_eval(self, node->nd_ensr); + if (node->nd_ensr) { + VALUE retval = prot_tag->retval; /* save retval */ + + rb_eval(self, node->nd_ensr); + return_value(retval); + } if (state) { JUMP_TAG(state); } @@ -1760,6 +1769,7 @@ rb_eval(self, node) if (node->nd_stts) { return_value(rb_eval(self, node->nd_stts)); } + return_check(); JUMP_TAG(TAG_RETURN); break; @@ -3700,11 +3710,39 @@ obj_instance_eval(self, src) return eval_under(CLASS_OF(self), self, src); } +mod_eval(arg) + VALUE *arg; +{ + return eval_under(arg[0], arg[0], arg[1]); +} + +static void +mod_eval_ensure(a) + int *a; +{ + if (a[0]) { + FL_TEST(the_scope, SCOPE_PRIVATE); + } + if (a[1]) { + FL_TEST(the_scope, SCOPE_MODFUNC); + } +} + static VALUE mod_module_eval(mod, src) VALUE mod, src; { - return eval_under(mod, mod, src); + int f[2]; + VALUE arg[2]; + + f[0] = FL_TEST(the_scope, SCOPE_PRIVATE); + f[1] = FL_TEST(the_scope, SCOPE_MODFUNC); + + FL_UNSET(the_scope, SCOPE_PRIVATE); + FL_UNSET(the_scope, SCOPE_MODFUNC); + + arg[0] = mod; arg[1] = src; + return rb_ensure(mod_eval, arg, mod_eval_ensure, f); } VALUE rb_load_path; @@ -5912,7 +5950,7 @@ f_throw(argc, argv) } #ifdef THREAD if (tt->tag == PROT_THREAD) { - Raise(eThreadError, "uncaught throw `%s' in thread 0x%x\n", + Raise(eThreadError, "uncaught throw `%s' in thread 0x%x", rb_id2name(t), curr_thread); } @@ -5921,30 +5959,27 @@ f_throw(argc, argv) } if (!tt) { - NameError("uncaught throw `%s'\n", rb_id2name(t)); + NameError("uncaught throw `%s'", rb_id2name(t)); } JUMP_TAG(TAG_THROW); /* not reached */ } static void -return_value(val) - VALUE val; +return_check() { struct tag *tt = prot_tag; - + while (tt) { if (tt->tag == PROT_FUNC) { - tt->retval = val; break; } #ifdef THREAD if (tt->tag == PROT_THREAD) { - Raise(eThreadError, "return from within thread 0x%x\n", + Raise(eThreadError, "return from within thread 0x%x", curr_thread); } #endif tt = tt->prev; } } - @@ -988,10 +988,18 @@ gc_call_finalizer_at_exit() RVALUE *p, *pend; int i; + /* run finalizers */ for (i = 0; i < heaps_used; i++) { p = heaps[i]; pend = p + HEAP_SLOTS; while (p < pend) { run_final(p); + p++; + } + } + /* run data object's finaliers */ + for (i = 0; i < heaps_used; i++) { + p = heaps[i]; pend = p + HEAP_SLOTS; + while (p < pend) { if (BUILTIN_TYPE(p) == T_DATA && DATA_PTR(p) && RANY(p)->as.data.dfree) @@ -49,14 +49,14 @@ rb_call_inits() Init_sym(); Init_var_tables(); Init_Object(); -#ifdef THREAD - Init_Thread(); -#endif Init_Comparable(); Init_Enumerable(); Init_eval(); Init_String(); Init_Exception(); +#ifdef THREAD + Init_Thread(); +#endif Init_Numeric(); Init_Bignum(); Init_Array(); diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb index 7c46fb5955..02720b2835 100644 --- a/lib/cgi-lib.rb +++ b/lib/cgi-lib.rb @@ -45,7 +45,7 @@ class CGI end module_function :escape, :unescape - def initialize + def initialize(input = $stdin) # exception messages should be printed to stdout. STDERR.reopen(STDOUT) @@ -54,7 +54,7 @@ class CGI when "GET" ENV['QUERY_STRING'] or "" when "POST" - $stdin.read ENV['CONTENT_LENGTH'].to_i + input.read ENV['CONTENT_LENGTH'].to_i else read_from_cmdline end.split(/&/).each do |x| diff --git a/lib/thread.rb b/lib/thread.rb index c47d7b20a4..5262ec539d 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -20,7 +20,7 @@ end class Mutex def initialize @waiting = [] - @locked = FALSE; + @locked = false; end def locked? @@ -28,33 +28,33 @@ class Mutex end def try_lock - result = FALSE - Thread.critical = TRUE + result = false + Thread.critical = true unless @locked - @locked = TRUE - result = TRUE + @locked = true + result = true end - Thread.critical = FALSE + Thread.critical = false result end def lock - while (Thread.critical = TRUE; @locked) + while (Thread.critical = true; @locked) @waiting.push Thread.current Thread.stop end - @locked = TRUE - Thread.critical = FALSE + @locked = true + Thread.critical = false self end def unlock return unless @locked - Thread.critical = TRUE + Thread.critical = true wait = @waiting @waiting = [] - @locked = FALSE - Thread.critical = FALSE + @locked = false + Thread.critical = false for w in wait w.run end @@ -82,20 +82,20 @@ class Queue end def push(obj) - Thread.critical = TRUE + Thread.critical = true @que.push obj t = @waiting.shift - Thread.critical = FALSE + Thread.critical = false t.run if t end - def pop non_block=FALSE + def pop non_block=false item = nil until item - Thread.critical = TRUE + Thread.critical = true if @que.length == 0 if non_block - Thread.critical = FALSE + Thread.critical = false raise ThreadError, "queue empty" end @waiting.push Thread.current @@ -104,7 +104,7 @@ class Queue item = @que.shift end end - Thread.critical = FALSE + Thread.critical = false item end @@ -125,7 +125,28 @@ class SizedQueue<Queue super() end + def max + @max + end + + def max=(max) + if @max >= max + @max = max + else + Thread.critical = TRUE + diff = max - @max + @max = max + diff.times do + t = @queue_wait.shift + t.run if t + end + Thread.critical = FALSE + @max + end + end + def push(obj) + Thread.critical = true while @que.length >= @max @queue_wait.push Thread.current Thread.stop @@ -134,6 +155,7 @@ class SizedQueue<Queue end def pop(*args) + Thread.critical = true if @que.length < @max t = @queue_wait.shift t.run if t @@ -58,8 +58,9 @@ static enum lex_state { EXPR_MID, /* newline significant, +/- is a sign. */ EXPR_END, /* newline significant, +/- is a operator. */ EXPR_ARG, /* newline significant, +/- may be a sign. */ - EXPR_FNAME, /* ignore newline, +/- is a operator. */ - EXPR_CLASS, /* immediate after `class' no here document. */ + EXPR_FNAME, /* ignore newline, +/- is a operator, no reserved words. */ + EXPR_DOT, /* immediate after `.', no reserved words. */ + EXPR_CLASS, /* immediate after `class', no here document. */ } lex_state; static int class_nest = 0; @@ -2459,6 +2460,7 @@ retry: } pushback(c); if (!isdigit(c)) { + lex_state = EXPR_DOT; return '.'; } c = '.'; @@ -2875,12 +2877,14 @@ retry: result = IVAR; break; default: - /* See if it is a reserved word. */ - kw = rb_reserved_word(tok(), toklen()); - if (kw) { - enum lex_state state = lex_state; - lex_state = kw->state; - return kw->id[state != EXPR_BEG]; + if (lex_state != EXPR_FNAME && lex_state != EXPR_DOT) { + /* See if it is a reserved word. */ + kw = rb_reserved_word(tok(), toklen()); + if (kw) { + enum lex_state state = lex_state; + lex_state = kw->state; + return kw->id[state != EXPR_BEG]; + } } if (lex_state == EXPR_FNAME) { @@ -2892,7 +2896,7 @@ retry: pushback(c); } } - else if (lex_state == EXPR_BEG){ + else if (lex_state == EXPR_BEG || lex_state == EXPR_DOT){ lex_state = EXPR_ARG; } else { diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el index d31b2d196e..f92d6fb382 100644 --- a/sample/ruby-mode.el +++ b/sample/ruby-mode.el @@ -234,7 +234,7 @@ The variable ruby-indent-level controls the amount of indentation. (setq w (char-after (point))) (cond ((and (not (eobp)) - (re-search-forward (format "[^\\]%c" w) indent-point t)) + (re-search-forward (format "[^\\]\\(\\\\\\\\\\)*%c" w) indent-point t)) nil) (t (setq in-string (point)) |