* 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
This commit is contained in:
parent
948ff2456b
commit
7422ccdd9e
60
ChangeLog
60
ChangeLog
@ -5,6 +5,11 @@ Tue Nov 13 16:49:16 2001 Usaku Nakamura <usa@ruby-lang.org>
|
|||||||
|
|
||||||
* win32/win32.c (do_spawn): ditto.
|
* 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>
|
Tue Nov 13 12:55:59 2001 Usaku Nakamura <usa@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (do_spawn): use CreateChild() instead of calling
|
* 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
|
* win32/win32.c, win32/win32.h (win32_free_environ): free environment
|
||||||
variables list. [new]
|
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>
|
Fri Nov 9 13:50:06 2001 Usaku Nakamura <usa@ruby-lang.org>
|
||||||
|
|
||||||
* win32/config.status.in: make CFLAGS same as Makefile's one.
|
* 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
|
* eval.c (rb_call0): adjust caller source file/line while
|
||||||
evaluating optional arguments.
|
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>
|
Thu Nov 8 18:21:02 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* file.c (path_check_1): forgot to initialize 'p'.
|
* file.c (path_check_1): forgot to initialize 'p'.
|
||||||
|
18
array.c
18
array.c
@ -1004,12 +1004,26 @@ rb_ary_reverse_m(ary)
|
|||||||
return rb_ary_reverse(rb_ary_dup(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
|
static int
|
||||||
sort_1(a, b)
|
sort_1(a, b)
|
||||||
VALUE *a, *b;
|
VALUE *a, *b;
|
||||||
{
|
{
|
||||||
VALUE retval = rb_yield(rb_assoc_new(*a, *b));
|
VALUE retval = rb_yield(rb_assoc_new(*a, *b));
|
||||||
return NUM2INT(retval);
|
return rb_cmpint(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1026,7 +1040,7 @@ sort_2(a, b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
retval = rb_funcall(*a, cmp, 1, *b);
|
retval = rb_funcall(*a, cmp, 1, *b);
|
||||||
return NUM2INT(retval);
|
return rb_cmpint(retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -17,7 +17,9 @@ AC_ARG_WITH(gcc, [--without-gcc never use gcc], [
|
|||||||
without_gcc=no;;
|
without_gcc=no;;
|
||||||
*) CC=$withval
|
*) CC=$withval
|
||||||
without_gcc=$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
|
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"
|
if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
|
||||||
then
|
then
|
||||||
|
10
enum.c
10
enum.c
@ -89,7 +89,7 @@ enum_find(argc, argv, obj)
|
|||||||
}
|
}
|
||||||
rb_gc_force_recycle((VALUE)memo);
|
rb_gc_force_recycle((VALUE)memo);
|
||||||
if (!NIL_P(if_none)) {
|
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;
|
return Qnil;
|
||||||
}
|
}
|
||||||
@ -299,7 +299,7 @@ min_i(i, memo)
|
|||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
else {
|
else {
|
||||||
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
|
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
|
||||||
if (NUM2LONG(cmp) < 0)
|
if (rb_cmpint(cmp) < 0)
|
||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
@ -316,7 +316,7 @@ min_ii(i, memo)
|
|||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
else {
|
else {
|
||||||
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
|
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
|
||||||
if (NUM2LONG(cmp) < 0)
|
if (rb_cmpint(cmp) < 0)
|
||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
@ -344,7 +344,7 @@ max_i(i, memo)
|
|||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
else {
|
else {
|
||||||
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
|
cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
|
||||||
if (NUM2LONG(cmp) > 0)
|
if (rb_cmpint(cmp) > 0)
|
||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
@ -361,7 +361,7 @@ max_ii(i, memo)
|
|||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
else {
|
else {
|
||||||
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
|
cmp = rb_yield(rb_assoc_new(i, memo->u1.value));
|
||||||
if (NUM2LONG(cmp) > 0)
|
if (rb_cmpint(cmp) > 0)
|
||||||
memo->u1.value = i;
|
memo->u1.value = i;
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
2
error.c
2
error.c
@ -324,7 +324,7 @@ exc_exception(argc, argv, self)
|
|||||||
if (argc == 0) return self;
|
if (argc == 0) return self;
|
||||||
if (argc == 1 && self == argv[0]) return self;
|
if (argc == 1 && self == argv[0]) return self;
|
||||||
exc = rb_obj_clone(self);
|
exc = rb_obj_clone(self);
|
||||||
rb_obj_call_init(exc, argc, argv);
|
exc_initialize(argc, argv, exc);
|
||||||
|
|
||||||
return exc;
|
return exc;
|
||||||
}
|
}
|
||||||
|
14
eval.c
14
eval.c
@ -930,6 +930,9 @@ error_print()
|
|||||||
else
|
else
|
||||||
fprintf(stderr, "%d", ruby_sourceline);
|
fprintf(stderr, "%d", ruby_sourceline);
|
||||||
}
|
}
|
||||||
|
else if (RARRAY(errat)->len == 0) {
|
||||||
|
error_pos();
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
VALUE mesg = RARRAY(errat)->ptr[0];
|
VALUE mesg = RARRAY(errat)->ptr[0];
|
||||||
|
|
||||||
@ -1342,8 +1345,9 @@ jump_tag_but_local_jump(state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_eval_cmd(cmd, arg)
|
rb_eval_cmd(cmd, arg, tcheck)
|
||||||
VALUE cmd, arg;
|
VALUE cmd, arg;
|
||||||
|
int tcheck;
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
VALUE val; /* OK */
|
VALUE val; /* OK */
|
||||||
@ -1365,7 +1369,7 @@ rb_eval_cmd(cmd, arg)
|
|||||||
ruby_frame->self = ruby_top_self;
|
ruby_frame->self = ruby_top_self;
|
||||||
ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_wrapper,0,0);
|
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;
|
ruby_safe_level = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1396,7 +1400,7 @@ rb_trap_eval(cmd, sig)
|
|||||||
PUSH_TAG(PROT_NONE);
|
PUSH_TAG(PROT_NONE);
|
||||||
PUSH_ITER(ITER_NOT);
|
PUSH_ITER(ITER_NOT);
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
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_ITER();
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
@ -1430,7 +1434,7 @@ superclass(self, node)
|
|||||||
rb_raise(rb_eTypeError, "undefined superclass `%s'",
|
rb_raise(rb_eTypeError, "undefined superclass `%s'",
|
||||||
rb_id2name(node->nd_vid));
|
rb_id2name(node->nd_vid));
|
||||||
default:
|
default:
|
||||||
rb_raise(rb_eTypeError, "superclass undefined");
|
break;
|
||||||
}
|
}
|
||||||
JUMP_TAG(state);
|
JUMP_TAG(state);
|
||||||
}
|
}
|
||||||
@ -5037,7 +5041,7 @@ eval(self, src, scope, file, line)
|
|||||||
err = rb_str_dup(ruby_errinfo);
|
err = rb_str_dup(ruby_errinfo);
|
||||||
}
|
}
|
||||||
errat = Qnil;
|
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);
|
rb_exc_raise(ruby_errinfo);
|
||||||
}
|
}
|
||||||
|
3
file.c
3
file.c
@ -2325,8 +2325,7 @@ rb_find_file_ext(filep, ext)
|
|||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
if (f[0] == '~') {
|
if (f[0] == '~') {
|
||||||
fname = *filep;
|
fname = rb_file_s_expand_path(1, filep);
|
||||||
fname = rb_file_s_expand_path(1, &fname);
|
|
||||||
if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {
|
if (rb_safe_level() >= 2 && OBJ_TAINTED(fname)) {
|
||||||
rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
|
rb_raise(rb_eSecurityError, "loading from unsafe file %s", f);
|
||||||
}
|
}
|
||||||
|
395
gc.c
395
gc.c
@ -345,6 +345,96 @@ rb_data_object_alloc(klass, datap, dmark, dfree)
|
|||||||
extern st_table *rb_class_tbl;
|
extern st_table *rb_class_tbl;
|
||||||
VALUE *rb_gc_stack_start = 0;
|
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
|
static inline int
|
||||||
is_pointer_to_heap(ptr)
|
is_pointer_to_heap(ptr)
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@ -365,73 +455,6 @@ is_pointer_to_heap(ptr)
|
|||||||
return Qfalse;
|
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
|
static void
|
||||||
mark_locations_array(x, n)
|
mark_locations_array(x, n)
|
||||||
register VALUE *x;
|
register VALUE *x;
|
||||||
@ -478,23 +501,6 @@ rb_mark_tbl(tbl)
|
|||||||
st_foreach(tbl, mark_entry, 0);
|
st_foreach(tbl, mark_entry, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
static int
|
||||||
mark_hashentry(key, value)
|
mark_hashentry(key, value)
|
||||||
VALUE key;
|
VALUE key;
|
||||||
@ -513,24 +519,6 @@ rb_mark_hash(tbl)
|
|||||||
st_foreach(tbl, mark_hashentry, 0);
|
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
|
void
|
||||||
rb_gc_mark_maybe(obj)
|
rb_gc_mark_maybe(obj)
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
@ -540,14 +528,47 @@ rb_gc_mark_maybe(obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
gc_mark_children(ptr)
|
rb_gc_mark(ptr)
|
||||||
VALUE ptr;
|
VALUE ptr;
|
||||||
{
|
{
|
||||||
register RVALUE *obj = RANY(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;
|
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)) {
|
if (FL_TEST(obj, FL_EXIVAR)) {
|
||||||
rb_mark_generic_ivar((VALUE)obj);
|
rb_mark_generic_ivar((VALUE)obj);
|
||||||
}
|
}
|
||||||
@ -568,7 +589,7 @@ gc_mark_children(ptr)
|
|||||||
case NODE_MASGN:
|
case NODE_MASGN:
|
||||||
case NODE_RESCUE:
|
case NODE_RESCUE:
|
||||||
case NODE_RESBODY:
|
case NODE_RESBODY:
|
||||||
PUSH_MARK((VALUE)obj->as.node.u2.node);
|
rb_gc_mark((VALUE)obj->as.node.u2.node);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case NODE_BLOCK: /* 1,3 */
|
case NODE_BLOCK: /* 1,3 */
|
||||||
case NODE_ARRAY:
|
case NODE_ARRAY:
|
||||||
@ -582,14 +603,14 @@ gc_mark_children(ptr)
|
|||||||
case NODE_CALL:
|
case NODE_CALL:
|
||||||
case NODE_DEFS:
|
case NODE_DEFS:
|
||||||
case NODE_OP_ASGN1:
|
case NODE_OP_ASGN1:
|
||||||
PUSH_MARK((VALUE)obj->as.node.u1.node);
|
rb_gc_mark((VALUE)obj->as.node.u1.node);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case NODE_SUPER: /* 3 */
|
case NODE_SUPER: /* 3 */
|
||||||
case NODE_FCALL:
|
case NODE_FCALL:
|
||||||
case NODE_DEFN:
|
case NODE_DEFN:
|
||||||
case NODE_NEWLINE:
|
case NODE_NEWLINE:
|
||||||
obj = RANY(obj->as.node.u3.node);
|
rb_gc_mark((VALUE)obj->as.node.u3.node);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case NODE_WHILE: /* 1,2 */
|
case NODE_WHILE: /* 1,2 */
|
||||||
case NODE_UNTIL:
|
case NODE_UNTIL:
|
||||||
@ -605,7 +626,7 @@ gc_mark_children(ptr)
|
|||||||
case NODE_MATCH3:
|
case NODE_MATCH3:
|
||||||
case NODE_OP_ASGN_OR:
|
case NODE_OP_ASGN_OR:
|
||||||
case NODE_OP_ASGN_AND:
|
case NODE_OP_ASGN_AND:
|
||||||
PUSH_MARK((VALUE)obj->as.node.u1.node);
|
rb_gc_mark((VALUE)obj->as.node.u1.node);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case NODE_METHOD: /* 2 */
|
case NODE_METHOD: /* 2 */
|
||||||
case NODE_NOT:
|
case NODE_NOT:
|
||||||
@ -620,8 +641,8 @@ gc_mark_children(ptr)
|
|||||||
case NODE_MODULE:
|
case NODE_MODULE:
|
||||||
case NODE_COLON3:
|
case NODE_COLON3:
|
||||||
case NODE_OPT_N:
|
case NODE_OPT_N:
|
||||||
obj = RANY(obj->as.node.u2.node);
|
rb_gc_mark((VALUE)obj->as.node.u2.node);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case NODE_HASH: /* 1 */
|
case NODE_HASH: /* 1 */
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
@ -635,15 +656,15 @@ gc_mark_children(ptr)
|
|||||||
case NODE_YIELD:
|
case NODE_YIELD:
|
||||||
case NODE_COLON2:
|
case NODE_COLON2:
|
||||||
case NODE_ARGS:
|
case NODE_ARGS:
|
||||||
obj = RANY(obj->as.node.u1.node);
|
rb_gc_mark((VALUE)obj->as.node.u1.node);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case NODE_SCOPE: /* 2,3 */
|
case NODE_SCOPE: /* 2,3 */
|
||||||
case NODE_CLASS:
|
case NODE_CLASS:
|
||||||
case NODE_BLOCK_PASS:
|
case NODE_BLOCK_PASS:
|
||||||
PUSH_MARK((VALUE)obj->as.node.u3.node);
|
rb_gc_mark((VALUE)obj->as.node.u3.node);
|
||||||
obj = RANY(obj->as.node.u2.node);
|
rb_gc_mark((VALUE)obj->as.node.u2.node);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case NODE_ZARRAY: /* - */
|
case NODE_ZARRAY: /* - */
|
||||||
case NODE_ZSUPER:
|
case NODE_ZSUPER:
|
||||||
@ -674,33 +695,32 @@ gc_mark_children(ptr)
|
|||||||
case NODE_ALLOCA:
|
case NODE_ALLOCA:
|
||||||
mark_locations_array((VALUE*)obj->as.node.u1.value,
|
mark_locations_array((VALUE*)obj->as.node.u1.value,
|
||||||
obj->as.node.u3.cnt);
|
obj->as.node.u3.cnt);
|
||||||
obj = RANY(obj->as.node.u2.node);
|
rb_gc_mark((VALUE)obj->as.node.u2.node);
|
||||||
goto Again;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (is_pointer_to_heap(obj->as.node.u1.node)) {
|
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)) {
|
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)) {
|
if (is_pointer_to_heap(obj->as.node.u3.node)) {
|
||||||
obj = RANY(obj->as.node.u3.node);
|
rb_gc_mark((VALUE)obj->as.node.u3.node);
|
||||||
goto Again;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return; /* no need to mark class. */
|
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) {
|
switch (obj->as.basic.flags & T_MASK) {
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
PUSH_MARK(obj->as.klass.super);
|
rb_gc_mark(obj->as.klass.super);
|
||||||
push_mark_tbl(obj->as.klass.m_tbl);
|
rb_mark_tbl(obj->as.klass.m_tbl);
|
||||||
push_mark_tbl(obj->as.klass.iv_tbl);
|
rb_mark_tbl(obj->as.klass.iv_tbl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
@ -708,18 +728,20 @@ gc_mark_children(ptr)
|
|||||||
int i, len = obj->as.array.len;
|
int i, len = obj->as.array.len;
|
||||||
VALUE *ptr = obj->as.array.ptr;
|
VALUE *ptr = obj->as.array.ptr;
|
||||||
|
|
||||||
PUSH_MARK_REGION(ptr,ptr+len);
|
for (i=0; i < len; i++)
|
||||||
|
rb_gc_mark(*ptr++);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_HASH:
|
case T_HASH:
|
||||||
push_mark_hash(obj->as.hash.tbl);
|
rb_mark_hash(obj->as.hash.tbl);
|
||||||
obj = RANY(obj->as.hash.ifnone);
|
rb_gc_mark(obj->as.hash.ifnone);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
obj = RANY(obj->as.string.orig);
|
if (obj->as.string.orig) {
|
||||||
goto Again;
|
rb_gc_mark((VALUE)obj->as.string.orig);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_DATA:
|
case T_DATA:
|
||||||
@ -727,7 +749,7 @@ gc_mark_children(ptr)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
push_mark_tbl(obj->as.object.iv_tbl);
|
rb_mark_tbl(obj->as.object.iv_tbl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
@ -739,23 +761,24 @@ gc_mark_children(ptr)
|
|||||||
|
|
||||||
case T_MATCH:
|
case T_MATCH:
|
||||||
if (obj->as.match.str) {
|
if (obj->as.match.str) {
|
||||||
obj = RANY(obj->as.match.str);
|
rb_gc_mark((VALUE)obj->as.match.str);
|
||||||
goto Again;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_VARMAP:
|
case T_VARMAP:
|
||||||
PUSH_MARK(obj->as.varmap.val);
|
rb_gc_mark(obj->as.varmap.val);
|
||||||
obj = RANY(obj->as.varmap.next);
|
rb_gc_mark((VALUE)obj->as.varmap.next);
|
||||||
goto Again;
|
break;
|
||||||
|
|
||||||
case T_SCOPE:
|
case T_SCOPE:
|
||||||
if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {
|
if (obj->as.scope.local_vars && (obj->as.scope.flags & SCOPE_MALLOC)) {
|
||||||
int n = obj->as.scope.local_tbl[0]+1;
|
int n = obj->as.scope.local_tbl[0]+1;
|
||||||
VALUE *vars = &obj->as.scope.local_vars[-1];
|
VALUE *vars = &obj->as.scope.local_vars[-1];
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
PUSH_MARK_REGION(vars,vars+n);
|
rb_gc_mark(*vars);
|
||||||
|
vars++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -764,7 +787,8 @@ gc_mark_children(ptr)
|
|||||||
int i, len = obj->as.rstruct.len;
|
int i, len = obj->as.rstruct.len;
|
||||||
VALUE *ptr = obj->as.rstruct.ptr;
|
VALUE *ptr = obj->as.rstruct.ptr;
|
||||||
|
|
||||||
PUSH_MARK_REGION(ptr,ptr+len);
|
for (i=0; i < len; i++)
|
||||||
|
rb_gc_mark(*ptr++);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -773,45 +797,6 @@ gc_mark_children(ptr)
|
|||||||
obj->as.basic.flags & T_MASK, obj,
|
obj->as.basic.flags & T_MASK, obj,
|
||||||
is_pointer_to_heap(obj)?"corrupted object":"non object");
|
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));
|
static void obj_free _((VALUE));
|
||||||
@ -821,31 +806,24 @@ gc_sweep()
|
|||||||
{
|
{
|
||||||
RVALUE *p, *pend, *final_list;
|
RVALUE *p, *pend, *final_list;
|
||||||
int freed = 0;
|
int freed = 0;
|
||||||
int i;
|
int i, used = heaps_used;
|
||||||
|
|
||||||
if (ruby_in_compile) {
|
if (ruby_in_compile) {
|
||||||
int marked = 0;
|
|
||||||
|
|
||||||
/* should not reclaim nodes during compilation */
|
/* 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];
|
p = heaps[i]; pend = p + heaps_limits[i];
|
||||||
while (p < pend) {
|
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);
|
rb_gc_mark((VALUE)p);
|
||||||
marked = 1;
|
|
||||||
}
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (marked) {
|
|
||||||
gc_mark();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
freelist = 0;
|
freelist = 0;
|
||||||
final_list = deferred_final_list;
|
final_list = deferred_final_list;
|
||||||
deferred_final_list = 0;
|
deferred_final_list = 0;
|
||||||
for (i = 0; i < heaps_used; i++) {
|
for (i = 0; i < used; i++) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
p = heaps[i]; pend = p + heaps_limits[i];
|
p = heaps[i]; pend = p + heaps_limits[i];
|
||||||
@ -905,7 +883,6 @@ void
|
|||||||
rb_gc_force_recycle(p)
|
rb_gc_force_recycle(p)
|
||||||
VALUE p;
|
VALUE p;
|
||||||
{
|
{
|
||||||
RANY(p)->type = BUILTIN_TYPE(p);
|
|
||||||
RANY(p)->as.free.flags = 0;
|
RANY(p)->as.free.flags = 0;
|
||||||
RANY(p)->as.free.next = freelist;
|
RANY(p)->as.free.next = freelist;
|
||||||
freelist = RANY(p);
|
freelist = RANY(p);
|
||||||
@ -1118,11 +1095,8 @@ rb_gc()
|
|||||||
if (during_gc) return;
|
if (during_gc) return;
|
||||||
during_gc++;
|
during_gc++;
|
||||||
|
|
||||||
mark_stack_overflow = 0;
|
init_mark_stack();
|
||||||
mark_stack = mark_stack_base;
|
|
||||||
#ifndef NO_REGION
|
|
||||||
mark_region_stack = mark_region_stack_base;
|
|
||||||
#endif
|
|
||||||
/* mark frame stack */
|
/* mark frame stack */
|
||||||
for (frame = ruby_frame; frame; frame = frame->prev) {
|
for (frame = ruby_frame; frame; frame = frame->prev) {
|
||||||
rb_gc_mark_frame(frame);
|
rb_gc_mark_frame(frame);
|
||||||
@ -1165,24 +1139,15 @@ rb_gc()
|
|||||||
/* mark generic instance variables for special constants */
|
/* mark generic instance variables for special constants */
|
||||||
rb_mark_generic_ivar_tbl();
|
rb_mark_generic_ivar_tbl();
|
||||||
|
|
||||||
gc_mark();
|
/* gc_mark objects whose marking are not completed*/
|
||||||
while (mark_stack_overflow) {
|
while (!MARK_STACK_EMPTY){
|
||||||
RVALUE *p, *pend;
|
if (mark_stack_overflow){
|
||||||
int i;
|
gc_mark_all();
|
||||||
|
break;
|
||||||
mark_stack_overflow = 0;
|
}else{
|
||||||
for (i = 0; i < heaps_used; i++) {
|
gc_mark_rest();
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
gc_sweep();
|
gc_sweep();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,7 +1350,7 @@ static VALUE
|
|||||||
run_single_final(args)
|
run_single_final(args)
|
||||||
VALUE *args;
|
VALUE *args;
|
||||||
{
|
{
|
||||||
rb_eval_cmd(args[0], args[1]);
|
rb_eval_cmd(args[0], args[1], 0);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
intern.h
3
intern.h
@ -40,6 +40,7 @@ VALUE rb_ary_join _((VALUE, VALUE));
|
|||||||
VALUE rb_ary_print_on _((VALUE, VALUE));
|
VALUE rb_ary_print_on _((VALUE, VALUE));
|
||||||
VALUE rb_ary_reverse _((VALUE));
|
VALUE rb_ary_reverse _((VALUE));
|
||||||
VALUE rb_ary_sort _((VALUE));
|
VALUE rb_ary_sort _((VALUE));
|
||||||
|
int rb_cmpint _((VALUE));
|
||||||
VALUE rb_ary_sort_bang _((VALUE));
|
VALUE rb_ary_sort_bang _((VALUE));
|
||||||
VALUE rb_ary_delete _((VALUE, VALUE));
|
VALUE rb_ary_delete _((VALUE, VALUE));
|
||||||
VALUE rb_ary_delete_at _((VALUE, long));
|
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_asgn _((ID, VALUE));
|
||||||
void rb_dvar_push _((ID, VALUE));
|
void rb_dvar_push _((ID, VALUE));
|
||||||
VALUE *rb_svar _((int));
|
VALUE *rb_svar _((int));
|
||||||
VALUE rb_eval_cmd _((VALUE, VALUE));
|
VALUE rb_eval_cmd _((VALUE, VALUE, int));
|
||||||
int rb_respond_to _((VALUE, ID));
|
int rb_respond_to _((VALUE, ID));
|
||||||
void rb_interrupt _((void));
|
void rb_interrupt _((void));
|
||||||
VALUE rb_apply _((VALUE, ID, VALUE));
|
VALUE rb_apply _((VALUE, ID, VALUE));
|
||||||
|
@ -39,9 +39,7 @@ File.foreach "config.status" do |line|
|
|||||||
next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name
|
next if $install_name and /^RUBY_INSTALL_NAME$/ =~ name
|
||||||
next if $so_name and /^RUBY_SO_NAME$/ =~ name
|
next if $so_name and /^RUBY_SO_NAME$/ =~ name
|
||||||
v = " CONFIG[\"" + name + "\"] = " +
|
v = " CONFIG[\"" + name + "\"] = " +
|
||||||
val.sub(/^\s*(.*)\s*$/, '\1').gsub(/\$\{?(\w+)\}?/) {
|
val.strip.gsub(/\$\{?(\w+)\}?/) {"$(#{$1})"}.dump + "\n"
|
||||||
"$(#{$1})"
|
|
||||||
}.dump + "\n"
|
|
||||||
if fast[name]
|
if fast[name]
|
||||||
v_fast << v
|
v_fast << v
|
||||||
else
|
else
|
||||||
|
1
parse.y
1
parse.y
@ -3404,6 +3404,7 @@ yylex()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
|
if (seen_uc) goto trailing_uc;
|
||||||
if (seen_point || seen_e) {
|
if (seen_point || seen_e) {
|
||||||
goto decode_num;
|
goto decode_num;
|
||||||
}
|
}
|
||||||
|
7
signal.c
7
signal.c
@ -355,7 +355,7 @@ sighandle(sig)
|
|||||||
rb_bug("trap_handler: Bad signal %d", sig);
|
rb_bug("trap_handler: Bad signal %d", sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BSD_SIGNAL)
|
#if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
|
||||||
ruby_signal(sig, sighandle);
|
ruby_signal(sig, sighandle);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -407,7 +407,7 @@ rb_trap_exit()
|
|||||||
VALUE trap_exit = trap_list[0];
|
VALUE trap_exit = trap_list[0];
|
||||||
|
|
||||||
trap_list[0] = 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
|
#endif
|
||||||
}
|
}
|
||||||
@ -628,6 +628,9 @@ sig_trap(argc, argv)
|
|||||||
arg.cmd = argv[1];
|
arg.cmd = argv[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OBJ_TAINTED(arg.cmd)) {
|
||||||
|
rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
|
||||||
|
}
|
||||||
#if !defined(NT)
|
#if !defined(NT)
|
||||||
/* disable interrupt */
|
/* disable interrupt */
|
||||||
# ifdef HAVE_SIGPROCMASK
|
# ifdef HAVE_SIGPROCMASK
|
||||||
|
12
string.c
12
string.c
@ -103,7 +103,7 @@ VALUE
|
|||||||
rb_str_new3(str)
|
rb_str_new3(str)
|
||||||
VALUE 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)->len = RSTRING(str)->len;
|
||||||
RSTRING(str2)->ptr = RSTRING(str)->ptr;
|
RSTRING(str2)->ptr = RSTRING(str)->ptr;
|
||||||
@ -124,13 +124,13 @@ rb_str_new4(orig)
|
|||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
if (FL_TEST(orig, STR_NO_ORIG)) {
|
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 {
|
else {
|
||||||
str = rb_str_new3(RSTRING(orig)->orig);
|
str = rb_str_new3(RSTRING(orig)->orig);
|
||||||
|
RBASIC(str)->klass = klass;
|
||||||
}
|
}
|
||||||
OBJ_FREEZE(str);
|
OBJ_FREEZE(str);
|
||||||
RBASIC(str)->klass = klass;
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -139,7 +139,6 @@ rb_str_new4(orig)
|
|||||||
RSTRING(str)->len = RSTRING(orig)->len;
|
RSTRING(str)->len = RSTRING(orig)->len;
|
||||||
RSTRING(str)->ptr = RSTRING(orig)->ptr;
|
RSTRING(str)->ptr = RSTRING(orig)->ptr;
|
||||||
RSTRING(orig)->orig = str;
|
RSTRING(orig)->orig = str;
|
||||||
RSTRING(str)->orig = 0;
|
|
||||||
OBJ_INFECT(str, orig);
|
OBJ_INFECT(str, orig);
|
||||||
OBJ_FREEZE(str);
|
OBJ_FREEZE(str);
|
||||||
|
|
||||||
@ -287,10 +286,11 @@ rb_str_dup(str)
|
|||||||
|
|
||||||
if (OBJ_FROZEN(str)) str2 = rb_str_new3(str);
|
if (OBJ_FROZEN(str)) str2 = rb_str_new3(str);
|
||||||
else if (FL_TEST(str, STR_NO_ORIG)) {
|
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) {
|
else if (RSTRING(str)->orig) {
|
||||||
str2 = rb_str_new3(RSTRING(str)->orig);
|
str2 = rb_str_new3(RSTRING(str)->orig);
|
||||||
|
RBASIC(str2)->klass = klass;
|
||||||
FL_UNSET(str2, FL_TAINT);
|
FL_UNSET(str2, FL_TAINT);
|
||||||
OBJ_INFECT(str2, str);
|
OBJ_INFECT(str2, str);
|
||||||
}
|
}
|
||||||
@ -300,7 +300,6 @@ rb_str_dup(str)
|
|||||||
if (FL_TEST(str, FL_EXIVAR))
|
if (FL_TEST(str, FL_EXIVAR))
|
||||||
rb_copy_generic_ivar(str2, str);
|
rb_copy_generic_ivar(str2, str);
|
||||||
OBJ_INFECT(str2, str);
|
OBJ_INFECT(str2, str);
|
||||||
RBASIC(str2)->klass = klass;
|
|
||||||
return str2;
|
return str2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,6 +447,7 @@ str_independent(str)
|
|||||||
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
|
||||||
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
|
||||||
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1;
|
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");
|
if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
39
variable.c
39
variable.c
@ -402,7 +402,7 @@ var_getter(id, var)
|
|||||||
ID id;
|
ID id;
|
||||||
VALUE *var;
|
VALUE *var;
|
||||||
{
|
{
|
||||||
if (!var || !*var) return Qnil;
|
if (!var) return Qnil;
|
||||||
return *var;
|
return *var;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +518,7 @@ static void
|
|||||||
rb_trace_eval(cmd, val)
|
rb_trace_eval(cmd, val)
|
||||||
VALUE 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
|
VALUE
|
||||||
@ -527,19 +527,19 @@ rb_f_trace_var(argc, argv)
|
|||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
{
|
{
|
||||||
VALUE var, cmd;
|
VALUE var, cmd;
|
||||||
ID id;
|
|
||||||
struct global_entry *entry;
|
struct global_entry *entry;
|
||||||
struct trace_var *trace;
|
struct trace_var *trace;
|
||||||
|
|
||||||
|
rb_secure(4);
|
||||||
if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
|
if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
|
||||||
cmd = rb_f_lambda();
|
cmd = rb_f_lambda();
|
||||||
}
|
}
|
||||||
if (NIL_P(cmd)) {
|
if (NIL_P(cmd)) {
|
||||||
return rb_f_untrace_var(argc, argv);
|
return rb_f_untrace_var(argc, argv);
|
||||||
}
|
}
|
||||||
id = rb_to_id(var);
|
entry = rb_global_entry(rb_to_id(var));
|
||||||
if (!st_lookup(rb_global_tbl, id, &entry)) {
|
if (OBJ_TAINTED(cmd)) {
|
||||||
rb_name_error(id, "undefined global variable %s", rb_id2name(id));
|
rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
|
||||||
}
|
}
|
||||||
trace = ALLOC(struct trace_var);
|
trace = ALLOC(struct trace_var);
|
||||||
trace->next = entry->var->trace;
|
trace->next = entry->var->trace;
|
||||||
@ -1419,17 +1419,28 @@ rb_cvar_singleton(obj)
|
|||||||
return CLASS_OF(obj);
|
return CLASS_OF(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static VALUE
|
||||||
cvar_override_check(id, a, b)
|
original_module(c)
|
||||||
VALUE a, b;
|
VALUE c;
|
||||||
{
|
{
|
||||||
|
if (TYPE(c) == T_ICLASS)
|
||||||
|
return RBASIC(c)->klass;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cvar_override_check(id, a)
|
||||||
|
VALUE a;
|
||||||
|
{
|
||||||
|
VALUE base = original_module(a);
|
||||||
|
|
||||||
a = RCLASS(a)->super;
|
a = RCLASS(a)->super;
|
||||||
while (a) {
|
while (a) {
|
||||||
if (RCLASS(a)->iv_tbl) {
|
if (RCLASS(a)->iv_tbl) {
|
||||||
if (st_lookup(RCLASS(a)->iv_tbl,id,0)) {
|
if (st_lookup(RCLASS(a)->iv_tbl,id,0)) {
|
||||||
rb_warning("class variable %s of %s is overridden by %s",
|
rb_warning("class variable %s of %s is overridden by %s",
|
||||||
rb_id2name(id), rb_class2name(a),
|
rb_id2name(id), rb_class2name(original_module(a)),
|
||||||
rb_class2name(b));
|
rb_class2name(base));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a = RCLASS(a)->super;
|
a = RCLASS(a)->super;
|
||||||
@ -1452,7 +1463,7 @@ rb_cvar_set(klass, id, val)
|
|||||||
rb_raise(rb_eSecurityError, "Insecure: can't modify class variable");
|
rb_raise(rb_eSecurityError, "Insecure: can't modify class variable");
|
||||||
st_insert(RCLASS(tmp)->iv_tbl,id,val);
|
st_insert(RCLASS(tmp)->iv_tbl,id,val);
|
||||||
if (ruby_verbose) {
|
if (ruby_verbose) {
|
||||||
cvar_override_check(id, tmp, klass);
|
cvar_override_check(id, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1482,7 +1493,7 @@ rb_cvar_declare(klass, id, val)
|
|||||||
}
|
}
|
||||||
st_insert(RCLASS(tmp)->iv_tbl,id,val);
|
st_insert(RCLASS(tmp)->iv_tbl,id,val);
|
||||||
if (ruby_verbose) {
|
if (ruby_verbose) {
|
||||||
cvar_override_check(id, tmp, klass);
|
cvar_override_check(id, tmp);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1505,7 +1516,7 @@ rb_cvar_get(klass, id)
|
|||||||
if (RCLASS(tmp)->iv_tbl) {
|
if (RCLASS(tmp)->iv_tbl) {
|
||||||
if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
|
if (st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
|
||||||
if (ruby_verbose) {
|
if (ruby_verbose) {
|
||||||
cvar_override_check(id, tmp, klass);
|
cvar_override_check(id, tmp);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user