mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* include/ruby/ruby.h: embeds the elements of an array into its
struct RArray for # of elements <= 3. * array.c: ditto. * gc.c (gc_mark_children): following the change of struct RArray. * ext/tk/tcltklib.c (ip_ruby_cmp): ditto. * parse.y (coverage): ditto. * proc.c (curry): ditto. * .gdbinit: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19723 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									517a1c3406
								
							
						
					
					
						commit
						c86ce094e2
					
				
					 8 changed files with 365 additions and 154 deletions
				
			
		
							
								
								
									
										29
									
								
								.gdbinit
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								.gdbinit
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -104,9 +104,34 @@ define rp
 | 
			
		|||
    print (struct RRegexp *)$arg0
 | 
			
		||||
  else
 | 
			
		||||
  if ($flags & RUBY_T_MASK) == RUBY_T_ARRAY
 | 
			
		||||
    printf "T_ARRAY: len=%ld ", ((struct RArray*)$arg0)->len
 | 
			
		||||
    if ($flags & RUBY_FL_USER1)
 | 
			
		||||
      set $len = (($flags & (RUBY_FL_USER3|RUBY_FL_USER4)) >> (RUBY_FL_USHIFT+3))
 | 
			
		||||
      printf "T_ARRAY: len=%ld ", $len
 | 
			
		||||
      printf "(embed) "
 | 
			
		||||
      if ($len == 0)
 | 
			
		||||
	printf "{(empty)} "
 | 
			
		||||
      else
 | 
			
		||||
	output/x *((VALUE*)((struct RArray*)$arg0)->as.ary) @ $len
 | 
			
		||||
	printf " "
 | 
			
		||||
      end
 | 
			
		||||
    else
 | 
			
		||||
      set $len = ((struct RArray*)$arg0)->as.heap.len
 | 
			
		||||
      printf "T_ARRAY: len=%ld ", $len
 | 
			
		||||
      if ($flags & RUBY_FL_USER2)
 | 
			
		||||
	printf "(shared) shared="
 | 
			
		||||
	output/x ((struct RArray*)$arg0)->as.heap.aux.shared
 | 
			
		||||
	printf " "
 | 
			
		||||
      else
 | 
			
		||||
	printf "(ownership) capa=%ld ", ((struct RArray*)$arg0)->as.heap.aux.capa
 | 
			
		||||
      end
 | 
			
		||||
      if ($len == 0)
 | 
			
		||||
	printf "{(empty)} "
 | 
			
		||||
      else
 | 
			
		||||
	output/x *((VALUE*)((struct RArray*)$arg0)->as.heap.ptr) @ $len
 | 
			
		||||
	printf " "
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    print (struct RArray *)$arg0
 | 
			
		||||
    x/xw ((struct RArray*)$arg0)->ptr
 | 
			
		||||
  else
 | 
			
		||||
  if ($flags & RUBY_T_MASK) == RUBY_T_FIXNUM
 | 
			
		||||
    printf "T_FIXNUM: "
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,20 @@
 | 
			
		|||
Thu Oct  9 14:37:59 2008  Yuki Sonoda (Yugui)  <yugui@yugui.jp>
 | 
			
		||||
 | 
			
		||||
	* include/ruby/ruby.h: embeds the elements of an array into its 
 | 
			
		||||
	  struct RArray for # of elements <= 3. 
 | 
			
		||||
 | 
			
		||||
	* array.c: ditto.
 | 
			
		||||
 | 
			
		||||
	* gc.c (gc_mark_children): following the change of struct RArray.
 | 
			
		||||
 | 
			
		||||
	* ext/tk/tcltklib.c (ip_ruby_cmp): ditto.
 | 
			
		||||
 | 
			
		||||
	* parse.y (coverage): ditto.
 | 
			
		||||
 | 
			
		||||
	* proc.c (curry): ditto.
 | 
			
		||||
 | 
			
		||||
	* .gdbinit: ditto.
 | 
			
		||||
 | 
			
		||||
Thu Oct  9 11:29:33 2008  NARUSE, Yui  <naruse@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* encoding.c (Init_Encoding): new instance method Encoding#names,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										421
									
								
								array.c
									
										
									
									
									
								
							
							
						
						
									
										421
									
								
								array.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -14,6 +14,7 @@
 | 
			
		|||
#include "ruby/ruby.h"
 | 
			
		||||
#include "ruby/util.h"
 | 
			
		||||
#include "ruby/st.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
VALUE rb_cArray;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,17 +39,119 @@ memfill(register VALUE *mem, register long size, register VALUE val)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ARY_SHARED_P(a) FL_TEST(a, ELTS_SHARED)
 | 
			
		||||
# define ARY_SHARED_P(ary) \
 | 
			
		||||
    (assert(!FL_TEST(ary, ELTS_SHARED) || !FL_TEST(ary, RARRAY_EMBED_FLAG)), \
 | 
			
		||||
     FL_TEST(ary,ELTS_SHARED))
 | 
			
		||||
# define ARY_EMBED_P(ary) \
 | 
			
		||||
    (assert(!FL_TEST(ary, ELTS_SHARED) || !FL_TEST(ary, RARRAY_EMBED_FLAG)), \
 | 
			
		||||
     FL_TEST(ary, RARRAY_EMBED_FLAG))
 | 
			
		||||
 | 
			
		||||
#define ARY_SET_LEN(ary, n) do { \
 | 
			
		||||
    RARRAY(ary)->len = (n);\
 | 
			
		||||
} while (0) 
 | 
			
		||||
#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr)
 | 
			
		||||
#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len)
 | 
			
		||||
#define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary)
 | 
			
		||||
#define ARY_EMBED_LEN(a) \
 | 
			
		||||
    (assert(ARY_EMBED_P(a)), \
 | 
			
		||||
     (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
 | 
			
		||||
	 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)))
 | 
			
		||||
 | 
			
		||||
#define ARY_CAPA(ary) RARRAY(ary)->aux.capa
 | 
			
		||||
#define RESIZE_CAPA(ary,capacity) do {\
 | 
			
		||||
    REALLOC_N(RARRAY(ary)->ptr, VALUE, (capacity));\
 | 
			
		||||
    RARRAY(ary)->aux.capa = (capacity);\
 | 
			
		||||
#define ARY_OWNS_HEAP_P(a) (!FL_TEST(a, ELTS_SHARED|RARRAY_EMBED_FLAG))
 | 
			
		||||
#define FL_SET_EMBED(a) do { \
 | 
			
		||||
    assert(!ARY_SHARED_P(a)); \
 | 
			
		||||
    assert(!OBJ_FROZEN(a)); \
 | 
			
		||||
    FL_SET(a, RARRAY_EMBED_FLAG); \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define FL_UNSET_EMBED(ary) FL_UNSET(ary, RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK)
 | 
			
		||||
#define FL_SET_SHARED(ary) do { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    FL_SET(ary, ELTS_SHARED); \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define FL_UNSET_SHARED(ary) FL_UNSET(ary, ELTS_SHARED)
 | 
			
		||||
 | 
			
		||||
#define ARY_SET_PTR(ary, p) do { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); \
 | 
			
		||||
    RARRAY(ary)->as.heap.ptr = (p); \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define ARY_SET_EMBED_LEN(ary, n) do { \
 | 
			
		||||
    long tmp_n = n; \
 | 
			
		||||
    assert(ARY_EMBED_P(ary)); \
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); \
 | 
			
		||||
    RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \
 | 
			
		||||
    RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define ARY_SET_HEAP_LEN(ary, n) do { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    RARRAY(ary)->as.heap.len = n; \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define ARY_SET_LEN(ary, n) do { \
 | 
			
		||||
    if (ARY_EMBED_P(ary)) { \
 | 
			
		||||
        ARY_SET_EMBED_LEN(ary, n); \
 | 
			
		||||
    } \
 | 
			
		||||
    else { \
 | 
			
		||||
        ARY_SET_HEAP_LEN(ary, n); \
 | 
			
		||||
    } \
 | 
			
		||||
    assert(RARRAY_LEN(ary) == n); \
 | 
			
		||||
} while (0) 
 | 
			
		||||
#define ARY_INCREASE_PTR(ary, n) do  { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); \
 | 
			
		||||
    RARRAY(ary)->as.heap.ptr += n; \
 | 
			
		||||
} while (0)
 | 
			
		||||
#define ARY_INCREASE_LEN(ary, n) do  { \
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); \
 | 
			
		||||
    if (ARY_EMBED_P(ary)) { \
 | 
			
		||||
        ARY_SET_EMBED_LEN(ary, RARRAY_LEN(ary)+n); \
 | 
			
		||||
    } \
 | 
			
		||||
    else { \
 | 
			
		||||
        RARRAY(ary)->as.heap.len += n; \
 | 
			
		||||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? RARRAY_EMBED_LEN_MAX : RARRAY(ary)->as.heap.aux.capa)
 | 
			
		||||
#define ARY_SET_CAPA(ary, n) do { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    assert(!ARY_SHARED_P(ary)); \
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); \
 | 
			
		||||
    RARRAY(ary)->as.heap.aux.capa = (n); \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define ARY_SHARED(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared)
 | 
			
		||||
#define ARY_SET_SHARED(ary, value) do { \
 | 
			
		||||
    assert(!ARY_EMBED_P(ary)); \
 | 
			
		||||
    assert(ARY_SHARED_P(ary)); \
 | 
			
		||||
    RARRAY(ary)->as.heap.aux.shared = (value); \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
RESIZE_CAPA(VALUE ary, long capacity)
 | 
			
		||||
{
 | 
			
		||||
    assert(!OBJ_FROZEN(ary)); 
 | 
			
		||||
    assert(!ARY_SHARED_P(ary)); 
 | 
			
		||||
    if (capacity > RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
        if (ARY_EMBED_P(ary)) {
 | 
			
		||||
            long len = ARY_EMBED_LEN(ary); 
 | 
			
		||||
            VALUE *ptr = ALLOC_N(VALUE, (capacity));
 | 
			
		||||
            MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len); 
 | 
			
		||||
            FL_UNSET_EMBED(ary); 
 | 
			
		||||
            ARY_SET_PTR(ary, ptr); 
 | 
			
		||||
            ARY_SET_HEAP_LEN(ary, len); 
 | 
			
		||||
        }
 | 
			
		||||
        else { 
 | 
			
		||||
            REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, (capacity));
 | 
			
		||||
        }
 | 
			
		||||
        ARY_SET_CAPA(ary, (capacity)); 
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        if (!ARY_EMBED_P(ary)) {
 | 
			
		||||
            long len = RARRAY_LEN(ary); 
 | 
			
		||||
            VALUE *ptr = RARRAY_PTR(ary); 
 | 
			
		||||
            MEMCPY(RARRAY(ary)->as.ary, ptr, VALUE, len); 
 | 
			
		||||
            FL_SET_EMBED(ary); 
 | 
			
		||||
            ARY_SET_LEN(ary, len); 
 | 
			
		||||
            xfree(ptr); 
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
rb_ary_modify_check(VALUE ary)
 | 
			
		||||
| 
						 | 
				
			
			@ -61,15 +164,23 @@ rb_ary_modify_check(VALUE ary)
 | 
			
		|||
static void
 | 
			
		||||
rb_ary_modify(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    VALUE *ptr;
 | 
			
		||||
 | 
			
		||||
    rb_ary_modify_check(ary);
 | 
			
		||||
    if (ARY_SHARED_P(ary)) {
 | 
			
		||||
	ptr = ALLOC_N(VALUE, RARRAY_LEN(ary));
 | 
			
		||||
	FL_UNSET(ary, ELTS_SHARED);
 | 
			
		||||
	RARRAY(ary)->aux.capa = RARRAY_LEN(ary);
 | 
			
		||||
	MEMCPY(ptr, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
 | 
			
		||||
	RARRAY(ary)->ptr = ptr;
 | 
			
		||||
        long len = RARRAY_LEN(ary);
 | 
			
		||||
        if (len <= RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
            VALUE *ptr = ARY_HEAP_PTR(ary);
 | 
			
		||||
            FL_UNSET_SHARED(ary);
 | 
			
		||||
            FL_SET_EMBED(ary);
 | 
			
		||||
            MEMCPY(ARY_EMBED_PTR(ary), ptr, VALUE, len);
 | 
			
		||||
            ARY_SET_EMBED_LEN(ary, len);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            VALUE *ptr = ALLOC_N(VALUE, len);
 | 
			
		||||
            FL_UNSET_SHARED(ary);
 | 
			
		||||
            ARY_SET_CAPA(ary, len);
 | 
			
		||||
            MEMCPY(ptr, RARRAY_PTR(ary), VALUE, len);
 | 
			
		||||
            ARY_SET_PTR(ary, ptr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -99,10 +210,8 @@ ary_alloc(VALUE klass)
 | 
			
		|||
{
 | 
			
		||||
    NEWOBJ(ary, struct RArray);
 | 
			
		||||
    OBJSETUP(ary, klass, T_ARRAY);
 | 
			
		||||
 | 
			
		||||
    ary->len = 0;
 | 
			
		||||
    ary->ptr = 0;
 | 
			
		||||
    ary->aux.capa = 0;
 | 
			
		||||
    FL_SET_EMBED((VALUE)ary);
 | 
			
		||||
    ARY_SET_EMBED_LEN((VALUE)ary, 0);
 | 
			
		||||
 | 
			
		||||
    return (VALUE)ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,9 +228,12 @@ ary_new(VALUE klass, long len)
 | 
			
		|||
	rb_raise(rb_eArgError, "array size too big");
 | 
			
		||||
    }
 | 
			
		||||
    ary = ary_alloc(klass);
 | 
			
		||||
    if (len == 0) len++;
 | 
			
		||||
    RARRAY(ary)->ptr = ALLOC_N(VALUE, len);
 | 
			
		||||
    RARRAY(ary)->aux.capa = len;
 | 
			
		||||
    if (len > RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
        FL_UNSET_EMBED(ary);
 | 
			
		||||
        ARY_SET_PTR(ary, ALLOC_N(VALUE, len));
 | 
			
		||||
        ARY_SET_CAPA(ary, len);
 | 
			
		||||
        ARY_SET_HEAP_LEN(ary, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +248,7 @@ rb_ary_new2(long len)
 | 
			
		|||
VALUE
 | 
			
		||||
rb_ary_new(void)
 | 
			
		||||
{
 | 
			
		||||
    return rb_ary_new2(ARY_DEFAULT_SIZE);
 | 
			
		||||
    return rb_ary_new2(RARRAY_EMBED_LEN_MAX);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +268,7 @@ rb_ary_new3(long n, ...)
 | 
			
		|||
    }
 | 
			
		||||
    va_end(ar);
 | 
			
		||||
 | 
			
		||||
    RARRAY(ary)->len = n;
 | 
			
		||||
    ARY_SET_LEN(ary, n);
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +280,7 @@ rb_ary_new4(long n, const VALUE *elts)
 | 
			
		|||
    ary = rb_ary_new2(n);
 | 
			
		||||
    if (n > 0 && elts) {
 | 
			
		||||
	MEMCPY(RARRAY_PTR(ary), elts, VALUE, n);
 | 
			
		||||
	RARRAY(ary)->len = n;
 | 
			
		||||
	ARY_SET_LEN(ary, n);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ary;
 | 
			
		||||
| 
						 | 
				
			
			@ -183,31 +295,48 @@ rb_ary_tmp_new(long len)
 | 
			
		|||
void
 | 
			
		||||
rb_ary_free(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    if (!ARY_SHARED_P(ary)) {
 | 
			
		||||
	xfree(RARRAY(ary)->ptr);
 | 
			
		||||
    if (ARY_OWNS_HEAP_P(ary)) {
 | 
			
		||||
	xfree(RARRAY_PTR(ary));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
ary_make_shared(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    assert(!ARY_EMBED_P(ary));
 | 
			
		||||
    if (ARY_SHARED_P(ary)) {
 | 
			
		||||
	return RARRAY(ary)->aux.shared;
 | 
			
		||||
	return ARY_SHARED(ary);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	NEWOBJ(shared, struct RArray);
 | 
			
		||||
	OBJSETUP(shared, 0, T_ARRAY);
 | 
			
		||||
        FL_UNSET_EMBED(shared);
 | 
			
		||||
 | 
			
		||||
	shared->len = RARRAY(ary)->len;
 | 
			
		||||
	shared->ptr = RARRAY(ary)->ptr;
 | 
			
		||||
	shared->aux.capa = RARRAY(ary)->aux.capa;
 | 
			
		||||
	RARRAY(ary)->aux.shared = (VALUE)shared;
 | 
			
		||||
	FL_SET(ary, ELTS_SHARED);
 | 
			
		||||
        ARY_SET_LEN((VALUE)shared, RARRAY_LEN(ary));
 | 
			
		||||
        ARY_SET_PTR((VALUE)shared, RARRAY_PTR(ary));
 | 
			
		||||
        ARY_SET_CAPA((VALUE)shared, ARY_CAPA(ary));
 | 
			
		||||
	FL_SET_SHARED(ary);
 | 
			
		||||
	ARY_SET_SHARED(ary, (VALUE)shared);
 | 
			
		||||
	OBJ_FREEZE(shared);
 | 
			
		||||
	return (VALUE)shared;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
ary_make_substitution(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    if (RARRAY_LEN(ary) <= RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
        VALUE subst = rb_ary_new2(RARRAY_LEN(ary));
 | 
			
		||||
        MEMCPY(ARY_EMBED_PTR(subst), RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
 | 
			
		||||
        ARY_SET_EMBED_LEN(subst, RARRAY_LEN(ary));
 | 
			
		||||
        return subst;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        return ary_make_shared(ary);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_assoc_new(VALUE car, VALUE cdr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -298,10 +427,12 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
 | 
			
		||||
    rb_ary_modify(ary);
 | 
			
		||||
    if (argc ==  0) {
 | 
			
		||||
	if (RARRAY_PTR(ary) && !ARY_SHARED_P(ary)) {
 | 
			
		||||
	    xfree(RARRAY(ary)->ptr);
 | 
			
		||||
	if (ARY_OWNS_HEAP_P(ary) && RARRAY_PTR(ary)) {
 | 
			
		||||
	    xfree(RARRAY_PTR(ary));
 | 
			
		||||
	}
 | 
			
		||||
	RARRAY(ary)->len = 0;
 | 
			
		||||
        FL_UNSET_SHARED(ary);
 | 
			
		||||
        FL_SET_EMBED(ary);
 | 
			
		||||
	ARY_SET_EMBED_LEN(ary, 0);
 | 
			
		||||
	if (rb_block_given_p()) {
 | 
			
		||||
	    rb_warning("given block not used");
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -333,12 +464,12 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
	}
 | 
			
		||||
	for (i=0; i<len; i++) {
 | 
			
		||||
	    rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
 | 
			
		||||
	    RARRAY(ary)->len = i + 1;
 | 
			
		||||
	    ARY_SET_LEN(ary, i + 1);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	memfill(RARRAY_PTR(ary), len, val);
 | 
			
		||||
	RARRAY(ary)->len = len;
 | 
			
		||||
	ARY_SET_LEN(ary, len);
 | 
			
		||||
    }
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -355,15 +486,11 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
static VALUE
 | 
			
		||||
rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
 | 
			
		||||
{
 | 
			
		||||
    VALUE ary = ary_alloc(klass);
 | 
			
		||||
 | 
			
		||||
    if (argc < 0) {
 | 
			
		||||
	rb_raise(rb_eArgError, "negative array size");
 | 
			
		||||
    VALUE ary = ary_new(klass, argc);
 | 
			
		||||
    if (argc > 0 && argv) {
 | 
			
		||||
        MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc);
 | 
			
		||||
        ARY_SET_LEN(ary, argc);
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY(ary)->ptr = ALLOC_N(VALUE, argc);
 | 
			
		||||
    RARRAY(ary)->aux.capa = argc;
 | 
			
		||||
    MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc);
 | 
			
		||||
    RARRAY(ary)->len = argc;
 | 
			
		||||
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -401,28 +528,41 @@ rb_ary_store(VALUE ary, long idx, VALUE val)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (idx >= RARRAY_LEN(ary)) {
 | 
			
		||||
	RARRAY(ary)->len = idx + 1;
 | 
			
		||||
	ARY_SET_LEN(ary, idx + 1);
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY_PTR(ary)[idx] = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
ary_shared_array(VALUE klass, VALUE ary)
 | 
			
		||||
ary_make_partial0(VALUE ary, long offset, long len)
 | 
			
		||||
{
 | 
			
		||||
    VALUE val = ary_alloc(klass);
 | 
			
		||||
    assert(offset >= 0);
 | 
			
		||||
    assert(len >= 0);
 | 
			
		||||
    assert(offset+len <= RARRAY_LEN(ary));
 | 
			
		||||
 | 
			
		||||
    ary_make_shared(ary);
 | 
			
		||||
    RARRAY(val)->ptr = RARRAY(ary)->ptr;
 | 
			
		||||
    RARRAY(val)->len = RARRAY(ary)->len;
 | 
			
		||||
    RARRAY(val)->aux.shared = RARRAY(ary)->aux.shared;
 | 
			
		||||
    FL_SET(val, ELTS_SHARED);
 | 
			
		||||
    return val;
 | 
			
		||||
    if (len <= RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
        return rb_ary_new4(len, RARRAY_PTR(ary) + offset);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        VALUE shared, result = ary_alloc(rb_obj_class(ary));
 | 
			
		||||
        FL_UNSET_EMBED(result);
 | 
			
		||||
 | 
			
		||||
        shared = ary_make_shared(ary);
 | 
			
		||||
        ARY_SET_PTR(result, RARRAY_PTR(ary));
 | 
			
		||||
        ARY_SET_LEN(result, RARRAY_LEN(ary));
 | 
			
		||||
        FL_SET_SHARED(result);
 | 
			
		||||
        ARY_SET_SHARED(result, shared);
 | 
			
		||||
 | 
			
		||||
        ARY_INCREASE_PTR(result, offset);
 | 
			
		||||
        ARY_SET_LEN(result, len);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
ary_shared_first(int argc, VALUE *argv, VALUE ary, int last)
 | 
			
		||||
ary_make_partial(int argc, VALUE *argv, VALUE ary, int last)
 | 
			
		||||
{
 | 
			
		||||
    VALUE nv, result;
 | 
			
		||||
    VALUE nv;
 | 
			
		||||
    long n;
 | 
			
		||||
    long offset = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -437,11 +577,7 @@ ary_shared_first(int argc, VALUE *argv, VALUE ary, int last)
 | 
			
		|||
    if (last) {
 | 
			
		||||
	offset = RARRAY_LEN(ary) - n;
 | 
			
		||||
    }
 | 
			
		||||
    result = ary_shared_array(rb_cArray, ary);
 | 
			
		||||
    RARRAY(result)->ptr += offset;
 | 
			
		||||
    RARRAY(result)->len = n;
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
    return ary_make_partial0(ary, offset, n);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -492,14 +628,14 @@ rb_ary_pop(VALUE ary)
 | 
			
		|||
    long n;
 | 
			
		||||
    rb_ary_modify_check(ary);
 | 
			
		||||
    if (RARRAY_LEN(ary) == 0) return Qnil;
 | 
			
		||||
    if (!ARY_SHARED_P(ary) &&
 | 
			
		||||
    if (ARY_OWNS_HEAP_P(ary) &&
 | 
			
		||||
	RARRAY_LEN(ary) * 3 < ARY_CAPA(ary) &&
 | 
			
		||||
	ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
 | 
			
		||||
    {
 | 
			
		||||
	RESIZE_CAPA(ary, RARRAY_LEN(ary) * 2);
 | 
			
		||||
    }
 | 
			
		||||
    n = RARRAY_LEN(ary)-1;
 | 
			
		||||
    RARRAY(ary)->len = n;
 | 
			
		||||
    ARY_SET_LEN(ary, n);
 | 
			
		||||
    return RARRAY_PTR(ary)[n];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -530,8 +666,8 @@ rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    rb_ary_modify_check(ary);
 | 
			
		||||
    result = ary_shared_first(argc, argv, ary, Qtrue);
 | 
			
		||||
    RARRAY(ary)->len -= RARRAY_LEN(result);
 | 
			
		||||
    result = ary_make_partial(argc, argv, ary, Qtrue);
 | 
			
		||||
    ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -546,14 +682,16 @@ rb_ary_shift(VALUE ary)
 | 
			
		|||
    if (!ARY_SHARED_P(ary)) {
 | 
			
		||||
	if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
 | 
			
		||||
	    MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+1, VALUE, RARRAY_LEN(ary)-1);
 | 
			
		||||
	    RARRAY(ary)->len--;
 | 
			
		||||
            ARY_INCREASE_LEN(ary, -1);
 | 
			
		||||
	    return top;
 | 
			
		||||
	}
 | 
			
		||||
        assert(!ARY_EMBED_P(ary)); /* ARY_EMBED_LEN_MAX < ARY_DEFAULT_SIZE */
 | 
			
		||||
 | 
			
		||||
	RARRAY_PTR(ary)[0] = Qnil;
 | 
			
		||||
	ary_make_shared(ary);
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY(ary)->ptr++;		/* shift ptr */
 | 
			
		||||
    RARRAY(ary)->len--;
 | 
			
		||||
    ARY_INCREASE_PTR(ary, 1);		/* shift ptr */
 | 
			
		||||
    ARY_INCREASE_LEN(ary, -1);
 | 
			
		||||
 | 
			
		||||
    return top;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -590,16 +728,15 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    rb_ary_modify_check(ary);
 | 
			
		||||
    result = ary_shared_first(argc, argv, ary, Qfalse);
 | 
			
		||||
    result = ary_make_partial(argc, argv, ary, Qfalse);
 | 
			
		||||
    n = RARRAY_LEN(result);
 | 
			
		||||
    if (ARY_SHARED_P(ary)) {
 | 
			
		||||
	RARRAY(ary)->ptr += n;
 | 
			
		||||
	RARRAY(ary)->len -= n;
 | 
			
		||||
	}
 | 
			
		||||
        ARY_INCREASE_PTR(ary, n);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+n, VALUE, RARRAY_LEN(ary)-n);
 | 
			
		||||
	RARRAY(ary)->len -= n;
 | 
			
		||||
    }
 | 
			
		||||
    ARY_INCREASE_LEN(ary, -n);
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -623,14 +760,14 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
 | 
			
		||||
    if (argc == 0) return ary;
 | 
			
		||||
    rb_ary_modify(ary);
 | 
			
		||||
    if (RARRAY(ary)->aux.capa <= (len = RARRAY(ary)->len) + argc) {
 | 
			
		||||
    if (ARY_CAPA(ary) <= (len = RARRAY_LEN(ary)) + argc) {
 | 
			
		||||
	RESIZE_CAPA(ary, len + argc + ARY_DEFAULT_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* sliding items */
 | 
			
		||||
    MEMMOVE(RARRAY(ary)->ptr + argc, RARRAY(ary)->ptr, VALUE, len);
 | 
			
		||||
    MEMCPY(RARRAY(ary)->ptr, argv, VALUE, argc);
 | 
			
		||||
    RARRAY(ary)->len += argc;
 | 
			
		||||
    MEMMOVE(RARRAY_PTR(ary) + argc, RARRAY_PTR(ary), VALUE, len);
 | 
			
		||||
    MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc);
 | 
			
		||||
    ARY_INCREASE_LEN(ary, argc);
 | 
			
		||||
    
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -664,8 +801,7 @@ rb_ary_entry(VALUE ary, long offset)
 | 
			
		|||
VALUE
 | 
			
		||||
rb_ary_subseq(VALUE ary, long beg, long len)
 | 
			
		||||
{
 | 
			
		||||
    VALUE klass, ary2, shared;
 | 
			
		||||
    VALUE *ptr;
 | 
			
		||||
    VALUE klass;
 | 
			
		||||
 | 
			
		||||
    if (beg > RARRAY_LEN(ary)) return Qnil;
 | 
			
		||||
    if (beg < 0 || len < 0) return Qnil;
 | 
			
		||||
| 
						 | 
				
			
			@ -676,15 +812,7 @@ rb_ary_subseq(VALUE ary, long beg, long len)
 | 
			
		|||
    klass = rb_obj_class(ary);
 | 
			
		||||
    if (len == 0) return ary_new(klass, 0);
 | 
			
		||||
 | 
			
		||||
    shared = ary_make_shared(ary);
 | 
			
		||||
    ptr = RARRAY_PTR(ary);
 | 
			
		||||
    ary2 = ary_alloc(klass);
 | 
			
		||||
    RARRAY(ary2)->ptr = ptr + beg;
 | 
			
		||||
    RARRAY(ary2)->len = len;
 | 
			
		||||
    RARRAY(ary2)->aux.shared = shared;
 | 
			
		||||
    FL_SET(ary2, ELTS_SHARED);
 | 
			
		||||
 | 
			
		||||
    return ary2;
 | 
			
		||||
    return ary_make_partial0(ary, beg, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
| 
						 | 
				
			
			@ -794,7 +922,7 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
	return RARRAY_PTR(ary)[0];
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	return ary_shared_first(argc, argv, ary, Qfalse);
 | 
			
		||||
	return ary_make_partial(argc, argv, ary, Qfalse);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -819,7 +947,7 @@ rb_ary_last(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
	return RARRAY_PTR(ary)[RARRAY_LEN(ary)-1];
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	return ary_shared_first(argc, argv, ary, Qtrue);
 | 
			
		||||
	return ary_make_partial(argc, argv, ary, Qtrue);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,7 +1131,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
 | 
			
		|||
	if (rlen > 0) {
 | 
			
		||||
	    MEMCPY(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
 | 
			
		||||
	}
 | 
			
		||||
	RARRAY(ary)->len = len;
 | 
			
		||||
	ARY_SET_LEN(ary, len);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	long alen;
 | 
			
		||||
| 
						 | 
				
			
			@ -1020,7 +1148,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
 | 
			
		|||
	if (len != rlen) {
 | 
			
		||||
	    MEMMOVE(RARRAY_PTR(ary) + beg + rlen, RARRAY_PTR(ary) + beg + len,
 | 
			
		||||
		    VALUE, RARRAY_LEN(ary) - (beg + len));
 | 
			
		||||
	    RARRAY(ary)->len = alen;
 | 
			
		||||
	    ARY_SET_LEN(ary, alen);
 | 
			
		||||
	}
 | 
			
		||||
	if (rlen > 0) {
 | 
			
		||||
	    MEMMOVE(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
 | 
			
		||||
| 
						 | 
				
			
			@ -1238,10 +1366,11 @@ VALUE
 | 
			
		|||
rb_ary_dup(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
 | 
			
		||||
 | 
			
		||||
    int is_embed = ARY_EMBED_P(dup);
 | 
			
		||||
    DUPSETUP(dup, ary);
 | 
			
		||||
    if (is_embed) FL_SET_EMBED(dup);
 | 
			
		||||
    MEMCPY(RARRAY_PTR(dup), RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
 | 
			
		||||
    RARRAY(dup)->len = RARRAY_LEN(ary);
 | 
			
		||||
    ARY_SET_LEN(dup, RARRAY_LEN(ary));
 | 
			
		||||
 | 
			
		||||
    return dup;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1548,8 +1677,9 @@ VALUE
 | 
			
		|||
rb_ary_sort_bang(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    rb_ary_modify(ary);
 | 
			
		||||
    assert(!ARY_SHARED_P(ary));
 | 
			
		||||
    if (RARRAY_LEN(ary) > 1) {
 | 
			
		||||
	VALUE tmp = ary_make_shared(ary);
 | 
			
		||||
	VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
 | 
			
		||||
	struct ary_sort_data data;
 | 
			
		||||
 | 
			
		||||
	RBASIC(tmp)->klass = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1558,18 +1688,39 @@ rb_ary_sort_bang(VALUE ary)
 | 
			
		|||
	data.opt_inited = 0;
 | 
			
		||||
	ruby_qsort(RARRAY_PTR(tmp), RARRAY_LEN(tmp), sizeof(VALUE),
 | 
			
		||||
		   rb_block_given_p()?sort_1:sort_2, &data);
 | 
			
		||||
	if (RARRAY(ary)->ptr != RARRAY(tmp)->ptr) {
 | 
			
		||||
	    if (!ARY_SHARED_P(ary)) xfree(RARRAY(ary)->ptr);
 | 
			
		||||
	    RARRAY(ary)->ptr = RARRAY(tmp)->ptr;
 | 
			
		||||
	    RARRAY(ary)->len = RARRAY(tmp)->len;
 | 
			
		||||
	    RARRAY(ary)->aux.capa = RARRAY(tmp)->aux.capa;
 | 
			
		||||
	    FL_SET(ary, ELTS_SHARED);
 | 
			
		||||
	};
 | 
			
		||||
	FL_UNSET(ary, ELTS_SHARED);
 | 
			
		||||
	RARRAY(tmp)->ptr = 0;
 | 
			
		||||
	RARRAY(tmp)->len = 0;
 | 
			
		||||
	RARRAY(tmp)->aux.capa = 0;
 | 
			
		||||
	RBASIC(tmp)->klass = rb_cArray;
 | 
			
		||||
 | 
			
		||||
        if (ARY_EMBED_P(ary) || ARY_EMBED_P(tmp)) {
 | 
			
		||||
            assert(ARY_EMBED_P(tmp));
 | 
			
		||||
            MEMCPY(RARRAY_PTR(ary), ARY_EMBED_PTR(tmp), VALUE, ARY_EMBED_LEN(tmp));
 | 
			
		||||
            ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            assert(!ARY_EMBED_P(ary));
 | 
			
		||||
            assert(!ARY_EMBED_P(tmp));
 | 
			
		||||
            if (RARRAY_PTR(ary) != RARRAY_PTR(tmp)) {
 | 
			
		||||
                assert(!ARY_SHARED_P(tmp));
 | 
			
		||||
                if (ARY_SHARED_P(ary)) {
 | 
			
		||||
                    FL_UNSET_SHARED(ary);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    xfree(ARY_HEAP_PTR(ary));
 | 
			
		||||
                }
 | 
			
		||||
                ARY_SET_PTR(ary, RARRAY_PTR(tmp));
 | 
			
		||||
                ARY_SET_HEAP_LEN(ary, RARRAY_LEN(tmp));
 | 
			
		||||
                ARY_SET_CAPA(ary, ARY_CAPA(tmp));
 | 
			
		||||
            } 
 | 
			
		||||
            else {
 | 
			
		||||
                FL_UNSET_SHARED(ary);
 | 
			
		||||
                ARY_SET_CAPA(ary, ARY_CAPA(tmp));
 | 
			
		||||
            }
 | 
			
		||||
            /* tmp was lost ownership for the ptr */
 | 
			
		||||
            FL_UNSET(tmp, FL_FREEZE);
 | 
			
		||||
            FL_SET_EMBED(tmp);
 | 
			
		||||
            ARY_SET_EMBED_LEN(tmp, 0);
 | 
			
		||||
            FL_SET(tmp, FL_FREEZE);
 | 
			
		||||
	}
 | 
			
		||||
        /* tmp will be GC'ed. */
 | 
			
		||||
        RBASIC(tmp)->klass = rb_cArray;
 | 
			
		||||
    }
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1778,7 +1929,7 @@ rb_ary_delete(VALUE ary, VALUE item)
 | 
			
		|||
 | 
			
		||||
    rb_ary_modify(ary);
 | 
			
		||||
    if (RARRAY_LEN(ary) > i2) {
 | 
			
		||||
	RARRAY(ary)->len = i2;
 | 
			
		||||
	ARY_SET_LEN(ary, i2);
 | 
			
		||||
	if (i2 * 2 < ARY_CAPA(ary) &&
 | 
			
		||||
	    ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
 | 
			
		||||
	    RESIZE_CAPA(ary, i2*2);
 | 
			
		||||
| 
						 | 
				
			
			@ -1804,7 +1955,7 @@ rb_ary_delete_at(VALUE ary, long pos)
 | 
			
		|||
    del = RARRAY_PTR(ary)[pos];
 | 
			
		||||
    MEMMOVE(RARRAY_PTR(ary)+pos, RARRAY_PTR(ary)+pos+1, VALUE,
 | 
			
		||||
	    RARRAY_LEN(ary)-pos-1);
 | 
			
		||||
    RARRAY(ary)->len--;
 | 
			
		||||
    ARY_INCREASE_LEN(ary, -1);
 | 
			
		||||
 | 
			
		||||
    return del;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1921,7 +2072,7 @@ rb_ary_reject_bang(VALUE ary)
 | 
			
		|||
 | 
			
		||||
    if (RARRAY_LEN(ary) == i2) return Qnil;
 | 
			
		||||
    if (i2 < RARRAY_LEN(ary))
 | 
			
		||||
	RARRAY(ary)->len = i2;
 | 
			
		||||
	ARY_SET_LEN(ary, i2);
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2089,22 +2240,30 @@ rb_ary_transpose(VALUE ary)
 | 
			
		|||
VALUE
 | 
			
		||||
rb_ary_replace(VALUE copy, VALUE orig)
 | 
			
		||||
{
 | 
			
		||||
    VALUE shared;
 | 
			
		||||
    VALUE *ptr;
 | 
			
		||||
 | 
			
		||||
    orig = to_ary(orig);
 | 
			
		||||
    rb_ary_modify_check(copy);
 | 
			
		||||
    if (copy == orig) return copy;
 | 
			
		||||
    shared = ary_make_shared(orig);
 | 
			
		||||
    if (!ARY_SHARED_P(copy)) {
 | 
			
		||||
	ptr = RARRAY(copy)->ptr;
 | 
			
		||||
	xfree(ptr);
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY(copy)->ptr = RARRAY(orig)->ptr;
 | 
			
		||||
    RARRAY(copy)->len = RARRAY(orig)->len;
 | 
			
		||||
    RARRAY(copy)->aux.shared = shared;
 | 
			
		||||
    FL_SET(copy, ELTS_SHARED);
 | 
			
		||||
 | 
			
		||||
    if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
 | 
			
		||||
        VALUE *ptr;
 | 
			
		||||
        if (ARY_OWNS_HEAP_P(copy)) xfree(RARRAY_PTR(copy));
 | 
			
		||||
        FL_UNSET_SHARED(copy);
 | 
			
		||||
        FL_SET_EMBED(copy);
 | 
			
		||||
        ptr = RARRAY_PTR(orig);
 | 
			
		||||
        MEMCPY(RARRAY_PTR(copy), ptr, VALUE, RARRAY_LEN(orig));
 | 
			
		||||
        ARY_SET_LEN(copy, RARRAY_LEN(orig));
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        VALUE shared = ary_make_shared(orig);
 | 
			
		||||
        if (ARY_OWNS_HEAP_P(copy)) {
 | 
			
		||||
            xfree(RARRAY_PTR(copy));
 | 
			
		||||
        }
 | 
			
		||||
        FL_UNSET_EMBED(copy);
 | 
			
		||||
        FL_SET_SHARED(copy);
 | 
			
		||||
        ARY_SET_PTR(copy, RARRAY_PTR(orig));
 | 
			
		||||
        ARY_SET_LEN(copy, RARRAY_LEN(orig));
 | 
			
		||||
        ARY_SET_SHARED(copy, shared);
 | 
			
		||||
    }
 | 
			
		||||
    return copy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2122,7 +2281,7 @@ VALUE
 | 
			
		|||
rb_ary_clear(VALUE ary)
 | 
			
		||||
{
 | 
			
		||||
    rb_ary_modify(ary);
 | 
			
		||||
    RARRAY(ary)->len = 0;
 | 
			
		||||
    ARY_SET_LEN(ary, 0);
 | 
			
		||||
    if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
 | 
			
		||||
	RESIZE_CAPA(ary, ARY_DEFAULT_SIZE * 2);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -2201,7 +2360,7 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
	    RESIZE_CAPA(ary, end);
 | 
			
		||||
	}
 | 
			
		||||
	rb_mem_clear(RARRAY_PTR(ary) + RARRAY_LEN(ary), end - RARRAY_LEN(ary));
 | 
			
		||||
	RARRAY(ary)->len = end;
 | 
			
		||||
	ARY_SET_LEN(ary, end);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (block_p) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2245,7 +2404,7 @@ rb_ary_plus(VALUE x, VALUE y)
 | 
			
		|||
    z = rb_ary_new2(len);
 | 
			
		||||
    MEMCPY(RARRAY_PTR(z), RARRAY_PTR(x), VALUE, RARRAY_LEN(x));
 | 
			
		||||
    MEMCPY(RARRAY_PTR(z) + RARRAY_LEN(x), RARRAY_PTR(y), VALUE, RARRAY_LEN(y));
 | 
			
		||||
    RARRAY(z)->len = len;
 | 
			
		||||
    ARY_SET_LEN(z, len);
 | 
			
		||||
    return z;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2307,7 +2466,7 @@ rb_ary_times(VALUE ary, VALUE times)
 | 
			
		|||
    len *= RARRAY_LEN(ary);
 | 
			
		||||
 | 
			
		||||
    ary2 = ary_new(rb_obj_class(ary), len);
 | 
			
		||||
    RARRAY(ary2)->len = len;
 | 
			
		||||
    ARY_SET_LEN(ary2, len);
 | 
			
		||||
 | 
			
		||||
    for (i=0; i<len; i+=RARRAY_LEN(ary)) {
 | 
			
		||||
	MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
 | 
			
		||||
| 
						 | 
				
			
			@ -2716,7 +2875,7 @@ rb_ary_uniq_bang(VALUE ary)
 | 
			
		|||
	    rb_ary_store(ary, j++, v);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY(ary)->len = j;
 | 
			
		||||
    ARY_SET_LEN(ary, j);
 | 
			
		||||
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2771,7 +2930,7 @@ rb_ary_compact_bang(VALUE ary)
 | 
			
		|||
    if (n * 2 < ARY_CAPA(ary) && ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
 | 
			
		||||
	RESIZE_CAPA(ary, n * 2);
 | 
			
		||||
    }
 | 
			
		||||
    RARRAY(ary)->len = n;
 | 
			
		||||
    ARY_SET_LEN(ary, n);
 | 
			
		||||
 | 
			
		||||
    return ary;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3168,7 +3327,7 @@ permute0(long n, long r, long *p, long index, int *used, VALUE values)
 | 
			
		|||
		const VALUE *values_array = RARRAY_PTR(values);
 | 
			
		||||
 | 
			
		||||
		for (j = 0; j < r; j++) result_array[j] = values_array[p[j]];
 | 
			
		||||
		RARRAY(result)->len = r;
 | 
			
		||||
		ARY_SET_LEN(result, r);
 | 
			
		||||
		rb_yield(result);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -3228,7 +3387,7 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
 | 
			
		|||
	long *p = (long*)RSTRING_PTR(t0);
 | 
			
		||||
	volatile VALUE t1 = tmpbuf(n,sizeof(int));
 | 
			
		||||
	int *used = (int*)RSTRING_PTR(t1);
 | 
			
		||||
	VALUE ary0 = ary_make_shared(ary); /* private defensive copy of ary */
 | 
			
		||||
	VALUE ary0 = ary_make_substitution(ary); /* private defensive copy of ary */
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < n; i++) used[i] = 0; /* initialize array */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3089,9 +3089,6 @@ ip_ruby_cmd(clientData, interp, argc, argv)
 | 
			
		|||
 | 
			
		||||
    /* get args */
 | 
			
		||||
    args = rb_ary_new2(argc - 2);
 | 
			
		||||
#ifdef HAVE_STRUCT_RARRAY_LEN
 | 
			
		||||
    RARRAY(args)->len = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    for(i = 3; i < argc; i++) {
 | 
			
		||||
#if TCL_MAJOR_VERSION >= 8
 | 
			
		||||
        str = Tcl_GetStringFromObj(argv[i], &len);
 | 
			
		||||
| 
						 | 
				
			
			@ -3099,14 +3096,14 @@ ip_ruby_cmd(clientData, interp, argc, argv)
 | 
			
		|||
#ifndef HAVE_STRUCT_RARRAY_LEN
 | 
			
		||||
	rb_ary_push(args, rb_tainted_str_new(str, len));
 | 
			
		||||
#else
 | 
			
		||||
        RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new(str, len);
 | 
			
		||||
        RARRAY(args)->as.heap.ptr[RARRAY(args)->as.heap.len++] = rb_tainted_str_new(str, len);
 | 
			
		||||
#endif
 | 
			
		||||
#else /* TCL_MAJOR_VERSION < 8 */
 | 
			
		||||
        DUMP2("arg:%s",argv[i]);
 | 
			
		||||
#ifndef HAVE_STRUCT_RARRAY_LEN
 | 
			
		||||
	rb_ary_push(args, rb_tainted_str_new2(argv[i]));
 | 
			
		||||
#else
 | 
			
		||||
        RARRAY(args)->ptr[RARRAY(args)->len++] = rb_tainted_str_new2(argv[i]);
 | 
			
		||||
        RARRAY(args)->as.heap.ptr[RARRAY(args)->as.heap.len++] = rb_tainted_str_new2(argv[i]);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -8298,7 +8295,7 @@ ip_invoke_with_position(argc, argv, obj, position)
 | 
			
		|||
    DUMP2("back from handler (current thread:%lx)", current);
 | 
			
		||||
 | 
			
		||||
    /* get result & free allocated memory */
 | 
			
		||||
    ret = RARRAY(result)->ptr[0];
 | 
			
		||||
    ret = RARRAY(result)->as.heap.ptr[0];
 | 
			
		||||
#if 0 /* use Tcl_EventuallyFree */
 | 
			
		||||
    Tcl_EventuallyFree((ClientData)alloc_done, TCL_DYNAMIC); /* XXXXXXXX */
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1462,7 +1462,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
 | 
			
		|||
 | 
			
		||||
      case T_ARRAY:
 | 
			
		||||
	if (FL_TEST(obj, ELTS_SHARED)) {
 | 
			
		||||
	    ptr = obj->as.array.aux.shared;
 | 
			
		||||
	    ptr = obj->as.array.as.heap.aux.shared;
 | 
			
		||||
	    goto again;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -504,7 +504,7 @@ VALUE rb_newobj(void);
 | 
			
		|||
    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)clone,(VALUE)obj);\
 | 
			
		||||
} while (0)
 | 
			
		||||
#define DUPSETUP(dup,obj) do {\
 | 
			
		||||
    OBJSETUP(dup,rb_obj_class(obj),(RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED));\
 | 
			
		||||
    OBJSETUP(dup,rb_obj_class(obj), (RBASIC(obj)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED)); \
 | 
			
		||||
    if (FL_TEST(obj, FL_EXIVAR)) rb_copy_generic_ivar((VALUE)dup,(VALUE)obj);\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -596,17 +596,34 @@ struct RString {
 | 
			
		|||
     RSTRING(str)->as.heap.ptr)
 | 
			
		||||
#define RSTRING_END(str) (RSTRING_PTR(str)+RSTRING_LEN(str))
 | 
			
		||||
 | 
			
		||||
#define RARRAY_EMBED_LEN_MAX 3
 | 
			
		||||
struct RArray {
 | 
			
		||||
    struct RBasic basic;
 | 
			
		||||
    long len;
 | 
			
		||||
    union {
 | 
			
		||||
	long capa;
 | 
			
		||||
	VALUE shared;
 | 
			
		||||
    } aux;
 | 
			
		||||
    VALUE *ptr;
 | 
			
		||||
	struct {
 | 
			
		||||
	    long len;
 | 
			
		||||
	    union {
 | 
			
		||||
		long capa;
 | 
			
		||||
		VALUE shared;
 | 
			
		||||
	    } aux;
 | 
			
		||||
	    VALUE *ptr;
 | 
			
		||||
	} heap;
 | 
			
		||||
	VALUE ary[RARRAY_EMBED_LEN_MAX];
 | 
			
		||||
    } as;
 | 
			
		||||
};
 | 
			
		||||
#define RARRAY_LEN(a) RARRAY(a)->len
 | 
			
		||||
#define RARRAY_PTR(a) RARRAY(a)->ptr
 | 
			
		||||
#define RARRAY_EMBED_FLAG FL_USER1
 | 
			
		||||
/* FL_USER2 is for ELTS_SHARED */
 | 
			
		||||
#define RARRAY_EMBED_LEN_MASK (FL_USER4|FL_USER3)
 | 
			
		||||
#define RARRAY_EMBED_LEN_SHIFT (FL_USHIFT+3)
 | 
			
		||||
#define RARRAY_LEN(a) \
 | 
			
		||||
    ((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ? \
 | 
			
		||||
     (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
 | 
			
		||||
	 (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)) : \
 | 
			
		||||
     RARRAY(a)->as.heap.len)
 | 
			
		||||
#define RARRAY_PTR(a) \
 | 
			
		||||
    ((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ? \
 | 
			
		||||
     RARRAY(a)->as.ary : \
 | 
			
		||||
     RARRAY(a)->as.heap.ptr)
 | 
			
		||||
 | 
			
		||||
struct RRegexp {
 | 
			
		||||
    struct RBasic basic;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								parse.y
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4945,7 +4945,7 @@ coverage(const char *f, int n)
 | 
			
		|||
	int i;
 | 
			
		||||
	RBASIC(lines)->klass = 0;
 | 
			
		||||
	for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
 | 
			
		||||
	RARRAY(lines)->len = n;
 | 
			
		||||
	RARRAY(lines)->as.heap.len = n;
 | 
			
		||||
	rb_hash_aset(coverages, fname, lines);
 | 
			
		||||
	return lines;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1674,11 +1674,7 @@ static VALUE curry(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_
 | 
			
		|||
static VALUE
 | 
			
		||||
make_curry_proc(VALUE proc, VALUE passed, VALUE arity)
 | 
			
		||||
{
 | 
			
		||||
    VALUE args = rb_ary_new2(3);
 | 
			
		||||
    RARRAY_PTR(args)[0] = proc;
 | 
			
		||||
    RARRAY_PTR(args)[1] = passed;
 | 
			
		||||
    RARRAY_PTR(args)[2] = arity;
 | 
			
		||||
    RARRAY_LEN(args) = 3;
 | 
			
		||||
    VALUE args = rb_ary_new3(3, proc, passed, arity);
 | 
			
		||||
    rb_ary_freeze(passed);
 | 
			
		||||
    rb_ary_freeze(args);
 | 
			
		||||
    return rb_proc_new(curry, args);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue