numo-narray-alt 0.11.2 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62b615bb540e3a9d9783fa984943437f42ad5bbcf93041dead8d770317d8fcf6
4
- data.tar.gz: 895c80b9b6544f09d04412a6a96439999752a9636d1b243127d96007f2574ba5
3
+ metadata.gz: 49f4c26235333f8e467b493aa8dda971e62599966dc12c0d81a5a0fae939bb6d
4
+ data.tar.gz: 134d4eafee1f7b1165c8700c3fb2038ed018c7e36043926ed382cc3f8d1e94c6
5
5
  SHA512:
6
- metadata.gz: d6b5ac1dbfd8bb0f448a8c073de8f7951a9f571b20c9f88b864549f31dd828209cd67c4e7b629f2756ece9e98de6ad26a5b37a8f6131f836de259e25895bfd23
7
- data.tar.gz: eea7716214274464d8e4fb4874d4415cf49a97ad7e0f15c15211257cb531604c7822913cf15d7a5ebba49df58de845b788a8558b04ac98ec3d5540fc62b527b3
6
+ metadata.gz: f9d2b83363362f38302ed35d4c3dba6807bdc90a343c0814adb78a0bd1055d7c0dd9690bbd4a69cab32b802d57f4c602f82405a17a0a5371a74d31602988165c
7
+ data.tar.gz: edd47b6629ca041b3db6b843cb15887ae0a8d64d2be53d0fd683009108091a4ea679cd2c41e030a31e67548d931fa328aa724cdd1c548ec6bda808fbe40ae773
@@ -8,6 +8,7 @@
8
8
  #include "numo/narray.h"
9
9
  #include "numo/template.h"
10
10
 
11
+ static ID id_copy;
11
12
  static ID id_mulsum;
12
13
  static ID id_store;
13
14
  static ID id_swap_byte;
@@ -105,7 +106,11 @@ static VALUE nary_swap_byte(VALUE self) {
105
106
  ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } };
106
107
  ndfunc_t ndf = { iter_swap_byte, FULL_LOOP | NDF_ACCEPT_BYTESWAP, 1, 1, ain, aout };
107
108
 
108
- v = na_ndloop(&ndf, 1, self);
109
+ if (RTEST(rb_obj_is_kind_of(self, numo_cBit))) {
110
+ v = TEST_INPLACE(self) ? self : rb_funcall(self, id_copy, 0);
111
+ } else {
112
+ v = na_ndloop(&ndf, 1, self);
113
+ }
109
114
  if (self != v) {
110
115
  na_copy_flags(self, v);
111
116
  }
@@ -359,6 +364,10 @@ static void na_check_reshape(int argc, VALUE* argv, VALUE self, size_t* shape) {
359
364
  } else if (total != NA_SIZE(na)) {
360
365
  rb_raise(rb_eArgError, "Total size must be same");
361
366
  }
367
+
368
+ if (argc > NA_MAX_DIMENSION) {
369
+ rb_raise(nary_eDimensionError, "ndim=%d is too many", argc);
370
+ }
362
371
  }
363
372
 
364
373
  /*
@@ -376,11 +385,15 @@ static VALUE na_reshape_bang(int argc, VALUE* argv, VALUE self) {
376
385
  ssize_t stride;
377
386
  stridx_t* stridx;
378
387
  int i;
388
+ VALUE tmp;
379
389
 
390
+ if (OBJ_FROZEN(self)) {
391
+ rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
392
+ }
380
393
  if (na_check_contiguous(self) == Qfalse) {
381
394
  rb_raise(rb_eStandardError, "cannot change shape of non-contiguous NArray");
382
395
  }
383
- shape = ALLOCA_N(size_t, argc);
396
+ shape = RB_ALLOCV_N(size_t, tmp, argc);
384
397
  na_check_reshape(argc, argv, self, shape);
385
398
 
386
399
  GetNArray(self, na);
@@ -391,7 +404,11 @@ static VALUE na_reshape_bang(int argc, VALUE* argv, VALUE self) {
391
404
  } else {
392
405
  stridx = na2->stridx;
393
406
  }
394
- stride = SDX_GET_STRIDE(na2->stridx[na->ndim - 1]);
407
+ if (na->ndim == 0) {
408
+ stride = nary_element_stride(self);
409
+ } else {
410
+ stride = SDX_GET_STRIDE(na2->stridx[na->ndim - 1]);
411
+ }
395
412
  for (i = argc; i--;) {
396
413
  SDX_SET_STRIDE(stridx[i], stride);
397
414
  stride *= shape[i];
@@ -402,6 +419,7 @@ static VALUE na_reshape_bang(int argc, VALUE* argv, VALUE self) {
402
419
  }
403
420
  }
404
421
  na_setup_shape(na, argc, shape);
422
+ RB_ALLOCV_END(tmp);
405
423
  return self;
406
424
  }
407
425
 
@@ -416,14 +434,15 @@ static VALUE na_reshape_bang(int argc, VALUE* argv, VALUE self) {
416
434
  static VALUE na_reshape(int argc, VALUE* argv, VALUE self) {
417
435
  size_t* shape;
418
436
  narray_t* na;
419
- VALUE copy;
437
+ VALUE copy, tmp;
420
438
 
421
- shape = ALLOCA_N(size_t, argc);
439
+ shape = RB_ALLOCV_N(size_t, tmp, argc);
422
440
  na_check_reshape(argc, argv, self, shape);
423
441
 
424
442
  copy = rb_funcall(self, rb_intern("dup"), 0);
425
443
  GetNArray(copy, na);
426
444
  na_setup_shape(na, argc, shape);
445
+ RB_ALLOCV_END(tmp);
427
446
  return copy;
428
447
  }
429
448
 
@@ -505,6 +524,9 @@ na_flatten_dim(VALUE self, int sd) {
505
524
  // set index
506
525
  idx2 = ALLOC_N(size_t, (shape[sd] == 0) ? 1 : shape[sd]);
507
526
  SDX_SET_INDEX(na2->stridx[sd], idx2);
527
+ if (shape[sd] == 0) {
528
+ return view;
529
+ }
508
530
  // init for md-loop
509
531
  fd = nd - sd;
510
532
  c = ALLOCA_N(size_t, fd);
@@ -965,6 +987,7 @@ void Init_nary_data(void) {
965
987
 
966
988
  // rb_define_method(cNArray, "dot", numo_na_dot, 1);
967
989
 
990
+ id_copy = rb_intern("copy");
968
991
  id_mulsum = rb_intern("mulsum");
969
992
  id_store = rb_intern("store");
970
993
  id_swap_byte = rb_intern("swap_byte");
@@ -439,7 +439,9 @@ static size_t na_index_parse_args(VALUE args, narray_t* na, na_index_arg_t* q, i
439
439
  }
440
440
  // new dimension
441
441
  else if (v == sym_new) {
442
- na_index_parse_each(v, 1, k, &q[j]);
442
+ // Past the last dimension, which is how the aref functions below tell
443
+ // a new axis from a real one.
444
+ na_index_parse_each(v, 1, na->ndim, &q[j]);
443
445
  j++;
444
446
  }
445
447
  // other dimension
@@ -465,6 +467,25 @@ static void na_get_strides_nadata(const narray_data_t* na, ssize_t* strides, ssi
465
467
  }
466
468
  }
467
469
 
470
+ // A new axis holds one element, so any stride addresses it. Give it the size of
471
+ // the block below it, to keep the chain na_check_ladder() walks: a break there
472
+ // costs contiguous?, and na_flatten_dim() takes the last dimension's stride as
473
+ // the flat one on the strength of that same chain.
474
+ static void na_index_set_newaxis_strides(
475
+ narray_view_t* na2, const int* newaxis, int n_newaxes, int ndim_new
476
+ ) {
477
+ int i, j;
478
+
479
+ for (i = n_newaxes - 1; i >= 0; i--) {
480
+ j = newaxis[i];
481
+ if (j + 1 < ndim_new && SDX_IS_STRIDE(na2->stridx[j + 1])) {
482
+ SDX_SET_STRIDE(
483
+ na2->stridx[j], SDX_GET_STRIDE(na2->stridx[j + 1]) * (ssize_t)na2->base.shape[j + 1]
484
+ );
485
+ }
486
+ }
487
+ }
488
+
468
489
  static void na_index_aref_nadata(
469
490
  narray_data_t* na1, narray_view_t* na2, na_index_arg_t* q, ssize_t elmsz, int ndim,
470
491
  int keep_dim
@@ -475,8 +496,11 @@ static void na_index_aref_nadata(
475
496
  ssize_t* strides_na1;
476
497
  size_t* index;
477
498
  ssize_t beg, step;
499
+ int* newaxis;
500
+ int n_newaxes = 0;
478
501
  VALUE m;
479
502
 
503
+ newaxis = ALLOCA_N(int, ndim);
480
504
  strides_na1 = ALLOCA_N(ssize_t, na1->base.ndim);
481
505
  na_get_strides_nadata(na1, strides_na1, elmsz);
482
506
 
@@ -503,6 +527,7 @@ static void na_index_aref_nadata(
503
527
 
504
528
  if (qi_orig_dim >= na1->base.ndim) {
505
529
  // new dimension
530
+ newaxis[n_newaxes++] = j;
506
531
  SDX_SET_STRIDE(na2->stridx[j], elmsz);
507
532
  } else if (q[i].idx != NULL) {
508
533
  // array index
@@ -521,6 +546,7 @@ static void na_index_aref_nadata(
521
546
  j++;
522
547
  total *= size;
523
548
  }
549
+ na_index_set_newaxis_strides(na2, newaxis, n_newaxes, j);
524
550
  na2->base.size = total;
525
551
  }
526
552
 
@@ -530,6 +556,10 @@ static void na_index_aref_naview(
530
556
  ) {
531
557
  int i, j;
532
558
  ssize_t total = 1;
559
+ int* newaxis;
560
+ int n_newaxes = 0;
561
+
562
+ newaxis = ALLOCA_N(int, ndim);
533
563
 
534
564
  for (i = j = 0; i < ndim; i++) {
535
565
  stridx_t sdx1;
@@ -560,6 +590,7 @@ static void na_index_aref_naview(
560
590
 
561
591
  if (qi_orig_dim >= na1->base.ndim) {
562
592
  // new dimension
593
+ newaxis[n_newaxes++] = j;
563
594
  SDX_SET_STRIDE(na2->stridx[j], elmsz);
564
595
  } else if (q[i].idx != NULL && SDX_IS_INDEX(sdx1)) {
565
596
  // index <- index
@@ -618,6 +649,7 @@ static void na_index_aref_naview(
618
649
  j++;
619
650
  total *= size;
620
651
  }
652
+ na_index_set_newaxis_strides(na2, newaxis, n_newaxes, j);
621
653
  na2->base.size = total;
622
654
  }
623
655
 
@@ -838,7 +870,10 @@ int na_get_result_dimension(
838
870
  }
839
871
 
840
872
  if (j != argc) {
841
- return check_index_count(argc, na->ndim, count_new, count_rest);
873
+ int nd = check_index_count(argc, na->ndim, count_new, count_rest);
874
+ if (nd != 0) {
875
+ return nd;
876
+ }
842
877
  }
843
878
 
844
879
  switch (na->type) {
@@ -275,7 +275,18 @@ void na_array_to_internal_shape(VALUE self, VALUE ary, size_t* shape) {
275
275
  }
276
276
  }
277
277
 
278
+ static void na_check_ndim(int ndim) {
279
+ if (ndim < 0) {
280
+ rb_raise(nary_eDimensionError, "ndim=%d is negative", ndim);
281
+ }
282
+ if (ndim > NA_MAX_DIMENSION) {
283
+ rb_raise(nary_eDimensionError, "ndim=%d is too many", ndim);
284
+ }
285
+ }
286
+
278
287
  void na_alloc_shape(narray_t* na, int ndim) {
288
+ na_check_ndim(ndim);
289
+
279
290
  na->ndim = ndim;
280
291
  na->size = 0;
281
292
  if (na->shape != NULL && na->shape != &(na->size)) {
@@ -288,12 +299,6 @@ void na_alloc_shape(narray_t* na, int ndim) {
288
299
  na->shape = &(na->size);
289
300
  break;
290
301
  default:
291
- if (ndim < 0) {
292
- rb_raise(nary_eDimensionError, "ndim=%d is negative", ndim);
293
- }
294
- if (ndim > NA_MAX_DIMENSION) {
295
- rb_raise(nary_eDimensionError, "ndim=%d is too many", ndim);
296
- }
297
302
  na->shape = ALLOC_N(size_t, ndim);
298
303
  }
299
304
  }
@@ -302,19 +307,23 @@ void na_setup_shape(narray_t* na, int ndim, size_t* shape) {
302
307
  int i;
303
308
  size_t size;
304
309
 
310
+ na_check_ndim(ndim);
311
+
312
+ for (i = 0, size = 1; i < ndim; i++) {
313
+ if (shape[i] != 0 && size > SIZE_MAX / shape[i]) {
314
+ rb_raise(rb_eRangeError, "total number of elements is too large");
315
+ }
316
+ size *= shape[i];
317
+ }
318
+
305
319
  na_alloc_shape(na, ndim);
306
320
 
307
- if (ndim == 0) {
308
- na->size = 1;
309
- } else if (ndim == 1) {
310
- na->size = shape[0];
311
- } else {
312
- for (i = 0, size = 1; i < ndim; i++) {
321
+ if (ndim > 1) {
322
+ for (i = 0; i < ndim; i++) {
313
323
  na->shape[i] = shape[i];
314
- size *= shape[i];
315
324
  }
316
- na->size = size;
317
325
  }
326
+ na->size = (ndim == 0) ? 1 : size;
318
327
  }
319
328
 
320
329
  static void na_setup(VALUE self, int ndim, size_t* shape) {
@@ -876,6 +885,9 @@ na_check_ladder(VALUE self, int start_dim) {
876
885
  narray_t* na;
877
886
  GetNArray(self, na);
878
887
 
888
+ if (na->ndim == 0) {
889
+ return Qtrue;
890
+ }
879
891
  if (start_dim < -na->ndim || start_dim >= na->ndim) {
880
892
  rb_bug("start_dim (%d) out of range", start_dim);
881
893
  }
@@ -920,6 +932,9 @@ na_check_contiguous(VALUE self) {
920
932
  if (NA_VIEW_STRIDX(na) == 0) {
921
933
  return Qtrue;
922
934
  }
935
+ if (NA_NDIM(na) == 0) {
936
+ return Qtrue;
937
+ }
923
938
  if (na_check_ladder(self, 0) == Qtrue) {
924
939
  elmsz = nary_element_stride(self);
925
940
  if (elmsz == NA_STRIDE_AT(na, NA_NDIM(na) - 1)) {
@@ -1043,6 +1058,7 @@ static VALUE na_expand_dims(VALUE self, VALUE vdim) {
1043
1058
 
1044
1059
  GetNArray(self, na);
1045
1060
  nd = na->ndim;
1061
+ na_check_ndim(nd + 1);
1046
1062
 
1047
1063
  dim = NUM2INT(vdim);
1048
1064
  if (dim < -nd - 1 || dim > nd) {
@@ -1272,7 +1288,11 @@ static VALUE nary_s_from_binary(int argc, VALUE* argv, VALUE type) {
1272
1288
  rb_raise(rb_eArgError, "second argument must be size or shape");
1273
1289
  }
1274
1290
  if (FIXNUM_P(velmsz)) {
1275
- byte_size = len * NUM2SIZET(velmsz);
1291
+ size_t elmsz = NUM2SIZET(velmsz);
1292
+ if (elmsz != 0 && len > SIZE_MAX / elmsz) {
1293
+ rb_raise(rb_eArgError, "specified size is too large");
1294
+ }
1295
+ byte_size = len * elmsz;
1276
1296
  } else {
1277
1297
  byte_size = ceil(len * NUM2DBL(velmsz));
1278
1298
  }
@@ -1315,7 +1335,7 @@ static VALUE nary_s_from_binary(int argc, VALUE* argv, VALUE type) {
1315
1335
  @return [Integer] stored length.
1316
1336
  */
1317
1337
  static VALUE nary_store_binary(int argc, VALUE* argv, VALUE self) {
1318
- size_t size, str_len, byte_size, offset;
1338
+ size_t size, str_len, byte_size, offset, view_offset = 0;
1319
1339
  int narg;
1320
1340
  VALUE vstr, voffset;
1321
1341
  VALUE velmsz;
@@ -1338,7 +1358,11 @@ static VALUE nary_store_binary(int argc, VALUE* argv, VALUE self) {
1338
1358
  size = NA_SIZE(na);
1339
1359
  velmsz = rb_const_get(rb_obj_class(self), id_element_byte_size);
1340
1360
  if (FIXNUM_P(velmsz)) {
1341
- byte_size = size * NUM2SIZET(velmsz);
1361
+ size_t elmsz = NUM2SIZET(velmsz);
1362
+ if (elmsz != 0 && size > SIZE_MAX / elmsz) {
1363
+ rb_raise(rb_eArgError, "string is too short to store");
1364
+ }
1365
+ byte_size = size * elmsz;
1342
1366
  } else {
1343
1367
  byte_size = ceil(size * NUM2DBL(velmsz));
1344
1368
  }
@@ -1346,12 +1370,34 @@ static VALUE nary_store_binary(int argc, VALUE* argv, VALUE self) {
1346
1370
  rb_raise(rb_eArgError, "string is too short to store");
1347
1371
  }
1348
1372
 
1349
- if (OBJ_FROZEN(vstr)) {
1373
+ if (na->type == NARRAY_VIEW_T) {
1374
+ narray_t* nab;
1375
+ size_t data_byte_size;
1376
+
1377
+ if (na_check_contiguous(self) == Qfalse) {
1378
+ rb_raise(rb_eStandardError, "cannot store binary data to non-contiguous NArray");
1379
+ }
1380
+ view_offset = NA_VIEW_OFFSET(na);
1381
+ if (!FIXNUM_P(velmsz) && view_offset != 0) {
1382
+ rb_raise(rb_eStandardError, "cannot store binary data to NArray view offset in bits");
1383
+ }
1384
+ GetNArray(NA_VIEW_DATA(na), nab);
1385
+ if (FIXNUM_P(velmsz)) {
1386
+ data_byte_size = NA_SIZE(nab) * NUM2SIZET(velmsz);
1387
+ } else {
1388
+ data_byte_size = ceil(NA_SIZE(nab) * NUM2DBL(velmsz));
1389
+ }
1390
+ if (view_offset > data_byte_size || byte_size > data_byte_size - view_offset) {
1391
+ rb_raise(rb_eArgError, "string is too long to store");
1392
+ }
1393
+ }
1394
+
1395
+ if (OBJ_FROZEN(vstr) && na->type != NARRAY_VIEW_T) {
1350
1396
  na_set_pointer(self, RSTRING_PTR(vstr) + offset, byte_size);
1351
1397
  rb_ivar_set(self, id_source, vstr);
1352
1398
  } else {
1353
- void* ptr = na_get_pointer_for_write(self);
1354
- memcpy(ptr, RSTRING_PTR(vstr) + offset, byte_size);
1399
+ char* ptr = na_get_pointer_for_write(self);
1400
+ memcpy(ptr + view_offset, RSTRING_PTR(vstr) + offset, byte_size);
1355
1401
  }
1356
1402
 
1357
1403
  return SIZET2NUM(byte_size);
@@ -1367,10 +1413,12 @@ static VALUE nary_to_binary(VALUE self) {
1367
1413
  char* ptr;
1368
1414
  VALUE str;
1369
1415
  narray_t* na;
1416
+ int offset_in_bits;
1370
1417
 
1371
1418
  GetNArray(self, na);
1372
1419
  if (na->type == NARRAY_VIEW_T) {
1373
- if (na_check_contiguous(self) == Qtrue) {
1420
+ offset_in_bits = RTEST(rb_obj_is_kind_of(self, numo_cBit)) && NA_VIEW_OFFSET(na) != 0;
1421
+ if (!offset_in_bits && na_check_contiguous(self) == Qtrue) {
1374
1422
  offset = NA_VIEW_OFFSET(na);
1375
1423
  } else {
1376
1424
  self = rb_funcall(self, id_dup, 0);
@@ -1402,7 +1450,7 @@ static VALUE nary_marshal_dump(VALUE self) {
1402
1450
  GetNArray(self, na);
1403
1451
  if (na->type == NARRAY_VIEW_T) {
1404
1452
  if (na_check_contiguous(self) == Qtrue) {
1405
- offset = NA_VIEW_OFFSET(na);
1453
+ offset = NA_VIEW_OFFSET(na) / sizeof(VALUE);
1406
1454
  } else {
1407
1455
  self = rb_funcall(self, id_dup, 0);
1408
1456
  }
@@ -1426,6 +1474,9 @@ static VALUE na_inplace(VALUE self);
1426
1474
  static VALUE nary_marshal_load(VALUE self, VALUE a) {
1427
1475
  VALUE v;
1428
1476
 
1477
+ if (OBJ_FROZEN(self)) {
1478
+ rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
1479
+ }
1429
1480
  if (TYPE(a) != T_ARRAY) {
1430
1481
  rb_raise(rb_eArgError, "marshal argument should be array");
1431
1482
  }
@@ -1440,6 +1491,9 @@ static VALUE nary_marshal_load(VALUE self, VALUE a) {
1440
1491
  NUM2INT(RARRAY_AREF(a, 0))
1441
1492
  );
1442
1493
  }
1494
+ if (TYPE(RARRAY_AREF(a, 1)) != T_ARRAY) {
1495
+ rb_raise(rb_eArgError, "marshal shape should be array");
1496
+ }
1443
1497
  na_initialize(self, RARRAY_AREF(a, 1));
1444
1498
  NA_FL0_SET(self, FIX2INT(RARRAY_AREF(a, 2)));
1445
1499
  v = RARRAY_AREF(a, 3);
@@ -1456,6 +1510,7 @@ static VALUE nary_marshal_load(VALUE self, VALUE a) {
1456
1510
  ptr = na_get_pointer_for_write(self);
1457
1511
  memcpy(ptr, RARRAY_PTR(v), NA_SIZE(na) * sizeof(VALUE));
1458
1512
  } else {
1513
+ Check_Type(v, T_STRING);
1459
1514
  rb_str_freeze(v);
1460
1515
  nary_store_binary(1, &v, self);
1461
1516
  if (TEST_BYTE_SWAPPED(self)) {
@@ -520,7 +520,7 @@ static void ndloop_set_stepidx(na_md_loop_t* lp, int j, VALUE vna, int* dim_map,
520
520
  if (n > 1 || nd > 0) {
521
521
  i = dim_map[k];
522
522
  LITER(lp, i, j).step = s;
523
- // LITER(lp,i,j).idx = NULL;
523
+ LITER(lp, i, j).idx = NULL;
524
524
  }
525
525
  s *= n;
526
526
  nd--;
@@ -539,7 +539,7 @@ static void ndloop_set_stepidx(na_md_loop_t* lp, int j, VALUE vna, int* dim_map,
539
539
  LITER(lp, i, j).idx = SDX_GET_INDEX(sdx);
540
540
  } else {
541
541
  LITER(lp, i, j).step = SDX_GET_STRIDE(sdx);
542
- // LITER(lp,i,j).idx = NULL;
542
+ LITER(lp, i, j).idx = NULL;
543
543
  }
544
544
  } else if (n == 1) {
545
545
  if (SDX_IS_INDEX(sdx)) {
@@ -1540,6 +1540,7 @@ static void loop_store_subnarray(ndfunc_t* nf, na_md_loop_t* lp, int i0, size_t*
1540
1540
  dim_map[i] = lp->trans_map[i + i0];
1541
1541
  }
1542
1542
  ndloop_set_stepidx(lp, 1, a, dim_map, NDL_READ);
1543
+ LITER(lp, i0, 1).pos = LITER(lp, 0, 1).pos;
1543
1544
  LARG(lp, 1).shape = &(na->shape[na->ndim - 1]);
1544
1545
 
1545
1546
  // loop body
@@ -13,10 +13,10 @@ extern "C" {
13
13
  #endif
14
14
  #endif
15
15
 
16
- #define NARRAY_VERSION "0.11.2"
16
+ #define NARRAY_VERSION "0.11.3"
17
17
  #define NARRAY_VERSION_MAJOR 0
18
18
  #define NARRAY_VERSION_MINOR 11
19
- #define NARRAY_VERSION_PATCH 2
19
+ #define NARRAY_VERSION_PATCH 3
20
20
  #define NARRAY_VERSION_CODE \
21
21
  (NARRAY_VERSION_MAJOR * 10000 + NARRAY_VERSION_MINOR * 100 + NARRAY_VERSION_PATCH)
22
22
 
@@ -1,6 +1,16 @@
1
1
  #ifndef NUMO_NARRAY_MH_BINCOUNT_H
2
2
  #define NUMO_NARRAY_MH_BINCOUNT_H 1
3
3
 
4
+ /* The items below index the output, whose size was fixed by an earlier scan of
5
+ the same array. Ruby code can run in between, so the bound is rechecked. */
6
+ static inline void na_bincount_check_item(size_t x, size_t n) {
7
+ if (x >= n) {
8
+ rb_raise(
9
+ rb_eIndexError, "item %" SZF "u is out of range of the output(size:%" SZF "u)", x, n
10
+ );
11
+ }
12
+ }
13
+
4
14
  #define DEF_BINCOUNT_FUNCS(tDType, tNAryClass) \
5
15
  static void iter_##tDType##_bincount_32(na_loop_t* const lp) { \
6
16
  char* p1; \
@@ -21,11 +31,13 @@
21
31
  if (idx1) { \
22
32
  for (size_t i = 0; i < m; i++) { \
23
33
  GET_DATA_INDEX(p1, idx1, tDType, x); \
34
+ na_bincount_check_item(x, n); \
24
35
  (*(u_int32_t*)(p2 + s2 * x))++; \
25
36
  } \
26
37
  } else { \
27
38
  for (size_t i = 0; i < m; i++) { \
28
39
  GET_DATA_STRIDE(p1, s1, tDType, x); \
40
+ na_bincount_check_item(x, n); \
29
41
  (*(u_int32_t*)(p2 + s2 * x))++; \
30
42
  } \
31
43
  } \
@@ -60,11 +72,13 @@
60
72
  if (idx1) { \
61
73
  for (size_t i = 0; i < m; i++) { \
62
74
  GET_DATA_INDEX(p1, idx1, tDType, x); \
75
+ na_bincount_check_item(x, n); \
63
76
  (*(u_int64_t*)(p2 + s2 * x))++; \
64
77
  } \
65
78
  } else { \
66
79
  for (size_t i = 0; i < m; i++) { \
67
80
  GET_DATA_STRIDE(p1, s1, tDType, x); \
81
+ na_bincount_check_item(x, n); \
68
82
  (*(u_int64_t*)(p2 + s2 * x))++; \
69
83
  } \
70
84
  } \
@@ -106,6 +120,7 @@
106
120
  for (size_t i = 0; i < l; i++) { \
107
121
  GET_DATA_STRIDE(p1, s1, tDType, x); \
108
122
  GET_DATA_STRIDE(p2, s2, float, w); \
123
+ na_bincount_check_item(x, n); \
109
124
  (*(float*)(p3 + s3 * x)) += w; \
110
125
  } \
111
126
  } \
@@ -146,6 +161,7 @@
146
161
  for (size_t i = 0; i < l; i++) { \
147
162
  GET_DATA_STRIDE(p1, s1, tDType, x); \
148
163
  GET_DATA_STRIDE(p2, s2, double, w); \
164
+ na_bincount_check_item(x, n); \
149
165
  (*(double*)(p3 + s3 * x)) += w; \
150
166
  } \
151
167
  } \
@@ -170,6 +186,14 @@
170
186
  rb_scan_args(argc, argv, "01:", &weight, &kw); \
171
187
  rb_get_kwargs(kw, table, 0, 1, opts); \
172
188
  \
189
+ size_t minlength = 0; \
190
+ if (opts[0] != Qundef) { \
191
+ minlength = NUM2SIZET(opts[0]); \
192
+ } \
193
+ if (!NIL_P(weight) && rb_obj_class(weight) != numo_cSFloat) { \
194
+ weight = rb_funcall(numo_cDFloat, id_cast, 1, weight); \
195
+ } \
196
+ \
173
197
  VALUE v = tDType##_minmax(0, 0, self); \
174
198
  if (m_num_to_data(RARRAY_AREF(v, 0)) < 0) { \
175
199
  rb_raise(rb_eArgError, "array items must be non-netagive"); \
@@ -177,11 +201,8 @@
177
201
  v = RARRAY_AREF(v, 1); \
178
202
  \
179
203
  size_t length = NUM2SIZET(v) + 1; \
180
- if (opts[0] != Qundef) { \
181
- const size_t minlength = NUM2SIZET(opts[0]); \
182
- if (minlength > length) { \
183
- length = minlength; \
184
- } \
204
+ if (minlength > length) { \
205
+ length = minlength; \
185
206
  } \
186
207
  \
187
208
  if (NIL_P(weight)) { \
@@ -207,14 +228,23 @@
207
228
  rb_scan_args(argc, argv, "01:", &weight, &kw); \
208
229
  rb_get_kwargs(kw, table, 0, 1, opts); \
209
230
  \
231
+ size_t minlength = 0; \
232
+ if (opts[0] != Qundef) { \
233
+ minlength = NUM2SIZET(opts[0]); \
234
+ } \
235
+ if (!NIL_P(weight) && rb_obj_class(weight) != numo_cSFloat) { \
236
+ weight = rb_funcall(numo_cDFloat, id_cast, 1, weight); \
237
+ } \
238
+ \
210
239
  VALUE v = tDType##_max(0, 0, self); \
211
240
  \
212
- size_t length = NUM2SIZET(v) + 1; \
213
- if (opts[0] != Qundef) { \
214
- const size_t minlength = NUM2SIZET(opts[0]); \
215
- if (minlength > length) { \
216
- length = minlength; \
217
- } \
241
+ const size_t max = NUM2SIZET(v); \
242
+ if (max == SIZE_MAX) { \
243
+ rb_raise(rb_eRangeError, "maximum item %" SZF "u is too large to size the output", max); \
244
+ } \
245
+ size_t length = max + 1; \
246
+ if (minlength > length) { \
247
+ length = minlength; \
218
248
  } \
219
249
  \
220
250
  if (NIL_P(weight)) { \
@@ -1,6 +1,20 @@
1
1
  #ifndef NUMO_NARRAY_MH_STORE_H
2
2
  #define NUMO_NARRAY_MH_STORE_H 1
3
3
 
4
+ /* The store loops below run Ruby code for every element, which can reallocate or
5
+ shrink the array being read: its buffer and length do not survive one. */
6
+ static inline bool na_store_rary_fetch(VALUE ary, size_t i, VALUE* x) {
7
+ if (!RB_TYPE_P(ary, T_ARRAY)) {
8
+ *x = ary;
9
+ return true;
10
+ }
11
+ if (i >= (size_t)RARRAY_LEN(ary)) {
12
+ return false;
13
+ }
14
+ *x = RARRAY_AREF(ary, (long)i);
15
+ return true;
16
+ }
17
+
4
18
  #define DEF_STORE_NUMERIC_FUNC(tDType, tNAryClass) \
5
19
  static VALUE tDType##_store(VALUE, VALUE); \
6
20
  \
@@ -134,7 +148,6 @@
134
148
  size_t i1; \
135
149
  size_t n1; \
136
150
  VALUE v1; \
137
- VALUE* ptr; \
138
151
  VALUE x; \
139
152
  double y; \
140
153
  tDType z; \
@@ -152,8 +165,13 @@
152
165
  i = 0; \
153
166
  if (lp->args[1].ptr) { \
154
167
  if (v1 == Qtrue) { \
155
- iter_##tDType##_store_##tDType(lp); \
156
168
  i = lp->args[1].shape[0]; \
169
+ if (i > n) { \
170
+ i = n; \
171
+ } \
172
+ NDL_CNT(lp) = i; \
173
+ iter_##tDType##_store_##tDType(lp); \
174
+ NDL_CNT(lp) = n; \
157
175
  if (idx1) { \
158
176
  idx1 += i; \
159
177
  } else { \
@@ -162,11 +180,9 @@
162
180
  } \
163
181
  goto loop_end; \
164
182
  } \
165
- ptr = &v1; \
166
183
  switch (TYPE(v1)) { \
167
184
  case T_ARRAY: \
168
185
  n1 = RARRAY_LEN(v1); \
169
- ptr = RARRAY_PTR(v1); \
170
186
  break; \
171
187
  case T_NIL: \
172
188
  n1 = 0; \
@@ -175,8 +191,8 @@
175
191
  n1 = 1; \
176
192
  } \
177
193
  if (idx1) { \
178
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) { \
179
- x = ptr[i1]; \
194
+ for (i = i1 = 0; i1 < n1 && i < n; i1++) { \
195
+ if (!na_store_rary_fetch(v1, i1, &x)) break; \
180
196
  if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, rb_cArithSeq)) { \
181
197
  nary_step_sequence(x, &len, &beg, &step); \
182
198
  for (c = 0; c < len && i < n; c++, i++) { \
@@ -187,11 +203,12 @@
187
203
  } else if (TYPE(x) != T_ARRAY) { \
188
204
  z = m_num_to_data(x); \
189
205
  SET_DATA_INDEX(p1, idx1, tDType, z); \
206
+ i++; \
190
207
  } \
191
208
  } \
192
209
  } else { \
193
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) { \
194
- x = ptr[i1]; \
210
+ for (i = i1 = 0; i1 < n1 && i < n; i1++) { \
211
+ if (!na_store_rary_fetch(v1, i1, &x)) break; \
195
212
  if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, rb_cArithSeq)) { \
196
213
  nary_step_sequence(x, &len, &beg, &step); \
197
214
  for (c = 0; c < len && i < n; c++, i++) { \
@@ -202,6 +219,7 @@
202
219
  } else if (TYPE(x) != T_ARRAY) { \
203
220
  z = m_num_to_data(x); \
204
221
  SET_DATA_STRIDE(p1, s1, tDType, z); \
222
+ i++; \
205
223
  } \
206
224
  } \
207
225
  } \
@@ -474,7 +492,7 @@
474
492
  robject_store_uint8(self, obj); \
475
493
  return self; \
476
494
  } \
477
- if (klass == numo_cRObject) { \
495
+ if (RTEST(rb_obj_is_kind_of(obj, numo_cRObject))) { \
478
496
  robject_store_robject(self, obj); \
479
497
  return self; \
480
498
  } \
@@ -9,6 +9,7 @@
9
9
  #include <ruby.h>
10
10
 
11
11
  #include "SFMT.h"
12
+ #include "mh/store.h"
12
13
  #include "numo/narray.h"
13
14
  #include "numo/template.h"
14
15
 
@@ -129,7 +130,9 @@ static void iter_bit_fill(na_loop_t* const lp) {
129
130
  p3 += s3;
130
131
  }
131
132
  } else {
132
- if (p3 > 0 || n < NB) {
133
+ a3 += p3 / NB;
134
+ p3 %= NB;
135
+ if (n > 0 && (p3 > 0 || n < NB)) {
133
136
  len = (int)(NB - p3);
134
137
  if ((int)n < len) {
135
138
  len = (int)n;
@@ -302,8 +305,11 @@ static inline void yield_each_with_index(BIT_DIGIT x, size_t* c, VALUE* a, int n
302
305
 
303
306
  static void iter_bit_each_with_index(na_loop_t* const lp) {
304
307
  size_t* c = (size_t*)(lp->opt_ptr);
305
- int nd = lp->ndim - 1;
306
- int md = lp->ndim + 1;
308
+ int nd = lp->ndim;
309
+ if (nd > 0) {
310
+ nd--;
311
+ }
312
+ int md = nd + 2;
307
313
  VALUE* a = ALLOCA_N(VALUE, md);
308
314
  size_t n;
309
315
  BIT_DIGIT* a1;
@@ -575,7 +581,7 @@ static void iter_bit_store_bit(na_loop_t* const lp) {
575
581
  o1 = (int)(p1 - p3);
576
582
  l1 = NB + o1;
577
583
  r1 = NB - o1;
578
- if (p3 > 0 || n < NB) {
584
+ if (n > 0 && (p3 > 0 || n < NB)) {
579
585
  len = (int)(NB - p3);
580
586
  if ((int)n < len) len = (int)n;
581
587
  if (o1 >= 0)
@@ -1252,7 +1258,7 @@ static VALUE bit_store_robject(VALUE self, VALUE obj) {
1252
1258
  static void iter_bit_store_array(na_loop_t* const lp) {
1253
1259
  size_t i, n;
1254
1260
  size_t i1, n1;
1255
- VALUE v1, *ptr;
1261
+ VALUE v1;
1256
1262
  BIT_DIGIT* a1;
1257
1263
  size_t p1;
1258
1264
  size_t s1, *idx1;
@@ -1269,8 +1275,13 @@ static void iter_bit_store_array(na_loop_t* const lp) {
1269
1275
 
1270
1276
  if (lp->args[1].ptr) {
1271
1277
  if (v1 == Qtrue) {
1272
- iter_bit_store_bit(lp);
1273
1278
  i = lp->args[1].shape[0];
1279
+ if (i > n) {
1280
+ i = n;
1281
+ }
1282
+ NDL_CNT(lp) = i;
1283
+ iter_bit_store_bit(lp);
1284
+ NDL_CNT(lp) = n;
1274
1285
  if (idx1) {
1275
1286
  idx1 += i;
1276
1287
  } else {
@@ -1280,12 +1291,9 @@ static void iter_bit_store_array(na_loop_t* const lp) {
1280
1291
  goto loop_end;
1281
1292
  }
1282
1293
 
1283
- ptr = &v1;
1284
-
1285
1294
  switch (TYPE(v1)) {
1286
1295
  case T_ARRAY:
1287
1296
  n1 = RARRAY_LEN(v1);
1288
- ptr = RARRAY_PTR(v1);
1289
1297
  break;
1290
1298
  case T_NIL:
1291
1299
  n1 = 0;
@@ -1295,8 +1303,8 @@ static void iter_bit_store_array(na_loop_t* const lp) {
1295
1303
  }
1296
1304
 
1297
1305
  if (idx1) {
1298
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
1299
- x = ptr[i1];
1306
+ for (i = i1 = 0; i1 < n1 && i < n; i1++) {
1307
+ if (!na_store_rary_fetch(v1, i1, &x)) break;
1300
1308
  if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, rb_cArithSeq)) {
1301
1309
  nary_step_sequence(x, &len, &beg, &step);
1302
1310
  for (c = 0; c < len && i < n; c++, i++) {
@@ -1305,17 +1313,17 @@ static void iter_bit_store_array(na_loop_t* const lp) {
1305
1313
  STORE_BIT(a1, p1 + *idx1, z);
1306
1314
  idx1++;
1307
1315
  }
1308
- }
1309
- if (TYPE(x) != T_ARRAY) {
1316
+ } else if (TYPE(x) != T_ARRAY) {
1310
1317
  if (x == Qnil) x = INT2FIX(0);
1311
1318
  z = m_num_to_data(x);
1312
1319
  STORE_BIT(a1, p1 + *idx1, z);
1313
1320
  idx1++;
1321
+ i++;
1314
1322
  }
1315
1323
  }
1316
1324
  } else {
1317
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
1318
- x = ptr[i1];
1325
+ for (i = i1 = 0; i1 < n1 && i < n; i1++) {
1326
+ if (!na_store_rary_fetch(v1, i1, &x)) break;
1319
1327
  if (rb_obj_is_kind_of(x, rb_cRange) || rb_obj_is_kind_of(x, rb_cArithSeq)) {
1320
1328
  nary_step_sequence(x, &len, &beg, &step);
1321
1329
  for (c = 0; c < len && i < n; c++, i++) {
@@ -1324,11 +1332,11 @@ static void iter_bit_store_array(na_loop_t* const lp) {
1324
1332
  STORE_BIT(a1, p1, z);
1325
1333
  p1 += s1;
1326
1334
  }
1327
- }
1328
- if (TYPE(x) != T_ARRAY) {
1335
+ } else if (TYPE(x) != T_ARRAY) {
1329
1336
  z = m_num_to_data(x);
1330
1337
  STORE_BIT(a1, p1, z);
1331
1338
  p1 += s1;
1339
+ i++;
1332
1340
  }
1333
1341
  }
1334
1342
  }
@@ -1688,7 +1696,7 @@ static void iter_bit_copy(na_loop_t* const lp) {
1688
1696
  o1 = (int)(p1 - p3);
1689
1697
  l1 = NB + o1;
1690
1698
  r1 = NB - o1;
1691
- if (p3 > 0 || n < NB) {
1699
+ if (n > 0 && (p3 > 0 || n < NB)) {
1692
1700
  len = (int)(NB - p3);
1693
1701
  if ((int)n < len) len = (int)n;
1694
1702
  if (o1 >= 0)
@@ -1782,7 +1790,7 @@ static void iter_bit_not(na_loop_t* const lp) {
1782
1790
  o1 = (int)(p1 - p3);
1783
1791
  l1 = NB + o1;
1784
1792
  r1 = NB - o1;
1785
- if (p3 > 0 || n < NB) {
1793
+ if (n > 0 && (p3 > 0 || n < NB)) {
1786
1794
  len = (int)(NB - p3);
1787
1795
  if ((int)n < len) len = (int)n;
1788
1796
  if (o1 >= 0)
@@ -1882,7 +1890,7 @@ static void iter_bit_and(na_loop_t* const lp) {
1882
1890
  r1 = NB - o1;
1883
1891
  l2 = NB + o2;
1884
1892
  r2 = NB - o2;
1885
- if (p3 > 0 || n < NB) {
1893
+ if (n > 0 && (p3 > 0 || n < NB)) {
1886
1894
  len = (int)(NB - p3);
1887
1895
  if ((int)n < len) len = (int)n;
1888
1896
  if (o1 >= 0)
@@ -2011,7 +2019,7 @@ static void iter_bit_or(na_loop_t* const lp) {
2011
2019
  r1 = NB - o1;
2012
2020
  l2 = NB + o2;
2013
2021
  r2 = NB - o2;
2014
- if (p3 > 0 || n < NB) {
2022
+ if (n > 0 && (p3 > 0 || n < NB)) {
2015
2023
  len = (int)(NB - p3);
2016
2024
  if ((int)n < len) len = (int)n;
2017
2025
  if (o1 >= 0)
@@ -2140,7 +2148,7 @@ static void iter_bit_xor(na_loop_t* const lp) {
2140
2148
  r1 = NB - o1;
2141
2149
  l2 = NB + o2;
2142
2150
  r2 = NB - o2;
2143
- if (p3 > 0 || n < NB) {
2151
+ if (n > 0 && (p3 > 0 || n < NB)) {
2144
2152
  len = (int)(NB - p3);
2145
2153
  if ((int)n < len) len = (int)n;
2146
2154
  if (o1 >= 0)
@@ -2269,7 +2277,7 @@ static void iter_bit_eq(na_loop_t* const lp) {
2269
2277
  r1 = NB - o1;
2270
2278
  l2 = NB + o2;
2271
2279
  r2 = NB - o2;
2272
- if (p3 > 0 || n < NB) {
2280
+ if (n > 0 && (p3 > 0 || n < NB)) {
2273
2281
  len = (int)(NB - p3);
2274
2282
  if ((int)n < len) len = (int)n;
2275
2283
  if (o1 >= 0)
@@ -283,7 +283,7 @@ static VALUE dcomplex_allocate(VALUE self) {
283
283
  case NARRAY_DATA_T:
284
284
  ptr = NA_DATA_PTR(na);
285
285
  if (na->size > 0 && ptr == NULL) {
286
- ptr = xmalloc(sizeof(dtype) * na->size);
286
+ ptr = xmalloc2(na->size, sizeof(dtype));
287
287
 
288
288
  NA_DATA_PTR(na) = ptr;
289
289
  NA_DATA_OWNED(na) = TRUE;
@@ -390,7 +390,7 @@ static VALUE dfloat_allocate(VALUE self) {
390
390
  case NARRAY_DATA_T:
391
391
  ptr = NA_DATA_PTR(na);
392
392
  if (na->size > 0 && ptr == NULL) {
393
- ptr = xmalloc(sizeof(dtype) * na->size);
393
+ ptr = xmalloc2(na->size, sizeof(dtype));
394
394
 
395
395
  NA_DATA_PTR(na) = ptr;
396
396
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE int16_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -266,7 +266,7 @@ static VALUE int32_allocate(VALUE self) {
266
266
  case NARRAY_DATA_T:
267
267
  ptr = NA_DATA_PTR(na);
268
268
  if (na->size > 0 && ptr == NULL) {
269
- ptr = xmalloc(sizeof(dtype) * na->size);
269
+ ptr = xmalloc2(na->size, sizeof(dtype));
270
270
 
271
271
  NA_DATA_PTR(na) = ptr;
272
272
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE int64_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE int8_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -304,7 +304,7 @@ static VALUE robject_allocate(VALUE self) {
304
304
  case NARRAY_DATA_T:
305
305
  ptr = NA_DATA_PTR(na);
306
306
  if (na->size > 0 && ptr == NULL) {
307
- ptr = xmalloc(sizeof(dtype) * na->size);
307
+ ptr = xmalloc2(na->size, sizeof(dtype));
308
308
 
309
309
  {
310
310
  size_t i;
@@ -281,7 +281,7 @@ static VALUE scomplex_allocate(VALUE self) {
281
281
  case NARRAY_DATA_T:
282
282
  ptr = NA_DATA_PTR(na);
283
283
  if (na->size > 0 && ptr == NULL) {
284
- ptr = xmalloc(sizeof(dtype) * na->size);
284
+ ptr = xmalloc2(na->size, sizeof(dtype));
285
285
 
286
286
  NA_DATA_PTR(na) = ptr;
287
287
  NA_DATA_OWNED(na) = TRUE;
@@ -388,7 +388,7 @@ static VALUE sfloat_allocate(VALUE self) {
388
388
  case NARRAY_DATA_T:
389
389
  ptr = NA_DATA_PTR(na);
390
390
  if (na->size > 0 && ptr == NULL) {
391
- ptr = xmalloc(sizeof(dtype) * na->size);
391
+ ptr = xmalloc2(na->size, sizeof(dtype));
392
392
 
393
393
  NA_DATA_PTR(na) = ptr;
394
394
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE uint16_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE uint32_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE uint64_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
@@ -265,7 +265,7 @@ static VALUE uint8_allocate(VALUE self) {
265
265
  case NARRAY_DATA_T:
266
266
  ptr = NA_DATA_PTR(na);
267
267
  if (na->size > 0 && ptr == NULL) {
268
- ptr = xmalloc(sizeof(dtype) * na->size);
268
+ ptr = xmalloc2(na->size, sizeof(dtype));
269
269
 
270
270
  NA_DATA_PTR(na) = ptr;
271
271
  NA_DATA_OWNED(na) = TRUE;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-narray-alt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.11.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
@@ -214,7 +214,7 @@ licenses:
214
214
  metadata:
215
215
  homepage_uri: https://github.com/yoshoku/numo-narray-alt
216
216
  changelog_uri: https://github.com/yoshoku/numo-narray-alt/blob/main/CHANGELOG.md
217
- documentation_uri: https://gemdocs.org/gems/numo-narray-alt/0.11.2/
217
+ documentation_uri: https://gemdocs.org/gems/numo-narray-alt/0.11.3/
218
218
  rubygems_mfa_required: 'true'
219
219
  post_install_message: |
220
220
  ===
@@ -238,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
238
  - !ruby/object:Gem::Version
239
239
  version: '0'
240
240
  requirements: []
241
- rubygems_version: 4.0.16
241
+ rubygems_version: 4.0.20
242
242
  specification_version: 4
243
243
  summary: Numo::NArray Alternative is a project forked from Numo::NArray.
244
244
  test_files: []