mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* string.c (str_gsub): reentrant check. [ruby-dev:24432]
* backport all SEGV bug fixes from CVS HEAD. [ruby-dev:24536] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7090 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
959077c8e0
commit
2ec51ee0d5
12 changed files with 272 additions and 110 deletions
76
ChangeLog
76
ChangeLog
|
@ -1,3 +1,29 @@
|
|||
Wed Oct 20 19:45:13 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* string.c (str_gsub): reentrant check. [ruby-dev:24432]
|
||||
|
||||
* backport all SEGV bug fixes from CVS HEAD. [ruby-dev:24536]
|
||||
|
||||
Wed Oct 20 04:17:55 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/dbm/dbm.c (fdbm_delete_if): should check if deleting element
|
||||
is a string. [ruby-dev:24490]
|
||||
|
||||
* ext/sdbm/init.c (fsdbm_delete_if): ditto.
|
||||
|
||||
Wed Oct 20 01:37:18 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_times): Array#* should return an instance of
|
||||
the class of right operand. [ruby-dev:24526]
|
||||
|
||||
* ext/zlib/zlib.c (zstream_detach_buffer): should not expose
|
||||
class-less object to Ruby world. [ruby-dev:24530]
|
||||
|
||||
* eval.c (proc_dup): provide Proc#dup as well. [ruby-talk:116915]
|
||||
|
||||
* eval.c (ruby_exec): stack marking position may be higher than
|
||||
expected. thanks to Guy Decoux. [ruby-core:03527]
|
||||
|
||||
Tue Oct 19 22:43:12 2004 Dave Thomas <dave@pragprog.com>
|
||||
|
||||
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_attr): If
|
||||
|
@ -36,6 +62,8 @@ Tue Oct 19 08:46:57 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|||
|
||||
* string.c (rb_str_upto): method result must be checked. [ruby-dev:24504]
|
||||
|
||||
* eval.c (error_print): ditto. [ruby-dev:24519]
|
||||
|
||||
Mon Oct 18 23:37:05 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* marshal.c (r_object0): check inheritance by the internal function.
|
||||
|
@ -6025,6 +6053,11 @@ Mon Oct 20 09:45:12 2003 NAKAMURA Usaku <usa@ruby-lang.org>
|
|||
|
||||
* lib/debug.rb (debug_command): remove debug print.
|
||||
|
||||
Wed Oct 20 00:25:41 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* eval.c (search_required): required name must not be changed before
|
||||
loading. [ruby-dev:24492]
|
||||
|
||||
Sun Oct 19 13:12:30 2003 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* lib/pathname.rb (foreachline, dir_foreach): add obsolete warning.
|
||||
|
@ -7008,6 +7041,35 @@ Thu Oct 2 00:21:11 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
|||
* test/soap/calc/*: give httpd config param "CGIInterpreter".
|
||||
"/usr/bin/env ruby" thing does not work under non-Unix boxes.
|
||||
|
||||
Sat Oct 2 00:42:20 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* marshal.c (r_byte): retrieve pointer from string value for each
|
||||
time. [ruby-dev:24404]
|
||||
|
||||
* marshal.c (r_bytes0): ditto.
|
||||
|
||||
* enum.c (sort_by_i): re-entrance check added. [ruby-dev:24399]
|
||||
|
||||
* io.c (io_read): should freeze all reading buffer.
|
||||
[ruby-dev:24400]
|
||||
|
||||
* string.c (rb_str_sum): should use bignums when bits is greater
|
||||
than or equals to sizeof(long)*CHAR_BITS. [ruby-dev:24395]
|
||||
|
||||
* eval.c (specific_eval): defer pointer retrieval to prevent
|
||||
unsafe sourcefile string modification. [ruby-dev:24382]
|
||||
|
||||
* string.c (rb_str_sum): wrong cast caused wrong result.
|
||||
[ruby-dev:24385]
|
||||
|
||||
* enum.c (enum_sort_by): hide temporary array from
|
||||
ObjectSpace.each_object. [ruby-dev:24386]
|
||||
|
||||
* string.c (rb_str_sum): check was done with false pointer.
|
||||
[ruby-dev:24383]
|
||||
|
||||
* string.c (rb_str_sum): string may be altered. [ruby-dev:24381]
|
||||
|
||||
Thu Oct 2 00:25:21 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* signal.c (ruby_signal_name): adjust to the prototype.
|
||||
|
@ -7171,6 +7233,20 @@ Sat Sep 27 09:44:18 2003 Minero Aoki <aamine@loveruby.net>
|
|||
|
||||
* test/fileutils/test_nowrite.rb: ditto.
|
||||
|
||||
Mon Sep 27 09:14:03 2004 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* array.c (rb_ary_delete): comparison may change the capacity.
|
||||
[ruby-dev:24348]
|
||||
|
||||
* array.c (rb_ary_fill): fill should honor length argument.
|
||||
[ruby-dev:24346]
|
||||
|
||||
* array.c (rb_ary_replace): should not use ptr from shared array.
|
||||
[ruby-dev:24345]
|
||||
|
||||
* ext/socket/socket.c (s_accept): don't retry for EWOULDBLOCK.
|
||||
[ruby-talk:113807]
|
||||
|
||||
Sat Sep 27 04:57:07 2003 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
||||
|
||||
* test/ruby/test_file.rb: new file. only asserts unlink-before-close
|
||||
|
|
22
array.c
22
array.c
|
@ -1855,8 +1855,7 @@ rb_ary_delete(ary, item)
|
|||
|
||||
if (rb_equal(e, item)) continue;
|
||||
if (i1 != i2) {
|
||||
if (RARRAY(ary)->len < i2) break;
|
||||
RARRAY(ary)->ptr[i2] = e;
|
||||
rb_ary_store(ary, i2, e);
|
||||
}
|
||||
i2++;
|
||||
}
|
||||
|
@ -1867,12 +1866,13 @@ rb_ary_delete(ary, item)
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
if (RARRAY(ary)->len > i2)
|
||||
if (RARRAY(ary)->len > i2) {
|
||||
RARRAY(ary)->len = i2;
|
||||
if (i2 * 2 < RARRAY(ary)->aux.capa &&
|
||||
if (i2 * 2 < RARRAY(ary)->aux.capa &&
|
||||
RARRAY(ary)->aux.capa > ARY_DEFAULT_SIZE) {
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2);
|
||||
RARRAY(ary)->aux.capa = i2 * 2;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, i2 * 2);
|
||||
RARRAY(ary)->aux.capa = i2 * 2;
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
|
@ -2170,8 +2170,8 @@ rb_ary_replace(copy, orig)
|
|||
shared = ary_make_shared(orig);
|
||||
if (RARRAY(copy)->ptr && !FL_TEST(copy, ELTS_SHARED))
|
||||
free(RARRAY(copy)->ptr);
|
||||
RARRAY(copy)->ptr = RARRAY(shared)->ptr;
|
||||
RARRAY(copy)->len = RARRAY(shared)->len;
|
||||
RARRAY(copy)->ptr = RARRAY(orig)->ptr;
|
||||
RARRAY(copy)->len = RARRAY(orig)->len;
|
||||
RARRAY(copy)->aux.shared = shared;
|
||||
FL_SET(copy, ELTS_SHARED);
|
||||
|
||||
|
@ -2280,7 +2280,7 @@ rb_ary_fill(argc, argv, ary)
|
|||
VALUE v;
|
||||
long i;
|
||||
|
||||
for (i=beg; i<RARRAY(ary)->len; i++) {
|
||||
for (i=beg; i<end; i++) {
|
||||
v = rb_yield(LONG2NUM(i));
|
||||
if (i>=RARRAY(ary)->len) break;
|
||||
RARRAY(ary)->ptr[i] = v;
|
||||
|
@ -2372,7 +2372,7 @@ rb_ary_times(ary, times)
|
|||
}
|
||||
|
||||
len = NUM2LONG(times);
|
||||
if (len == 0) return rb_ary_new2(0);
|
||||
if (len == 0) return ary_new(rb_obj_class(ary), 0);
|
||||
if (len < 0) {
|
||||
rb_raise(rb_eArgError, "negative argument");
|
||||
}
|
||||
|
@ -2890,7 +2890,7 @@ flatten(ary, idx, ary2, memo)
|
|||
while (i < lim) {
|
||||
VALUE tmp;
|
||||
|
||||
tmp = rb_check_array_type(RARRAY(ary)->ptr[i]);
|
||||
tmp = rb_check_array_type(rb_ary_elt(ary, i));
|
||||
if (!NIL_P(tmp)) {
|
||||
n = flatten(ary, i, tmp, memo);
|
||||
i += n; lim += n;
|
||||
|
|
7
enum.c
7
enum.c
|
@ -389,6 +389,9 @@ sort_by_i(i, ary)
|
|||
NODE *memo;
|
||||
|
||||
v = rb_yield(i);
|
||||
if (RBASIC(ary)->klass) {
|
||||
rb_raise(rb_eRuntimeError, "sort_by reentered");
|
||||
}
|
||||
memo = rb_node_newnode(NODE_MEMO, v, i, 0);
|
||||
rb_ary_push(ary, (VALUE)memo);
|
||||
return Qnil;
|
||||
|
@ -486,6 +489,7 @@ enum_sort_by(obj)
|
|||
else {
|
||||
ary = rb_ary_new();
|
||||
}
|
||||
RBASIC(ary)->klass = 0;
|
||||
rb_iterate(rb_each, obj, sort_by_i, ary);
|
||||
if (RARRAY(ary)->len > 1) {
|
||||
qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), sort_by_cmp, 0);
|
||||
|
@ -493,6 +497,7 @@ enum_sort_by(obj)
|
|||
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||
RARRAY(ary)->ptr[i] = RNODE(RARRAY(ary)->ptr[i])->u2.value;
|
||||
}
|
||||
RBASIC(ary)->klass = rb_cArray;
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
@ -879,7 +884,7 @@ enum_zip(argc, argv, obj)
|
|||
NODE *memo;
|
||||
|
||||
for (i=0; i<argc; i++) {
|
||||
argv[i] = rb_convert_type(argv[i], T_ARRAY, "Array", "to_ary");
|
||||
argv[i] = rb_convert_type(argv[i], T_ARRAY, "Array", "to_a");
|
||||
}
|
||||
result = rb_block_given_p() ? Qnil : rb_ary_new();
|
||||
memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), 0);
|
||||
|
|
61
eval.c
61
eval.c
|
@ -1127,7 +1127,8 @@ error_print()
|
|||
|
||||
eclass = CLASS_OF(ruby_errinfo);
|
||||
if (EXEC_TAG() == 0) {
|
||||
e = rb_obj_as_string(ruby_errinfo);
|
||||
e = rb_funcall(ruby_errinfo, rb_intern("message"), 0, 0);
|
||||
StringValue(e);
|
||||
einfo = RSTRING(e)->ptr;
|
||||
elen = RSTRING(e)->len;
|
||||
}
|
||||
|
@ -1441,13 +1442,11 @@ ruby_cleanup(ex)
|
|||
return ex;
|
||||
}
|
||||
|
||||
int
|
||||
ruby_exec()
|
||||
static int
|
||||
ruby_exec_internal()
|
||||
{
|
||||
int state;
|
||||
volatile NODE *tmp;
|
||||
|
||||
Init_stack((void*)&tmp);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
PUSH_ITER(ITER_NOT);
|
||||
/* default visibility is private at toplevel */
|
||||
|
@ -1467,6 +1466,15 @@ ruby_stop(ex)
|
|||
exit(ruby_cleanup(ex));
|
||||
}
|
||||
|
||||
int
|
||||
ruby_exec()
|
||||
{
|
||||
volatile NODE *tmp;
|
||||
|
||||
Init_stack((void*)&tmp);
|
||||
return ruby_exec_internal();
|
||||
}
|
||||
|
||||
void
|
||||
ruby_run()
|
||||
{
|
||||
|
@ -5472,6 +5480,7 @@ rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
|
|||
if ((++tick & 0xff) == 0) {
|
||||
CHECK_INTS; /* better than nothing */
|
||||
stack_check();
|
||||
rb_gc_finalize_deferred();
|
||||
}
|
||||
PUSH_ITER(itr);
|
||||
PUSH_FRAME();
|
||||
|
@ -7800,6 +7809,21 @@ blk_copy_prev(block)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
blk_dup(dup, orig)
|
||||
struct BLOCK *dup, *orig;
|
||||
{
|
||||
MEMCPY(dup, orig, struct BLOCK, 1);
|
||||
frame_dup(&dup->frame);
|
||||
|
||||
if (dup->iter) {
|
||||
blk_copy_prev(dup);
|
||||
}
|
||||
else {
|
||||
dup->prev = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MISSING: documentation
|
||||
*/
|
||||
|
@ -7814,15 +7838,25 @@ proc_clone(self)
|
|||
Data_Get_Struct(self, struct BLOCK, orig);
|
||||
bind = Data_Make_Struct(rb_obj_class(self),struct BLOCK,blk_mark,blk_free,data);
|
||||
CLONESETUP(bind, self);
|
||||
MEMCPY(data, orig, struct BLOCK, 1);
|
||||
frame_dup(&data->frame);
|
||||
blk_dup(data, orig);
|
||||
|
||||
if (data->iter) {
|
||||
blk_copy_prev(data);
|
||||
}
|
||||
else {
|
||||
data->prev = 0;
|
||||
}
|
||||
return bind;
|
||||
}
|
||||
|
||||
/*
|
||||
* MISSING: documentation
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
proc_dup(self)
|
||||
VALUE self;
|
||||
{
|
||||
struct BLOCK *orig, *data;
|
||||
VALUE bind;
|
||||
|
||||
Data_Get_Struct(self, struct BLOCK, orig);
|
||||
bind = Data_Make_Struct(rb_obj_class(self),struct BLOCK,blk_mark,blk_free,data);
|
||||
blk_dup(data, orig);
|
||||
|
||||
return bind;
|
||||
}
|
||||
|
@ -9159,6 +9193,7 @@ Init_Proc()
|
|||
rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
|
||||
|
||||
rb_define_method(rb_cProc, "clone", proc_clone, 0);
|
||||
rb_define_method(rb_cProc, "dup", proc_dup, 0);
|
||||
rb_define_method(rb_cProc, "call", proc_call, -2);
|
||||
rb_define_method(rb_cProc, "arity", proc_arity, 0);
|
||||
rb_define_method(rb_cProc, "[]", proc_call, -2);
|
||||
|
|
|
@ -388,6 +388,7 @@ fdbm_delete_if(obj)
|
|||
|
||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||
keystr = RARRAY(ary)->ptr[i];
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
if (dbm_delete(dbm, key)) {
|
||||
|
|
|
@ -366,6 +366,7 @@ fsdbm_delete_if(obj)
|
|||
|
||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||
keystr = RARRAY(ary)->ptr[i];
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
if (sdbm_delete(dbm, key)) {
|
||||
|
|
|
@ -275,6 +275,8 @@ bsock_setsockopt(sock, lev, optname, val)
|
|||
rb_secure(2);
|
||||
level = NUM2INT(lev);
|
||||
option = NUM2INT(optname);
|
||||
GetOpenFile(sock, fptr);
|
||||
|
||||
switch (TYPE(val)) {
|
||||
case T_FIXNUM:
|
||||
i = FIX2INT(val);
|
||||
|
@ -294,7 +296,6 @@ bsock_setsockopt(sock, lev, optname, val)
|
|||
break;
|
||||
}
|
||||
|
||||
GetOpenFile(sock, fptr);
|
||||
if (setsockopt(fileno(fptr->f), level, option, v, vlen) < 0)
|
||||
rb_sys_fail(fptr->path);
|
||||
|
||||
|
@ -2095,7 +2096,7 @@ sock_s_gethostbyaddr(argc, argv)
|
|||
t = AF_INET6;
|
||||
}
|
||||
#endif
|
||||
h = gethostbyaddr((char*)RSTRING(addr)->ptr, RSTRING(addr)->len, t);
|
||||
h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, t);
|
||||
if (h == NULL) {
|
||||
#ifdef HAVE_HSTRERROR
|
||||
extern int h_errno;
|
||||
|
@ -2136,14 +2137,15 @@ sock_s_getservbyaname(argc, argv)
|
|||
|
||||
rb_scan_args(argc, argv, "11", &service, &proto);
|
||||
if (NIL_P(proto)) proto = rb_str_new2("tcp");
|
||||
else StringValue(proto);
|
||||
StringValue(service);
|
||||
StringValue(proto);
|
||||
|
||||
sp = getservbyname((char*)RSTRING(service)->ptr, RSTRING(proto)->ptr);
|
||||
sp = getservbyname(StringValueCStr(service), StringValueCStr(proto));
|
||||
if (sp) {
|
||||
port = ntohs(sp->s_port);
|
||||
}
|
||||
else {
|
||||
char *s = StringValuePtr(service);
|
||||
char *s = RSTRING(service)->ptr;
|
||||
char *end;
|
||||
|
||||
port = strtoul(s, &end, 0);
|
||||
|
|
|
@ -530,6 +530,7 @@ zstream_detach_buffer(z)
|
|||
z->buf_filled = 0;
|
||||
z->stream.next_out = 0;
|
||||
z->stream.avail_out = 0;
|
||||
RBASIC(dst)->klass = rb_cString;
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
|
176
gc.c
176
gc.c
|
@ -39,13 +39,21 @@
|
|||
*/
|
||||
#define __libc_ia64_register_backing_store_base (4ULL<<61)
|
||||
#else
|
||||
#ifdef HAVE_UNWIND_H
|
||||
#include <unwind.h>
|
||||
#else
|
||||
#pragma weak __libc_ia64_register_backing_store_base
|
||||
extern unsigned long __libc_ia64_register_backing_store_base;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
void re_free_registers _((struct re_registers*));
|
||||
void rb_io_fptr_finalize _((struct OpenFile*));
|
||||
int rb_io_fptr_finalize _((struct OpenFile*));
|
||||
|
||||
#if !defined(setjmp) && defined(HAVE__SETJMP)
|
||||
#define setjmp(env) _setjmp(env)
|
||||
|
@ -84,6 +92,7 @@ static unsigned long malloc_increase = 0;
|
|||
static unsigned long malloc_limit = GC_MALLOC_LIMIT;
|
||||
static void run_final();
|
||||
static VALUE nomem_error;
|
||||
static void garbage_collect();
|
||||
|
||||
void
|
||||
rb_memerror()
|
||||
|
@ -111,11 +120,11 @@ ruby_xmalloc(size)
|
|||
malloc_increase += size;
|
||||
|
||||
if (malloc_increase > malloc_limit) {
|
||||
rb_gc();
|
||||
garbage_collect();
|
||||
}
|
||||
RUBY_CRITICAL(mem = malloc(size));
|
||||
if (!mem) {
|
||||
rb_gc();
|
||||
garbage_collect();
|
||||
RUBY_CRITICAL(mem = malloc(size));
|
||||
if (!mem) {
|
||||
rb_memerror();
|
||||
|
@ -152,7 +161,7 @@ ruby_xrealloc(ptr, size)
|
|||
malloc_increase += size;
|
||||
RUBY_CRITICAL(mem = realloc(ptr, size));
|
||||
if (!mem) {
|
||||
rb_gc();
|
||||
garbage_collect();
|
||||
RUBY_CRITICAL(mem = realloc(ptr, size));
|
||||
if (!mem) {
|
||||
rb_memerror();
|
||||
|
@ -170,7 +179,6 @@ ruby_xfree(x)
|
|||
RUBY_CRITICAL(free(x));
|
||||
}
|
||||
|
||||
extern int ruby_in_compile;
|
||||
static int dont_gc;
|
||||
static int during_gc;
|
||||
static int need_call_final = 0;
|
||||
|
@ -373,7 +381,7 @@ rb_newobj()
|
|||
{
|
||||
VALUE obj;
|
||||
|
||||
if (!freelist) rb_gc();
|
||||
if (!freelist) garbage_collect();
|
||||
|
||||
obj = (VALUE)freelist;
|
||||
freelist = freelist->as.free.next;
|
||||
|
@ -405,21 +413,22 @@ rb_data_object_alloc(klass, datap, dmark, dfree)
|
|||
extern st_table *rb_class_tbl;
|
||||
VALUE *rb_gc_stack_start = 0;
|
||||
|
||||
#ifdef DJGPP
|
||||
/* set stack size (http://www.delorie.com/djgpp/v2faq/faq15_9.html) */
|
||||
unsigned int _stklen = 0x180000; /* 1.5 kB */
|
||||
#endif
|
||||
|
||||
#if defined(DJGPP) || defined(_WIN32_WCE)
|
||||
static unsigned int STACK_LEVEL_MAX = 65535;
|
||||
#else
|
||||
#ifdef __human68k__
|
||||
extern unsigned int _stacksize;
|
||||
#elif defined(__human68k__)
|
||||
unsigned int _stacksize = 262144;
|
||||
# define STACK_LEVEL_MAX (_stacksize - 4096)
|
||||
# undef HAVE_GETRLIMIT
|
||||
#else
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
#elif defined(HAVE_GETRLIMIT)
|
||||
static unsigned int STACK_LEVEL_MAX = 655300;
|
||||
#else
|
||||
# define STACK_LEVEL_MAX 655300
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef C_ALLOCA
|
||||
# define SET_STACK_END VALUE stack_end; alloca(0);
|
||||
|
@ -982,27 +991,49 @@ gc_mark_children(ptr, lev)
|
|||
|
||||
static void obj_free _((VALUE));
|
||||
|
||||
static void
|
||||
finalize_list(p)
|
||||
RVALUE *p;
|
||||
{
|
||||
while (p) {
|
||||
RVALUE *tmp = p->as.free.next;
|
||||
run_final((VALUE)p);
|
||||
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
||||
p->as.free.flags = 0;
|
||||
p->as.free.next = freelist;
|
||||
freelist = p;
|
||||
}
|
||||
p = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_unused_heaps()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = j = 1; j < heaps_used; i++) {
|
||||
if (heaps[i].limit == 0) {
|
||||
free(heaps[i].slot);
|
||||
heaps_used--;
|
||||
}
|
||||
else {
|
||||
if (i != j) {
|
||||
heaps[j] = heaps[i];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gc_sweep()
|
||||
{
|
||||
RVALUE *p, *pend, *final_list;
|
||||
int freed = 0;
|
||||
int i, j;
|
||||
int i;
|
||||
unsigned long live = 0;
|
||||
|
||||
if (ruby_in_compile && ruby_parser_stack_on_heap()) {
|
||||
/* should not reclaim nodes during compilation
|
||||
if yacc's semantic stack is not allocated on machine stack */
|
||||
for (i = 0; i < heaps_used; i++) {
|
||||
p = heaps[i].slot; pend = p + heaps[i].limit;
|
||||
while (p < pend) {
|
||||
if (!(p->as.basic.flags&FL_MARK) && BUILTIN_TYPE(p) == T_NODE)
|
||||
gc_mark((VALUE)p, 0);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mark_source_filename(ruby_sourcefile);
|
||||
st_foreach(source_filenames, sweep_source_filename, 0);
|
||||
|
||||
|
@ -1067,35 +1098,10 @@ gc_sweep()
|
|||
|
||||
/* clear finalization list */
|
||||
if (final_list) {
|
||||
RVALUE *tmp;
|
||||
|
||||
if (rb_prohibit_interrupt || ruby_in_compile) {
|
||||
deferred_final_list = final_list;
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = final_list; p; p = tmp) {
|
||||
tmp = p->as.free.next;
|
||||
run_final((VALUE)p);
|
||||
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
||||
p->as.free.flags = 0;
|
||||
p->as.free.next = freelist;
|
||||
freelist = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = j = 1; j < heaps_used; i++) {
|
||||
if (heaps[i].limit == 0) {
|
||||
free(heaps[i].slot);
|
||||
heaps_used--;
|
||||
}
|
||||
else {
|
||||
if (i != j) {
|
||||
heaps[j] = heaps[i];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
deferred_final_list = final_list;
|
||||
return;
|
||||
}
|
||||
free_unused_heaps();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1281,8 +1287,8 @@ int rb_setjmp (rb_jmp_buf);
|
|||
#endif /* __human68k__ or DJGPP */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
void
|
||||
rb_gc()
|
||||
static void
|
||||
garbage_collect()
|
||||
{
|
||||
struct gc_list *list;
|
||||
struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug?? */
|
||||
|
@ -1342,14 +1348,21 @@ rb_gc()
|
|||
{
|
||||
ucontext_t ctx;
|
||||
VALUE *top, *bot;
|
||||
#ifdef HAVE_UNWIND_H
|
||||
_Unwind_Context *unwctx = _UNW_createContextForSelf();
|
||||
#endif
|
||||
|
||||
getcontext(&ctx);
|
||||
mark_locations_array((VALUE*)&ctx.uc_mcontext,
|
||||
((size_t)(sizeof(VALUE)-1 + sizeof ctx.uc_mcontext)/sizeof(VALUE)));
|
||||
bot = (VALUE*)__libc_ia64_register_backing_store_base;
|
||||
#if defined(__FreeBSD__)
|
||||
top = (VALUE*)ctx.uc_mcontext.mc_special.bspstore;
|
||||
#ifdef HAVE_UNWIND_H
|
||||
_UNW_currentContext(unwctx);
|
||||
bot = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSP);
|
||||
top = (VALUE*)(long)_UNW_getAR(unwctx, _UNW_AR_BSPSTORE);
|
||||
_UNW_destroyContext(unwctx);
|
||||
#else
|
||||
top = (VALUE*)ctx.uc_mcontext.sc_ar_bsp;
|
||||
bot = (VALUE*)__libc_ia64_register_backing_store_base;
|
||||
top = (VALUE*)ctx.uc_mcontext.IA64_BSPSTORE;
|
||||
#endif
|
||||
rb_gc_mark_locations(bot, top);
|
||||
}
|
||||
|
@ -1387,6 +1400,13 @@ rb_gc()
|
|||
gc_sweep();
|
||||
}
|
||||
|
||||
void
|
||||
rb_gc()
|
||||
{
|
||||
garbage_collect();
|
||||
rb_gc_finalize_deferred();
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* GC.start => nil
|
||||
|
@ -1408,9 +1428,16 @@ void
|
|||
Init_stack(addr)
|
||||
VALUE *addr;
|
||||
{
|
||||
#if defined(__human68k__)
|
||||
extern void *_SEND;
|
||||
rb_gc_stack_start = _SEND;
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
memset(&m, 0, sizeof(m));
|
||||
VirtualQuery(&m, &m, sizeof(m));
|
||||
rb_gc_stack_start =
|
||||
STACK_UPPER((VALUE *)&m, (VALUE *)m.BaseAddress,
|
||||
(VALUE *)((char *)m.BaseAddress + m.RegionSize) - 1);
|
||||
#elif defined(STACK_END_ADDRESS)
|
||||
extern void *STACK_END_ADDRESS;
|
||||
rb_gc_stack_start = STACK_END_ADDRESS;
|
||||
#else
|
||||
if (!addr) addr = (VALUE *)&addr;
|
||||
STACK_UPPER(&addr, addr, ++addr);
|
||||
|
@ -1764,6 +1791,18 @@ run_final(obj)
|
|||
rb_thread_critical = critical_save;
|
||||
}
|
||||
|
||||
void
|
||||
rb_gc_finalize_deferred()
|
||||
{
|
||||
RVALUE *p = deferred_final_list;
|
||||
|
||||
deferred_final_list = 0;
|
||||
if (p) {
|
||||
finalize_list(p);
|
||||
free_unused_heaps();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rb_gc_call_finalizer_at_exit()
|
||||
{
|
||||
|
@ -1772,14 +1811,7 @@ rb_gc_call_finalizer_at_exit()
|
|||
|
||||
/* run finalizers */
|
||||
if (need_call_final) {
|
||||
if (deferred_final_list) {
|
||||
p = deferred_final_list;
|
||||
while (p) {
|
||||
RVALUE *tmp = p;
|
||||
p = p->as.free.next;
|
||||
run_final((VALUE)tmp);
|
||||
}
|
||||
}
|
||||
finalize_list(deferred_final_list);
|
||||
for (i = 0; i < heaps_used; i++) {
|
||||
p = heaps[i].slot; pend = p + heaps[i].limit;
|
||||
while (p < pend) {
|
||||
|
|
1
intern.h
1
intern.h
|
@ -240,6 +240,7 @@ void rb_gc_mark _((VALUE));
|
|||
void rb_gc_force_recycle _((VALUE));
|
||||
void rb_gc _((void));
|
||||
void rb_gc_copy_finalizer _((VALUE,VALUE));
|
||||
void rb_gc_finalize_deferred _((void));
|
||||
void rb_gc_call_finalizer_at_exit _((void));
|
||||
VALUE rb_gc_enable _((void));
|
||||
VALUE rb_gc_disable _((void));
|
||||
|
|
|
@ -76,10 +76,14 @@ class SimpleDelegator<Delegator
|
|||
@_sd_obj = obj
|
||||
end
|
||||
|
||||
def initialize_copy(obj)
|
||||
def clone(obj)
|
||||
super
|
||||
__setobj__(obj.__getobj__.clone)
|
||||
end
|
||||
def dup(obj)
|
||||
super
|
||||
__setobj__(obj.__getobj__.dup)
|
||||
end
|
||||
end
|
||||
|
||||
# backward compatibility ^_^;;;
|
||||
|
@ -108,9 +112,13 @@ def DelegateClass(superclass)
|
|||
def __setobj__(obj)
|
||||
@_dc_obj = obj
|
||||
end
|
||||
def initialize_copy(obj)
|
||||
def clone(obj)
|
||||
super
|
||||
__setobj__(obj.__getobj__.clone)
|
||||
__setobj__(obj.__getobj__.clone)
|
||||
end
|
||||
def dup(obj)
|
||||
super
|
||||
__setobj__(obj.__getobj__.dup)
|
||||
end
|
||||
}
|
||||
for method in methods
|
||||
|
|
10
string.c
10
string.c
|
@ -2037,6 +2037,9 @@ str_gsub(argc, argv, str, bang)
|
|||
if (iter) {
|
||||
rb_match_busy(match);
|
||||
val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
|
||||
if (RSTRING(str)->ptr == buf) {
|
||||
rb_raise(rb_eRuntimeError, "gsub reentered");
|
||||
}
|
||||
rb_backref_set(match);
|
||||
}
|
||||
else {
|
||||
|
@ -4297,7 +4300,7 @@ rb_str_crypt(str, salt)
|
|||
{
|
||||
extern char *crypt();
|
||||
VALUE result;
|
||||
char *s, *cr;
|
||||
char *s;
|
||||
|
||||
StringValue(salt);
|
||||
if (RSTRING(salt)->len < 2)
|
||||
|
@ -4305,10 +4308,7 @@ rb_str_crypt(str, salt)
|
|||
|
||||
if (RSTRING(str)->ptr) s = RSTRING(str)->ptr;
|
||||
else s = "";
|
||||
cr = crypt(s, RSTRING(salt)->ptr);
|
||||
s = ALLOCA_N(char, strlen(cr));
|
||||
strcpy(s, cr);
|
||||
result = rb_str_new2(s);
|
||||
result = rb_str_new2(crypt(s, RSTRING(salt)->ptr));
|
||||
OBJ_INFECT(result, str);
|
||||
OBJ_INFECT(result, salt);
|
||||
return result;
|
||||
|
|
Loading…
Add table
Reference in a new issue