summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--eval.c57
-rw-r--r--gc.c8
-rw-r--r--inits.c6
-rw-r--r--lib/cgi-lib.rb4
-rw-r--r--lib/thread.rb58
-rw-r--r--parse.y22
-rw-r--r--sample/ruby-mode.el2
8 files changed, 131 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index 64971316c6..d69cfd04f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/eval.c b/eval.c
index 570a4a490f..8f9e0691ec 100644
--- a/eval.c
+++ b/eval.c
@@ -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;
}
}
-
diff --git a/gc.c b/gc.c
index 36cb6d1d5d..4dbc59475b 100644
--- a/gc.c
+++ b/gc.c
@@ -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)
diff --git a/inits.c b/inits.c
index 5d6532fedc..6486de251f 100644
--- a/inits.c
+++ b/inits.c
@@ -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
diff --git a/parse.y b/parse.y
index 589c58c9ac..d36c3f7f54 100644
--- a/parse.y
+++ b/parse.y
@@ -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))