115 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto f7142cd327 mruby-random: make Kernel#srand and #rand private 2025-03-07 17:17:43 +09:00
Yukihiro "Matz" Matsumoto 8f184a356b mruby-random: use presym for initialization 2024-06-14 00:15:25 +09:00
Yukihiro "Matz" Matsumoto cf785a6133 mruby-random: move variable declarations to initialization 2024-05-07 17:57:41 +09:00
leviongit ad62d7809e fix: Array#shuffle(!) result distribution 2024-04-04 20:36:44 +02:00
Yukihiro "Matz" Matsumoto 05e9fa34af mruby-random: rename a conflicting local variable 2024-01-08 19:12:55 +09:00
Yukihiro "Matz" Matsumoto 27c2f9ac38 mruby-random (mrb_ary_sample): reduce the scope of loop variables 2024-01-08 07:23:03 +09:00
Yukihiro "Matz" Matsumoto 78bbf75981 mruby-random/random.c: avoid mrb_get_args() 2023-01-26 11:13:48 +09:00
Yukihiro "Matz" Matsumoto c7f1195ccb mruby-random: fix size of kw symbol arrays 2022-11-30 21:50:08 +09:00
Yukihiro "Matz" Matsumoto dfeda0acc8 random.c: remove Random::DEFAULT. 2022-08-28 08:01:59 +09:00
Yukihiro "Matz" Matsumoto 7dec6e776e mruby-random/random.c: pointer to uint32_t cast may fail with clang. 2022-06-17 10:06:07 +09:00
Yukihiro "Matz" Matsumoto f1d669024a mruby-random/random.c: srand to use pointer address as a seed.
Utilize process randomiser which may not be provided by non Linux OSes.
With those OSes, rand() would return same values if the processes are
invoked within a second.
2022-06-17 07:14:29 +09:00
Yukihiro "Matz" Matsumoto 267c26d20b mruby-random/random.c: randomize Random::DEFAULT.
Using time(2) and randomized pointer address. May not work well with old
OSes without process randomiser.
2022-06-17 07:12:12 +09:00
Yukihiro "Matz" Matsumoto 0a63cdd594 mruby-random/random.c: use random: keyword argument.
For Array#sample and Array#shuffle. They used to take optional ordinal
argument for Random object but CRuby uses `random:` keyword argument.
Now mruby is compatible with CRuby here.
2022-06-16 11:17:22 +09:00
Yukihiro "Matz" Matsumoto 0a52f171aa mruby-random/random.c: factored out Random argument retrieval. 2022-05-16 14:17:20 +09:00
Yukihiro "Matz" Matsumoto 45f61e3879 class.c (mrb_get_args): remove I specifier (istruct); close #5706 2022-05-07 17:35:45 +09:00
Yukihiro "Matz" Matsumoto 50b1ded350 mruby-random/random.c: use rand_i() extensively. 2022-05-04 08:07:02 +09:00
dearblue 9b9424fe32 Strict acquisition of the Random class given by mrb_get_args()
This is to prevent data corruption of the substituted `Random` instance.
If the `Object::Random` constants are redefined to a different `MRB_TT_ISTRUCT` object class, they can pass `mrb_get_args()` validation.

The following is an example of how the `Array#shuffle` method rewrites the data of a non `Random` instance.

```c
// code.c

#include <mruby.h>
#include <mruby/class.h>
#include <mruby/compile.h>
#include <mruby/istruct.h>

#define EVAL_LIT(MRB, ...) mrb_load_string((MRB), #__VA_ARGS__)

static mrb_value
fake_initialize(mrb_state *mrb, mrb_value self)
{
  char *p = ISTRUCT_PTR(self);

  for (int i = 0; i < ISTRUCT_DATA_SIZE; i++) {
    p[i] = 'A' + i;
  }

  return self;
}

static mrb_value
fake_to_bytes(mrb_state *mrb, mrb_value self)
{
  const char *p = ISTRUCT_PTR(self);
  return mrb_str_new(mrb, p, ISTRUCT_DATA_SIZE);
}

int
main(int argc, char *argv[])
{
  mrb_state *mrb = mrb_open();

  struct RClass *fake = mrb_define_class(mrb, "Fake", mrb->object_class);
  MRB_SET_INSTANCE_TT(fake, MRB_TT_ISTRUCT);
  mrb_define_method(mrb, fake, "initialize", fake_initialize, MRB_ARGS_NONE());
  mrb_define_method(mrb, fake, "to_bytes", fake_to_bytes, MRB_ARGS_NONE());

  EVAL_LIT(mrb,
    Random = Fake \n
    fake = Fake.new \n
    p [fake, fake.to_bytes] \n
    p a = (1..10).to_a \n
    p a.shuffle(fake) \n
    p [fake, fake.to_bytes]
  );

  mrb_close(mrb);

  return 0;
}
```

```console
% `bin/mruby-config --cc --cflags --ldflags` code.c `bin/mruby-config --libs`
% ./a.out
[#<Fake:0x8007d8f20>, "ABCDEFGHIJKLMNOPQRSTUVWX"]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 7, 8, 10, 2, 6, 9, 3, 4, 5]
[#<Fake:0x8007d8f20>, "\xe81{\v\fM\xb0D<\x99\xb1V+l\x84\x86QRSTUVWX"]
```
2022-05-03 13:35:29 +09:00
dearblue 7bb4a57e56 Added Random.#bytes method
ref: https://docs.ruby-lang.org/ja/3.0.0/method/Random/i/bytes.html
2021-10-31 23:36:10 +09:00
dearblue b774832ee1 Make mrb_static_assert() a variable argument
`mrb_static_assert()` extends the macro function to take one or two arguments.
If the argument is other than that, an error will occur.

References:
- static_assert のメッセージ省略を許可 - cpprefjp C++日本語リファレンス
  https://cpprefjp.github.io/lang/cpp17/extending_static_assert.html
- c - Overloading Macro on Number of Arguments - Stack Overflow
  https://stackoverflow.com/a/11763277
2021-10-24 23:11:52 +09:00
dearblue 2121b6e689 Stirs internal state when seed is set in Random
This is to avoid the approximation of `Random#rand` when `seed`s are close together.

For example, the first `#rand` values after doing `Random#srand(0)` and `Random#srand(1)` are very similar.

Below is the sequence of mruby before this patch was given a `seed` of `0...20`:

```console
% bin/mruby -e 'r = Random.new; 20.times { |i| r.srand(i); puts "seed=%2d  %s" % [i, 10.times.map { "%0.3f" % r.rand }.join(" ")] }'
seed= 0  0.643 0.585 0.198 0.732 0.087 0.605 0.548 0.468 0.573 0.966
seed= 1  0.643 0.585 0.198 0.607 0.370 0.605 0.633 0.593 0.395 0.439
seed= 2  0.643 0.585 0.197 0.981 0.652 0.730 0.875 0.713 0.529 0.269
seed= 3  0.643 0.585 0.198 0.857 0.934 0.730 0.960 0.216 0.286 0.523
seed= 4  0.643 0.585 0.197 0.231 0.217 0.605 0.959 0.958 0.478 0.482
seed= 5  0.643 0.585 0.197 0.106 0.249 0.605 0.044 0.330 0.925 0.047
seed= 6  0.643 0.585 0.197 0.481 0.781 0.731 0.285 0.960 0.804 0.725
seed= 7  0.643 0.585 0.197 0.356 0.813 0.731 0.370 0.711 0.937 0.448
seed= 8  0.643 0.585 0.198 0.732 0.329 0.108 0.243 0.974 0.766 0.936
seed= 9  0.643 0.585 0.198 0.607 0.611 0.108 0.827 0.102 0.962 0.597
seed=10  0.643 0.585 0.198 0.981 0.393 0.233 0.569 0.723 0.472 0.805
seed=11  0.643 0.585 0.198 0.857 0.676 0.233 0.154 0.222 0.603 0.371
seed=12  0.643 0.585 0.198 0.231 0.458 0.108 0.654 0.979 0.928 0.577
seed=13  0.643 0.585 0.198 0.106 0.490 0.108 0.239 0.355 0.749 0.831
seed=14  0.643 0.585 0.198 0.481 0.523 0.233 0.981 0.486 0.505 0.131
seed=15  0.643 0.585 0.198 0.356 0.555 0.234 0.565 0.233 0.011 0.666
seed=16  0.643 0.585 0.197 0.730 0.573 0.611 0.904 0.512 0.971 0.153
seed=17  0.643 0.585 0.197 0.605 0.855 0.611 0.240 0.636 0.041 0.509
seed=18  0.643 0.585 0.196 0.979 0.137 0.736 0.229 0.765 0.674 0.832
seed=19  0.643 0.585 0.197 0.855 0.420 0.736 0.566 0.268 0.183 0.219
```
2021-08-21 15:37:12 +09:00
Yukihiro "Matz" Matsumoto 40c4c5d344 random.c: use I specifier for mrb_get_args(); ref #5530 2021-08-14 15:28:38 +09:00
Yukihiro "Matz" Matsumoto 5c804cf68f Remove redundant include headers.
- stdlib.h
- stddef.h
- stdint.h
- stdarg.h
- limits.h
- float.h
2021-07-25 13:07:10 +09:00
Yukihiro "Matz" Matsumoto 4d249c28d9 Skip tests that use Float inside; ref #5421 2021-04-24 12:04:08 +09:00
Yukihiro "Matz" Matsumoto 237f3339bf random.c: refactoring; #5421
- `Random.rand` with `MRB_NO_FLOAT` behaves as `Random.rand(100)`
- `Random.rand(i)` where `i<0` raises `ArgumentError`
2021-04-24 11:15:53 +09:00
Yukihiro "Matz" Matsumoto 98821d2725 random.c: fixed seed underflow bug.
`MRB_INT_MIN` does not have a corresponding positive value.
2021-03-20 14:40:54 +09:00
Yukihiro "Matz" Matsumoto 5d37160455 Use MRB_SYM() more extensively. 2021-02-26 15:05:55 +09:00
Yukihiro "Matz" Matsumoto 17ecf14511 Revert "Minimize the changes in #5277"
This reverts commit dc51d89ac2.
2021-01-26 10:57:07 +09:00
Yukihiro "Matz" Matsumoto dc51d89ac2 Minimize the changes in #5277
Instead of including `mruby/presym.h` everywhere, we provided the
fallback `mruby/presym.inc` under `include/mruby` directory, and specify
`-I<build-dir>/include` before `-I<top-dir>/include` in `presym.rake`.
So even when someone drops `-I<build-dir>/include` in compiler options,
it just compiles without failure.
2021-01-22 18:38:53 +09:00
KOBAYASHI Shuji 90b53f4c29 Avoid including presym.inc in existing header files
Addressed an issue where existing programs linking `libmruby.a` could only
be built by adding `<build-dir>/include` to compiler's include path.
2021-01-11 09:21:07 +09:00
John Bampton f7c5c00d6e 🔒 Fix missing HTTPS on links 2020-12-19 17:36:39 +10:00
Yukihiro "Matz" Matsumoto 5134031e18 Use mrb_int_value() instead of mrb_fixnum_value().
Where fixnum overflow can happen.
2020-10-12 18:20:05 +09:00
Yukihiro "Matz" Matsumoto 3e71359d7a Update mruby-random gem to support 32 bit platforms.
`sizeof(rand_state)` had been bigger than `sizeof(void*)*3`. Changed
random number generator to `Xorshift96` on 32 bit platforms.
2020-10-12 18:20:04 +09:00
Yukihiro "Matz" Matsumoto 2b188ed8a1 Reorganize Integer system.
- Integrate `Fixnum` and `Integer`
- Remove `Integral`
- `int / int -> int`
- Replace `mrb_fixnum()` to `mrb_int()`
- Replace `mrb_fixnum_value()` to `mrb_int_value()`.
- Use `mrb_integer_p()` instead of `mrb_fixnum_p()`
2020-10-12 18:19:54 +09:00
dearblue 80fe9838d2 Integrate Fixnum class into Integer class
* The `Fixnum` constant is now an alias for the `Integer` class.
* Remove `struct mrb_state::fixnum_class` member.
  If necessary, use `struct mrb_state::integer_class` instead.
2020-10-12 16:21:44 +09:00
Yukihiro "Matz" Matsumoto 44a07393f4 Use xoshiro128++ instead of xorshift96/128. 2020-10-12 16:21:41 +09:00
Yukihiro "Matz" Matsumoto 0b22bf4a89 Fix rand_real to return random number [0,1) not [0,1]. 2020-10-12 16:21:41 +09:00
Yukihiro "Matz" Matsumoto 8a87549315 Rename float configuration option names.
- `MRB_WITHOUT_FLOAT` => `MRB_NO_FLOAT`
- `MRB_USE_FLOAT` => `MRB_USE_FLOAT32`

The former is to use `USE_XXX` naming convention. The latter is to make
sure `float` is 32bit float and not floating point number in general.
2020-10-12 16:21:40 +09:00
Yukihiro "Matz" Matsumoto 67d92c48b5 Avoid breaking the result array by side-effect in C++. 2020-10-12 16:21:31 +09:00
Yukihiro "Matz" Matsumoto 2a366ffba8 Use functions that take symbols to reduce string litrals in C. 2020-10-12 16:20:59 +09:00
Yukihiro "Matz" Matsumoto eddd324979 Add MRB_SYM() for inline symbols. 2020-10-12 16:20:41 +09:00
Rory OConnell 3cf48713a2 Work around more MSC optimzer bugs 2020-06-29 14:25:59 -07:00
Rory OConnell b1017b2651 Reduce scope of volatile keyword for MSC bug 2020-06-26 21:44:31 -07:00
Rory OConnell b8d896e56a Narrower scope working around MSC bug 2020-06-26 21:16:17 -07:00
Rory OConnell db296e9593 work around MSC optimization generating non functional code 2020-06-26 15:13:04 -07:00
KOBAYASHI Shuji feaf80d899 Use type predicate macros instead of mrb_type if possible
For efficiency with `MRB_WORD_BOXING` (implement type predicate macros for
all `enum mrb_vtype`).
2019-09-26 22:23:27 +09:00
KOBAYASHI Shuji 7993b87235 Fix build of mruby-random on 32-bit mode 2019-08-27 10:48:25 +09:00
KOBAYASHI Shuji 7178a5e7d3 Fix Array#sample with MRB_INT32
Array index became potentially negative because `uint32_t` is cast to
`mrb_int`.
2019-08-26 20:23:46 +09:00
KOBAYASHI Shuji b9350f908f Remove unused random.h 2019-08-26 18:08:32 +09:00
Yukihiro "Matz" Matsumoto 866a9e6481 Use MRB_TT_ISTRUCT for Random to reduce memory.
When the size of Xorshift128 seed (`sizeof(uint32)*4`) is bigger than
ISTRUCT_DATA_SIZE, `Random` uses Xorshift96 instead.
2019-07-24 10:48:00 +09:00
Yukihiro "Matz" Matsumoto f99e9963b2 Switch random generator from Mersenne Twister to Xorshit128.
Now `rand` can be used with `MRB_WITHOUT_FLOAT`; ref #4576
2019-07-22 15:49:59 +09:00