diff options
Diffstat (limited to 'ext/-test-/memory_view')
| -rw-r--r-- | ext/-test-/memory_view/depend | 164 | ||||
| -rw-r--r-- | ext/-test-/memory_view/extconf.rb | 5 | ||||
| -rw-r--r-- | ext/-test-/memory_view/memory_view.c | 450 |
3 files changed, 619 insertions, 0 deletions
diff --git a/ext/-test-/memory_view/depend b/ext/-test-/memory_view/depend new file mode 100644 index 0000000000..a6ffd76f45 --- /dev/null +++ b/ext/-test-/memory_view/depend @@ -0,0 +1,164 @@ +# AUTOGENERATED DEPENDENCIES START +memory_view.o: $(RUBY_EXTCONF_H) +memory_view.o: $(arch_hdrdir)/ruby/config.h +memory_view.o: $(hdrdir)/ruby.h +memory_view.o: $(hdrdir)/ruby/assert.h +memory_view.o: $(hdrdir)/ruby/backward.h +memory_view.o: $(hdrdir)/ruby/backward/2/assume.h +memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h +memory_view.o: $(hdrdir)/ruby/backward/2/bool.h +memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h +memory_view.o: $(hdrdir)/ruby/backward/2/limits.h +memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h +memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h +memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h +memory_view.o: $(hdrdir)/ruby/defines.h +memory_view.o: $(hdrdir)/ruby/intern.h +memory_view.o: $(hdrdir)/ruby/internal/abi.h +memory_view.o: $(hdrdir)/ruby/internal/anyargs.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/double.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/int.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/short.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +memory_view.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +memory_view.o: $(hdrdir)/ruby/internal/assume.h +memory_view.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +memory_view.o: $(hdrdir)/ruby/internal/attr/artificial.h +memory_view.o: $(hdrdir)/ruby/internal/attr/cold.h +memory_view.o: $(hdrdir)/ruby/internal/attr/const.h +memory_view.o: $(hdrdir)/ruby/internal/attr/constexpr.h +memory_view.o: $(hdrdir)/ruby/internal/attr/deprecated.h +memory_view.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +memory_view.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +memory_view.o: $(hdrdir)/ruby/internal/attr/error.h +memory_view.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +memory_view.o: $(hdrdir)/ruby/internal/attr/forceinline.h +memory_view.o: $(hdrdir)/ruby/internal/attr/format.h +memory_view.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +memory_view.o: $(hdrdir)/ruby/internal/attr/noalias.h +memory_view.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h +memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h +memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h +memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h +memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h +memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h +memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +memory_view.o: $(hdrdir)/ruby/internal/attr/warning.h +memory_view.o: $(hdrdir)/ruby/internal/attr/weakref.h +memory_view.o: $(hdrdir)/ruby/internal/cast.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +memory_view.o: $(hdrdir)/ruby/internal/compiler_since.h +memory_view.o: $(hdrdir)/ruby/internal/config.h +memory_view.o: $(hdrdir)/ruby/internal/constant_p.h +memory_view.o: $(hdrdir)/ruby/internal/core.h +memory_view.o: $(hdrdir)/ruby/internal/core/rarray.h +memory_view.o: $(hdrdir)/ruby/internal/core/rbasic.h +memory_view.o: $(hdrdir)/ruby/internal/core/rbignum.h +memory_view.o: $(hdrdir)/ruby/internal/core/rclass.h +memory_view.o: $(hdrdir)/ruby/internal/core/rdata.h +memory_view.o: $(hdrdir)/ruby/internal/core/rfile.h +memory_view.o: $(hdrdir)/ruby/internal/core/rhash.h +memory_view.o: $(hdrdir)/ruby/internal/core/robject.h +memory_view.o: $(hdrdir)/ruby/internal/core/rregexp.h +memory_view.o: $(hdrdir)/ruby/internal/core/rstring.h +memory_view.o: $(hdrdir)/ruby/internal/core/rstruct.h +memory_view.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +memory_view.o: $(hdrdir)/ruby/internal/ctype.h +memory_view.o: $(hdrdir)/ruby/internal/dllexport.h +memory_view.o: $(hdrdir)/ruby/internal/dosish.h +memory_view.o: $(hdrdir)/ruby/internal/error.h +memory_view.o: $(hdrdir)/ruby/internal/eval.h +memory_view.o: $(hdrdir)/ruby/internal/event.h +memory_view.o: $(hdrdir)/ruby/internal/fl_type.h +memory_view.o: $(hdrdir)/ruby/internal/gc.h +memory_view.o: $(hdrdir)/ruby/internal/glob.h +memory_view.o: $(hdrdir)/ruby/internal/globals.h +memory_view.o: $(hdrdir)/ruby/internal/has/attribute.h +memory_view.o: $(hdrdir)/ruby/internal/has/builtin.h +memory_view.o: $(hdrdir)/ruby/internal/has/c_attribute.h +memory_view.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +memory_view.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +memory_view.o: $(hdrdir)/ruby/internal/has/extension.h +memory_view.o: $(hdrdir)/ruby/internal/has/feature.h +memory_view.o: $(hdrdir)/ruby/internal/has/warning.h +memory_view.o: $(hdrdir)/ruby/internal/intern/array.h +memory_view.o: $(hdrdir)/ruby/internal/intern/bignum.h +memory_view.o: $(hdrdir)/ruby/internal/intern/class.h +memory_view.o: $(hdrdir)/ruby/internal/intern/compar.h +memory_view.o: $(hdrdir)/ruby/internal/intern/complex.h +memory_view.o: $(hdrdir)/ruby/internal/intern/cont.h +memory_view.o: $(hdrdir)/ruby/internal/intern/dir.h +memory_view.o: $(hdrdir)/ruby/internal/intern/enum.h +memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h +memory_view.o: $(hdrdir)/ruby/internal/intern/error.h +memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h +memory_view.o: $(hdrdir)/ruby/internal/intern/file.h +memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h +memory_view.o: $(hdrdir)/ruby/internal/intern/io.h +memory_view.o: $(hdrdir)/ruby/internal/intern/load.h +memory_view.o: $(hdrdir)/ruby/internal/intern/marshal.h +memory_view.o: $(hdrdir)/ruby/internal/intern/numeric.h +memory_view.o: $(hdrdir)/ruby/internal/intern/object.h +memory_view.o: $(hdrdir)/ruby/internal/intern/parse.h +memory_view.o: $(hdrdir)/ruby/internal/intern/proc.h +memory_view.o: $(hdrdir)/ruby/internal/intern/process.h +memory_view.o: $(hdrdir)/ruby/internal/intern/random.h +memory_view.o: $(hdrdir)/ruby/internal/intern/range.h +memory_view.o: $(hdrdir)/ruby/internal/intern/rational.h +memory_view.o: $(hdrdir)/ruby/internal/intern/re.h +memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h +memory_view.o: $(hdrdir)/ruby/internal/intern/select.h +memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +memory_view.o: $(hdrdir)/ruby/internal/intern/set.h +memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h +memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h +memory_view.o: $(hdrdir)/ruby/internal/intern/string.h +memory_view.o: $(hdrdir)/ruby/internal/intern/struct.h +memory_view.o: $(hdrdir)/ruby/internal/intern/thread.h +memory_view.o: $(hdrdir)/ruby/internal/intern/time.h +memory_view.o: $(hdrdir)/ruby/internal/intern/variable.h +memory_view.o: $(hdrdir)/ruby/internal/intern/vm.h +memory_view.o: $(hdrdir)/ruby/internal/interpreter.h +memory_view.o: $(hdrdir)/ruby/internal/iterator.h +memory_view.o: $(hdrdir)/ruby/internal/memory.h +memory_view.o: $(hdrdir)/ruby/internal/method.h +memory_view.o: $(hdrdir)/ruby/internal/module.h +memory_view.o: $(hdrdir)/ruby/internal/newobj.h +memory_view.o: $(hdrdir)/ruby/internal/scan_args.h +memory_view.o: $(hdrdir)/ruby/internal/special_consts.h +memory_view.o: $(hdrdir)/ruby/internal/static_assert.h +memory_view.o: $(hdrdir)/ruby/internal/stdalign.h +memory_view.o: $(hdrdir)/ruby/internal/stdbool.h +memory_view.o: $(hdrdir)/ruby/internal/stdckdint.h +memory_view.o: $(hdrdir)/ruby/internal/symbol.h +memory_view.o: $(hdrdir)/ruby/internal/value.h +memory_view.o: $(hdrdir)/ruby/internal/value_type.h +memory_view.o: $(hdrdir)/ruby/internal/variable.h +memory_view.o: $(hdrdir)/ruby/internal/warning_push.h +memory_view.o: $(hdrdir)/ruby/internal/xmalloc.h +memory_view.o: $(hdrdir)/ruby/memory_view.h +memory_view.o: $(hdrdir)/ruby/missing.h +memory_view.o: $(hdrdir)/ruby/ruby.h +memory_view.o: $(hdrdir)/ruby/st.h +memory_view.o: $(hdrdir)/ruby/subst.h +memory_view.o: memory_view.c +# AUTOGENERATED DEPENDENCIES END diff --git a/ext/-test-/memory_view/extconf.rb b/ext/-test-/memory_view/extconf.rb new file mode 100644 index 0000000000..123b80b8d0 --- /dev/null +++ b/ext/-test-/memory_view/extconf.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: false +require "mkmf" + +require_relative "../auto_ext.rb" +auto_ext(inc: true) diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c new file mode 100644 index 0000000000..63f0beb81e --- /dev/null +++ b/ext/-test-/memory_view/memory_view.c @@ -0,0 +1,450 @@ +#include "ruby.h" + +#ifdef HAVE_RUBY_MEMORY_VIEW_H +#include "ruby/memory_view.h" + +#define STRUCT_ALIGNOF(T, result) do { \ + (result) = RUBY_ALIGNOF(T); \ +} while(0) + +static ID id_str; +static VALUE sym_format; +static VALUE sym_native_size_p; +static VALUE sym_offset; +static VALUE sym_size; +static VALUE sym_repeat; +static VALUE sym_obj; +static VALUE sym_byte_size; +static VALUE sym_readonly; +static VALUE sym_format; +static VALUE sym_item_size; +static VALUE sym_ndim; +static VALUE sym_shape; +static VALUE sym_strides; +static VALUE sym_sub_offsets; +static VALUE sym_endianness; +static VALUE sym_little_endian; +static VALUE sym_big_endian; + +static bool +exportable_string_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags) +{ + VALUE str = rb_ivar_get(obj, id_str); + rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(str), RSTRING_LEN(str), true); + return true; +} + +static bool +exportable_string_memory_view_available_p(VALUE obj) +{ + VALUE str = rb_ivar_get(obj, id_str); + return !NIL_P(str); +} + +static const rb_memory_view_entry_t exportable_string_memory_view_entry = { + exportable_string_get_memory_view, + NULL, + exportable_string_memory_view_available_p +}; + +static VALUE +memory_view_available_p(VALUE mod, VALUE obj) +{ + return rb_memory_view_available_p(obj) ? Qtrue : Qfalse; +} + +static VALUE +memory_view_register(VALUE mod, VALUE obj) +{ + return rb_memory_view_register(obj, &exportable_string_memory_view_entry) ? Qtrue : Qfalse; +} + +static VALUE +memory_view_item_size_from_format(VALUE mod, VALUE format) +{ + const char *c_str = NULL; + if (!NIL_P(format)) + c_str = StringValueCStr(format); + const char *err = NULL; + ssize_t item_size = rb_memory_view_item_size_from_format(c_str, &err); + if (!err) + return rb_assoc_new(SSIZET2NUM(item_size), Qnil); + else + return rb_assoc_new(SSIZET2NUM(item_size), rb_str_new_cstr(err)); +} + +static VALUE +memory_view_parse_item_format(VALUE mod, VALUE format) +{ + const char *c_str = NULL; + if (!NIL_P(format)) + c_str = StringValueCStr(format); + const char *err = NULL; + + rb_memory_view_item_component_t *members; + size_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; + 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)); + rb_hash_aset(member, sym_native_size_p, members[i].native_size_p ? Qtrue : Qfalse); + rb_hash_aset(member, sym_endianness, members[i].little_endian_p ? sym_little_endian : sym_big_endian); + rb_hash_aset(member, sym_offset, SSIZET2NUM(members[i].offset)); + rb_hash_aset(member, sym_size, SSIZET2NUM(members[i].size)); + rb_hash_aset(member, sym_repeat, SSIZET2NUM(members[i].repeat)); + rb_ary_push(ary, member); + } + xfree(members); + rb_ary_push(result, ary); + rb_ary_push(result, Qnil); + } + else { + rb_ary_push(result, Qnil); // members + rb_ary_push(result, rb_str_new_cstr(err)); + } + + return result; +} + +static VALUE +memory_view_get_memory_view_info(VALUE mod, VALUE obj) +{ + rb_memory_view_t view; + + if (!rb_memory_view_get(obj, &view, 0)) { + return Qnil; + } + + VALUE hash = rb_hash_new(); + rb_hash_aset(hash, sym_obj, view.obj); + rb_hash_aset(hash, sym_byte_size, SSIZET2NUM(view.byte_size)); + rb_hash_aset(hash, sym_readonly, view.readonly ? Qtrue : Qfalse); + rb_hash_aset(hash, sym_format, view.format ? rb_str_new_cstr(view.format) : Qnil); + rb_hash_aset(hash, sym_item_size, SSIZET2NUM(view.item_size)); + rb_hash_aset(hash, sym_ndim, SSIZET2NUM(view.ndim)); + + if (view.shape) { + VALUE shape = rb_ary_new_capa(view.ndim); + rb_hash_aset(hash, sym_shape, shape); + } + else { + rb_hash_aset(hash, sym_shape, Qnil); + } + + if (view.strides) { + VALUE strides = rb_ary_new_capa(view.ndim); + rb_hash_aset(hash, sym_strides, strides); + } + else { + rb_hash_aset(hash, sym_strides, Qnil); + } + + if (view.sub_offsets) { + VALUE sub_offsets = rb_ary_new_capa(view.ndim); + rb_hash_aset(hash, sym_sub_offsets, sub_offsets); + } + else { + rb_hash_aset(hash, sym_sub_offsets, Qnil); + } + + rb_memory_view_release(&view); + + return hash; +} + +static VALUE +memory_view_fill_contiguous_strides(VALUE mod, VALUE ndim_v, VALUE item_size_v, VALUE shape_v, VALUE row_major_p) +{ + ssize_t i, ndim = NUM2SSIZET(ndim_v); + + Check_Type(shape_v, T_ARRAY); + ssize_t *shape = ALLOC_N(ssize_t, ndim); + for (i = 0; i < ndim; ++i) { + shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i)); + } + + ssize_t *strides = ALLOC_N(ssize_t, ndim); + rb_memory_view_fill_contiguous_strides(ndim, NUM2SSIZET(item_size_v), shape, RTEST(row_major_p), strides); + + VALUE result = rb_ary_new_capa(ndim); + for (i = 0; i < ndim; ++i) { + rb_ary_push(result, SSIZET2NUM(strides[i])); + } + + xfree(strides); + xfree(shape); + + return result; +} + +static VALUE +memory_view_get_ref_count(VALUE obj) +{ + if (rb_memory_view_exported_object_registry == Qundef) { + return Qnil; + } + + st_table *table; + TypedData_Get_Struct(rb_memory_view_exported_object_registry, st_table, + &rb_memory_view_exported_object_registry_data_type, + table); + + st_data_t count; + if (st_lookup(table, (st_data_t)obj, &count)) { + return ULL2NUM(count); + } + + return Qnil; +} + +static VALUE +memory_view_ref_count_while_exporting_i(VALUE obj, long n) +{ + if (n == 0) { + return memory_view_get_ref_count(obj); + } + + rb_memory_view_t view; + if (!rb_memory_view_get(obj, &view, 0)) { + return Qnil; + } + + VALUE ref_count = memory_view_ref_count_while_exporting_i(obj, n-1); + rb_memory_view_release(&view); + + return ref_count; +} + +static VALUE +memory_view_ref_count_while_exporting(VALUE mod, VALUE obj, VALUE n) +{ + Check_Type(n, T_FIXNUM); + 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) +{ + if (!NIL_P(s)) { + Check_Type(s, T_STRING); + } + rb_ivar_set(obj, id_str, s); + return Qnil; +} + +static bool +mdview_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags) +{ + VALUE buf_v = rb_ivar_get(obj, id_str); + VALUE format_v = rb_ivar_get(obj, SYM2ID(sym_format)); + VALUE shape_v = rb_ivar_get(obj, SYM2ID(sym_shape)); + VALUE strides_v = rb_ivar_get(obj, SYM2ID(sym_strides)); + + const char *err; + const ssize_t item_size = rb_memory_view_item_size_from_format(RSTRING_PTR(format_v), &err); + if (item_size < 0) { + return false; + } + + ssize_t ndim = RARRAY_LEN(shape_v); + if (!NIL_P(strides_v) && RARRAY_LEN(strides_v) != ndim) { + rb_raise(rb_eArgError, "strides has an invalid dimension"); + } + + ssize_t *shape = ALLOC_N(ssize_t, ndim); + ssize_t *strides = ALLOC_N(ssize_t, ndim); + ssize_t i; + if (!NIL_P(strides_v)) { + for (i = 0; i < ndim; ++i) { + shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i)); + strides[i] = NUM2SSIZET(RARRAY_AREF(strides_v, i)); + } + } + else { + for (i = 0; i < ndim; ++i) { + shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i)); + } + + i = ndim - 1; + strides[i] = item_size; + for (; i > 0; --i) { + strides[i-1] = strides[i] * shape[i]; + } + } + + rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(buf_v), RSTRING_LEN(buf_v), true); + view->format = RSTRING_PTR(format_v); + view->item_size = item_size; + view->ndim = ndim; + view->shape = shape; + view->strides = strides; + view->sub_offsets = NULL; + + return true; +} + +static bool +mdview_release_memory_view(VALUE obj, rb_memory_view_t *view) +{ + xfree((void *)view->shape); + xfree((void *)view->strides); + + return true; +} + +static bool +mdview_memory_view_available_p(VALUE obj) +{ + return true; +} + +static const rb_memory_view_entry_t mdview_memory_view_entry = { + mdview_get_memory_view, + mdview_release_memory_view, + mdview_memory_view_available_p +}; + +static VALUE +mdview_initialize(VALUE obj, VALUE buf, VALUE format, VALUE shape, VALUE strides) +{ + Check_Type(buf, T_STRING); + StringValue(format); + Check_Type(shape, T_ARRAY); + if (!NIL_P(strides)) Check_Type(strides, T_ARRAY); + + rb_ivar_set(obj, id_str, buf); + rb_ivar_set(obj, SYM2ID(sym_format), format); + rb_ivar_set(obj, SYM2ID(sym_shape), shape); + rb_ivar_set(obj, SYM2ID(sym_strides), strides); + return Qnil; +} + +static VALUE +mdview_aref(VALUE obj, VALUE indices_v) +{ + Check_Type(indices_v, T_ARRAY); + + rb_memory_view_t view; + if (!rb_memory_view_get(obj, &view, 0)) { + rb_raise(rb_eRuntimeError, "rb_memory_view_get: failed"); + } + + if (RARRAY_LEN(indices_v) != view.ndim) { + rb_raise(rb_eKeyError, "Indices has an invalid dimension"); + } + + VALUE buf_indices; + ssize_t *indices = ALLOCV_N(ssize_t, buf_indices, view.ndim); + + ssize_t i; + for (i = 0; i < view.ndim; ++i) { + indices[i] = NUM2SSIZET(RARRAY_AREF(indices_v, i)); + } + + VALUE result = rb_memory_view_get_item(&view, indices); + ALLOCV_END(buf_indices); + rb_memory_view_release(&view); + + return result; +} + +#endif /* HAVE_RUBY_MEMORY_VIEW_H */ + +void +Init_memory_view(void) +{ + rb_ext_ractor_safe(true); +#ifdef HAVE_RUBY_MEMORY_VIEW_H + VALUE mMemoryViewTestUtils = rb_define_module("MemoryViewTestUtils"); + + rb_define_module_function(mMemoryViewTestUtils, "available?", memory_view_available_p, 1); + rb_define_module_function(mMemoryViewTestUtils, "register", memory_view_register, 1); + rb_define_module_function(mMemoryViewTestUtils, "item_size_from_format", memory_view_item_size_from_format, 1); + rb_define_module_function(mMemoryViewTestUtils, "parse_item_format", memory_view_parse_item_format, 1); + 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); + rb_memory_view_register(cExportableString, &exportable_string_memory_view_entry); + + VALUE cMDView = rb_define_class_under(mMemoryViewTestUtils, "MultiDimensionalView", rb_cObject); + rb_define_method(cMDView, "initialize", mdview_initialize, 4); + rb_define_method(cMDView, "[]", mdview_aref, 1); + rb_memory_view_register(cMDView, &mdview_memory_view_entry); + + id_str = rb_intern_const("__str__"); + sym_format = ID2SYM(rb_intern_const("format")); + sym_native_size_p = ID2SYM(rb_intern_const("native_size_p")); + sym_offset = ID2SYM(rb_intern_const("offset")); + sym_size = ID2SYM(rb_intern_const("size")); + sym_repeat = ID2SYM(rb_intern_const("repeat")); + sym_obj = ID2SYM(rb_intern_const("obj")); + sym_byte_size = ID2SYM(rb_intern_const("byte_size")); + sym_readonly = ID2SYM(rb_intern_const("readonly")); + sym_format = ID2SYM(rb_intern_const("format")); + sym_item_size = ID2SYM(rb_intern_const("item_size")); + sym_ndim = ID2SYM(rb_intern_const("ndim")); + sym_shape = ID2SYM(rb_intern_const("shape")); + sym_strides = ID2SYM(rb_intern_const("strides")); + sym_sub_offsets = ID2SYM(rb_intern_const("sub_offsets")); + sym_endianness = ID2SYM(rb_intern_const("endianness")); + sym_little_endian = ID2SYM(rb_intern_const("little_endian")); + sym_big_endian = ID2SYM(rb_intern_const("big_endian")); + +#ifdef WORDS_BIGENDIAN + rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_big_endian); +#else + rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_little_endian); +#endif + +#define DEF_ALIGNMENT_CONST(type, TYPE) do { \ + int alignment; \ + STRUCT_ALIGNOF(type, alignment); \ + rb_const_set(mMemoryViewTestUtils, rb_intern_const(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \ +} while(0) + + DEF_ALIGNMENT_CONST(short, SHORT); + DEF_ALIGNMENT_CONST(int, INT); + DEF_ALIGNMENT_CONST(long, LONG); + DEF_ALIGNMENT_CONST(LONG_LONG, LONG_LONG); + DEF_ALIGNMENT_CONST(int16_t, INT16); + DEF_ALIGNMENT_CONST(int32_t, INT32); + DEF_ALIGNMENT_CONST(int64_t, INT64); + DEF_ALIGNMENT_CONST(intptr_t, INTPTR); + DEF_ALIGNMENT_CONST(float, FLOAT); + DEF_ALIGNMENT_CONST(double, DOUBLE); + +#undef DEF_ALIGNMENT_CONST + +#endif /* HAVE_RUBY_MEMORY_VIEW_H */ +} |
