ruby-changes:14908
From: akr <ko1@a...>
Date: Sun, 28 Feb 2010 11:32:25 +0900 (JST)
Subject: [ruby-changes:14908] Ruby:r26778 (trunk): * pack.c (pack_pack): generalized integer packer implemented.
akr 2010-02-28 11:32:09 +0900 (Sun, 28 Feb 2010) New Revision: 26778 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26778 Log: * pack.c (pack_pack): generalized integer packer implemented. (pack_unpack): generalized integer unpacker implemented. Modified files: trunk/ChangeLog trunk/pack.c Index: ChangeLog =================================================================== --- ChangeLog (revision 26777) +++ ChangeLog (revision 26778) @@ -1,3 +1,8 @@ +Sun Feb 28 11:25:16 2010 Tanaka Akira <akr@f...> + + * pack.c (pack_pack): generalized integer packer implemented. + (pack_unpack): generalized integer unpacker implemented. + Sun Feb 28 06:58:53 2010 Tanaka Akira <akr@f...> * pack.c (swap32): use __builtin_bswap32 on gcc 4.3.0 or later. @@ -9,9 +14,9 @@ Sat Feb 27 15:54:55 2010 Tanaka Akira <akr@f...> - * pack.c: check assuption on QUAD_SIZE and SIZEOF_LONG. + * pack.c: check assumption on QUAD_SIZE and SIZEOF_LONG. - * bignum.c: check assuption on SIZEOF_LONG and SIZEOF_BDIGITS. + * bignum.c: check assumption on SIZEOF_LONG and SIZEOF_BDIGITS. Sat Feb 27 03:48:18 2010 Tanaka Akira <akr@f...> @@ -34,12 +39,12 @@ (rb_quad_pack): use quad_buf_complement. don't raise for large values. (rb_quad_unpack): use quad_buf_complement. - (quad_buf_complement): new function extracted frm rb_quad_pack. + (quad_buf_complement): new function extracted from rb_quad_pack. add one after bitwise negation. Fri Feb 26 21:29:48 2010 Tanaka Akira <akr@f...> - * configure.in (RSHIFT): add parenthesis to supress warning. + * configure.in (RSHIFT): add parenthesis to suppress warning. Fri Feb 26 20:51:47 2010 Yusuke Endoh <mame@t...> @@ -87,7 +92,7 @@ (getting IC directly) and is for the AOT compilation development. * compile.c, iseq.c, insns.def: Change the approach to handling inline - cahce (IC) type operand to enable the above change. + cache (IC) type operand to enable the above change. This change also affects ISeq#to_a method. The inline cache operand will be dumped by fixnum, the index of inline cache, in other words, inline cache identity. Index: pack.c =================================================================== --- pack.c (revision 26777) +++ pack.c (revision 26778) @@ -282,7 +282,9 @@ } #define QUAD_SIZE 8 +#define MAX_INTEGER_PACK_SIZE 8 /* #define FORCE_BIG_PACK */ + static const char toofew[] = "too few arguments"; static void encodes(VALUE,const char*,long,int,int); @@ -715,7 +717,7 @@ pack_integer: switch (integer_size) { -#ifdef HAVE_INT16_T +#if defined(HAVE_INT16_T) && !defined(FORCE_BIG_PACK) case SIZEOF_INT16_T: while (len-- > 0) { int16_t v; @@ -728,7 +730,7 @@ break; #endif -#ifdef HAVE_INT32_T +#if defined(HAVE_INT32_T) && !defined(FORCE_BIG_PACK) case SIZEOF_INT32_T: while (len-- > 0) { int32_t v; @@ -747,36 +749,43 @@ int64_t v; from = NEXTFROM; - v = num2i32(from); + v = num2i32(from); /* can return 64bit value if SIZEOF_LONG == SIZEOF_INT64_T */ if (bigendian_p != BIGENDIAN_P()) v = swap64(v); rb_str_buf_cat(res, (char *)&v, sizeof(int64_t)); } break; #else -# if QUAD_SIZE % SIZEOF_LONG != 0 -# error unexpected QUAD_SIZE : SIZEOF_LONG ratio -# endif - case QUAD_SIZE: + +#endif + + default: + if (integer_size > MAX_INTEGER_PACK_SIZE) + rb_bug("unexpected intger size for pack: %d", integer_size); while (len-- > 0) { - unsigned long tmp[QUAD_SIZE/SIZEOF_LONG]; + unsigned long tmp[(MAX_INTEGER_PACK_SIZE+SIZEOF_LONG-1)/SIZEOF_LONG]; + int num_longs = (integer_size+SIZEOF_LONG-1)/SIZEOF_LONG; + int i; from = NEXTFROM; - rb_big_pack(from, tmp, QUAD_SIZE/SIZEOF_LONG); - if (BIGENDIAN_P()) { - int i; - for (i = 0; i < QUAD_SIZE/SIZEOF_LONG/2; i++) { + rb_big_pack(from, tmp, num_longs); + if (bigendian_p) { + for (i = 0; i < num_longs/2; i++) { unsigned long t = tmp[i]; - tmp[i] = tmp[QUAD_SIZE/SIZEOF_LONG-i-1]; - tmp[QUAD_SIZE/SIZEOF_LONG-i-1] = t; + tmp[i] = tmp[num_longs-1-i]; + tmp[num_longs-1-i] = t; } } - rb_str_buf_cat(res, (char*)tmp, QUAD_SIZE); + if (bigendian_p != BIGENDIAN_P()) { + for (i = 0; i < num_longs; i++) + tmp[i] = swapl(tmp[i]); + } + rb_str_buf_cat(res, + bigendian_p ? + (char*)tmp + sizeof(long)*num_longs - integer_size : + (char*)tmp, + integer_size); } break; -#endif - - default: - rb_bug("unexpected intger size for pack: %d", integer_size); } break; @@ -1567,7 +1576,7 @@ unpack_integer: switch (integer_size) { -#ifdef HAVE_INT16_T +#if defined(HAVE_INT16_T) && !defined(FORCE_BIG_PACK) case SIZEOF_INT16_T: if (signed_p) { PACK_LENGTH_ADJUST_SIZE(sizeof(int16_t)); @@ -1594,7 +1603,7 @@ break; #endif -#ifdef HAVE_INT32_T +#if defined(HAVE_INT32_T) && !defined(FORCE_BIG_PACK) case SIZEOF_INT32_T: if (signed_p) { PACK_LENGTH_ADJUST_SIZE(sizeof(int32_t)); @@ -1646,40 +1655,41 @@ PACK_ITEM_ADJUST(); } break; -#else -# if QUAD_SIZE % SIZEOF_LONG != 0 -# error unexpected QUAD_SIZE : SIZEOF_LONG ratio -# endif - case QUAD_SIZE: - if (bigendian_p != BIGENDIAN_P()) - rb_bug("unexpected endian for unpack"); - PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE); +#endif + + default: + if (integer_size > MAX_INTEGER_PACK_SIZE) + rb_bug("unexpected intger size for pack: %d", integer_size); + PACK_LENGTH_ADJUST_SIZE(integer_size); while (len-- > 0) { - unsigned long tmp[QUAD_SIZE/SIZEOF_LONG+1]; - memcpy(tmp, s, QUAD_SIZE); - if (BIGENDIAN_P()) { - int i; - for (i = 0; i < (QUAD_SIZE/SIZEOF_LONG)/2; i++) { + unsigned long tmp[(MAX_INTEGER_PACK_SIZE+SIZEOF_LONG)/SIZEOF_LONG]; + int num_longs = (integer_size+SIZEOF_LONG)/SIZEOF_LONG; + int i; + + if (signed_p && (signed char)s[bigendian_p ? 0 : (integer_size-1)] < 0) + memset(tmp, 0xff, sizeof(long)*num_longs); + else + memset(tmp, 0, sizeof(long)*num_longs); + if (bigendian_p) + memcpy((char*)(tmp + num_longs) - integer_size, s, integer_size); + else + memcpy(tmp, s, integer_size); + if (bigendian_p) { + for (i = 0; i < num_longs/2; i++) { unsigned long t = tmp[i]; - tmp[i] = tmp[(QUAD_SIZE/SIZEOF_LONG)-i-1]; - tmp[(QUAD_SIZE/SIZEOF_LONG)-i-1] = t; + tmp[i] = tmp[num_longs-1-i]; + tmp[num_longs-1-i] = t; } } - s += QUAD_SIZE; - if (signed_p) { - UNPACK_PUSH(rb_big_unpack(tmp, QUAD_SIZE/SIZEOF_LONG)); + if (bigendian_p != BIGENDIAN_P()) { + for (i = 0; i < num_longs; i++) + tmp[i] = swapl(tmp[i]); } - else { - tmp[QUAD_SIZE/SIZEOF_LONG] = 0; - UNPACK_PUSH(rb_big_unpack(tmp, QUAD_SIZE/SIZEOF_LONG+1)); - } + s += integer_size; + UNPACK_PUSH(rb_big_unpack(tmp, num_longs)); } PACK_ITEM_ADJUST(); break; -#endif - - default: - rb_bug("unexpected intger size for unpack"); } case 'f': -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/