diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-02-28 02:32:09 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-02-28 02:32:09 +0000 |
commit | 334244eb5d45e263874c739490213f4b87ab8e5b (patch) | |
tree | e3f27ab13b82d4c5f780e93dce08d01bcd3f7b89 | |
parent | f828d53066ef30db67b167aad25919e34ed1571a (diff) |
* pack.c (pack_pack): generalized integer packer implemented.
(pack_unpack): generalized integer unpacker implemented.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26778 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | pack.c | 104 |
2 files changed, 67 insertions, 52 deletions
@@ -1,3 +1,8 @@ +Sun Feb 28 11:25:16 2010 Tanaka Akira <akr@fsij.org> + + * pack.c (pack_pack): generalized integer packer implemented. + (pack_unpack): generalized integer unpacker implemented. + Sun Feb 28 06:58:53 2010 Tanaka Akira <akr@fsij.org> * pack.c (swap32): use __builtin_bswap32 on gcc 4.3.0 or later. @@ -9,9 +14,9 @@ Sun Feb 28 00:38:18 2010 Tanaka Akira <akr@fsij.org> Sat Feb 27 15:54:55 2010 Tanaka Akira <akr@fsij.org> - * 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@fsij.org> @@ -34,12 +39,12 @@ Fri Feb 26 21:36:51 2010 Tanaka Akira <akr@fsij.org> (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@fsij.org> - * 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@tsg.ne.jp> @@ -87,7 +92,7 @@ Thu Feb 25 00:43:57 2010 Koichi Sasada <ko1@atdot.net> (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. @@ -282,7 +282,9 @@ num2i32(VALUE x) } #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_pack(VALUE ary, VALUE fmt) 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 @@ pack_pack(VALUE ary, VALUE fmt) 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 @@ pack_pack(VALUE ary, VALUE fmt) 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 @@ pack_unpack(VALUE str, VALUE fmt) 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 @@ pack_unpack(VALUE str, VALUE fmt) 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_unpack(VALUE str, VALUE fmt) 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)); - } - else { - tmp[QUAD_SIZE/SIZEOF_LONG] = 0; - UNPACK_PUSH(rb_big_unpack(tmp, QUAD_SIZE/SIZEOF_LONG+1)); + if (bigendian_p != BIGENDIAN_P()) { + for (i = 0; i < num_longs; i++) + tmp[i] = swapl(tmp[i]); } + 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': |