Permalink
Browse files

* array.c (rb_ary_sort_bang): returns self, even if its length is

  less than 2.

* eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if
  SCOPE_DONT_RECYCLE of ruby_scope is set.


git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@1156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
matz committed Feb 2, 2001
1 parent df18df6 commit bb85be162005536fd28d19e809dcd58cefc03535
Showing with 159 additions and 77 deletions.
  1. +17 −0 ChangeLog
  2. +2 −1 ToDo
  3. +25 −3 array.c
  4. +1 −1 env.h
  5. +59 −20 eval.c
  6. +11 −11 gc.c
  7. +1 −0 intern.h
  8. +4 −4 io.c
  9. +15 −15 lib/irb/ruby-lex.rb
  10. +1 −1 lib/observer.rb
  11. +3 −4 parse.y
  12. +3 −3 range.c
  13. +13 −13 re.c
  14. +4 −1 string.c
View
@@ -1,10 +1,27 @@
+Fri Feb 2 16:14:51 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_sort_bang): returns self, even if its length is
+ less than 2.
+
+ * eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if
+ SCOPE_DONT_RECYCLE of ruby_scope is set.
+
Wed Jan 31 22:27:29 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* configure.in: gcc-2.95.2-7(cygwin) support.
add -mwin32 if available.
* cygwin/GNUmakefile: ditto.
+Tue Jan 30 17:56:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_fetch): new method.
+
+Mon Jan 29 17:36:19 2001 TOYOFUKU Chikanobu <toyofuku@juice.or.jp>
+
+ * eval.c (rb_eval): nd_iter evaluation should be wrapped by
+ BEGIN_CALLARGS and END_CALLARGS.
+
Mon Jan 29 14:25:39 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (block_pass): return from block jumps directory to
View
3 ToDo
@@ -44,11 +44,13 @@ Hacking Interpreter
* warn for inconsistent local variable usage (lv m and method m at the same time).
* MicroRuby
* Built-in Interactive Ruby.
+* regex /\ba/ on "[a in HIRAGANA]a[a in HIRAGANA]"
Standard Libraries
- Module#define_method which takes a name and a body (block, proc or method).
- Enume#inject
+- Array#fetch
* Enumerable#sort_by for Schwartzian transformation
* String#scanf(?)
* Object#fmt(?)
@@ -69,7 +71,6 @@ Standard Libraries
* fork_and_kill_other_threads.
* way to specify immortal (fork endurance) thread;
* or raise ForkException to every thread but fork caller.
-* Array#fetch
* Hash::new{default} or recommend Hash#fetch?
Extension Libraries
View
28 array.c
@@ -384,7 +384,7 @@ rb_ary_entry(ary, offset)
if (RARRAY(ary)->len == 0) return Qnil;
if (offset < 0) {
- offset = RARRAY(ary)->len + offset;
+ offset += RARRAY(ary)->len;
}
if (offset < 0 || RARRAY(ary)->len <= offset) {
return Qnil;
@@ -431,7 +431,7 @@ rb_ary_aref(argc, argv, ary)
beg = NUM2LONG(arg1);
len = NUM2LONG(arg2);
if (beg < 0) {
- beg = RARRAY(ary)->len + beg;
+ beg += RARRAY(ary)->len;
}
return rb_ary_subseq(ary, beg, len);
}
@@ -480,6 +480,27 @@ rb_ary_last(ary)
return RARRAY(ary)->ptr[RARRAY(ary)->len-1];
}
+static VALUE
+rb_ary_fetch(argc, argv, ary)
+ int argc;
+ VALUE *argv;
+ VALUE ary;
+{
+ VALUE pos, ifnone;
+ long idx;
+
+ rb_scan_args(argc, argv, "11", &pos, &ifnone);
+ idx = NUM2LONG(pos);
+
+ if (idx < 0) {
+ idx += RARRAY(ary)->len;
+ }
+ if (idx < 0 || RARRAY(ary)->len <= idx) {
+ return ifnone;
+ }
+ return RARRAY(ary)->ptr[idx];
+}
+
static VALUE
rb_ary_index(ary, val)
VALUE ary;
@@ -979,7 +1000,7 @@ rb_ary_sort_bang(ary)
VALUE ary;
{
rb_ary_modify(ary);
- if (RARRAY(ary)->len <= 1) return Qnil;
+ if (RARRAY(ary)->len <= 1) return ary;
FL_SET(ary, ARY_TMPLOCK); /* prohibit modification during sort */
rb_ensure(sort_internal, ary, sort_unlock, ary);
@@ -1649,6 +1670,7 @@ Init_Array()
rb_define_method(rb_cArray, "[]", rb_ary_aref, -1);
rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
rb_define_method(rb_cArray, "at", rb_ary_at, 1);
+ rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
rb_define_method(rb_cArray, "first", rb_ary_first, 0);
rb_define_method(rb_cArray, "last", rb_ary_last, 0);
rb_define_method(rb_cArray, "concat", rb_ary_concat, 1);
View
2 env.h
@@ -37,7 +37,7 @@ extern struct SCOPE {
struct RBasic super;
ID *local_tbl;
VALUE *local_vars;
- int flag;
+ int flags;
} *ruby_scope;
#define SCOPE_ALLOCA 0
View
79 eval.c
@@ -602,6 +602,8 @@ struct RVarmap *ruby_dyna_vars;
ruby_dyna_vars = 0;
#define POP_VARS() \
+ if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) \
+ FL_SET(_old, DVAR_DONT_RECYCLE); \
ruby_dyna_vars = _old; \
}
@@ -808,7 +810,7 @@ static VALUE ruby_wrapper; /* security wrapper */
OBJSETUP(_scope, 0, T_SCOPE); \
_scope->local_tbl = 0; \
_scope->local_vars = 0; \
- _scope->flag = 0; \
+ _scope->flags = 0; \
_old = ruby_scope; \
ruby_scope = _scope; \
scope_vmode = SCOPE_PUBLIC;
@@ -819,18 +821,18 @@ static rb_thread_t main_thread;
static void scope_dup _((struct SCOPE *));
#define POP_SCOPE() \
- if (ruby_scope->flag & SCOPE_DONT_RECYCLE) {\
+ if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\
if (_old) scope_dup(_old); \
} \
- if (!(ruby_scope->flag & SCOPE_MALLOC)) {\
+ if (!(ruby_scope->flags & SCOPE_MALLOC)) {\
ruby_scope->local_vars = 0; \
ruby_scope->local_tbl = 0; \
- if (!(ruby_scope->flag & SCOPE_DONT_RECYCLE) && \
+ if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \
ruby_scope != top_scope) { \
rb_gc_force_recycle((VALUE)ruby_scope);\
} \
} \
- ruby_scope->flag |= SCOPE_NOSTACK; \
+ ruby_scope->flags |= SCOPE_NOSTACK; \
ruby_scope = _old; \
scope_vmode = _vmode; \
}
@@ -1305,7 +1307,7 @@ rb_eval_cmd(cmd, arg)
val = eval(ruby_top_self, cmd, Qnil, 0, 0);
}
- if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
+ if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
scope_dup(saved_scope);
ruby_scope = saved_scope;
ruby_safe_level = safe;
@@ -2234,24 +2236,24 @@ rb_eval(self, n)
state = EXEC_TAG();
if (state == 0) {
+ PUSH_ITER(ITER_PRE);
if (nd_type(node) == NODE_ITER) {
- PUSH_ITER(ITER_PRE);
result = rb_eval(self, node->nd_iter);
- POP_ITER();
}
else {
VALUE recv;
char *file = ruby_sourcefile;
int line = ruby_sourceline;
_block.flags &= ~BLOCK_D_SCOPE;
+ BEGIN_CALLARGS;
recv = rb_eval(self, node->nd_iter);
- PUSH_ITER(ITER_PRE);
+ END_CALLARGS;
ruby_sourcefile = file;
ruby_sourceline = line;
result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
- POP_ITER();
}
+ POP_ITER();
}
else if (_block.tag->dst == state) {
state &= TAG_MASK;
@@ -3580,8 +3582,11 @@ rb_yield_0(val, self, klass, acheck)
pop_state:
POP_ITER();
POP_CLASS();
+#if 0
if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
- !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
+ (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) ||
+ !(block->tag->flags & BLOCK_DYNAMIC) ||
+ !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE))) {
struct RVarmap *vars, *tmp;
if (ruby_dyna_vars->id == 0) {
@@ -3594,10 +3599,26 @@ rb_yield_0(val, self, klass, acheck)
}
}
}
+#else
+ if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
+ !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
+ struct RVarmap *vars = ruby_dyna_vars;
+
+ if (ruby_dyna_vars->id == 0) {
+ vars = ruby_dyna_vars->next;
+ rb_gc_force_recycle((VALUE)ruby_dyna_vars);
+ while (vars && vars->id != 0) {
+ struct RVarmap *tmp = vars->next;
+ rb_gc_force_recycle((VALUE)vars);
+ vars = tmp;
+ }
+ }
+ }
+#endif
POP_VARS();
ruby_block = block;
ruby_frame = ruby_frame->prev;
- if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
+ if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
scope_dup(old_scope);
ruby_scope = old_scope;
if (state) {
@@ -4739,7 +4760,6 @@ eval(self, src, scope, file, line)
}
Data_Get_Struct(scope, struct BLOCK, data);
-
/* PUSH BLOCK from data */
frame = data->frame;
frame.tmp = ruby_frame; /* gc protection */
@@ -4785,14 +4805,33 @@ eval(self, src, scope, file, line)
POP_CLASS();
ruby_in_eval--;
if (!NIL_P(scope)) {
+ int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;
+
ruby_frame = frame.tmp;
- if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
- scope_dup(old_scope);
ruby_scope = old_scope;
ruby_block = old_block;
ruby_dyna_vars = old_dyna_vars;
data->vmode = scope_vmode; /* write back visibility mode */
scope_vmode = old_vmode;
+ if (dont_recycle) {
+ struct tag *tag;
+ struct RVarmap *vars;
+
+ scope_dup(ruby_scope);
+ for (tag=prot_tag; tag; tag=tag->prev) {
+ scope_dup(tag->scope);
+ }
+ if (ruby_block) {
+ struct BLOCK *block = ruby_block;
+ while (block) {
+ block->tag->flags |= BLOCK_DYNAMIC;
+ block = block->prev;
+ }
+ }
+ for (vars = ruby_dyna_vars; vars; vars = vars->next) {
+ FL_SET(vars, DVAR_DONT_RECYCLE);
+ }
+ }
}
else {
ruby_frame->iter = iter;
@@ -5116,7 +5155,7 @@ rb_load(fname, wrap)
}
}
ruby_frame->last_func = last_func;
- if (ruby_scope->flag == SCOPE_ALLOCA && ruby_class == rb_cObject) {
+ if (ruby_scope->flags == SCOPE_ALLOCA && ruby_class == rb_cObject) {
if (ruby_scope->local_tbl) /* toplevel was empty */
free(ruby_scope->local_tbl);
}
@@ -5896,16 +5935,16 @@ scope_dup(scope)
ID *tbl;
VALUE *vars;
- scope->flag |= SCOPE_DONT_RECYCLE;
- if (scope->flag & SCOPE_MALLOC) return;
+ scope->flags |= SCOPE_DONT_RECYCLE;
+ if (scope->flags & SCOPE_MALLOC) return;
if (scope->local_tbl) {
tbl = scope->local_tbl;
vars = ALLOC_N(VALUE, tbl[0]+1);
*vars++ = scope->local_vars[-1];
MEMCPY(vars, scope->local_vars, VALUE, tbl[0]);
scope->local_vars = vars;
- scope->flag |= SCOPE_MALLOC;
+ scope->flags |= SCOPE_MALLOC;
}
}
@@ -6163,7 +6202,7 @@ static int
blk_orphan(data)
struct BLOCK *data;
{
- if (!(data->scope->flag & SCOPE_NOSTACK)) {
+ if (!(data->scope->flags & SCOPE_NOSTACK)) {
return 0;
}
if ((data->tag->flags & BLOCK_ORPHAN)) {
Oops, something went wrong.

0 comments on commit bb85be1

Please sign in to comment.