diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c index 621614b111..f7c5090087 100644 --- a/ext/-test-/memory_view/memory_view.c +++ b/ext/-test-/memory_view/memory_view.c @@ -80,15 +80,15 @@ memory_view_parse_item_format(VALUE mod, VALUE format) const char *err = NULL; rb_memory_view_item_component_t *members; - size_t n_members; + ssize_t n_members; ssize_t item_size = rb_memory_view_parse_item_format(c_str, &members, &n_members, &err); VALUE result = rb_ary_new_capa(3); rb_ary_push(result, SSIZET2NUM(item_size)); if (!err) { - VALUE ary = rb_ary_new_capa((long)n_members); - size_t i; + VALUE ary = rb_ary_new_capa(n_members); + ssize_t i; for (i = 0; i < n_members; ++i) { VALUE member = rb_hash_new(); rb_hash_aset(member, sym_format, rb_str_new(&members[i].format, 1)); @@ -230,26 +230,6 @@ memory_view_ref_count_while_exporting(VALUE mod, VALUE obj, VALUE n) return memory_view_ref_count_while_exporting_i(obj, FIX2LONG(n)); } -static VALUE -memory_view_extract_item_members(VALUE mod, VALUE str, VALUE format) -{ - StringValue(str); - StringValue(format); - - rb_memory_view_item_component_t *members; - size_t n_members; - const char *err = NULL; - (void)rb_memory_view_parse_item_format(RSTRING_PTR(format), &members, &n_members, &err); - if (err != NULL) { - rb_raise(rb_eArgError, "Unable to parse item format"); - } - - VALUE item = rb_memory_view_extract_item_members(RSTRING_PTR(str), members, n_members); - xfree(members); - - return item; -} - static VALUE expstr_initialize(VALUE obj, VALUE s) { @@ -366,7 +346,6 @@ Init_memory_view(void) rb_define_module_function(mMemoryViewTestUtils, "get_memory_view_info", memory_view_get_memory_view_info, 1); rb_define_module_function(mMemoryViewTestUtils, "fill_contiguous_strides", memory_view_fill_contiguous_strides, 4); rb_define_module_function(mMemoryViewTestUtils, "ref_count_while_exporting", memory_view_ref_count_while_exporting, 2); - rb_define_module_function(mMemoryViewTestUtils, "extract_item_members", memory_view_extract_item_members, 2); VALUE cExportableString = rb_define_class_under(mMemoryViewTestUtils, "ExportableString", rb_cObject); rb_define_method(cExportableString, "initialize", expstr_initialize, 1); diff --git a/include/ruby/memory_view.h b/include/ruby/memory_view.h index 6d6aeffa6e..e2c5cd9a03 100644 --- a/include/ruby/memory_view.h +++ b/include/ruby/memory_view.h @@ -128,10 +128,9 @@ RBIMPL_ATTR_NOALIAS() int rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly); ssize_t rb_memory_view_parse_item_format(const char *format, rb_memory_view_item_component_t **members, - size_t *n_members, const char **err); + ssize_t *n_members, const char **err); ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err); void *rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices); -VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members); int rb_memory_view_available_p(VALUE obj); int rb_memory_view_get(VALUE obj, rb_memory_view_t* memory_view, int flags); diff --git a/memory_view.c b/memory_view.c index d89648317d..8b2a2c051d 100644 --- a/memory_view.c +++ b/memory_view.c @@ -12,18 +12,6 @@ #include "internal/util.h" #include "ruby/memory_view.h" -#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG -# define INTPTR2NUM LL2NUM -# define UINTPTR2NUM ULL2NUM -#elif SIZEOF_INTPTR_T == SIZEOF_LONG -# define INTPTR2NUM LONG2NUM -# define UINTPTR2NUM ULONG2NUM -#else -# define INTPTR2NUM INT2NUM -# define UINTPTR2NUM UINT2NUM -#endif - - #define STRUCT_ALIGNOF(T, result) do { \ (result) = RUBY_ALIGNOF(T); \ } while(0) @@ -406,13 +394,13 @@ calculate_padding(ssize_t total, ssize_t alignment_size) { ssize_t rb_memory_view_parse_item_format(const char *format, rb_memory_view_item_component_t **members, - size_t *n_members, const char **err) + ssize_t *n_members, const char **err) { if (format == NULL) return 1; VALUE error = Qnil; ssize_t total = 0; - size_t len = 0; + ssize_t len = 0; bool alignment = false; ssize_t max_alignment_size = 0; @@ -570,215 +558,6 @@ rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices) return ptr; } -static void -switch_endianness(uint8_t *buf, ssize_t len) -{ - RUBY_ASSERT(buf != NULL); - RUBY_ASSERT(len >= 0); - - uint8_t *p = buf; - uint8_t *q = buf + len - 1; - - while (q - p > 0) { - uint8_t t = *p; - *p = *q; - *q = t; - ++p; - --q; - } -} - -static inline VALUE -extract_item_member(const uint8_t *ptr, const rb_memory_view_item_component_t *member, const size_t i, - uint8_t *buf, const size_t buf_size) -{ - RUBY_ASSERT(ptr != NULL); - RUBY_ASSERT(member != NULL); - -#ifdef WORDS_BIGENDIAN - const bool native_endian_p = !member->little_endian_p; -#else - const bool native_endian_p = member->little_endian_p; -#endif - - const uint8_t *p = ptr + member->offset + i * member->size; - - if (member->format == 'c') { - return INT2FIX(*(char *)p); - } - else if (member->format == 'C') { - return INT2FIX(*(unsigned char *)p); - } - - const uint8_t *q = p; - - if (!native_endian_p) { - RUBY_ASSERT(buf != NULL); - MEMCPY(buf, p, uint8_t, member->size); - switch_endianness(buf, member->size); - q = buf; - } - - switch (member->format) { - case 's': - if (member->native_size_p) { - return INT2FIX(*(short *)q); - } - else { - return INT2FIX(*(int16_t *)q); - } - - case 'S': - case 'n': - case 'v': - if (member->native_size_p) { - return UINT2NUM(*(unsigned short *)q); - } - else { - return INT2FIX(*(uint16_t *)q); - } - - case 'i': - return INT2NUM(*(int *)q); - - case 'I': - return UINT2NUM(*(unsigned int *)q); - - case 'l': - if (member->native_size_p) { - return LONG2NUM(*(long *)q); - } - else { - return LONG2NUM(*(int32_t *)q); - } - - case 'L': - case 'N': - case 'V': - if (member->native_size_p) { - return ULONG2NUM(*(unsigned long *)q); - } - else { - return ULONG2NUM(*(uint32_t *)q); - } - - case 'f': - case 'e': - case 'g': - return DBL2NUM(*(float *)q); - - case 'q': - if (member->native_size_p) { - return LL2NUM(*(LONG_LONG *)q); - } - else { -#if SIZEOF_INT64_t == SIZEOF_LONG - return LONG2NUM(*(int64_t *)q); -#else - return LL2NUM(*(int64_t *)q); -#endif - } - - case 'Q': - if (member->native_size_p) { - return ULL2NUM(*(unsigned LONG_LONG *)q); - } - else { -#if SIZEOF_UINT64_t == SIZEOF_LONG - return ULONG2NUM(*(uint64_t *)q); -#else - return ULL2NUM(*(uint64_t *)q); -#endif - } - - case 'd': - case 'E': - case 'G': - return DBL2NUM(*(double *)q); - - case 'j': - return INTPTR2NUM(*(intptr_t *)q); - - case 'J': - return UINTPTR2NUM(*(uintptr_t *)q); - - default: - UNREACHABLE_RETURN(Qnil); - } -} - -/* Return a value of the extracted member. */ -VALUE -rb_memory_view_extract_item_member(const void *ptr, const rb_memory_view_item_component_t *member, const size_t i) -{ - if (ptr == NULL) return Qnil; - if (member == NULL) return Qnil; - if (i >= member->repeat) return Qnil; - -#ifdef WORDS_BIGENDIAN - const bool native_endian_p = !member->little_endian_p; -#else - const bool native_endian_p = member->little_endian_p; -#endif - - VALUE buf_v = 0; - uint8_t *buf; - if (!native_endian_p) { - buf = ALLOCV_N(uint8_t, buf_v, member->size); - } - - VALUE v = extract_item_member(ptr, member, i, buf, member->size); - - if (buf_v) ALLOCV_END(buf_v); - return v; -} - -/* Return a value that consists of item members. - * When an item is a single member, the return value is a single value. - * When an item consists of multiple members, an array will be returned. */ -VALUE -rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members) -{ - if (ptr == NULL) return Qnil; - if (members == NULL) return Qnil; - if (n_members == 0) return Qnil; - - if (n_members == 1 && members[0].repeat == 1) { - return rb_memory_view_extract_item_member(ptr, members, 0); - } - - size_t i, max_size = 0; - bool need_switch_endianness_p = false; - for (i = 0; i < n_members; ++i) { - if (max_size < members[i].size) { - max_size = members[i].size; - } -#ifdef WORDS_BIGENDIAN - need_switch_endianness_p |= members[i].little_endian_p; -#else - need_switch_endianness_p |= !members[i].little_endian_p; -#endif - } - - VALUE buf_v = 0; - uint8_t *buf = NULL; - if (need_switch_endianness_p) { - buf = ALLOCV_N(uint8_t, buf_v, max_size); - } - - VALUE item = rb_ary_new(); - for (i = 0; i < n_members; ++i) { - size_t j; - for (j = 0; j < members[i].repeat; ++j) { - VALUE v = extract_item_member(ptr, &members[i], j, buf, max_size); - rb_ary_push(item, v); - } - } - - if (buf_v) ALLOCV_END(buf_v); - return item; -} - static const rb_memory_view_entry_t * lookup_memory_view_entry(VALUE klass) { diff --git a/test/ruby/test_memory_view.rb b/test/ruby/test_memory_view.rb index 0150e18c72..baf544c227 100644 --- a/test/ruby/test_memory_view.rb +++ b/test/ruby/test_memory_view.rb @@ -197,57 +197,6 @@ class TestMemoryView < Test::Unit::TestCase assert_equal(expected_result, members) end - def test_rb_memory_view_extract_item_members - m = MemoryViewTestUtils - assert_equal(1, m.extract_item_members([1].pack("c"), "c")) - assert_equal([1, 2], m.extract_item_members([1, 2].pack("ii"), "ii")) - assert_equal([1, 2, 3], m.extract_item_members([1, 2, 3].pack("cls"), "cls")) - end - - def test_rb_memory_view_extract_item_members_endianness - m = MemoryViewTestUtils - assert_equal([0x0102, 0x0304], m.extract_item_members([1, 2, 3, 4].pack("c*"), "S>2")) - assert_equal([0x0102, 0x0304], m.extract_item_members([1, 2, 3, 4].pack("c*"), "n2")) - assert_equal([0x0201, 0x0403], m.extract_item_members([1, 2, 3, 4].pack("c*"), "S<2")) - assert_equal([0x0201, 0x0403], m.extract_item_members([1, 2, 3, 4].pack("c*"), "v2")) - assert_equal(0x01020304, m.extract_item_members([1, 2, 3, 4].pack("c*"), "L>")) - assert_equal(0x01020304, m.extract_item_members([1, 2, 3, 4].pack("c*"), "N")) - assert_equal(0x04030201, m.extract_item_members([1, 2, 3, 4].pack("c*"), "L<")) - assert_equal(0x04030201, m.extract_item_members([1, 2, 3, 4].pack("c*"), "V")) - assert_equal(0x0102030405060708, m.extract_item_members([1, 2, 3, 4, 5, 6, 7, 8].pack("c*"), "Q>")) - assert_equal(0x0807060504030201, m.extract_item_members([1, 2, 3, 4, 5, 6, 7, 8].pack("c*"), "Q<")) - end - - def test_rb_memory_view_extract_item_members_float - m = MemoryViewTestUtils - packed = [1.23].pack("f") - assert_equal(packed.unpack("f")[0], m.extract_item_members(packed, "f")) - end - - def test_rb_memory_view_extract_item_members_float_endianness - m = MemoryViewTestUtils - hi, lo = [1.23].pack("f").unpack("L")[0].divmod(0x10000) - packed = [lo, hi].pack("S*") - assert_equal(packed.unpack("e")[0], m.extract_item_members(packed, "e")) - packed = [hi, lo].pack("S*") - assert_equal(packed.unpack("g")[0], m.extract_item_members(packed, "g")) - end - - def test_rb_memory_view_extract_item_members_doble - m = MemoryViewTestUtils - packed = [1.23].pack("d") - assert_equal(1.23, m.extract_item_members(packed, "d")) - end - - def test_rb_memory_view_extract_item_members_doble_endianness - m = MemoryViewTestUtils - hi, lo = [1.23].pack("d").unpack("Q")[0].divmod(0x10000) - packed = [lo, hi].pack("L*") - assert_equal(packed.unpack("E")[0], m.extract_item_members(packed, "E")) - packed = [hi, lo].pack("L*") - assert_equal(packed.unpack("G")[0], m.extract_item_members(packed, "G")) - end - def test_rb_memory_view_available_p es = MemoryViewTestUtils::ExportableString.new("ruby") assert_equal(true, MemoryViewTestUtils.available?(es))