11#include "internal/variable.h"
16#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
17# define INTPTR2NUM LL2NUM
18# define UINTPTR2NUM ULL2NUM
19#elif SIZEOF_INTPTR_T == SIZEOF_LONG
20# define INTPTR2NUM LONG2NUM
21# define UINTPTR2NUM ULONG2NUM
23# define INTPTR2NUM INT2NUM
24# define UINTPTR2NUM UINT2NUM
28#define STRUCT_ALIGNOF(T, result) do { \
29 (result) = RUBY_ALIGNOF(T); \
45exported_object_registry_mark(
void *
ptr)
48 st_foreach(exported_object_table, exported_object_registry_mark_key_i, 0);
52exported_object_registry_free(
void *
ptr)
57 exported_object_table =
NULL;
62 "memory_view/exported_object_registry",
64 exported_object_registry_mark,
65 exported_object_registry_free,
100register_exported_object(
VALUE obj)
108unregister_exported_object(
VALUE obj)
117static ID id_memory_view;
134 if (!
NIL_P(entry_obj)) {
149 const ssize_t ndim = view->
ndim;
150 const ssize_t *shape = view->
shape;
151 const ssize_t *strides = view->
strides;
154 for (i = ndim - 1; i >= 0; --i) {
155 if (strides[i] != n)
return false;
165 const ssize_t ndim = view->
ndim;
166 const ssize_t *shape = view->
shape;
167 const ssize_t *strides = view->
strides;
170 for (i = 0; i < ndim; ++i) {
171 if (strides[i] != n)
return false;
181 ssize_t i, n = item_size;
183 for (i = ndim - 1; i >= 0; --i) {
189 for (i = 0; i < ndim; ++i) {
217#ifdef HAVE_TRUE_LONG_LONG
218static const char native_types[] =
"sSiIlLqQjJ";
220static const char native_types[] =
"sSiIlLjJ";
222static const char endianness_types[] =
"sSiIlLqQjJ";
231get_format_size(
const char *format,
bool *native_p, ssize_t *alignment,
endianness_t *endianness, ssize_t *
count,
const char **next_format,
VALUE *
error)
243 const int type_char = *format;
250 if (
strchr(native_types, type_char)) {
257 rb_sprintf(
"Unable to specify native size for '%c'", type_char));
265 if (!
strchr(endianness_types, type_char)) {
268 rb_sprintf(
"Unable to specify endianness for '%c'", type_char));
289 if (
'0' <= ch && ch <=
'9') {
291 while (
'0' <= (ch = format[i]) && ch <=
'9') {
298 *next_format = &format[i];
312 return sizeof(short);
343 return sizeof(float);
349 return sizeof(LONG_LONG);
358 return sizeof(double);
375calculate_padding(ssize_t total, ssize_t alignment_size) {
376 if (alignment_size > 1) {
377 ssize_t res = total % alignment_size;
379 return alignment_size - res;
388 size_t *n_members,
const char **
err)
390 if (format ==
NULL)
return 1;
395 bool alignment =
false;
396 ssize_t max_alignment_size = 0;
398 const char *p = format;
413 bool native_size_p =
false;
414 ssize_t alignment_size = 0;
417 const ssize_t
size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &
count, &p, &
error);
422 if (max_alignment_size < alignment_size) {
423 max_alignment_size = alignment_size;
426 const ssize_t padding = alignment ? calculate_padding(total, alignment_size) : 0;
435 if (alignment && max_alignment_size > 0) {
436 const ssize_t padding = calculate_padding(total, max_alignment_size);
440 if (members && n_members) {
443 ssize_t i = 0,
offset = 0;
444 const char *p = format;
446 const int type_char = *p;
449 ssize_t alignment_size = 0;
452 const ssize_t
size = get_format_size(p, &native_size_p, &alignment_size, &endianness, &
count, &p,
NULL);
454 const ssize_t padding = alignment ? calculate_padding(
offset, alignment_size) : 0;
457 if (type_char !=
'x') {
458#ifdef WORDS_BIGENDIAN
469 little_endian_p =
true;
475 little_endian_p =
false;
483 .native_size_p = native_size_p,
484 .little_endian_p = little_endian_p,
514 if (view->
ndim == 1) {
516 return ptr + indices[0] * stride;
525 for (i = 0; i < view->
ndim; ++i) {
526 stride *= view->
shape[i];
528 for (i = 0; i < view->
ndim; ++i) {
529 stride /= view->
shape[i];
530 ptr += indices[i] * stride;
535 for (i = 0; i < view->
ndim; ++i) {
541 for (i = 0; i < view->
ndim; ++i) {
577#ifdef WORDS_BIGENDIAN
585 if (member->
format ==
'c') {
588 else if (member->
format ==
'C') {
589 return INT2FIX(*(
unsigned char *)p);
600 unsigned LONG_LONG ull;
613 if (!native_endian_p) {
674#if SIZEOF_INT64_t == SIZEOF_LONG
686#if SIZEOF_UINT64_t == SIZEOF_LONG
717 return extract_item_member(
ptr, member, i);
728 if (n_members == 0)
return Qnil;
730 if (n_members == 1 && members[0].repeat == 1) {
736 for (i = 0; i < n_members; ++i) {
737 for (j = 0; j < members[i].
repeat; ++j) {
738 VALUE v = extract_item_member(
ptr, &members[i], j);
756 "Unable to parse item format at %"PRIdSIZE" in \"%s\"",
780lookup_memory_view_entry(
VALUE klass)
783 while (
NIL_P(entry_obj)) {
821 bool rv = (*entry->
get_func)(obj, view, flags);
823 register_exported_object(view->
obj);
843 unregister_exported_object(view->
obj);
864 exported_object_table);
868 id_memory_view = rb_intern_const(
"__memory_view__");
VALUE rb_ary_push(VALUE ary, VALUE item)
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy iff RUBY_DEBUG is truthy.
#define UNREACHABLE_RETURN
char * strchr(char *, char)
const signed char ruby_digit36_to_number_table[]
void rb_gc_mark(VALUE ptr)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
void rb_raise(VALUE exc, const char *fmt,...)
int rb_typeddata_is_kind_of(VALUE obj, const rb_data_type_t *data_type)
VALUE rb_exc_new_str(VALUE etype, VALUE str)
void rb_warning(const char *fmt,...)
VALUE rb_class_get_superclass(VALUE)
Returns the superclass of klass The return value might be an iclass of a module, unlike rb_class_supe...
VALUE rb_cObject
Object class.
VALUE rb_cBasicObject
BasicObject class.
st_table * rb_init_identtable(void)
#define rb_exc_new_cstr(exc, str)
VALUE rb_ivar_set(VALUE, ID, VALUE)
Internal header for Hash.
Internal header corresponding util.c.
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define MEMCPY(p1, p2, type, n)
void * rb_memory_view_get_item_pointer(rb_memory_view_t *view, const ssize_t *indices)
bool rb_memory_view_is_row_major_contiguous(const rb_memory_view_t *view)
bool rb_memory_view_release(rb_memory_view_t *view)
VALUE rb_memory_view_extract_item_members(const void *ptr, const rb_memory_view_item_component_t *members, const size_t n_members)
ssize_t rb_memory_view_item_size_from_format(const char *format, const char **err)
bool rb_memory_view_get(VALUE obj, rb_memory_view_t *view, int flags)
void Init_MemoryView(void)
void rb_memory_view_fill_contiguous_strides(const ssize_t ndim, const ssize_t item_size, const ssize_t *const shape, const bool row_major_p, ssize_t *const strides)
bool rb_memory_view_available_p(VALUE obj)
bool rb_memory_view_is_column_major_contiguous(const rb_memory_view_t *view)
VALUE rb_memory_view_exported_object_registry
bool rb_memory_view_register(VALUE klass, const rb_memory_view_entry_t *entry)
VALUE rb_memory_view_extract_item_member(const void *ptr, const rb_memory_view_item_component_t *member, const size_t i)
bool rb_memory_view_init_as_byte_array(rb_memory_view_t *view, VALUE obj, void *data, const ssize_t len, const bool readonly)
VALUE rb_memory_view_get_item(rb_memory_view_t *view, const ssize_t *indices)
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)
#define STRUCT_ALIGNOF(T, result)
void rb_memory_view_prepare_item_desc(rb_memory_view_t *view)
const rb_data_type_t rb_memory_view_exported_object_registry_data_type
uint32_t u32[type_roomof(hash_salt_t, uint32_t)]
#define RTYPEDDATA_DATA(v)
#define TypedData_Wrap_Struct(klass, data_type, sval)
@ RUBY_TYPED_FREE_IMMEDIATELY
unsigned long long uint64_t
VALUE rb_sprintf(const char *,...)
rb_memory_view_release_func_t release_func
rb_memory_view_available_p_func_t available_p_func
rb_memory_view_get_func_t get_func
const rb_memory_view_item_component_t * components
const ssize_t * sub_offsets
struct rb_memory_view_t::@106 item_desc
void error(const char *msg)
#define ASSERT_vm_locking()
#define RB_VM_LOCK_ENTER()
#define RB_VM_LOCK_LEAVE()