summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-13 08:19:52 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-11-13 08:19:52 +0000
commit7422ccdd9e2fb2b28844879d5117d8fdc000c944 (patch)
tree9a6e9129ad35a2c0306e222f4ad2c59163849ee8
parent948ff2456bc7839817ea043b42b6423538ab873c (diff)
* signal.c (sighandle): should not re-register sighandler if
POSIX_SIGNAL is defined. * eval.c (error_print): errat array may be empty. * eval.c (rb_eval_cmd): should not upgrade safe level unless explicitly specified by argument newly added. * signal.c (sig_trap): should not allow tainted trap closure. * variable.c (rb_f_trace_var): should not allow trace_var on safe level higher than 3. * variable.c (rb_f_trace_var): should not allow tainted trace closure. * gc.c: do not use static stack until system stack overflows. * eval.c (eval): should call Exception#exception instead of calling rb_exc_new3() directly. * error.c (exc_exception): set "mesg" directly to the clone. it might be better to set mesg via some method for flexibility. * variable.c (cvar_override_check): should print original module name, if 'a' is T_ICLASS. * parse.y (yylex): float '1_.0' should not be allowed. * variable.c (var_getter): should care about var as Qfalse (ruby-bugs#PR199). * array.c (cmpint): <=> or block for {min,max} may return bignum. * array.c (sort_1): use rb_compint. * array.c (sort_2): ditto. * enum.c (min_ii): ditto. * enum.c (min_ii): ditto. * enum.c (max_i): ditto. * enum.c (max_ii): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1827 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog60
-rw-r--r--array.c18
-rw-r--r--configure.in4
-rw-r--r--enum.c10
-rw-r--r--error.c2
-rw-r--r--eval.c18
-rw-r--r--file.c3
-rw-r--r--gc.c417
-rw-r--r--intern.h3
-rw-r--r--mkconfig.rb4
-rw-r--r--parse.y1
-rw-r--r--signal.c7
-rw-r--r--string.c12
-rw-r--r--variable.c37
14 files changed, 327 insertions, 269 deletions
diff --git a/ChangeLog b/ChangeLog
index c2977eea27..37652f567f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,11 @@ Tue Nov 13 16:49:16 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c (do_spawn): ditto.
+Tue Nov 13 14:39:11 2001 WATANABE Tetsuya <tetsu@jpn.hp.com>
+
+ * signal.c (sighandle): should not re-register sighandler if
+ POSIX_SIGNAL is defined.
+
Tue Nov 13 12:55:59 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c (do_spawn): use CreateChild() instead of calling
@@ -70,6 +75,45 @@ Tue Nov 13 12:38:12 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/win32.c, win32/win32.h (win32_free_environ): free environment
variables list. [new]
+Mon Nov 12 16:48:48 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (error_print): errat array may be empty.
+
+Mon Nov 12 01:30:37 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_eval_cmd): should not upgrade safe level unless
+ explicitly specified by argument newly added.
+
+ * signal.c (sig_trap): should not allow tainted trap closure.
+
+ * variable.c (rb_f_trace_var): should not allow trace_var on safe
+ level higher than 3.
+
+ * variable.c (rb_f_trace_var): should not allow tainted trace
+ closure.
+
+Sun Nov 11 00:12:23 2001 TAMURA Takashi <sheepman@tcn.zaq.ne.jp>
+
+ * gc.c: do not use static stack until system stack overflows.
+
+Sat Nov 10 03:57:09 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (eval): should call Exception#exception instead of
+ calling rb_exc_new3() directly.
+
+ * error.c (exc_exception): set "mesg" directly to the clone. it
+ might be better to set mesg via some method for flexibility.
+
+Sat Nov 10 00:14:24 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * variable.c (cvar_override_check): should print original module
+ name, if 'a' is T_ICLASS.
+
+ * parse.y (yylex): float '1_.0' should not be allowed.
+
+ * variable.c (var_getter): should care about var as Qfalse
+ (ruby-bugs#PR199).
+
Fri Nov 9 13:50:06 2001 Usaku Nakamura <usa@ruby-lang.org>
* win32/config.status.in: make CFLAGS same as Makefile's one.
@@ -82,6 +126,22 @@ Thu Nov 8 20:20:37 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* eval.c (rb_call0): adjust caller source file/line while
evaluating optional arguments.
+Thu Nov 8 18:41:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (cmpint): <=> or block for {min,max} may return bignum.
+
+ * array.c (sort_1): use rb_compint.
+
+ * array.c (sort_2): ditto.
+
+ * enum.c (min_ii): ditto.
+
+ * enum.c (min_ii): ditto.
+
+ * enum.c (max_i): ditto.
+
+ * enum.c (max_ii): ditto.
+
Thu Nov 8 18:21:02 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* file.c (path_check_1): forgot to initialize 'p'.
diff --git a/array.c b/array.c
index 79131901e3..0dfa3aef40 100644
--- a/array.c
+++ b/array.c
@@ -1004,12 +1004,26 @@ rb_ary_reverse_m(ary)
return rb_ary_reverse(rb_ary_dup(ary));
}
+int
+rb_cmpint(cmp)
+ VALUE cmp;
+{
+ if (FIXNUM_P(cmp)) return NUM2LONG(cmp);
+ if (TYPE(cmp) == T_BIGNUM) {
+ if (RBIGNUM(cmp)->sign) return 1;
+ return -1;
+ }
+ if (rb_funcall(cmp, '>', 1, INT2FIX(0))) return 1;
+ if (rb_funcall(cmp, '<', 1, INT2FIX(0))) return -1;
+ return 0;
+}
+
static int
sort_1(a, b)
VALUE *a, *b;
{
VALUE retval = rb_yield(rb_assoc_new(*a, *b));
- return NUM2INT(retval);
+ return rb_cmpint(retval);
}
static int
@@ -1026,7 +1040,7 @@ sort_2(a, b)
}
retval = rb_funcall(*a, cmp, 1, *b);
- return NUM2INT(retval);
+ return rb_cmpint(retval);
}
static VALUE
diff --git a/configure.in b/configure.in
index b752a81ab7..390daf410a 100644
--- a/configure.in
+++ b/configure.in
@@ -17,7 +17,9 @@ AC_ARG_WITH(gcc, [--without-gcc never use gcc], [
without_gcc=no;;
*) CC=$withval
without_gcc=$withval;;
- esac], [without_gcc=no])
+ esac], [
+ CC=gcc
+ without_gcc=no])
dnl If the user switches compilers, we can't believe the cache
if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
then
diff --git a/enum.c b/enum.c
index dfa846c05f..af01645220 100644
--- a/enum.c
+++ b/enum.c
@@ -89,7 +89,7 @@ enum_find(argc, argv, obj)
}
rb_gc_force_recycle((VALUE)memo);
if (!NIL_P(if_none)) {
- rb_eval_cmd(if_none, rb_ary_new2(0));
+ rb_eval_cmd(if_none, rb_ary_new2(0), 0);
}
return Qnil;
}
@@ -299,7 +299,7 @@ min_i(i, memo)
memo->u1.value = i;
else {
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
- if (NUM2LONG(cmp) < 0)
+ if (rb_cmpint(cmp) < 0)
memo->u1.value = i;
}
return Qnil;
@@ -316,7 +316,7 @@ min_ii(i, memo)
memo->u1.value = i;
else {
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
- if (NUM2LONG(cmp) < 0)
+ if (rb_cmpint(cmp) < 0)
memo->u1.value = i;
}
return Qnil;
@@ -344,7 +344,7 @@ max_i(i, memo)
memo->u1.value = i;
else {
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
- if (NUM2LONG(cmp) > 0)
+ if (rb_cmpint(cmp) > 0)
memo->u1.value = i;
}
return Qnil;
@@ -361,7 +361,7 @@ max_ii(i, memo)
memo->u1.value = i;
else {
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
- if (NUM2LONG(cmp) > 0)
+ if (rb_cmpint(cmp) > 0)
memo->u1.value = i;
}
return Qnil;
diff --git a/error.c b/error.c
index 06efcb83a2..4d56f80e70 100644
--- a/error.c
+++ b/error.c
@@ -324,7 +324,7 @@ exc_exception(argc, argv, self)
if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
exc = rb_obj_clone(self);
- rb_obj_call_init(exc, argc, argv);
+ exc_initialize(argc, argv, exc);
return exc;
}
diff --git a/eval.c b/eval.c
index 8774d1da84..01be68249b 100644
--- a/eval.c
+++ b/eval.c
@@ -924,12 +924,15 @@ error_print()
errat = Qnil;
}
POP_TAG();
- if (NIL_P(errat)) {
+ if (NIL_P(errat)){
if (ruby_sourcefile)
fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline);
else
fprintf(stderr, "%d", ruby_sourceline);
}
+ else if (RARRAY(errat)->len == 0) {
+ error_pos();
+ }
else {
VALUE mesg = RARRAY(errat)->ptr[0];
@@ -1342,8 +1345,9 @@ jump_tag_but_local_jump(state)
}
VALUE
-rb_eval_cmd(cmd, arg)
+rb_eval_cmd(cmd, arg, tcheck)
VALUE cmd, arg;
+ int tcheck;
{
int state;
VALUE val; /* OK */
@@ -1365,7 +1369,7 @@ rb_eval_cmd(cmd, arg)
ruby_frame->self = ruby_top_self;
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_wrapper,0,0);
- if (OBJ_TAINTED(cmd)) {
+ if (tcheck && OBJ_TAINTED(cmd)) {
ruby_safe_level = 4;
}
@@ -1396,7 +1400,7 @@ rb_trap_eval(cmd, sig)
PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) {
- val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)));
+ val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0);
}
POP_ITER();
POP_TAG();
@@ -1430,7 +1434,7 @@ superclass(self, node)
rb_raise(rb_eTypeError, "undefined superclass `%s'",
rb_id2name(node->nd_vid));
default:
- rb_raise(rb_eTypeError, "superclass undefined");
+ break;
}
JUMP_TAG(state);
}
@@ -4257,7 +4261,7 @@ static unsigned int STACK_LEVEL_MAX = 65535;
#ifdef __human68k__
extern unsigned int _stacksize;
# define STACK_LEVEL_MAX (_stacksize - 4096)
-#undef HAVE_GETRLIMIT
+# undef HAVE_GETRLIMIT
#else
#ifdef HAVE_GETRLIMIT
static unsigned int STACK_LEVEL_MAX = 655300;
@@ -5037,7 +5041,7 @@ eval(self, src, scope, file, line)
err = rb_str_dup(ruby_errinfo);
}
errat = Qnil;
- rb_exc_raise(rb_exc_new3(CLASS_OF(ruby_errinfo), err));
+ rb_exc_raise(rb_funcall(ruby_errinfo, rb_intern("exception"), 1, err));
}
rb_exc_raise(ruby_errinfo);
}
diff --git a/file.c b/file.c
index bcce2008a5..628c3e9b8a 100644
--- a/file.c
+++ b/file.c
@@ -2325,8 +2325,7 @@ rb_find_file_ext(filep, ext)
int i, j;
if (f[0] == '~') {
- fname = *filep;
- fname = rb_file_s_expand_path(1, &fname);
+ fname = rb_file_s_expand_path(1, filep);
if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {
rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
}
diff --git a/gc.c b/gc.c
index 0f489659e5..17858f0270 100644
--- a/gc.c
+++ b/gc.c
@@ -345,6 +345,96 @@ rb_data_object_alloc(klass, datap, dmark, dfree)
extern st_table *rb_class_tbl;
VALUE *rb_gc_stack_start = 0;
+
+#define MARK_STACK_MAX 1024
+static VALUE mark_stack[MARK_STACK_MAX];
+static VALUE *mark_stack_ptr;
+static int mark_stack_overflow;
+
+static void
+init_mark_stack()
+{
+ mark_stack_overflow = 0;
+ mark_stack_ptr = mark_stack;
+ memset(mark_stack, 0, MARK_STACK_MAX);
+}
+
+#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack)
+
+static int mark_all;
+
+static void rb_gc_mark_children(VALUE ptr);
+static void
+gc_mark_all()
+{
+ RVALUE *p, *pend;
+ int i;
+ mark_all = 0;
+ while(!mark_all){
+ mark_all = 1;
+ for (i = 0; i < heaps_used; i++) {
+ p = heaps[i]; pend = p + heaps_limits[i];
+ while (p < pend) {
+ if (!(rb_special_const_p((VALUE)p))
+ && p->as.basic.flags&FL_MARK) {
+ rb_gc_mark_children((VALUE)p);
+ }
+ p++;
+ }
+ }
+ }
+}
+
+static void
+gc_mark_rest()
+{
+ VALUE tmp_arry[MARK_STACK_MAX];
+ VALUE *p;
+
+ p = (mark_stack_ptr - mark_stack) + tmp_arry;
+ memcpy(tmp_arry, mark_stack, MARK_STACK_MAX);
+
+ init_mark_stack();
+
+ while(p != tmp_arry){
+ p--;
+ rb_gc_mark(*p);
+ }
+}
+
+#if defined(DJGPP)
+# define STACK_LEVEL_MAX 65535;
+#elif defined(__human68k__)
+extern unsigned int _stacksize;
+# define STACK_LEVEL_MAX (_stacksize - 4096)
+#else
+# define STACK_LEVEL_MAX 655300
+#endif
+
+#ifdef C_ALLOCA
+# define SET_STACK_END VALUE stack_end; alloca(0);
+# define STACK_END (&stack_end)
+#else
+# if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS)
+# define SET_STACK_END VALUE *stack_end = __builtin_frame_address(0);
+# else
+# define SET_STACK_END VALUE *stack_end = alloca(1);
+# endif
+# define STACK_END (stack_end)
+#endif
+#ifdef __sparc__
+# define STACK_LENGTH (rb_gc_stack_start - STACK_END + 0x80)
+#else
+# define STACK_LENGTH ((STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END\
+ : STACK_END - rb_gc_stack_start)
+#endif
+
+#define CHECK_STACK(ret) do {\
+ SET_STACK_END;\
+ ret = (STACK_LENGTH > STACK_LEVEL_MAX);\
+} while (0)\
+
+
static inline int
is_pointer_to_heap(ptr)
void *ptr;
@@ -365,73 +455,6 @@ is_pointer_to_heap(ptr)
return Qfalse;
}
-#define MARK_STACK_SIZE 4096
-static VALUE mark_stack_base[MARK_STACK_SIZE];
-static VALUE *mark_stack;
-static int mark_stack_overflow = 0;
-
-#define PUSH_MARK(obj) do {\
- if (mark_stack_overflow) {\
- FL_SET((obj),FL_MARK);\
- }\
- else {\
- if (mark_stack - mark_stack_base >= MARK_STACK_SIZE) {\
- mark_stack_overflow = 1;\
- }\
- else {\
- if ( rb_special_const_p(obj) /* special const not marked */\
- || FL_TEST((obj),FL_MARK)) /* already marked */ {\
- }\
- else {\
- *mark_stack++ = (obj);\
- }\
- }\
- }\
-} while (0)
-
-#define POP_MARK() (*--mark_stack)
-
-#define MARK_EMPTY() (mark_stack == mark_stack_base)
-
-#ifdef NO_REGION
-
-#define PUSH_MARK_REGION(a,b) do {\
- VALUE *tmp_beg_ptr = (a);\
- while (tmp_beg_ptr < (b)) {\
- PUSH_MARK(*tmp_beg_ptr);\
- tmp_beg_ptr++;\
- }\
-} while (0)
-
-#else
-
-#define MARK_REGION_STACK_SIZE 1024
-static VALUE *mark_region_stack_base[MARK_REGION_STACK_SIZE];
-static VALUE **mark_region_stack;
-
-#define PUSH_MARK_REGION(a,b) do {\
- if (mark_region_stack - mark_region_stack_base >= MARK_REGION_STACK_SIZE || (b) - (a) < 3) {\
- VALUE *tmp_beg_ptr = (a);\
- while (tmp_beg_ptr < (b)) {\
- PUSH_MARK(*tmp_beg_ptr);\
- tmp_beg_ptr++;\
- }\
- }\
- else {\
- *mark_region_stack++ = (a);\
- *mark_region_stack++ = (b);\
- }\
-} while (0)
-
-#define POP_MARK_REGION(a,b) do {\
- (b) = (*--mark_region_stack);\
- (a) = (*--mark_region_stack);\
-} while (0)
-
-#define MARK_REGION_EMPTY() (mark_region_stack == mark_region_stack_base)
-
-#endif
-
static void
mark_locations_array(x, n)
register VALUE *x;
@@ -479,23 +502,6 @@ rb_mark_tbl(tbl)
}
static int
-push_entry(key, value)
- ID key;
- VALUE value;
-{
- PUSH_MARK(value);
- return ST_CONTINUE;
-}
-
-static void
-push_mark_tbl(tbl)
- st_table *tbl;
-{
- if (!tbl) return;
- st_foreach(tbl, push_entry, 0);
-}
-
-static int
mark_hashentry(key, value)
VALUE key;
VALUE value;
@@ -513,24 +519,6 @@ rb_mark_hash(tbl)
st_foreach(tbl, mark_hashentry, 0);
}
-static int
-push_hashentry(key, value)
- VALUE key;
- VALUE value;
-{
- PUSH_MARK(key);
- PUSH_MARK(value);
- return ST_CONTINUE;
-}
-
-static void
-push_mark_hash(tbl)
- st_table *tbl;
-{
- if (!tbl) return;
- st_foreach(tbl, push_hashentry, 0);
-}
-
void
rb_gc_mark_maybe(obj)
VALUE obj;
@@ -540,14 +528,47 @@ rb_gc_mark_maybe(obj)
}
}
-static void
-gc_mark_children(ptr)
+void
+rb_gc_mark(ptr)
VALUE ptr;
{
register RVALUE *obj = RANY(ptr);
- Top:
+ if (!mark_stack_overflow){
+ int ret;
+ CHECK_STACK(ret);
+ if (ret) {
+ if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
+ *mark_stack_ptr = ptr;
+ mark_stack_ptr++;
+ return;
+ }else{
+ mark_stack_overflow = 1;
+ printf("mark_stack_overflow\n");
+ }
+ }
+ }
+
+ if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */
+ if (obj->as.basic.flags == 0) return; /* free cell */
+ if (obj->as.basic.flags & FL_MARK) return; /* already marked */
+
obj->as.basic.flags |= FL_MARK;
+
+ if (mark_stack_overflow){
+ mark_all &= 0;
+ return;
+ }else{
+ rb_gc_mark_children(ptr);
+ }
+}
+
+void
+rb_gc_mark_children(ptr)
+ VALUE ptr;
+{
+ register RVALUE *obj = RANY(ptr);
+
if (FL_TEST(obj, FL_EXIVAR)) {
rb_mark_generic_ivar((VALUE)obj);
}
@@ -568,7 +589,7 @@ gc_mark_children(ptr)
case NODE_MASGN:
case NODE_RESCUE:
case NODE_RESBODY:
- PUSH_MARK((VALUE)obj->as.node.u2.node);
+ rb_gc_mark((VALUE)obj->as.node.u2.node);
/* fall through */
case NODE_BLOCK: /* 1,3 */
case NODE_ARRAY:
@@ -582,14 +603,14 @@ gc_mark_children(ptr)
case NODE_CALL:
case NODE_DEFS:
case NODE_OP_ASGN1:
- PUSH_MARK((VALUE)obj->as.node.u1.node);
+ rb_gc_mark((VALUE)obj->as.node.u1.node);
/* fall through */
case NODE_SUPER: /* 3 */
case NODE_FCALL:
case NODE_DEFN:
case NODE_NEWLINE:
- obj = RANY(obj->as.node.u3.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u3.node);
+ break;
case NODE_WHILE: /* 1,2 */
case NODE_UNTIL:
@@ -605,7 +626,7 @@ gc_mark_children(ptr)
case NODE_MATCH3:
case NODE_OP_ASGN_OR:
case NODE_OP_ASGN_AND:
- PUSH_MARK((VALUE)obj->as.node.u1.node);
+ rb_gc_mark((VALUE)obj->as.node.u1.node);
/* fall through */
case NODE_METHOD: /* 2 */
case NODE_NOT:
@@ -620,8 +641,8 @@ gc_mark_children(ptr)
case NODE_MODULE:
case NODE_COLON3:
case NODE_OPT_N:
- obj = RANY(obj->as.node.u2.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u2.node);
+ break;
case NODE_HASH: /* 1 */
case NODE_LIT:
@@ -635,15 +656,15 @@ gc_mark_children(ptr)
case NODE_YIELD:
case NODE_COLON2:
case NODE_ARGS:
- obj = RANY(obj->as.node.u1.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u1.node);
+ break;
case NODE_SCOPE: /* 2,3 */
case NODE_CLASS:
case NODE_BLOCK_PASS:
- PUSH_MARK((VALUE)obj->as.node.u3.node);
- obj = RANY(obj->as.node.u2.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u3.node);
+ rb_gc_mark((VALUE)obj->as.node.u2.node);
+ break;
case NODE_ZARRAY: /* - */
case NODE_ZSUPER:
@@ -674,52 +695,53 @@ gc_mark_children(ptr)
case NODE_ALLOCA:
mark_locations_array((VALUE*)obj->as.node.u1.value,
obj->as.node.u3.cnt);
- obj = RANY(obj->as.node.u2.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u2.node);
+ break;
#endif
default:
if (is_pointer_to_heap(obj->as.node.u1.node)) {
- PUSH_MARK((VALUE)obj->as.node.u1.node);
+ rb_gc_mark((VALUE)obj->as.node.u1.node);
}
if (is_pointer_to_heap(obj->as.node.u2.node)) {
- PUSH_MARK((VALUE)obj->as.node.u2.node);
+ rb_gc_mark((VALUE)obj->as.node.u2.node);
}
if (is_pointer_to_heap(obj->as.node.u3.node)) {
- obj = RANY(obj->as.node.u3.node);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.node.u3.node);
}
}
return; /* no need to mark class. */
}
- PUSH_MARK(obj->as.basic.klass);
+ rb_gc_mark(obj->as.basic.klass);
switch (obj->as.basic.flags & T_MASK) {
case T_ICLASS:
case T_CLASS:
case T_MODULE:
- PUSH_MARK(obj->as.klass.super);
- push_mark_tbl(obj->as.klass.m_tbl);
- push_mark_tbl(obj->as.klass.iv_tbl);
+ rb_gc_mark(obj->as.klass.super);
+ rb_mark_tbl(obj->as.klass.m_tbl);
+ rb_mark_tbl(obj->as.klass.iv_tbl);
break;
case T_ARRAY:
- {
- int i, len = obj->as.array.len;
- VALUE *ptr = obj->as.array.ptr;
+ {
+ int i, len = obj->as.array.len;
+ VALUE *ptr = obj->as.array.ptr;
- PUSH_MARK_REGION(ptr,ptr+len);
- }
- break;
+ for (i=0; i < len; i++)
+ rb_gc_mark(*ptr++);
+ }
+ break;
case T_HASH:
- push_mark_hash(obj->as.hash.tbl);
- obj = RANY(obj->as.hash.ifnone);
- goto Again;
+ rb_mark_hash(obj->as.hash.tbl);
+ rb_gc_mark(obj->as.hash.ifnone);
+ break;
case T_STRING:
- obj = RANY(obj->as.string.orig);
- goto Again;
+ if (obj->as.string.orig) {
+ rb_gc_mark((VALUE)obj->as.string.orig);
+ }
break;
case T_DATA:
@@ -727,7 +749,7 @@ gc_mark_children(ptr)
break;
case T_OBJECT:
- push_mark_tbl(obj->as.object.iv_tbl);
+ rb_mark_tbl(obj->as.object.iv_tbl);
break;
case T_FILE:
@@ -739,79 +761,42 @@ gc_mark_children(ptr)
case T_MATCH:
if (obj->as.match.str) {
- obj = RANY(obj->as.match.str);
- goto Again;
+ rb_gc_mark((VALUE)obj->as.match.str);
}
break;
case T_VARMAP:
- PUSH_MARK(obj->as.varmap.val);
- obj = RANY(obj->as.varmap.next);
- goto Again;
+ rb_gc_mark(obj->as.varmap.val);
+ rb_gc_mark((VALUE)obj->as.varmap.next);
+ break;
case T_SCOPE:
if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {
int n = obj->as.scope.local_tbl[0]+1;
VALUE *vars = &obj->as.scope.local_vars[-1];
-
- PUSH_MARK_REGION(vars,vars+n);
+ while (n--) {
+ rb_gc_mark(*vars);
+ vars++;
+ }
}
break;
case T_STRUCT:
- {
- int i, len = obj->as.rstruct.len;
- VALUE *ptr = obj->as.rstruct.ptr;
+ {
+ int i, len = obj->as.rstruct.len;
+ VALUE *ptr = obj->as.rstruct.ptr;
- PUSH_MARK_REGION(ptr,ptr+len);
- }
- break;
+ for (i=0; i < len; i++)
+ rb_gc_mark(*ptr++);
+ }
+ break;
default:
rb_bug("rb_gc_mark(): unknown data type 0x%x(0x%x) %s",
obj->as.basic.flags & T_MASK, obj,
is_pointer_to_heap(obj)?"corrupted object":"non object");
}
- return;
-
- Again:
- if (rb_special_const_p(obj)) return; /* special const not marked */
- if (RBASIC(obj)->flags == 0) return; /* free cell */
- if (FL_TEST((obj),FL_MARK)) return; /* already marked */
- goto Top;
-}
-
-void
-rb_gc_mark(ptr)
- VALUE ptr;
-{
- if (rb_special_const_p(ptr)) return; /* special const not marked */
- if (RBASIC(ptr)->flags == 0) return; /* free cell */
- if (RBASIC(ptr)->flags & FL_MARK) return; /* already marked */
- gc_mark_children(ptr);
-}
-
-static void
-gc_mark()
-{
- while (!MARK_EMPTY()) {
- rb_gc_mark(POP_MARK());
-#ifndef NO_REGION
- while (!MARK_REGION_EMPTY()) {
- VALUE *p, *pend;
-
- POP_MARK_REGION(p, pend);
- while (p < pend) {
- rb_gc_mark(*p);
- p++;
- }
- while (!MARK_EMPTY()) {
- rb_gc_mark(POP_MARK());
- }
- }
-#endif
- }
}
static void obj_free _((VALUE));
@@ -821,31 +806,24 @@ gc_sweep()
{
RVALUE *p, *pend, *final_list;
int freed = 0;
- int i;
+ int i, used = heaps_used;
if (ruby_in_compile) {
- int marked = 0;
-
/* should not reclaim nodes during compilation */
- for (i = 0; i < heaps_used; i++) {
+ for (i = 0; i < used; i++) {
p = heaps[i]; pend = p + heaps_limits[i];
while (p < pend) {
- if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE) {
+ if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE)
rb_gc_mark((VALUE)p);
- marked = 1;
- }
p++;
}
}
- if (marked) {
- gc_mark();
- }
}
freelist = 0;
final_list = deferred_final_list;
deferred_final_list = 0;
- for (i = 0; i < heaps_used; i++) {
+ for (i = 0; i < used; i++) {
int n = 0;
p = heaps[i]; pend = p + heaps_limits[i];
@@ -905,7 +883,6 @@ void
rb_gc_force_recycle(p)
VALUE p;
{
- RANY(p)->type = BUILTIN_TYPE(p);
RANY(p)->as.free.flags = 0;
RANY(p)->as.free.next = freelist;
freelist = RANY(p);
@@ -1118,11 +1095,8 @@ rb_gc()
if (during_gc) return;
during_gc++;
- mark_stack_overflow = 0;
- mark_stack = mark_stack_base;
-#ifndef NO_REGION
- mark_region_stack = mark_region_stack_base;
-#endif
+ init_mark_stack();
+
/* mark frame stack */
for (frame = ruby_frame; frame; frame = frame->prev) {
rb_gc_mark_frame(frame);
@@ -1164,25 +1138,16 @@ rb_gc()
/* mark generic instance variables for special constants */
rb_mark_generic_ivar_tbl();
-
- gc_mark();
- while (mark_stack_overflow) {
- RVALUE *p, *pend;
- int i;
-
- mark_stack_overflow = 0;
- for (i = 0; i < heaps_used; i++) {
- p = heaps[i]; pend = p + heaps_limits[i];
- while (p < pend) {
- if (p->as.basic.flags&FL_MARK) {
- gc_mark_children((VALUE)p);
- }
- p++;
- }
+
+ /* gc_mark objects whose marking are not completed*/
+ while (!MARK_STACK_EMPTY){
+ if (mark_stack_overflow){
+ gc_mark_all();
+ break;
+ }else{
+ gc_mark_rest();
}
- gc_mark();
}
-
gc_sweep();
}
@@ -1385,7 +1350,7 @@ static VALUE
run_single_final(args)
VALUE *args;
{
- rb_eval_cmd(args[0], args[1]);
+ rb_eval_cmd(args[0], args[1], 0);
return Qnil;
}
diff --git a/intern.h b/intern.h
index 8337de4585..35d913e71d 100644
--- a/intern.h
+++ b/intern.h
@@ -40,6 +40,7 @@ VALUE rb_ary_join _((VALUE, VALUE));
VALUE rb_ary_print_on _((VALUE, VALUE));
VALUE rb_ary_reverse _((VALUE));
VALUE rb_ary_sort _((VALUE));
+int rb_cmpint _((VALUE));
VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, VALUE));
VALUE rb_ary_delete_at _((VALUE, long));
@@ -135,7 +136,7 @@ VALUE rb_dvar_ref _((ID));
void rb_dvar_asgn _((ID, VALUE));
void rb_dvar_push _((ID, VALUE));
VALUE *rb_svar _((int));
-VALUE rb_eval_cmd _((VALUE, VALUE));
+VALUE rb_eval_cmd _((VALUE, VALUE, int));
int rb_respond_to _((VALUE, ID));
void rb_interrupt _((void));
VALUE rb_apply _((VALUE, ID, VALUE));
diff --git a/mkconfig.rb b/mkconfig.rb
index 05b5916997..473c592c5b 100644
--- a/mkconfig.rb
+++ b/mkconfig.rb
@@ -39,9 +39,7 @@ File.foreach "config.status" do |line|
next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name
next if $so_name and /^RUBY_SO_NAME$/ =~ name
v = " CONFIG[\"" + name + "\"] = " +
- val.sub(/^\s*(.*)\s*$/, '\1').gsub(/\$\{?(\w+)\}?/) {
- "$(#{$1})"
- }.dump + "\n"
+ val.strip.gsub(/\$\{?(\w+)\}?/) {"$(#{$1})"}.dump + "\n"
if fast[name]
v_fast << v
else
diff --git a/parse.y b/parse.y
index 89c63ab34c..54bccbad3e 100644
--- a/parse.y
+++ b/parse.y
@@ -3404,6 +3404,7 @@ yylex()
break;
case '.':
+ if (seen_uc) goto trailing_uc;
if (seen_point || seen_e) {
goto decode_num;
}
diff --git a/signal.c b/signal.c
index 57e70024de..d20e5dcf75 100644
--- a/signal.c
+++ b/signal.c
@@ -355,7 +355,7 @@ sighandle(sig)
rb_bug("trap_handler: Bad signal %d", sig);
}
-#if !defined(BSD_SIGNAL)
+#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
ruby_signal(sig, sighandle);
#endif
@@ -407,7 +407,7 @@ rb_trap_exit()
VALUE trap_exit = trap_list[0];
trap_list[0] = 0;
- rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)));
+ rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0)), 0);
}
#endif
}
@@ -628,6 +628,9 @@ sig_trap(argc, argv)
arg.cmd = argv[1];
}
+ if (OBJ_TAINTED(arg.cmd)) {
+ rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
+ }
#if !defined(NT)
/* disable interrupt */
# ifdef HAVE_SIGPROCMASK
diff --git a/string.c b/string.c
index 183db6a7fe..01ee1b5e92 100644
--- a/string.c
+++ b/string.c
@@ -103,7 +103,7 @@ VALUE
rb_str_new3(str)
VALUE str;
{
- VALUE str2 = rb_obj_alloc(rb_cString);
+ VALUE str2 = rb_obj_alloc(rb_obj_class(str));
RSTRING(str2)->len = RSTRING(str)->len;
RSTRING(str2)->ptr = RSTRING(str)->ptr;
@@ -124,13 +124,13 @@ rb_str_new4(orig)
VALUE str;
if (FL_TEST(orig, STR_NO_ORIG)) {
- str = rb_str_new(RSTRING(orig)->ptr, RSTRING(orig)->len);
+ str = rb_str_new0(klass, RSTRING(orig)->ptr, RSTRING(orig)->len);
}
else {
str = rb_str_new3(RSTRING(orig)->orig);
+ RBASIC(str)->klass = klass;
}
OBJ_FREEZE(str);
- RBASIC(str)->klass = klass;
return str;
}
else {
@@ -139,7 +139,6 @@ rb_str_new4(orig)
RSTRING(str)->len = RSTRING(orig)->len;
RSTRING(str)->ptr = RSTRING(orig)->ptr;
RSTRING(orig)->orig = str;
- RSTRING(str)->orig = 0;
OBJ_INFECT(str, orig);
OBJ_FREEZE(str);
@@ -287,10 +286,11 @@ rb_str_dup(str)
if (OBJ_FROZEN(str)) str2 = rb_str_new3(str);
else if (FL_TEST(str, STR_NO_ORIG)) {
- str2 = rb_str_new(RSTRING(str)->ptr, RSTRING(str)->len);
+ str2 = rb_str_new0(klass, RSTRING(str)->ptr, RSTRING(str)->len);
}
else if (RSTRING(str)->orig) {
str2 = rb_str_new3(RSTRING(str)->orig);
+ RBASIC(str2)->klass = klass;
FL_UNSET(str2, FL_TAINT);
OBJ_INFECT(str2, str);
}
@@ -300,7 +300,6 @@ rb_str_dup(str)
if (FL_TEST(str, FL_EXIVAR))
rb_copy_generic_ivar(str2, str);
OBJ_INFECT(str2, str);
- RBASIC(str2)->klass = klass;
return str2;
}
@@ -448,6 +447,7 @@ str_independent(str)
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1;
+ if (RBASIC(str)->flags == 0) abort();
if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig");
return 0;
}
diff --git a/variable.c b/variable.c
index fc02f749f7..1f8f2fb7ff 100644
--- a/variable.c
+++ b/variable.c
@@ -402,7 +402,7 @@ var_getter(id, var)
ID id;
VALUE *var;
{
- if (!var || !*var) return Qnil;
+ if (!var) return Qnil;
return *var;
}
@@ -518,7 +518,7 @@ static void
rb_trace_eval(cmd, val)
VALUE cmd, val;
{
- rb_eval_cmd(cmd, rb_ary_new3(1, val));
+ rb_eval_cmd(cmd, rb_ary_new3(1, val), 0);
}
VALUE
@@ -527,19 +527,19 @@ rb_f_trace_var(argc, argv)
VALUE *argv;
{
VALUE var, cmd;
- ID id;
struct global_entry *entry;
struct trace_var *trace;
+ rb_secure(4);
if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
cmd = rb_f_lambda();
}
if (NIL_P(cmd)) {
return rb_f_untrace_var(argc, argv);
}
- id = rb_to_id(var);
- if (!st_lookup(rb_global_tbl, id, &entry)) {
- rb_name_error(id, "undefined global variable %s", rb_id2name(id));
+ entry = rb_global_entry(rb_to_id(var));
+ if (OBJ_TAINTED(cmd)) {
+ rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
}
trace = ALLOC(struct trace_var);
trace->next = entry->var->trace;
@@ -1419,17 +1419,28 @@ rb_cvar_singleton(obj)
return CLASS_OF(obj);
}
+static VALUE
+original_module(c)
+ VALUE c;
+{
+ if (TYPE(c) == T_ICLASS)
+ return RBASIC(c)->klass;
+ return c;
+}
+
static void
-cvar_override_check(id, a, b)
- VALUE a, b;
+cvar_override_check(id, a)
+ VALUE a;
{
+ VALUE base = original_module(a);
+
a = RCLASS(a)->super;
while (a) {
if (RCLASS(a)->iv_tbl) {
if (st_lookup(RCLASS(a)->iv_tbl,id,0)) {
rb_warning("class variable %s of %s is overridden by %s",
- rb_id2name(id), rb_class2name(a),
- rb_class2name(b));
+ rb_id2name(id), rb_class2name(original_module(a)),
+ rb_class2name(base));
}
}
a = RCLASS(a)->super;
@@ -1452,7 +1463,7 @@ rb_cvar_set(klass, id, val)
rb_raise(rb_eSecurityError, "Insecure: can't modify class variable");
st_insert(RCLASS(tmp)->iv_tbl,id,val);
if (ruby_verbose) {
- cvar_override_check(id, tmp, klass);
+ cvar_override_check(id, tmp);
}
return;
}
@@ -1482,7 +1493,7 @@ rb_cvar_declare(klass, id, val)
}
st_insert(RCLASS(tmp)->iv_tbl,id,val);
if (ruby_verbose) {
- cvar_override_check(id, tmp, klass);
+ cvar_override_check(id, tmp);
}
return;
}
@@ -1505,7 +1516,7 @@ rb_cvar_get(klass, id)
if (RCLASS(tmp)->iv_tbl) {
if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
if (ruby_verbose) {
- cvar_override_check(id, tmp, klass);
+ cvar_override_check(id, tmp);
}
return value;
}