From 159687bef3b6066e6ca146022a5e8d9d107b4547 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 29 Dec 2023 15:04:37 +0900 Subject: [PATCH 001/117] mruby-pack: add tests for unpack1 method; ref #6134 --- mrbgems/mruby-pack/test/pack.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mrbgems/mruby-pack/test/pack.rb b/mrbgems/mruby-pack/test/pack.rb index 6045f788f..a3f110ba8 100644 --- a/mrbgems/mruby-pack/test/pack.rb +++ b/mrbgems/mruby-pack/test/pack.rb @@ -156,3 +156,18 @@ assert 'pack/unpack "U"' do assert_raise(RangeError) { [-1].pack("U") } assert_raise(RangeError) { [0x40000000].pack("U") } end + +assert 'unpack1' do + d = 1234 + assert_equal(d, [d].pack("i").unpack1("i")) + d = "foobar" + assert_equal(d, [d].pack("a*").unpack1("a*")) + assert_equal(d, [d].pack("A*").unpack1("A*")) + assert_equal(d, [d].pack("Z*").unpack1("Z*")) + assert_equal(d, [d].pack("m").unpack1("m")) + assert_equal(d, [d].pack("M").unpack1("M")) + d = "10010101" + assert_equal(d, [d].pack("b*").unpack1("b*")) + d = "f00b00" + assert_equal(d, [d].pack("h*").unpack1("h*")) +end From fca2bbdcca4acf687f679aa04a5d1977387df6de Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 15:09:53 +0900 Subject: [PATCH 002/117] mruby-pack (unpack_str): the scope of the variable `cp` can be reduced --- mrbgems/mruby-pack/src/pack.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 75d8e1a94..2e469b8b0 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -731,7 +731,7 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, CHECK_UNPACK_LEN(mrb, slen, ary); mrb_value dst; - const char *cp, *sptr; + const char *sptr; int copylen; sptr = (const char*)src; @@ -741,6 +741,8 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, copylen = slen; if (slen >= 0 && flags & PACK_FLAG_Z) { /* "Z" */ + const char *cp; + if ((cp = (const char*)memchr(sptr, '\0', slen)) != NULL) { copylen = (int)(cp - sptr); if (count == -1) { From 7765c23f699f2f1f70cbfc528ac625aae3edc17b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 15:11:06 +0900 Subject: [PATCH 003/117] mruby-pack (pack_hex): the scope of variables `a` and `b` can be reduced --- mrbgems/mruby-pack/src/pack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 2e469b8b0..50ebb906a 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -766,7 +766,6 @@ unpack_str(mrb_state *mrb, const void *src, int slen, mrb_value ary, int count, static int pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, unsigned int flags) { - int a, b; unsigned int ashift, bshift; long slen; char *dptr, *dptr0, *sptr; @@ -795,7 +794,8 @@ pack_hex(mrb_state *mrb, mrb_value src, mrb_value dst, mrb_int didx, int count, dptr0 = dptr; for (; count > 0; count -= 2) { - a = b = 0; + int a = 0, b = 0; + if (slen > 0) { a = hex2int(*sptr++); if (a < 0) break; From 1871ff14db5acba256063f7737bf2dbc4eeda0dd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 15:31:44 +0900 Subject: [PATCH 004/117] mruby-pack (pack_unpack): skip continuous extraction from unpack1 Ref #6134 --- mrbgems/mruby-pack/src/pack.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 50ebb906a..a3b5b4b04 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -1669,18 +1669,23 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) switch (dir) { case PACK_DIR_HEX: srcidx += unpack_hex(mrb, sptr, srclen - srcidx, result, count, flags); + if (single) goto single_return; continue; case PACK_DIR_BSTR: srcidx += unpack_bstr(mrb, sptr, srclen - srcidx, result, count, flags); + if (single) goto single_return; continue; case PACK_DIR_STR: srcidx += unpack_str(mrb, sptr, srclen - srcidx, result, count, flags); + if (single) goto single_return; continue; case PACK_DIR_BASE64: srcidx += unpack_base64(mrb, sptr, srclen - srcidx, result); + if (single) goto single_return; continue; case PACK_DIR_QENC: srcidx += unpack_qenc(mrb, sptr, srclen - srcidx, result); + if (single) goto single_return; continue; default: break; @@ -1731,6 +1736,7 @@ pack_unpack(mrb_state *mrb, mrb_value str, int single) } } if (single) { + single_return: if (RARRAY_LEN(result) > 0) { return RARRAY_PTR(result)[0]; } From 8cbd4638f455c153539d3e713c74aaf779f5b9f7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 15:33:57 +0900 Subject: [PATCH 005/117] mruby-pack (u64tostr): `len` should always be positive Add `mrb_assert()` instead of just skipping the function. --- mrbgems/mruby-pack/src/pack.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index a3b5b4b04..fa6114e2a 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -291,13 +291,11 @@ static void u64tostr(char *buf, size_t len, uint64_t n) { #ifdef MRB_NO_STDIO + mrb_assert(len > 0); + char *bufend = buf + len; char *p = bufend - 1; - if (len < 1) { - return; - } - *p-- = '\0'; len--; @@ -323,9 +321,7 @@ static void i64tostr(char *buf, size_t len, int64_t n) { #ifdef MRB_NO_STDIO - if (len < 1) { - return; - } + mrb_assert(len > 0); if (n < 0) { *buf++ = '-'; From 56b67f86134b3bb1c2397598bf180af40343719a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 15:35:55 +0900 Subject: [PATCH 006/117] mruby-pack (u64tostr): reimplement the function - direct conversion of single digit numbers - remove unnecessary update of `line` variable - simplify the body according to the assertion --- mrbgems/mruby-pack/src/pack.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index fa6114e2a..743b8663b 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -293,23 +293,22 @@ u64tostr(char *buf, size_t len, uint64_t n) #ifdef MRB_NO_STDIO mrb_assert(len > 0); + if (n < 10) { + buf[0] = '0' + n; + buf[1] = '\0'; + return; + } + char *bufend = buf + len; char *p = bufend - 1; *p-- = '\0'; len--; - if (n > 0) { - for (; len > 0 && n > 0; len--, n /= 10) { - *p-- = '0' + (n % 10); - } - p++; + for (; len > 0 && n > 0; len--, n /= 10) { + *p-- = '0' + (n % 10); } - else if (len > 0) { - *p = '0'; - len--; - } - + p++; memmove(buf, p, bufend - p); #else snprintf(buf, len, "%" PRIu64, n); From 39f48d732a4200798f395a5861150a47e667cf06 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 30 Dec 2023 16:02:20 +0900 Subject: [PATCH 007/117] mruby-pack: update README.md 'X' and '@' directives are not listed --- mrbgems/mruby-pack/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-pack/README.md b/mrbgems/mruby-pack/README.md index 10a538095..2871fb4b3 100644 --- a/mrbgems/mruby-pack/README.md +++ b/mrbgems/mruby-pack/README.md @@ -45,7 +45,9 @@ There is no dependency on other mrbgems. - V : 32-bit unsigned, VAX (little-endian) byte order - v : 16-bit unsigned, VAX (little-endian) byte order - x : null byte -- Z : same as "a", except that null is added with * +- X : back up bytes +- Z : same as "a", except that null is added with \* +- @ : absolute position ## License From 8094ac27d73437b31486b376a129a025ba5d592c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 31 Dec 2023 00:43:02 +0900 Subject: [PATCH 008/117] NEWS: add mruby3.3 changes description --- NEWS | 126 ++++++++++++++++++++++++++++++------------------ doc/mruby3.3.md | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 48 deletions(-) create mode 100644 doc/mruby3.3.md diff --git a/NEWS b/NEWS index 36f955ebe..a3893089c 100644 --- a/NEWS +++ b/NEWS @@ -1,63 +1,93 @@ NEWS ---- -# User visible changes in `mruby3.2` +# User visible changes in `mruby3.3` from `mruby3.2` # The language -- Now `a::B = c` should evaluate `a` then `c`. -- Anonymous arguments `*`, `**`, `&` can be passed for forwarding. -- Multi-precision integer is available now via `mruby-bigint` gem. +- aliases work properly with `super` +- `callee` method work differently with aliases in mruby +- define `Kernel#respond_to_missing?` method +- `_inspect` method (`inspect` with recursive check) is removed +- `__printstr` method is removed; use `print` instead + +# Configuration + +- mruby can be built using Docker now. Try `docker-compose build` for example. +- New Platform: Nintendo Wii +- Improved Platforms: Android, Dreamcast + +# mruby memory API + +- `mrb_default_allocf` can be overridden by the application +- `mrb_open_allocf` will be deprecated # mruby VM and bytecode -- `OP_ARYDUP` was renamed to `OP_ARYSPLAT`. The instruction name - was changed but instruction number and basic behavior have not - changed (except that `ARYDUP nil` makes `[]`). +- [#5870](https://github.com/mruby/mruby/issues/5870) Use OP_LOADINEG instead of OP_LOADI -# Tools +# Changes in mrbgems -## `mruby` +- mruby-bin-config: new options --cxx,--cxxflags,--as,--asflags,--objc,--objcflags +- mruby-binding-eval (merged with mruby-eval) #5989 +- mruby-binding: renamed from mruby-binding-core +- mruby-enumerator: remove internal attribute methods obj, args, kwd, meth, fib. +- mruby-fiber: Add a new mrb_fiber_new() with MRB_API +- mruby-fiber: Allows calling `Fiber#resume` from C +- mruby-fiber: `Fiber#to_s` format changed +- mruby-io: Add "x" mode option for IO.open +- mruby-method: `Method#to_s` format changed +- mruby-pack: support new directives j,J,b,B +- mruby-range-ext: new method `Range#overlap?` +- mruby-string-ext: Add `String#valid_encoding?` method -- `-b` only specifies the script is the binary. The files loaded by `-r` are not affected by the option. -- `mruby` now loads complied binary if the suffix is `.mrb`. +# Bugs Fixed -## `mrbc` +- [#5712](https://github.com/mruby/mruby/issues/5712) No "make install" +- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#** is missing +- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code +- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error +- [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed +- [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable +- [#5949](https://github.com/mruby/mruby/issues/5949) Caller appears to report wrong line when block passed and brackets omitted +- [#5974](https://github.com/mruby/mruby/issues/5974) Invalid escape sequences in gem_init.c on windows +- [#5975](https://github.com/mruby/mruby/issues/5975) Equals comparison fails on extreme ends of 64-bit integers +- [#5985](https://github.com/mruby/mruby/issues/5985) Sign extension with OP_LOADI32 in get_int_operand() +- [#5986](https://github.com/mruby/mruby/issues/5986) Fix bugs in String#bytesplice +- [#5987](https://github.com/mruby/mruby/issues/5987) ~(-1 << 64) is incorrect +- [#5991](https://github.com/mruby/mruby/issues/5991) 'gets' method not working in mruby-3.2.0 +- [#5995](https://github.com/mruby/mruby/issues/5995) One seemingly unnecessary parameter is passed in the block parameters +- [#6029](https://github.com/mruby/mruby/issues/6029) mruby build fails under mrbgems directory +- [#6041](https://github.com/mruby/mruby/issues/6041) GC Performance may have degraded +- [#6051](https://github.com/mruby/mruby/issues/6051) Null pointer dereference in mrb_addrinfo_unix_path +- [#6052](https://github.com/mruby/mruby/issues/6052) Null pointer dereference while handling the Proc class +- [#6065](https://github.com/mruby/mruby/issues/6065) Null pointer dereference while handling the Proc class +- [#6066](https://github.com/mruby/mruby/issues/6066) Null pointer dereference involving Struct.new() +- [#6067](https://github.com/mruby/mruby/issues/6067) Null pointer dereference in mrb_string_value_cstr +- [#6068](https://github.com/mruby/mruby/issues/6068) Stack overflow in mrb_vm_exec +- [#6087](https://github.com/mruby/mruby/issues/6087) 'Remote branch HEAD not found in upstream origin' error on build +- [#6089](https://github.com/mruby/mruby/issues/6089) binding.eval() handles def expressions differently from CRuby +- [#6098](https://github.com/mruby/mruby/issues/6098) Fails to call superclass of wrapped method +- [#6108](https://github.com/mruby/mruby/issues/6108) VM crashes with break +- [#6134](https://github.com/mruby/mruby/issues/6134) String#unpack1 returns an array instead of a single string -- Add `--no-optimize` option to disable optimization. +# Pull Requests (User Visible Ones) -# mrbgems - -## mruby-class-ext - -- Add `Class#subclasses` method. -- Add `Module#undefined_instance_methods` method. - -## New bundled gems - -- mruby-errno from [https://github.com/iij/mruby-errno.git] -- mruby-set from [https://github.com/yui-knk/mruby-set.git] -- mruby-dir from [https://github.com/iij/mruby-dir.git] - -# CVEs - -Following CVEs are fixed. - -- [CVE-2022-0080](https://nvd.nist.gov/vuln/detail/CVE-2022-0080) -- [CVE-2022-0240](https://nvd.nist.gov/vuln/detail/CVE-2022-0240) -- [CVE-2022-0326](https://nvd.nist.gov/vuln/detail/CVE-2022-0326) -- [CVE-2022-0481](https://nvd.nist.gov/vuln/detail/CVE-2022-0481) -- [CVE-2022-0525](https://nvd.nist.gov/vuln/detail/CVE-2022-0525) -- [CVE-2022-0570](https://nvd.nist.gov/vuln/detail/CVE-2022-0570) -- [CVE-2022-0614](https://nvd.nist.gov/vuln/detail/CVE-2022-0614) -- [CVE-2022-0623](https://nvd.nist.gov/vuln/detail/CVE-2022-0623) -- [CVE-2022-0630](https://nvd.nist.gov/vuln/detail/CVE-2022-0630) -- [CVE-2022-0631](https://nvd.nist.gov/vuln/detail/CVE-2022-0631) -- [CVE-2022-0632](https://nvd.nist.gov/vuln/detail/CVE-2022-0632) -- [CVE-2022-0717](https://nvd.nist.gov/vuln/detail/CVE-2022-0717) -- [CVE-2022-0890](https://nvd.nist.gov/vuln/detail/CVE-2022-0890) -- [CVE-2022-1106](https://nvd.nist.gov/vuln/detail/CVE-2022-1106) -- [CVE-2022-1212](https://nvd.nist.gov/vuln/detail/CVE-2022-1212) -- [CVE-2022-1276](https://nvd.nist.gov/vuln/detail/CVE-2022-1276) -- [CVE-2022-1286](https://nvd.nist.gov/vuln/detail/CVE-2022-1286) -- [CVE-2022-1934](https://nvd.nist.gov/vuln/detail/CVE-2022-1934) +- [#5870](https://github.com/mruby/mruby/pull/5870) Use OP_LOADINEG instead of OP_LOADI +- [#5966](https://github.com/mruby/mruby/pull/5966) Update default.gembox add mruby debugger mrdb +- [#5979](https://github.com/mruby/mruby/pull/5979) Allow Class#allocate to be prohibited +- [#5989](https://github.com/mruby/mruby/pull/5989) Integrate mruby-binding-eval into mruby-eval +- [#5961](https://github.com/mruby/mruby/pull/5961) Add Docker to build and run all mruby tests. Run pre-commit and generate YARD docs with Docker +- [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory +- [#6009](https://github.com/mruby/mruby/pull/6009) Avoid adding /bintest which does not exist +- [#6012](https://github.com/mruby/mruby/pull/6012) Allow tests to be disabled for specific gems; warn about disabled tests +- [#6013](https://github.com/mruby/mruby/pull/6013) Fix Android toolchain +- [#6032](https://github.com/mruby/mruby/pull/6032) Rake: update task clean to remove bin and build folders +- [#6045](https://github.com/mruby/mruby/pull/6045) Fixes escape sequence bug and enhancements in Presym scanning +- [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC +- [#6081](https://github.com/mruby/mruby/pull/6081) Add "x" mode option for IO.open +- [#6086](https://github.com/mruby/mruby/pull/6086) Add build config for Nintendo Wii +- [#6097](https://github.com/mruby/mruby/pull/6097) Add a new mrb_fiber_new() with MRB_API +- [#6106](https://github.com/mruby/mruby/pull/6106) Ease fiber limitations +- [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf +- [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails diff --git a/doc/mruby3.3.md b/doc/mruby3.3.md new file mode 100644 index 000000000..5fc5ca4eb --- /dev/null +++ b/doc/mruby3.3.md @@ -0,0 +1,90 @@ +# User visible changes in `mruby3.3` from `mruby3.2` + +# The language + +- aliases work properly with `super` +- `callee` method work differently with aliases in mruby +- define `Kernel#respond_to_missing?` method +- `_inspect` method (`inspect` with recursive check) is removed +- `__printstr` method is removed; use `print` instead + +# Configuration + +- mruby can be built using Docker now. Try `docker-compose build` for example. +- New Platform: Nintendo Wii +- Improved Platforms: Android, Dreamcast + +# mruby memory API + +- `mrb_default_allocf` can be overridden by the application +- `mrb_open_allocf` will be deprecated + +# mruby VM and bytecode + +- [#5870](https://github.com/mruby/mruby/issues/5870) Use OP_LOADINEG instead of OP_LOADI + +# Changes in mrbgems + +- mruby-bin-config: new options --cxx,--cxxflags,--as,--asflags,--objc,--objcflags +- mruby-binding-eval (merged with mruby-eval) #5989 +- mruby-binding: renamed from mruby-binding-core +- mruby-enumerator: remove internal attribute methods obj, args, kwd, meth, fib. +- mruby-fiber: Add a new mrb_fiber_new() with MRB_API +- mruby-fiber: Allows calling `Fiber#resume` from C +- mruby-fiber: `Fiber#to_s` format changed +- mruby-io: Add "x" mode option for IO.open +- mruby-method: `Method#to_s` format changed +- mruby-pack: support new directives j,J,b,B +- mruby-range-ext: new method `Range#overlap?` +- mruby-string-ext: Add `String#valid_encoding?` method + +# Bugs Fixed + +- [#5712](https://github.com/mruby/mruby/issues/5712) No "make install" +- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#\*\* is missing +- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code +- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error +- [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed +- [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable +- [#5949](https://github.com/mruby/mruby/issues/5949) Caller appears to report wrong line when block passed and brackets omitted +- [#5974](https://github.com/mruby/mruby/issues/5974) Invalid escape sequences in gem_init.c on windows +- [#5975](https://github.com/mruby/mruby/issues/5975) Equals comparison fails on extreme ends of 64-bit integers +- [#5985](https://github.com/mruby/mruby/issues/5985) Sign extension with OP_LOADI32 in get_int_operand() +- [#5986](https://github.com/mruby/mruby/issues/5986) Fix bugs in String#bytesplice +- [#5987](https://github.com/mruby/mruby/issues/5987) ~(-1 << 64) is incorrect +- [#5991](https://github.com/mruby/mruby/issues/5991) 'gets' method not working in mruby-3.2.0 +- [#5995](https://github.com/mruby/mruby/issues/5995) One seemingly unnecessary parameter is passed in the block parameters +- [#6029](https://github.com/mruby/mruby/issues/6029) mruby build fails under mrbgems directory +- [#6041](https://github.com/mruby/mruby/issues/6041) GC Performance may have degraded +- [#6051](https://github.com/mruby/mruby/issues/6051) Null pointer dereference in mrb_addrinfo_unix_path +- [#6052](https://github.com/mruby/mruby/issues/6052) Null pointer dereference while handling the Proc class +- [#6065](https://github.com/mruby/mruby/issues/6065) Null pointer dereference while handling the Proc class +- [#6066](https://github.com/mruby/mruby/issues/6066) Null pointer dereference involving Struct.new() +- [#6067](https://github.com/mruby/mruby/issues/6067) Null pointer dereference in mrb_string_value_cstr +- [#6068](https://github.com/mruby/mruby/issues/6068) Stack overflow in mrb_vm_exec +- [#6087](https://github.com/mruby/mruby/issues/6087) 'Remote branch HEAD not found in upstream origin' error on build +- [#6089](https://github.com/mruby/mruby/issues/6089) binding.eval() handles def expressions differently from CRuby +- [#6098](https://github.com/mruby/mruby/issues/6098) Fails to call superclass of wrapped method +- [#6108](https://github.com/mruby/mruby/issues/6108) VM crashes with break +- [#6134](https://github.com/mruby/mruby/issues/6134) String#unpack1 returns an array instead of a single string + +# Pull Requests (User Visible Ones) + +- [#5870](https://github.com/mruby/mruby/pull/5870) Use OP_LOADINEG instead of OP_LOADI +- [#5966](https://github.com/mruby/mruby/pull/5966) Update default.gembox add mruby debugger mrdb +- [#5979](https://github.com/mruby/mruby/pull/5979) Allow Class#allocate to be prohibited +- [#5989](https://github.com/mruby/mruby/pull/5989) Integrate mruby-binding-eval into mruby-eval +- [#5961](https://github.com/mruby/mruby/pull/5961) Add Docker to build and run all mruby tests. Run pre-commit and generate YARD docs with Docker +- [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory +- [#6009](https://github.com/mruby/mruby/pull/6009) Avoid adding /bintest which does not exist +- [#6012](https://github.com/mruby/mruby/pull/6012) Allow tests to be disabled for specific gems; warn about disabled tests +- [#6013](https://github.com/mruby/mruby/pull/6013) Fix Android toolchain +- [#6032](https://github.com/mruby/mruby/pull/6032) Rake: update task clean to remove bin and build folders +- [#6045](https://github.com/mruby/mruby/pull/6045) Fixes escape sequence bug and enhancements in Presym scanning +- [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC +- [#6081](https://github.com/mruby/mruby/pull/6081) Add "x" mode option for IO.open +- [#6086](https://github.com/mruby/mruby/pull/6086) Add build config for Nintendo Wii +- [#6097](https://github.com/mruby/mruby/pull/6097) Add a new mrb_fiber_new() with MRB_API +- [#6106](https://github.com/mruby/mruby/pull/6106) Ease fiber limitations +- [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf +- [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails From 19d0ea803df756164c91ac142949d9e74c60b4e8 Mon Sep 17 00:00:00 2001 From: John Bampton Date: Sun, 31 Dec 2023 21:57:58 +1000 Subject: [PATCH 009/117] Fix `pre-commit` failure from `prettier` --- .github/linters/.yaml-lint.yml | 2 ++ .github/workflows/oss-fuzz.yml | 4 ++-- .github/workflows/super-linter.yml | 4 ++-- .gitignore | 1 + .pre-commit-config.yaml | 1 + .prettierrc | 3 +++ SECURITY.md | 2 +- build_config/dreamcast_shelf.rb | 2 +- doc/guides/compile.md | 4 ++-- doc/guides/debugger.md | 4 ++-- doc/guides/gc-arena-howto.md | 2 +- doc/guides/link.md | 12 ++++++------ doc/guides/mrbconf.md | 8 ++++---- doc/guides/mrbgems.md | 6 +++--- doc/guides/symbol.md | 14 +++++++------- doc/internal/boxing.md | 4 ++-- doc/mruby3.0.md | 9 +++++---- docker-compose.yml | 2 +- mrbgems/mruby-bigint/README-fgmp.md | 16 ++++++++-------- mrbgems/mruby-io/README.md | 4 ++-- mrbgems/mruby-pack/README.md | 2 +- 21 files changed, 57 insertions(+), 49 deletions(-) create mode 100644 .prettierrc diff --git a/.github/linters/.yaml-lint.yml b/.github/linters/.yaml-lint.yml index be4c88798..f5e0ee462 100644 --- a/.github/linters/.yaml-lint.yml +++ b/.github/linters/.yaml-lint.yml @@ -4,6 +4,8 @@ extends: default rules: + comments: + min-spaces-from-content: 1 document-start: disable line-length: disable truthy: false diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index ce5023a67..c4e0b3d10 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -11,12 +11,12 @@ jobs: - name: Build Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master with: - oss-fuzz-project-name: 'mruby' + oss-fuzz-project-name: "mruby" dry-run: false - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: - oss-fuzz-project-name: 'mruby' + oss-fuzz-project-name: "mruby" fuzz-seconds: 600 dry-run: false - name: Upload Crash diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 8d817ef4d..d250a7f98 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -9,8 +9,8 @@ permissions: jobs: build: permissions: - contents: read # for actions/checkout to fetch code - statuses: write # for github/super-linter/slim to mark status of each linter run + contents: read # for actions/checkout to fetch code + statuses: write # for github/super-linter/slim to mark status of each linter run name: Lint Code Base runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index eb5b5ddfa..e604347b9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,6 @@ compile_commands.json compile_flags.txt cscope.files cscope.out +node_modules tags !Gemfile.lock diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e66cc3b3d..d344920fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -54,6 +54,7 @@ repos: rev: v4.0.0-alpha.8 hooks: - id: prettier + exclude: ^doc/internal/opcode\.md$ - repo: https://github.com/igorshubovych/markdownlint-cli rev: v0.38.0 hooks: diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..81b81d20d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "bracketSpacing": false +} diff --git a/SECURITY.md b/SECURITY.md index 779b06c32..bd80d2dd9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,7 +11,7 @@ We consider the following issues as vulnerabilities: - Remote code execution - Crash caused by a valid Ruby script -We *don't* consider the following issues as vulnerabilities: +We _don't_ consider the following issues as vulnerabilities: - Runtime C undefined behavior (including integer overflow) - Crash caused by misused API diff --git a/build_config/dreamcast_shelf.rb b/build_config/dreamcast_shelf.rb index 7a4cc1afc..0edd9470c 100644 --- a/build_config/dreamcast_shelf.rb +++ b/build_config/dreamcast_shelf.rb @@ -34,7 +34,7 @@ MRuby::CrossBuild.new("dreamcast") do |conf| cc.defines << %w(_arch_sub_pristine) end - # C++ compiler + # C++ compiler conf.cxx do |cxx| cxx.command = conf.cc.command.dup cxx.include_paths = conf.cc.include_paths.dup diff --git a/doc/guides/compile.md b/doc/guides/compile.md index 579a49d7a..dab175613 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -80,7 +80,7 @@ conf.toolchain :clang #### Visual Studio 2010, 2012 and 2013 Toolchain configuration for Visual Studio on Windows. If you use the -[Visual Studio Command Prompt](https://msdn.microsoft.com/en-us/library/ms229859\(v=vs.110\).aspx), +[Visual Studio Command Prompt](), you normally do not have to specify this manually, since it gets automatically detected by our build process. ```ruby @@ -460,7 +460,7 @@ compile for `i386` a directory called `i386` is created under the build directory. The cross compilation workflow starts in the same way as the normal -compilation by compiling all *native* libraries and binaries, except +compilation by compiling all _native_ libraries and binaries, except for we don't have `host/mrbc` directory (`host` directory itself works as placeholder for `mrbc`). Afterwards the cross compilation process proceeds like this: diff --git a/doc/guides/debugger.md b/doc/guides/debugger.md index 60be1cc8f..dba9fb57d 100644 --- a/doc/guides/debugger.md +++ b/doc/guides/debugger.md @@ -62,7 +62,7 @@ $ mrdb sample.rb You can execute the shell commands listed below: | command | description | -|:----------------:|:--------------------------------------------------------------------------| +| :--------------: | :------------------------------------------------------------------------ | | run | execute programs | | step | execute stepping | | continue | execute continuing program | @@ -83,7 +83,7 @@ You can debug the mruby binary files. #### 2.2.2.1 Debugging the binary files - notice -To debug mruby binary files, you need to compile mruby files with option `-g`. + To debug mruby binary files, you need to compile mruby files with option `-g`. ```bash $ mrbc -g sample.rb diff --git a/doc/guides/gc-arena-howto.md b/doc/guides/gc-arena-howto.md index 31bee93f1..2ac2bdfd4 100644 --- a/doc/guides/gc-arena-howto.md +++ b/doc/guides/gc-arena-howto.md @@ -4,7 +4,7 @@ _This is an English translation of [Matz's blog post][matz blog post] written in Japanese._ _Some parts are updated to reflect recent changes._ -[matz blog post]: +[matz blog post]: https://www.rubyist.net/~matz/20130731.html When you are extending mruby using C language, you may encounter mysterious "arena overflow error" or memory leak or very slow diff --git a/doc/guides/link.md b/doc/guides/link.md index 491efc413..ac19aa234 100644 --- a/doc/guides/link.md +++ b/doc/guides/link.md @@ -51,8 +51,8 @@ for example: To retrieve compiler options used to build `mruby`, you can use `mruby-config` command with following options: -- `--cc` compiler name -- `--cflags` options passed to compiler +- `--cc` compiler name +- `--cflags` options passed to compiler ```console $ mruby-config --cflags @@ -66,10 +66,10 @@ compatible to mruby configuration. To retrieve linker options, you can use `mruby-config` with following options: -- `--ld` linker name -- `--ldflags` options passed to linker -- `--ldflags-before-libs` options passed to linker before linked libraries -- `--libs` linked libraries +- `--ld` linker name +- `--ldflags` options passed to linker +- `--ldflags-before-libs` options passed to linker before linked libraries +- `--libs` linked libraries ```console $ mruby-config --ldflags diff --git a/doc/guides/mrbconf.md b/doc/guides/mrbconf.md index dc1538506..823a0ba17 100644 --- a/doc/guides/mrbconf.md +++ b/doc/guides/mrbconf.md @@ -25,7 +25,7 @@ MRuby::Build.new do |conf| end ``` -***NOTE*** +**_NOTE_** - Use common definitions (`conf.defines`) instead of per-compiler definitions (e.g., `conf.cc.defines`) unless there is a special reason not to. - It is now deprecated to edit the `include/mruby/mrbconf.h` file or give it directly as a compiler flag, as was the case before. @@ -123,7 +123,7 @@ end - Defines value is `1024`. - Specifies number of `RBasic` per each heap page. -- To calculate the number of bytes per heap page, it is "(size of management data per heap page) + (size per object) * `MRB_HEAP_PAGE_SIZE`". +- To calculate the number of bytes per heap page, it is "(size of management data per heap page) + (size per object) \* `MRB_HEAP_PAGE_SIZE`". In mruby 3.1.0, the "size of management data per heap page" is 6 words, also "size per object" is 6 words. For a 32-bit CPU, `(6 * 4) + (6 * 4) * MRB_HEAP_PAGE_SIZE` gives the bytes of size per heap page. Conversely, for example, to keep the size per heap page to 4 Ki bytes, @@ -135,7 +135,7 @@ end - Default value is `4`. - If you're allocating data types that requires alignment more than default value define the -largest value of required alignment. + largest value of required alignment. `POOL_PAGE_SIZE` @@ -149,7 +149,7 @@ largest value of required alignment. - If defined enables fixed size `mrb_state` atexit stack. - Raises `RuntimeError` when `mrb_state_atexit` call count to same `mrb_state` exceeds -`MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. + `MRB_FIXED_STATE_ATEXIT_STACK_SIZE`'s value. `MRB_FIXED_STATE_ATEXIT_STACK_SIZE` diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md index 999629d4d..fe086c1e9 100644 --- a/doc/guides/mrbgems.md +++ b/doc/guides/mrbgems.md @@ -248,7 +248,7 @@ Version requirement supports following operators: - '<=': is equal or lesser - '~>': is equal or greater and is lesser than the next major version - example 1: '~> 2.2.2' means '>= 2.2.2' and '< 2.3.0' - - example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' + - example 2: '~> 2.2' means '>= 2.2.0' and '< 3.0.0' When more than one version requirements is passed, the dependency must satisfy all of it. @@ -395,8 +395,8 @@ override existing classes or add new ones in this way. Put all Ruby files into the `mrblib` directory and all C files into the `src` directory. mruby codes under `mrblib` directory would be executed after gem init C -function is called. Make sure *mruby script* depends on *C code* and -*C code* doesn't depend on *mruby script*. +function is called. Make sure _mruby script_ depends on _C code_ and +_C code_ doesn't depend on _mruby script_. ### Pre-Conditions diff --git a/doc/guides/symbol.md b/doc/guides/symbol.md index c76420da9..bae789b64 100644 --- a/doc/guides/symbol.md +++ b/doc/guides/symbol.md @@ -57,13 +57,13 @@ To save RAM, `mruby` can use compile-time allocation of some symbols. You can use following macros to get preallocated symbols by including `mruby/presym.h` header. -- `MRB_SYM(xor)` //=> xor (Word characters) -- `MRB_SYM_B(xor)` //=> xor! (Method with Bang) -- `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) -- `MRB_SYM_E(xor)` //=> xor= (Method with Equal) -- `MRB_CVSYM(xor)` //=> @@xor (Class Variable) -- `MRB_IVSYM(xor)` //=> @xor (Instance Variable) -- `MRB_OPSYM(xor)` //=> ^ (Operator) +- `MRB_SYM(xor)` //=> xor (Word characters) +- `MRB_SYM_B(xor)` //=> xor! (Method with Bang) +- `MRB_SYM_Q(xor)` //=> xor? (Method with Question mark) +- `MRB_SYM_E(xor)` //=> xor= (Method with Equal) +- `MRB_CVSYM(xor)` //=> @@xor (Class Variable) +- `MRB_IVSYM(xor)` //=> @xor (Instance Variable) +- `MRB_OPSYM(xor)` //=> ^ (Operator) For `MRB_OPSYM()`, specify the names corresponding to operators (see `MRuby::Presym::OPERATORS` in `lib/mruby/presym.rb` for the names that diff --git a/doc/internal/boxing.md b/doc/internal/boxing.md index eb03de74b..0cae591e6 100644 --- a/doc/internal/boxing.md +++ b/doc/internal/boxing.md @@ -15,7 +15,7 @@ Some values (called immediate values, e.g. integers, booleans, symbols, etc.) ar The Word boxing packing bit patterns are like following: | Types | Bit Pattern | -|--------|---------------------------------------| +| ------ | ------------------------------------- | | object | `xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000` | | fixnum | `xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx1` | | nil | `00000000 00000000 00000000 00000000` | @@ -34,7 +34,7 @@ NaN boxing packs the Ruby data in a floating-point numbers, which represent NaN The NaN boxing packing bit patterns are like following: | Types | Bit Pattern | -|--------|---------------------------------------------------------------------------| +| ------ | ------------------------------------------------------------------------- | | float | `SEEEEEEE EEEEFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF` | | +/-inf | `S1111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000` | | nan | `01111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000` | diff --git a/doc/mruby3.0.md b/doc/mruby3.0.md index 3f7418c49..9d211abb5 100644 --- a/doc/mruby3.0.md +++ b/doc/mruby3.0.md @@ -42,10 +42,10 @@ We have ported some new syntax from CRuby. ## Renamed for consistency Some configuration macro names are changed for consistency (use `MRB_USE_XXX` - or `MRB_NO_XXX`). +or `MRB_NO_XXX`). -| mruby2 | mruby3 | -|--------------------------------|---------------------------| +| mruby2 | mruby3 | +| ------------------------------ | ------------------------- | | `MRB_ENABLE_ALL_SYMBOLS` | `MRB_USE_ALL_SYMBOLS` | | `MRB_ENABLE_CXX_ABI` | `MRB_USE_CXX_ABI` | | `MRB_ENABLE_CXX_EXCEPTION` | `MRB_USE_CXX_EXCEPTION` | @@ -149,7 +149,8 @@ No more operand extension ## Changed Instructions -Jump addresses used to be specified by absolute offset from the start of `iseq`. Now they are relative offset from the address of the next instruction. +Jump addresses used to be specified by absolute offset from the start of `iseq`. Now they are relative offset from the +address of the next instruction. ## `Random` now use `xoshiro128++`. diff --git a/docker-compose.yml b/docker-compose.yml index 55b61a874..009947b0f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3.8' +version: "3.8" services: test: build: diff --git a/mrbgems/mruby-bigint/README-fgmp.md b/mrbgems/mruby-bigint/README-fgmp.md index 591188c12..7693f3c1f 100644 --- a/mrbgems/mruby-bigint/README-fgmp.md +++ b/mrbgems/mruby-bigint/README-fgmp.md @@ -73,18 +73,18 @@ MS-DOS 286 C compiler (see credits above) 1. fgmp is considerably slower than gmp 2. fgmp does not implement the following: - all mpq_* - internal mpn_* functions - mpz_perfect_square_p - mpz_inp_raw, mpz_out_raw - mp_set_memory_functions, mpz_out_str, mpz_inp_str + - all mpq\_\* + - internal mpn\_\* functions + - mpz_perfect_square_p + - mpz_inp_raw, mpz_out_raw + - mp_set_memory_functions, mpz_out_str, mpz_inp_str 3. fgmp implements the following in addition to the routines in GNU gmp. - `int mpz_jacobi(MP_INT *a, MP_INT *b)` - - finds the jacobi symbol (a/b) + `int mpz_jacobi(MP_INT *a, MP_INT *b)` + - finds the jacobi symbol (a/b) 4. mpz_sizeinbase often overestimates the exact value 5. To convert your gmp based program to fgmp (subject to the -above) + above) - recompile your source. Make sure to include the gmp.h file included with fgmp rather than that included with gmp. (The point is to recompile diff --git a/mrbgems/mruby-io/README.md b/mrbgems/mruby-io/README.md index 21138ace4..99c48f3d6 100644 --- a/mrbgems/mruby-io/README.md +++ b/mrbgems/mruby-io/README.md @@ -17,7 +17,7 @@ Add the line below to your build configuration. - | method | mruby-io | memo | -|----------------------------|----------|----------| +| -------------------------- | -------- | -------- | | IO.binread | | | | IO.binwrite | | | | IO.copy_stream | | | @@ -102,7 +102,7 @@ Add the line below to your build configuration. - | method | mruby-io | memo | -|-----------------------------|----------|----------| +| --------------------------- | -------- | -------- | | File.absolute_path | | | | File.atime | | | | File.basename | o | | diff --git a/mrbgems/mruby-pack/README.md b/mrbgems/mruby-pack/README.md index 10a538095..d108f2a09 100644 --- a/mrbgems/mruby-pack/README.md +++ b/mrbgems/mruby-pack/README.md @@ -45,7 +45,7 @@ There is no dependency on other mrbgems. - V : 32-bit unsigned, VAX (little-endian) byte order - v : 16-bit unsigned, VAX (little-endian) byte order - x : null byte -- Z : same as "a", except that null is added with * +- Z : same as "a", except that null is added with \* ## License From e4713990440b13a98f28f0f721d2d232e266af31 Mon Sep 17 00:00:00 2001 From: John Bampton Date: Mon, 1 Jan 2024 17:19:53 +1000 Subject: [PATCH 010/117] actions: label more files for build --- .github/labeler.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/labeler.yml b/.github/labeler.yml index 742fc2b3f..bdd33ca72 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -7,11 +7,17 @@ build: - any: - changed-files: - any-glob-to-any-file: + - Dockerfile - Makefile - Rakefile + - appveyor.yml + - build_config.rb - build_config/**/* + - docker-compose.yml - lib/**/* + - minirake - tasks/**/* + - .travis.yml core: - any: - changed-files: From 519a2cbd59fc8b5d11700247eddde4a46db3edd0 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 31 Dec 2023 14:18:54 +0900 Subject: [PATCH 011/117] Fixed when combined `mrb_fiber_resume()` and `Fiber#transfer` For example, the following code was crashing. ```c #include #include #include int main(int argc, char *argv[]) { mrb_state *mrb = mrb_open(); mrb_value fiber = mrb_load_string(mrb, "Fiber.new { Fiber.new { 12345.6789 }.transfer }"); mrb_value res = mrb_fiber_resume(mrb, fiber, 0, NULL); mrb_p(mrb, res); mrb_close(mrb); return 0; } ``` --- src/vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index 759fd977a..a5c1dee9c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2399,7 +2399,8 @@ RETRY_TRY_BLOCK: mrb->c = c->prev ? c->prev : mrb->root_c; c->prev = NULL; mrb->c->status = MRB_FIBER_RUNNING; - if (c->vmexec) { + if (c->vmexec || + (mrb->c == mrb->root_c && mrb->c->ci == mrb->c->cibase) /* case using Fiber#transfer in mrb_fiber_resume() */) { mrb_gc_arena_restore(mrb, ai); c->vmexec = FALSE; mrb->jmp = prev_jmp; From e71e1bc50e5277ea1c276e6dd1f76bf12c6973fa Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 1 Jan 2024 23:05:12 +0900 Subject: [PATCH 012/117] mruby-hash-ext: reduce the scope of the loop variable `i` --- mrbgems/mruby-hash-ext/src/hash-ext.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mrbgems/mruby-hash-ext/src/hash-ext.c b/mrbgems/mruby-hash-ext/src/hash-ext.c index b634373f4..7ec21c61c 100644 --- a/mrbgems/mruby-hash-ext/src/hash-ext.c +++ b/mrbgems/mruby-hash-ext/src/hash-ext.c @@ -24,14 +24,14 @@ hash_values_at(mrb_state *mrb, mrb_value hash) { const mrb_value *argv; mrb_value result; - mrb_int argc, i; + mrb_int argc; int ai; mrb_get_args(mrb, "*", &argv, &argc); result = mrb_ary_new_capa(mrb, argc); if (argc == 0) return result; ai = mrb_gc_arena_save(mrb); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i])); mrb_gc_arena_restore(mrb, ai); } @@ -53,12 +53,12 @@ hash_slice(mrb_state *mrb, mrb_value hash) { const mrb_value *argv; mrb_value result; - mrb_int argc, i; + mrb_int argc; mrb_get_args(mrb, "*", &argv, &argc); result = mrb_hash_new_capa(mrb, argc); if (argc == 0) return result; /* empty hash */ - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { mrb_value key = argv[i]; mrb_value val; @@ -85,11 +85,11 @@ hash_except(mrb_state *mrb, mrb_value hash) { const mrb_value *argv; mrb_value result; - mrb_int argc, i; + mrb_int argc; mrb_get_args(mrb, "*", &argv, &argc); result = mrb_hash_dup(mrb, hash); - for (i = 0; i < argc; i++) { + for (mrb_int i = 0; i < argc; i++) { mrb_hash_delete_key(mrb, result, argv[i]); } return result; From d944a079a37249bfbae3420275a62461c1c9234e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 2 Jan 2024 08:35:22 +0900 Subject: [PATCH 013/117] mruby-numeric-ext (int_digits): avoid variable name override --- mrbgems/mruby-numeric-ext/src/numeric_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 4833f05fd..097a902f3 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -165,8 +165,7 @@ int_digits(mrb_state *mrb, mrb_value self) } while (mrb_bint_cmp(mrb, x, zero) > 0) { - mrb_value q = mrb_bint_mod(mrb, x, bv); - mrb_ary_push(mrb, digits, q); + mrb_ary_push(mrb, digits, mrb_bint_mod(mrb, x, bv)); x = mrb_bint_div(mrb, x, bv); if (!mrb_bigint_p(x)) { mrb_int n = mrb_integer(x); From d632085b5be5fff332d640151f928e017d8bd878 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 2 Jan 2024 15:22:45 +0900 Subject: [PATCH 014/117] mruby-bigint (udiv): narrow the scope of loop variable 'i' --- mrbgems/mruby-bigint/core/bigint.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 97f545473..884089188 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -478,7 +478,6 @@ udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy) } mpz_t q, x, y; - size_t i; mrb_assert(!uzero(yy)); /* divided by zero */ mpz_init(mrb, &q); @@ -502,6 +501,8 @@ udiv(mrb_state *mrb, mpz_t *qq, mpz_t *rr, mpz_t *xx, mpz_t *yy) else qhat = (((mp_dbl_limb)x.p[j+yd] << DIG_SIZE) + x.p[j+yd-1]) / z; if (qhat) { + size_t i; + for (i=0; i Date: Tue, 2 Jan 2024 15:23:33 +0900 Subject: [PATCH 015/117] mruby-bigint (mrb_bint_new_float): narrow the scope of variable 'f' --- mrbgems/mruby-bigint/core/bigint.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mrbgems/mruby-bigint/core/bigint.c b/mrbgems/mruby-bigint/core/bigint.c index 884089188..8877ab7e7 100644 --- a/mrbgems/mruby-bigint/core/bigint.c +++ b/mrbgems/mruby-bigint/core/bigint.c @@ -1112,7 +1112,6 @@ mrb_bint_new_float(mrb_state *mrb, mrb_float x) mrb_float bi = 1.0 / b; size_t rn; mp_limb *rp; - mp_limb f; for (rn = 1; x >= b; rn++) x *= bi; @@ -1120,7 +1119,7 @@ mrb_bint_new_float(mrb_state *mrb, mrb_float x) mpz_realloc(mrb, r, rn); rp = r->p; for (size_t i=rn-1;;i--) { - f = LOW((mp_limb)x); + mp_limb f = LOW((mp_limb)x); x -= f; mrb_assert(x < 1.0); rp[i] = f; From 93bda0d27f189dd742a6499493f14f71ad597da4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 3 Jan 2024 16:05:46 +0900 Subject: [PATCH 016/117] mruby-fiber (fiber_init_fiber): rename conflicting local variables --- mrbgems/mruby-fiber/src/fiber.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index baddf65ce..bb11787fe 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -43,12 +43,12 @@ fiber_init_fiber(mrb_state *mrb, struct RFiber *f, const struct RProc *p) c->stend = c->stbase + slen; { - mrb_value *p = c->stbase; - mrb_value *pend = c->stend; + mrb_value *s = c->stbase; + mrb_value *send = c->stend; - while (p < pend) { - SET_NIL_VALUE(*p); - p++; + while (s < send) { + SET_NIL_VALUE(*s); + s++; } } From 7861422cbe873956afe2107f56c93dda1904141a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 3 Jan 2024 16:07:15 +0900 Subject: [PATCH 017/117] mruby-fiber (fiber_switch): reduce the scope of local variables --- mrbgems/mruby-fiber/src/fiber.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index bb11787fe..c0fd4d751 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -252,8 +252,6 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr } fiber_switch_context(mrb, c); if (status == MRB_FIBER_CREATED) { - mrb_value *b, *e; - if (!c->ci->proc) { return fiber_error(mrb, "double resume (current)"); } @@ -267,8 +265,10 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr } else { mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ - b = c->stbase+1; - e = b + len; + + mrb_value *b = c->stbase+1; + mrb_value *e = b + len; + while (b Date: Thu, 4 Jan 2024 10:08:22 +0900 Subject: [PATCH 018/117] mruby-errno (mrb_sce_sys_fail): remove redundant assignment --- mrbgems/mruby-errno/src/errno.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mrbgems/mruby-errno/src/errno.c b/mrbgems/mruby-errno/src/errno.c index b2059f465..71ab61e25 100644 --- a/mrbgems/mruby-errno/src/errno.c +++ b/mrbgems/mruby-errno/src/errno.c @@ -288,7 +288,6 @@ mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls) if (argc == 1) { msg = mrb_nil_value(); } - exc = mrb_obj_value(e); mrb_sce_init(mrb, exc, msg, no); mrb_exc_raise(mrb, exc); return mrb_nil_value(); /* NOTREACHED */ From 9ee7d955e3ee15cfb6d72f7db6e1dffa3e4f1fbe Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 4 Jan 2024 11:18:14 +0900 Subject: [PATCH 019/117] mruby-metaprog: narrow the scope of a local variable --- mrbgems/mruby-metaprog/src/metaprog.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 3b93574c1..f1fe097c7 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -176,7 +176,6 @@ static mrb_value mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass) { mrb_value ary; - struct RClass *oldklass; khash_t(st) *set = kh_init(st, mrb); if (!recur) { @@ -187,8 +186,8 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *kl } else { khash_t(st) *undef = kh_init(st, mrb); + struct RClass *oldklass = NULL; - oldklass = NULL; while (klass && (klass != oldklass)) { method_entry_loop(mrb, klass, set, undef); oldklass = klass; From 20dd737a4a8c29fe25e0fc6442ec295c91b83049 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 5 Jan 2024 13:00:55 +0900 Subject: [PATCH 020/117] mruby-io (io_s_popen): remove `fflush(stdin)` Flushing input I/O should be useless. --- mrbgems/mruby-io/src/io.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 1767f66ba..6b506c4aa 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -522,8 +522,6 @@ io_s_popen(mrb_state *mrb, mrb_value klass) } if (!doexec) { - // XXX - fflush(stdin); fflush(stdout); fflush(stderr); } From f1b8d38eb59782d0df31c7c4d193751da1eee24c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 5 Jan 2024 13:02:39 +0900 Subject: [PATCH 021/117] mruby-io: narrow a local variable scope --- mrbgems/mruby-io/src/io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 6b506c4aa..8d04ed3af 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -102,12 +102,11 @@ io_get_open_fptr(mrb_state *mrb, mrb_value io) static void io_set_process_status(mrb_state *mrb, pid_t pid, int status) { - struct RClass *c_process, *c_status; + struct RClass *c_status = NULL; mrb_value v; - c_status = NULL; if (mrb_class_defined_id(mrb, MRB_SYM(Process))) { - c_process = mrb_module_get_id(mrb, MRB_SYM(Process)); + struct RClass *c_process = mrb_module_get_id(mrb, MRB_SYM(Process)); if (mrb_const_defined(mrb, mrb_obj_value(c_process), MRB_SYM(Status))) { c_status = mrb_class_get_under_id(mrb, c_process, MRB_SYM(Status)); } From e1b65011835cf2881f932cd9545f12100be57c47 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 5 Jan 2024 13:03:33 +0900 Subject: [PATCH 022/117] mruby-io: fix local variable initialization redundancy --- mrbgems/mruby-io/src/io.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 8d04ed3af..265716cdf 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -1220,26 +1220,22 @@ time2timeval(mrb_state *mrb, mrb_value time) static mrb_value io_s_pipe(mrb_state *mrb, mrb_value klass) { - mrb_value r = mrb_nil_value(); - mrb_value w = mrb_nil_value(); - struct mrb_io *fptr_r; - struct mrb_io *fptr_w; int pipes[2]; if (io_pipe(mrb, pipes) == -1) { mrb_sys_fail(mrb, "pipe"); } - r = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - fptr_r = io_alloc(mrb); + mrb_value r = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); + struct mrb_io *fptr_r = io_alloc(mrb); fptr_r->fd = pipes[0]; fptr_r->readable = 1; DATA_TYPE(r) = &mrb_io_type; DATA_PTR(r) = fptr_r; io_init_buf(mrb, fptr_r); - w = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); - fptr_w = io_alloc(mrb); + mrb_value w = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); + struct mrb_io *fptr_w = io_alloc(mrb); fptr_w->fd = pipes[1]; fptr_w->writable = 1; fptr_w->sync = 1; From b06fdb4bfa89b1818bc23d90cd4fb3c160c4da06 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 6 Jan 2024 08:30:56 +0900 Subject: [PATCH 023/117] mruby-io/file.c: reduce the scope of local variables --- mrbgems/mruby-io/src/file.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 2bfef3030..4116d4777 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -120,15 +120,13 @@ mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) { const mrb_value *argv; mrb_int argc, i; - char *path; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0; i < argc; i++) { - const char *utf8_path; mrb_value pathv = argv[i]; mrb_ensure_string_type(mrb, pathv); - utf8_path = RSTRING_CSTR(mrb, pathv); - path = mrb_locale_from_utf8(utf8_path, -1); + const char *utf8_path = RSTRING_CSTR(mrb, pathv); + char *path = mrb_locale_from_utf8(utf8_path, -1); if (UNLINK(path) < 0) { mrb_locale_free(path); mrb_sys_fail(mrb, utf8_path); From 2eeb19a5ed9af2028b1ab3dac78b14e7decffeb0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 6 Jan 2024 14:31:32 +0900 Subject: [PATCH 024/117] mruby-kernel-ext (mrb_f_caller): remove unnecessary condition check --- mrbgems/mruby-kernel-ext/src/kernel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 89116f63a..6bdcc9469 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -59,7 +59,7 @@ mrb_f_caller(mrb_state *mrb, mrb_value self) if (n < 0) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%d)", n); } - if (n == 0 || bt_len <= lev) { + if (n == 0) { return mrb_ary_new(mrb); } if (bt_len <= n + lev) n = bt_len - lev - 1; From d47f1b4df3f0a8f8f7f731b4edc1a6e9bb6f7ee4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 6 Jan 2024 14:32:54 +0900 Subject: [PATCH 025/117] array.c (ary_expand_capa): remove unnecessary condition check --- src/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/array.c b/src/array.c index 01ccd85a8..76a1f8b69 100644 --- a/src/array.c +++ b/src/array.c @@ -215,7 +215,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) capa = len; } } - if (capa < len || capa > ARY_MAX_SIZE) { + if (capa > ARY_MAX_SIZE) { ary_too_big(mrb); } From be3b93ecb923ee08eeac70618614e459fad953aa Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 6 Jan 2024 14:33:50 +0900 Subject: [PATCH 026/117] array.c (ary_expand_capa): rename a conflicting local variable --- src/array.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/array.c b/src/array.c index 76a1f8b69..7e2d03c65 100644 --- a/src/array.c +++ b/src/array.c @@ -221,12 +221,12 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) if (ARY_EMBED_P(a)) { mrb_value *ptr = ARY_EMBED_PTR(a); - mrb_int len = ARY_EMBED_LEN(a); + mrb_int slen = ARY_EMBED_LEN(a); mrb_value *expanded_ptr = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*capa); ARY_UNSET_EMBED_FLAG(a); - array_copy(expanded_ptr, ptr, len); - a->as.heap.len = len; + array_copy(expanded_ptr, ptr, slen); + a->as.heap.len = slen; a->as.heap.aux.capa = capa; a->as.heap.ptr = expanded_ptr; } From 2cf6f7f5c7540d800e9a5f473ebd900d1936373e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 7 Jan 2024 23:54:59 +0900 Subject: [PATCH 027/117] mruby-rational: move misplaced `#ifndef MRB_NO_FLOAT` --- mrbgems/mruby-rational/src/rational.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index b3a5f945c..9bdea6957 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -702,9 +702,10 @@ rational_div(mrb_state *mrb, mrb_value x) static mrb_value rational_pow(mrb_state *mrb, mrb_value x) { +#ifndef MRB_NO_FLOAT mrb_value y = mrb_get_arg1(mrb); struct mrb_rational *p1 = rational_ptr(mrb, x); -#ifndef MRB_NO_FLOAT + double d1, d2; switch (mrb_type(y)) { From 27c2f9ac380bfb6733d96c4766764d7790d2717e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 8 Jan 2024 07:23:03 +0900 Subject: [PATCH 028/117] mruby-random (mrb_ary_sample): reduce the scope of loop variables --- mrbgems/mruby-random/src/random.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index c47702e94..025c4f369 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -344,19 +344,18 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) } else { mrb_value result; - mrb_int i, j; if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number"); if (n > len) n = len; result = mrb_ary_new_capa(mrb, n); - for (i=0; i Date: Mon, 8 Jan 2024 19:12:55 +0900 Subject: [PATCH 029/117] mruby-random: rename a conflicting local variable --- mrbgems/mruby-random/src/random.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index 025c4f369..98d4fce4d 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -349,20 +349,20 @@ mrb_ary_sample(mrb_state *mrb, mrb_value ary) if (n > len) n = len; result = mrb_ary_new_capa(mrb, n); for (mrb_int i=0; i Date: Mon, 8 Jan 2024 23:18:57 +0900 Subject: [PATCH 030/117] mruby-math: fix spacing --- mrbgems/mruby-math/src/math.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 75f0a2202..fdb533dcf 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -105,7 +105,7 @@ double erfc(double x); double erf(double x) { - static const double two_sqrtpi = 1.128379167095512574; + static const double two_sqrtpi = 1.128379167095512574; double sum = x; double term = x; double xsqr = x*x; @@ -129,7 +129,7 @@ erf(double x) double erfc(double x) { - static const double one_sqrtpi= 0.564189583547756287; + static const double one_sqrtpi = 0.564189583547756287; double a = 1; double b = x; double c = x; From 8a2e88390bee4f602e81fe310f90e503c34f1f8f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 07:47:57 +0900 Subject: [PATCH 031/117] mruby-math: reduce the scope of a local variable --- mrbgems/mruby-math/src/math.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index fdb533dcf..26a6eaa40 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -137,7 +137,7 @@ erfc(double x) double q1; double q2 = b/d; double n = 1.0; - double t; + if (fabs(x) < 2.2) { return 1.0 - erf(x); } @@ -145,7 +145,7 @@ erfc(double x) return 2.0 - erfc(-x); } do { - t = a*n+b*x; + double t = a*n+b*x; a = b; b = t; t = c*n+d*x; From 51c4c4716a0e54b4e0a0c5c9f7c27db1572329be Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 07:59:42 +0900 Subject: [PATCH 032/117] mruby-math: use `log1p(x)` instead of `log(1.0+x)` --- mrbgems/mruby-math/src/math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 26a6eaa40..76ee57481 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -74,7 +74,7 @@ atanh(double x) } else { /* Basic formula for atanh */ - y = 0.5 * (log(1.0+x) - log(1.0-x)); + y = 0.5 * (log1p(x) - log1p(-x)); } return y; From af3482d562111cb5705485c97713949d73c4b9a5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 08:01:28 +0900 Subject: [PATCH 033/117] mruby-math: use `erfc(x)` instead of `1.0 - erf(x)` --- mrbgems/mruby-math/src/math.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 76ee57481..0d2f4cc48 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -139,7 +139,7 @@ erfc(double x) double n = 1.0; if (fabs(x) < 2.2) { - return 1.0 - erf(x); + return erfc(x); } if (x < 0.0) { /*signbit(x)*/ return 2.0 - erfc(-x); From a5e83075d4ff9fbb662794f6cc01907bbb8f49e1 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 08:22:26 +0900 Subject: [PATCH 034/117] string.c: reduce the scope of a local variable --- src/string.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/string.c b/src/string.c index b7e3a6504..47a6ebfe0 100644 --- a/src/string.c +++ b/src/string.c @@ -400,13 +400,12 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co /* Searching */ while (p < pend && pend - p >= slen) { - const char *pivot; if (memcmp(p, s, slen) == 0) { return off; } - pivot = p + qstable[(unsigned char)p[slen - 1]]; + const char *pivot = p + qstable[(unsigned char)p[slen - 1]]; if (pivot >= pend || pivot < p /* overflowed */) { return -1; } do { From 64a4bf0e28fdebda2e82652208d9eb3c9db728e3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 10:19:37 +0900 Subject: [PATCH 035/117] string.c: avoid infinite loop; fix #6143 `mrb_utf8len` returns 0 for invalid characters. --- src/string.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 47a6ebfe0..5c770ec11 100644 --- a/src/string.c +++ b/src/string.c @@ -409,7 +409,10 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co if (pivot >= pend || pivot < p /* overflowed */) { return -1; } do { - p += mrb_utf8len(p, pend); + mrb_int len = mrb_utf8len(p, pend); + + if (len == 0) p++; /* invalid character */ + else p += len; off++; } while (p < pivot); } From f1d01a6107f9315590f56c05c83a23f761b310d6 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 10:39:03 +0900 Subject: [PATCH 036/117] string.c (mrb_utf8len): should return 1 for invalid chars; ref #6143 --- src/string.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/string.c b/src/string.c index 5c770ec11..6441d653b 100644 --- a/src/string.c +++ b/src/string.c @@ -278,6 +278,7 @@ mrb_utf8len(const char* p, const char* e) mrb_int len = mrb_utf8len_table[(unsigned char)p[0] >> 3]; if (len > e - p) return 1; switch (len) { + case 0: case 1: return 1; case 4: @@ -409,10 +410,7 @@ str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, co if (pivot >= pend || pivot < p /* overflowed */) { return -1; } do { - mrb_int len = mrb_utf8len(p, pend); - - if (len == 0) p++; /* invalid character */ - else p += len; + p += mrb_utf8len(p, pend); off++; } while (p < pivot); } From f3ebef117254889eb4b2f828bd49508933076cf2 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 11:00:44 +0900 Subject: [PATCH 037/117] mruby-string (chars2bytes): reduce the scope of local variables --- src/string.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/string.c b/src/string.c index 6441d653b..f4011756f 100644 --- a/src/string.c +++ b/src/string.c @@ -330,12 +330,12 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) return idx; } else { - mrb_int i, b, n; + mrb_int b = 0; const char *p = RSTRING_PTR(s) + off; const char *e = RSTRING_END(s); - for (b=i=0; p Date: Tue, 9 Jan 2024 11:44:12 +0900 Subject: [PATCH 038/117] string.c: avoid RSTRING_CHAR_LEN() if possible Current code scan the string twice (once from RSTRING_CHAR_LEN, and once from chars2bytes), but those scans are not necessary. Just point the end of the string. --- src/string.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/string.c b/src/string.c index f4011756f..562a62bd7 100644 --- a/src/string.c +++ b/src/string.c @@ -2070,8 +2070,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) mrb_int pos; if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { - pos = RSTRING_CHAR_LEN(str); - pos = chars2bytes(str, 0, pos); + pos = RSTRING_LEN(str); } else if (pos >= 0) { pos = chars2bytes(str, 0, pos); From 59a1d7493762f7895cc8432bce6f7da5942e4aaf Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 9 Jan 2024 13:00:41 +0900 Subject: [PATCH 039/117] string.c: inline `str_range_to_bytes` --- src/string.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/string.c b/src/string.c index 562a62bd7..c3fb46f3b 100644 --- a/src/string.c +++ b/src/string.c @@ -555,17 +555,12 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) return mrb_obj_value(s); } -static void -str_range_to_bytes(mrb_value str, mrb_int *pos, mrb_int *len) -{ - *pos = chars2bytes(str, 0, *pos); - *len = chars2bytes(str, *pos, *len); -} #ifdef MRB_UTF8_STRING static inline mrb_value str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) { - str_range_to_bytes(str, &beg, &len); + beg = chars2bytes(str, 0, beg); + len = chars2bytes(str, beg, len); return mrb_str_byte_subseq(mrb, str, beg, len); } #else @@ -1297,7 +1292,8 @@ mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_ if (beg < 0 || beg > charlen) { str_out_of_index(mrb, indx); } /* fall through */ case STR_CHAR_RANGE_CORRECTED: - str_range_to_bytes(str, &beg, &len); + beg = chars2bytes(str, 0, beg); + len = chars2bytes(str, beg, len); /* fall through */ case STR_BYTE_RANGE_CORRECTED: if (mrb_int_add_overflow(beg, len, &len)) { From 1d243bc58bb44976f0fd476f9a08d83ced84dee5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 10:52:57 +0900 Subject: [PATCH 040/117] string.c (bytes2chars): takes a string object instead of `char*` --- src/string.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/string.c b/src/string.c index c3fb46f3b..263ab8dfb 100644 --- a/src/string.c +++ b/src/string.c @@ -345,9 +345,10 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) /* map byte offset to character index */ static mrb_int -bytes2chars(char *p, mrb_int len, mrb_int bi) +bytes2chars(mrb_value s, mrb_int bi) { - const char *e = p + (size_t)len; + const char *p = RSTRING_PTR(s); + const char *e = RSTRING_END(s); const char *pivot = p + bi; mrb_int i; @@ -440,8 +441,8 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value(); #else #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) -#define chars2bytes(p, off, ci) (ci) -#define bytes2chars(p, end, bi) (bi) +#define chars2bytes(s, off, ci) (ci) +#define bytes2chars(s, bi) (bi) #define char_adjust(beg, end, ptr) (ptr) #define char_backtrack(ptr, end) ((end) - 1) #define BYTES_ALIGN_CHECK(pos) @@ -2082,8 +2083,8 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) } pos = str_rindex(mrb, str, sub, pos); if (pos >= 0) { - pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); - BYTES_ALIGN_CHECK(pos); + pos = bytes2chars(str, pos); + if (pos < 0) return mrb_nil_value(); return mrb_int_value(mrb, pos); } return mrb_nil_value(); From e39e4ea26dfb98d71a0f00bbdbf99d3eca825aa1 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 11:09:47 +0900 Subject: [PATCH 041/117] string.c (chars2bytes): small refactoring --- src/string.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/string.c b/src/string.c index 263ab8dfb..c19f6003e 100644 --- a/src/string.c +++ b/src/string.c @@ -330,16 +330,15 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) return idx; } else { - mrb_int b = 0; - const char *p = RSTRING_PTR(s) + off; + const char *p0 = RSTRING_PTR(s) + off; + const char *p = p0; const char *e = RSTRING_END(s); - - for (mrb_int i=0; p 0 || p > e) len++; + return len; } } From df0a5e838d2ce451a671d86da8f17fd4797f8fd2 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 12:41:28 +0900 Subject: [PATCH 042/117] string.c (chars2bytes): use early return --- src/string.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/string.c b/src/string.c index c19f6003e..934b37ff3 100644 --- a/src/string.c +++ b/src/string.c @@ -329,17 +329,19 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) if (RSTR_ASCII_P(mrb_str_ptr(s))) { return idx; } - else { - const char *p0 = RSTRING_PTR(s) + off; - const char *p = p0; - const char *e = RSTRING_END(s); - while (p < e && idx--) { - p += mrb_utf8len(p, e); - } - mrb_int len = (mrb_int)(p-p0); - if (idx > 0 || p > e) len++; - return len; + + const char *p0 = RSTRING_PTR(s) + off; + const char *p = p0; + const char *e = RSTRING_END(s); + + while (p < e && idx--) { + if ((*p & 0x80) == 0) p++; + else p += mrb_utf8len(p, e); } + + mrb_int len = (mrb_int)(p-p0); + if (idx > 0 || p > e) len++; + return len; } /* map byte offset to character index */ From 4c859e754de641b0a71f4ec231ca46581e62bfc3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 14:40:39 +0900 Subject: [PATCH 043/117] string.c (bytes2chars): skip scanning if the string is ASCII only --- src/string.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/string.c b/src/string.c index 934b37ff3..411de76e6 100644 --- a/src/string.c +++ b/src/string.c @@ -348,6 +348,10 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) static mrb_int bytes2chars(mrb_value s, mrb_int bi) { + if (RSTR_ASCII_P(mrb_str_ptr(s))) { + return bi; + } + const char *p = RSTRING_PTR(s); const char *e = RSTRING_END(s); const char *pivot = p + bi; From 31f2d936573e90059cf413f07705aa1d29b44fdd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 15:36:07 +0900 Subject: [PATCH 044/117] string.c (bytes2chars): skip calling mrb_utf8len() if possible If (ch < 0x80) the length of the character (in bytes) should be 1, so we don't have to call mrb_utf8len(). --- src/string.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 411de76e6..c6f419247 100644 --- a/src/string.c +++ b/src/string.c @@ -358,7 +358,8 @@ bytes2chars(mrb_value s, mrb_int bi) mrb_int i; for (i = 0; p < pivot; i++) { - p += mrb_utf8len(p, e); + if ((*p & 0x80) == 0) p++; + else p += mrb_utf8len(p, e); } if (p != pivot) return -1; return i; From c2f148e15d96e0d65879cb5c07f98c8b8eebbdef Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 16:21:39 +0900 Subject: [PATCH 045/117] string.c (mrb_memsearch_qs): reduce the scope of local variables --- src/string.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index c6f419247..a972caba6 100644 --- a/src/string.c +++ b/src/string.c @@ -477,15 +477,17 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr return -1; } else { - const unsigned char *x = xs, *xe = xs + m; const unsigned char *y = ys; ptrdiff_t qstable[256]; /* Preprocessing */ for (int i = 0; i < 256; i++) qstable[i] = m + 1; + + const unsigned char *x = xs, *xe = xs + m; for (; x < xe; x++) qstable[*x] = xe - x; + /* Searching */ for (; y + m <= ys + n; y += *(qstable + y[m])) { if (*xs == *y && memcmp(xs, y, m) == 0) From 787439455ce2188037ee6d8a0fb4cc28a9e1a887 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 10 Jan 2024 17:31:04 +0900 Subject: [PATCH 046/117] string.c: remove the macro BYTES_ALIGN_CHECK which is no longer used --- src/string.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/string.c b/src/string.c index a972caba6..14f6433c4 100644 --- a/src/string.c +++ b/src/string.c @@ -444,15 +444,13 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) return str_index_str_by_char_search(mrb, p, pend, s, slen, off); } -#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value(); #else #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) #define chars2bytes(s, off, ci) (ci) #define bytes2chars(s, bi) (bi) #define char_adjust(beg, end, ptr) (ptr) #define char_backtrack(ptr, end) ((end) - 1) -#define BYTES_ALIGN_CHECK(pos) -#define str_index_str_by_char(mrb, str, sub, pos) str_index_str(mrb, str, sub, pos) +#define str_index_str_by_char(mrb, str, sub, pos) str_index_str((mrb), (str), (sub), (pos)) #endif #ifndef MRB_QS_SHORT_STRING_LENGTH @@ -489,7 +487,7 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr qstable[*x] = xe - x; /* Searching */ - for (; y + m <= ys + n; y += *(qstable + y[m])) { + for (; y + m <= ys + n; y += qstable[y[m]]) { if (*xs == *y && memcmp(xs, y, m) == 0) return (mrb_int)(y - ys); } From 514c926e970feb21c2dfac2c6a4c5bfe573f72a5 Mon Sep 17 00:00:00 2001 From: dearblue Date: Wed, 3 Jan 2024 21:07:24 +0900 Subject: [PATCH 047/117] Update the `mruby3.3.md` file - Remove items changed by mruby 3.2. - The commit hash or pull request number will be written along with the changes. - Add some items. --- NEWS | 149 +++++++++++++++++++++++++++++++++++++++--------- doc/mruby3.3.md | 149 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 242 insertions(+), 56 deletions(-) diff --git a/NEWS b/NEWS index a3893089c..4c5900b1e 100644 --- a/NEWS +++ b/NEWS @@ -3,91 +3,184 @@ NEWS # User visible changes in `mruby3.3` from `mruby3.2` +"**_NOTE_**:" are changes to be aware of. + # The language -- aliases work properly with `super` -- `callee` method work differently with aliases in mruby -- define `Kernel#respond_to_missing?` method +- aliases work properly with `super` ([2ad3f0e](https://github.com/mruby/mruby/commit/2ad3f0e)) +- `callee` method work differently with aliases in mruby ([f2dc76e](https://github.com/mruby/mruby/commit/f2dc76e)) +- define `Kernel#respond_to_missing?` method ([347586e](https://github.com/mruby/mruby/commit/347586e)) - `_inspect` method (`inspect` with recursive check) is removed -- `__printstr` method is removed; use `print` instead + ([e2bbf75](https://github.com/mruby/mruby/commit/e2bbf75), [5cb0c74](https://github.com/mruby/mruby/commit/5cb0c74), [113565a](https://github.com/mruby/mruby/commit/113565a), + [0713f2a](https://github.com/mruby/mruby/commit/0713f2a), [6ae6b63](https://github.com/mruby/mruby/commit/6ae6b63), [fc9fffc](https://github.com/mruby/mruby/commit/fc9fffc)) +- `__printstr__` method is removed; use `print` instead + ([acecee0](https://github.com/mruby/mruby/commit/acecee0), [192e6e3](https://github.com/mruby/mruby/commit/192e6e3)) +- New method `String#bytesplice` ([5274647](https://github.com/mruby/mruby/commit/5274647), [a2e2e83](https://github.com/mruby/mruby/commit/a2e2e83)) +- Allow `return` in blocks to cross C boundaries ([#6125](https://github.com/mruby/mruby/pull/6125)) # Configuration -- mruby can be built using Docker now. Try `docker-compose build` for example. -- New Platform: Nintendo Wii -- Improved Platforms: Android, Dreamcast +- mruby can be built using Docker now. Try `docker-compose build` for example. ([#5961](https://github.com/mruby/mruby/pull/5961)) +- New Platform: DJGPP (MS-DOS) ([#6022](https://github.com/mruby/mruby/pull/6022)) +- New Platform: Nintendo Wii ([#6086](https://github.com/mruby/mruby/pull/6086)) +- Improved Platform: Android ([#6013](https://github.com/mruby/mruby/pull/6013)) +- Improved Platform: Dreamcast ([#6130](https://github.com/mruby/mruby/pull/6130)) +- Allow tests to be disabled for specific gems; warn about disabled tests ([#6012](https://github.com/mruby/mruby/pull/6012)) +- Replace `MRB_NO_DIRECT_THREADING` with `MRB_USE_VM_SWITCH_DISPATCH` ([#5902](https://github.com/mruby/mruby/pull/5902)) # mruby memory API -- `mrb_default_allocf` can be overridden by the application -- `mrb_open_allocf` will be deprecated +- `mrb_default_allocf` can be overridden by the application ([34c5d96](https://github.com/mruby/mruby/commit/34c5d96)) +- `mrb_open_allocf` will be deprecated ([cfee5c2](https://github.com/mruby/mruby/commit/cfee5c2)) -# mruby VM and bytecode +# Changes in C API -- [#5870](https://github.com/mruby/mruby/issues/5870) Use OP_LOADINEG instead of OP_LOADI +- add new error handling API functions ([8c8bbd9](https://github.com/mruby/mruby/commit/8c8bbd9)) +- Add `mrb_vm_ci_env_clear()` function with `MRB_API` ([#5945](https://github.com/mruby/mruby/pull/5945)) +- a new function `mrb_check_frozen_value()` ([ccdf75c](https://github.com/mruby/mruby/commit/ccdf75c)) +- avoid formatting in `mrb_bug()` ([82a48bd](https://github.com/mruby/mruby/commit/82a48bd))
+ **_NOTE_**: If you are using it, you must give a simple string or replace it with a call to `mrb_raise()` series. +- stop using `mrbc_` prefix for compiler context ([c5e3cbe](https://github.com/mruby/mruby/commit/c5e3cbe))
+ The same names are provided as before, but we recommend replacing them. +- Allow `Class#allocate` to be prohibited + ([#5979](https://github.com/mruby/mruby/pull/5979), [#6122](https://github.com/mruby/mruby/pull/6122), [#6123](https://github.com/mruby/mruby/pull/6123))
+ To disable `#allocate`, use `MRB_UNDEF_ALLOCATOR()`. + This is also automatically applied when the subclass is created, but to explicitly allow it, use `MRB_DEFINE_ALLOCATOR()`. # Changes in mrbgems -- mruby-bin-config: new options --cxx,--cxxflags,--as,--asflags,--objc,--objcflags -- mruby-binding-eval (merged with mruby-eval) #5989 -- mruby-binding: renamed from mruby-binding-core -- mruby-enumerator: remove internal attribute methods obj, args, kwd, meth, fib. -- mruby-fiber: Add a new mrb_fiber_new() with MRB_API -- mruby-fiber: Allows calling `Fiber#resume` from C -- mruby-fiber: `Fiber#to_s` format changed -- mruby-io: Add "x" mode option for IO.open -- mruby-method: `Method#to_s` format changed -- mruby-pack: support new directives j,J,b,B -- mruby-range-ext: new method `Range#overlap?` -- mruby-string-ext: Add `String#valid_encoding?` method +- **default.gembox**: Add mruby debugger mrdb (`mruby-bin-debugger`) ([#5966](https://github.com/mruby/mruby/pull/5966)) +- **mruby-bin-config**: new options `--cxx`, `--cxxflags`, `--as`, `--asflags`, `--objc`, `--objcflags` ([#6054](https://github.com/mruby/mruby/pull/6054)) +- **mruby-binding**: renamed from `mruby-binding-core` of mruby3.2 ([11af5db](https://github.com/mruby/mruby/commit/11af5db))
+ **_NOTE_**: If using `mruby-binding-core` of mruby 3.2, replace it with `mruby-binding`. +- **mruby-binding**: implemented `Binding#initialize_copy` method ([#5517](https://github.com/mruby/mruby/pull/5517)) +- **mruby-binding**: `Kernel#binding` responds only to calls from Ruby ([#5981](https://github.com/mruby/mruby/pull/5981)) +- **mruby-compar-ext**: Comparable#clamp to accept nil as arguments ([836bebc](https://github.com/mruby/mruby/commit/836bebc)) +- **mruby-compiler**: add print name for identifier tokens ([d7b2e3a](https://github.com/mruby/mruby/commit/d7b2e3a)) +- **mruby-data**: allow empty Data ([927a9df](https://github.com/mruby/mruby/commit/927a9df)) +- **mruby-enumerator**: remove internal attribute methods `obj`, `args`, `kwd`, `meth`, `fib`. ([735fa24](https://github.com/mruby/mruby/commit/735fa24)) +- **mruby-enumerator**: add Enumerator#size ([861f8bd](https://github.com/mruby/mruby/commit/861f8bd)) +- **mruby-eval**: merged `mruby-binding` of mruby3.2 ([501b22a](https://github.com/mruby/mruby/commit/501b22a), [#5989](https://github.com/mruby/mruby/pull/5989))
+ **_NOTE_**: If using `mruby-binding` of mruby 3.2, replace it with `mruby-eval`. +- **mruby-fiber**: Add a new `mrb_fiber_new()` with `MRB_API` ([#6097](https://github.com/mruby/mruby/pull/6097)) +- **mruby-fiber**: Allows calling `Fiber#resume` from C ([#6106](https://github.com/mruby/mruby/pull/6106)) +- **mruby-fiber**: `Fiber#to_s` format changed ([#6105](https://github.com/mruby/mruby/pull/6105)) +- **mruby-io**: add File#atime and File#ctime ([321cfe9](https://github.com/mruby/mruby/commit/321cfe9)) +- **mruby-io**: Add "x" mode option for `IO.open` ([#6081](https://github.com/mruby/mruby/pull/6081)) +- **mruby-io**: File.new should not take blocks ([53de964](https://github.com/mruby/mruby/commit/53de964)) +- **mruby-method**: `Method#to_s` format changed ([f5bc82f](https://github.com/mruby/mruby/commit/f5bc82f), [02f189c](https://github.com/mruby/mruby/commit/02f189c)) +- **mruby-numeric-ext**: `int.pow(n,m)` to take bigint as exponential ([d482eab](https://github.com/mruby/mruby/commit/d482eab)) +- **mruby-pack**: support new directives `j`, `J`, `b`, `B`, `#` + ([2a1e3a5](https://github.com/mruby/mruby/commit/2a1e3a5), [e7021f1](https://github.com/mruby/mruby/commit/e7021f1), [e17f325](https://github.com/mruby/mruby/commit/e17f325)) +- **mruby-range-ext**: new method `Range#overlap?` ([384d0e2](https://github.com/mruby/mruby/commit/384d0e2)) +- **mruby-string-ext**: Add `String#valid_encoding?` method ([eabe2d9](https://github.com/mruby/mruby/commit/eabe2d9)) +- **mruby-struct**: allow empty Struct when a name is not given ([c212ede](https://github.com/mruby/mruby/commit/c212ede)) +- **mruby-time**: should allow year before 1900 ([e5de08b](https://github.com/mruby/mruby/commit/e5de08b)) +- **mruby-time**: support bigint to time_t if necessary ([7096d27](https://github.com/mruby/mruby/commit/7096d27)) +- **mruby-time**: need to handle negative time_t ([b064d7e](https://github.com/mruby/mruby/commit/b064d7e)) + +# Changes in build system + +- Extended `rake install` task ([#5928](https://github.com/mruby/mruby/pull/5928))
+ **_NOTE_**: Due to this impact, executable files in the `mruby/bin/` directory by default are now symbolic links (batch files on Windows). + If previously relied on those executables, should be replaced with direct references to the entity created under the build directory (e.g. `mruby/build/host/bin/`). +- Encode and decode escape characters for presym ([#6011](https://github.com/mruby/mruby/pull/6011)) +- Rakefile: remove default build target directories in `deep_clean` ([#6032](https://github.com/mruby/mruby/pull/6032), [1e38569](https://github.com/mruby/mruby/commit/1e38569)) + +# Other breaking changes + +- `mrb_f_raise()` is now an internal function + ([#5923](https://github.com/mruby/mruby/pull/5923), [#6070](https://github.com/mruby/mruby/pull/6070)) +- `mrb_make_exception()` is now an internal function with different parameters + ([431f83e](https://github.com/mruby/mruby/commit/431f83e), [78137f3](https://github.com/mruby/mruby/commit/78137f3)) +- The `File#path` method no longer uses the `#to_path` method for implicit conversion + ([d86c4a7](https://github.com/mruby/mruby/commit/d86c4a7)) +- stop mrb isolation for each test file ([a20fbe5](https://github.com/mruby/mruby/commit/a20fbe5)) +- RBreak remembers the CI location ([#6103](https://github.com/mruby/mruby/pull/6103)) # Bugs Fixed -- [#5712](https://github.com/mruby/mruby/issues/5712) No "make install" -- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#** is missing -- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code -- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error +- [#5932](https://github.com/mruby/mruby/issues/5932) How to create a block using the C API? mrb_yield keeps crashing! - [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed - [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable +- [#5946](https://github.com/mruby/mruby/pull/5946) Don't switch constant search path from modules to Object - [#5949](https://github.com/mruby/mruby/issues/5949) Caller appears to report wrong line when block passed and brackets omitted +- [0906cd7](https://github.com/mruby/mruby/commit/0906cd7) numeric.c: fix rounding function issues with big numbers - [#5974](https://github.com/mruby/mruby/issues/5974) Invalid escape sequences in gem_init.c on windows - [#5975](https://github.com/mruby/mruby/issues/5975) Equals comparison fails on extreme ends of 64-bit integers - [#5985](https://github.com/mruby/mruby/issues/5985) Sign extension with OP_LOADI32 in get_int_operand() - [#5986](https://github.com/mruby/mruby/issues/5986) Fix bugs in String#bytesplice - [#5987](https://github.com/mruby/mruby/issues/5987) ~(-1 << 64) is incorrect - [#5991](https://github.com/mruby/mruby/issues/5991) 'gets' method not working in mruby-3.2.0 +- [#5994](https://github.com/mruby/mruby/pull/5994) fix typo in mrbgems/mruby-io/src/io.c - [#5995](https://github.com/mruby/mruby/issues/5995) One seemingly unnecessary parameter is passed in the block parameters +- [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory +- [b47c8b7](https://github.com/mruby/mruby/commit/b47c8b7) gc.c (clear_all_old): fix a generational GC bug - [#6029](https://github.com/mruby/mruby/issues/6029) mruby build fails under mrbgems directory +- [a264965](https://github.com/mruby/mruby/commit/a264965) mruby-os-memsize/memsize.c: fix irep size calculation +- [3310e10](https://github.com/mruby/mruby/commit/3310e10) mruby-test/mrbgem.rake: fix mrb_state handling bug - [#6041](https://github.com/mruby/mruby/issues/6041) GC Performance may have degraded +- [#6044](https://github.com/mruby/mruby/issues/6044) Generated presym/table.h contains invalid characters - [#6051](https://github.com/mruby/mruby/issues/6051) Null pointer dereference in mrb_addrinfo_unix_path - [#6052](https://github.com/mruby/mruby/issues/6052) Null pointer dereference while handling the Proc class +- [#6055](https://github.com/mruby/mruby/pull/6055) Fix libmruby name for VisualC++ +- [#6060](https://github.com/mruby/mruby/issues/6060) SEGFAULT Issue Related to Fiber Usage in ngx_mruby Development +- [#6061](https://github.com/mruby/mruby/issues/6061) Performance issue in String#codepoints +- [#6064](https://github.com/mruby/mruby/issues/6064) MRUBY_PACKAGE_DIR does not always have a value. - [#6065](https://github.com/mruby/mruby/issues/6065) Null pointer dereference while handling the Proc class - [#6066](https://github.com/mruby/mruby/issues/6066) Null pointer dereference involving Struct.new() - [#6067](https://github.com/mruby/mruby/issues/6067) Null pointer dereference in mrb_string_value_cstr - [#6068](https://github.com/mruby/mruby/issues/6068) Stack overflow in mrb_vm_exec +- [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC +- [#6084](https://github.com/mruby/mruby/issues/6084) Incorrect symbolic sinks in binary built on Linux - [#6087](https://github.com/mruby/mruby/issues/6087) 'Remote branch HEAD not found in upstream origin' error on build - [#6089](https://github.com/mruby/mruby/issues/6089) binding.eval() handles def expressions differently from CRuby - [#6098](https://github.com/mruby/mruby/issues/6098) Fails to call superclass of wrapped method +- [#6099](https://github.com/mruby/mruby/issues/6099) `ensure` section is not executed if the function exits via a return in a proc - [#6108](https://github.com/mruby/mruby/issues/6108) VM crashes with break +- [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf +- [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails +- [#6126](https://github.com/mruby/mruby/pull/6126) Fixed return value of `OP_RETURN_BLK` called directly under C function - [#6134](https://github.com/mruby/mruby/issues/6134) String#unpack1 returns an array instead of a single string +- [#6136](https://github.com/mruby/mruby/pull/6136) Fixed when combined `mrb_fiber_resume()` and `Fiber#transfer` # Pull Requests (User Visible Ones) -- [#5870](https://github.com/mruby/mruby/pull/5870) Use OP_LOADINEG instead of OP_LOADI +- [#5517](https://github.com/mruby/mruby/pull/5517) Fixed local variables not separated between copied binding objects +- [#5902](https://github.com/mruby/mruby/pull/5902) Replace `MRB_NO_DIRECT_THREADING` with `MRB_USE_VM_SWITCH_DISPATCH` +- [#5923](https://github.com/mruby/mruby/pull/5923) Demotion `mrb_f_raise()` from `MRB_API` +- [#5928](https://github.com/mruby/mruby/pull/5928) Improved `rake install` +- [#5945](https://github.com/mruby/mruby/pull/5945) Avoid exposure for `REnv` objects +- [#5946](https://github.com/mruby/mruby/pull/5946) Don't switch constant search path from modules to Object - [#5966](https://github.com/mruby/mruby/pull/5966) Update default.gembox add mruby debugger mrdb - [#5979](https://github.com/mruby/mruby/pull/5979) Allow Class#allocate to be prohibited +- [#5981](https://github.com/mruby/mruby/pull/5981) `Kernel#binding` responds only to calls from Ruby - [#5989](https://github.com/mruby/mruby/pull/5989) Integrate mruby-binding-eval into mruby-eval - [#5961](https://github.com/mruby/mruby/pull/5961) Add Docker to build and run all mruby tests. Run pre-commit and generate YARD docs with Docker +- [#5994](https://github.com/mruby/mruby/pull/5994) fix typo in mrbgems/mruby-io/src/io.c - [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory - [#6009](https://github.com/mruby/mruby/pull/6009) Avoid adding /bintest which does not exist +- [#6011](https://github.com/mruby/mruby/pull/6011) Encode and decode escape characters for presym - [#6012](https://github.com/mruby/mruby/pull/6012) Allow tests to be disabled for specific gems; warn about disabled tests - [#6013](https://github.com/mruby/mruby/pull/6013) Fix Android toolchain +- [#6022](https://github.com/mruby/mruby/pull/6022) Build configuration for MS-DOS and DJGPP - [#6032](https://github.com/mruby/mruby/pull/6032) Rake: update task clean to remove bin and build folders - [#6045](https://github.com/mruby/mruby/pull/6045) Fixes escape sequence bug and enhancements in Presym scanning +- [#6054](https://github.com/mruby/mruby/pull/6054) Extends `bin/mruby-config` +- [#6055](https://github.com/mruby/mruby/pull/6055) Fix libmruby name for VisualC++ +- [#6070](https://github.com/mruby/mruby/pull/6070) Demotion mrb_f_raise() in kernel.c from MRB_API too - [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC - [#6081](https://github.com/mruby/mruby/pull/6081) Add "x" mode option for IO.open - [#6086](https://github.com/mruby/mruby/pull/6086) Add build config for Nintendo Wii - [#6097](https://github.com/mruby/mruby/pull/6097) Add a new mrb_fiber_new() with MRB_API +- [#6103](https://github.com/mruby/mruby/pull/6103) RBreak remembers the CI location +- [#6105](https://github.com/mruby/mruby/pull/6105) Implement `Fiber#to_s` method - [#6106](https://github.com/mruby/mruby/pull/6106) Ease fiber limitations - [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf - [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails +- [#6122](https://github.com/mruby/mruby/pull/6122) Prohibit `Class#allocate` in a different way +- [#6123](https://github.com/mruby/mruby/pull/6123) Inherit `MRB_FL_UNDEF_ALLOCATE` in subclasses +- [#6125](https://github.com/mruby/mruby/pull/6125) Allow `OP_RETURN_BLK` to cross C boundaries +- [#6126](https://github.com/mruby/mruby/pull/6126) Fixed return value of `OP_RETURN_BLK` called directly under C function +- [#6130](https://github.com/mruby/mruby/pull/6130) `dreamcast_shelf build config`: complete overhaul +- [#6136](https://github.com/mruby/mruby/pull/6136) Fixed when combined `mrb_fiber_resume()` and `Fiber#transfer` diff --git a/doc/mruby3.3.md b/doc/mruby3.3.md index 5fc5ca4eb..560b6f02e 100644 --- a/doc/mruby3.3.md +++ b/doc/mruby3.3.md @@ -1,90 +1,183 @@ # User visible changes in `mruby3.3` from `mruby3.2` +"**_NOTE_**:" are changes to be aware of. + # The language -- aliases work properly with `super` -- `callee` method work differently with aliases in mruby -- define `Kernel#respond_to_missing?` method +- aliases work properly with `super` ([2ad3f0e](https://github.com/mruby/mruby/commit/2ad3f0e)) +- `callee` method work differently with aliases in mruby ([f2dc76e](https://github.com/mruby/mruby/commit/f2dc76e)) +- define `Kernel#respond_to_missing?` method ([347586e](https://github.com/mruby/mruby/commit/347586e)) - `_inspect` method (`inspect` with recursive check) is removed -- `__printstr` method is removed; use `print` instead + ([e2bbf75](https://github.com/mruby/mruby/commit/e2bbf75), [5cb0c74](https://github.com/mruby/mruby/commit/5cb0c74), [113565a](https://github.com/mruby/mruby/commit/113565a), + [0713f2a](https://github.com/mruby/mruby/commit/0713f2a), [6ae6b63](https://github.com/mruby/mruby/commit/6ae6b63), [fc9fffc](https://github.com/mruby/mruby/commit/fc9fffc)) +- `__printstr__` method is removed; use `print` instead + ([acecee0](https://github.com/mruby/mruby/commit/acecee0), [192e6e3](https://github.com/mruby/mruby/commit/192e6e3)) +- New method `String#bytesplice` ([5274647](https://github.com/mruby/mruby/commit/5274647), [a2e2e83](https://github.com/mruby/mruby/commit/a2e2e83)) +- Allow `return` in blocks to cross C boundaries ([#6125](https://github.com/mruby/mruby/pull/6125)) # Configuration -- mruby can be built using Docker now. Try `docker-compose build` for example. -- New Platform: Nintendo Wii -- Improved Platforms: Android, Dreamcast +- mruby can be built using Docker now. Try `docker-compose build` for example. ([#5961](https://github.com/mruby/mruby/pull/5961)) +- New Platform: DJGPP (MS-DOS) ([#6022](https://github.com/mruby/mruby/pull/6022)) +- New Platform: Nintendo Wii ([#6086](https://github.com/mruby/mruby/pull/6086)) +- Improved Platform: Android ([#6013](https://github.com/mruby/mruby/pull/6013)) +- Improved Platform: Dreamcast ([#6130](https://github.com/mruby/mruby/pull/6130)) +- Allow tests to be disabled for specific gems; warn about disabled tests ([#6012](https://github.com/mruby/mruby/pull/6012)) +- Replace `MRB_NO_DIRECT_THREADING` with `MRB_USE_VM_SWITCH_DISPATCH` ([#5902](https://github.com/mruby/mruby/pull/5902)) # mruby memory API -- `mrb_default_allocf` can be overridden by the application -- `mrb_open_allocf` will be deprecated +- `mrb_default_allocf` can be overridden by the application ([34c5d96](https://github.com/mruby/mruby/commit/34c5d96)) +- `mrb_open_allocf` will be deprecated ([cfee5c2](https://github.com/mruby/mruby/commit/cfee5c2)) -# mruby VM and bytecode +# Changes in C API -- [#5870](https://github.com/mruby/mruby/issues/5870) Use OP_LOADINEG instead of OP_LOADI +- add new error handling API functions ([8c8bbd9](https://github.com/mruby/mruby/commit/8c8bbd9)) +- Add `mrb_vm_ci_env_clear()` function with `MRB_API` ([#5945](https://github.com/mruby/mruby/pull/5945)) +- a new function `mrb_check_frozen_value()` ([ccdf75c](https://github.com/mruby/mruby/commit/ccdf75c)) +- avoid formatting in `mrb_bug()` ([82a48bd](https://github.com/mruby/mruby/commit/82a48bd))
+ **_NOTE_**: If you are using it, you must give a simple string or replace it with a call to `mrb_raise()` series. +- stop using `mrbc_` prefix for compiler context ([c5e3cbe](https://github.com/mruby/mruby/commit/c5e3cbe))
+ The same names are provided as before, but we recommend replacing them. +- Allow `Class#allocate` to be prohibited + ([#5979](https://github.com/mruby/mruby/pull/5979), [#6122](https://github.com/mruby/mruby/pull/6122), [#6123](https://github.com/mruby/mruby/pull/6123))
+ To disable `#allocate`, use `MRB_UNDEF_ALLOCATOR()`. + This is also automatically applied when the subclass is created, but to explicitly allow it, use `MRB_DEFINE_ALLOCATOR()`. # Changes in mrbgems -- mruby-bin-config: new options --cxx,--cxxflags,--as,--asflags,--objc,--objcflags -- mruby-binding-eval (merged with mruby-eval) #5989 -- mruby-binding: renamed from mruby-binding-core -- mruby-enumerator: remove internal attribute methods obj, args, kwd, meth, fib. -- mruby-fiber: Add a new mrb_fiber_new() with MRB_API -- mruby-fiber: Allows calling `Fiber#resume` from C -- mruby-fiber: `Fiber#to_s` format changed -- mruby-io: Add "x" mode option for IO.open -- mruby-method: `Method#to_s` format changed -- mruby-pack: support new directives j,J,b,B -- mruby-range-ext: new method `Range#overlap?` -- mruby-string-ext: Add `String#valid_encoding?` method +- **default.gembox**: Add mruby debugger mrdb (`mruby-bin-debugger`) ([#5966](https://github.com/mruby/mruby/pull/5966)) +- **mruby-bin-config**: new options `--cxx`, `--cxxflags`, `--as`, `--asflags`, `--objc`, `--objcflags` ([#6054](https://github.com/mruby/mruby/pull/6054)) +- **mruby-binding**: renamed from `mruby-binding-core` of mruby3.2 ([11af5db](https://github.com/mruby/mruby/commit/11af5db))
+ **_NOTE_**: If using `mruby-binding-core` of mruby 3.2, replace it with `mruby-binding`. +- **mruby-binding**: implemented `Binding#initialize_copy` method ([#5517](https://github.com/mruby/mruby/pull/5517)) +- **mruby-binding**: `Kernel#binding` responds only to calls from Ruby ([#5981](https://github.com/mruby/mruby/pull/5981)) +- **mruby-compar-ext**: Comparable#clamp to accept nil as arguments ([836bebc](https://github.com/mruby/mruby/commit/836bebc)) +- **mruby-compiler**: add print name for identifier tokens ([d7b2e3a](https://github.com/mruby/mruby/commit/d7b2e3a)) +- **mruby-data**: allow empty Data ([927a9df](https://github.com/mruby/mruby/commit/927a9df)) +- **mruby-enumerator**: remove internal attribute methods `obj`, `args`, `kwd`, `meth`, `fib`. ([735fa24](https://github.com/mruby/mruby/commit/735fa24)) +- **mruby-enumerator**: add Enumerator#size ([861f8bd](https://github.com/mruby/mruby/commit/861f8bd)) +- **mruby-eval**: merged `mruby-binding` of mruby3.2 ([501b22a](https://github.com/mruby/mruby/commit/501b22a), [#5989](https://github.com/mruby/mruby/pull/5989))
+ **_NOTE_**: If using `mruby-binding` of mruby 3.2, replace it with `mruby-eval`. +- **mruby-fiber**: Add a new `mrb_fiber_new()` with `MRB_API` ([#6097](https://github.com/mruby/mruby/pull/6097)) +- **mruby-fiber**: Allows calling `Fiber#resume` from C ([#6106](https://github.com/mruby/mruby/pull/6106)) +- **mruby-fiber**: `Fiber#to_s` format changed ([#6105](https://github.com/mruby/mruby/pull/6105)) +- **mruby-io**: add File#atime and File#ctime ([321cfe9](https://github.com/mruby/mruby/commit/321cfe9)) +- **mruby-io**: Add "x" mode option for `IO.open` ([#6081](https://github.com/mruby/mruby/pull/6081)) +- **mruby-io**: File.new should not take blocks ([53de964](https://github.com/mruby/mruby/commit/53de964)) +- **mruby-method**: `Method#to_s` format changed ([f5bc82f](https://github.com/mruby/mruby/commit/f5bc82f), [02f189c](https://github.com/mruby/mruby/commit/02f189c)) +- **mruby-numeric-ext**: `int.pow(n,m)` to take bigint as exponential ([d482eab](https://github.com/mruby/mruby/commit/d482eab)) +- **mruby-pack**: support new directives `j`, `J`, `b`, `B`, `#` + ([2a1e3a5](https://github.com/mruby/mruby/commit/2a1e3a5), [e7021f1](https://github.com/mruby/mruby/commit/e7021f1), [e17f325](https://github.com/mruby/mruby/commit/e17f325)) +- **mruby-range-ext**: new method `Range#overlap?` ([384d0e2](https://github.com/mruby/mruby/commit/384d0e2)) +- **mruby-string-ext**: Add `String#valid_encoding?` method ([eabe2d9](https://github.com/mruby/mruby/commit/eabe2d9)) +- **mruby-struct**: allow empty Struct when a name is not given ([c212ede](https://github.com/mruby/mruby/commit/c212ede)) +- **mruby-time**: should allow year before 1900 ([e5de08b](https://github.com/mruby/mruby/commit/e5de08b)) +- **mruby-time**: support bigint to time_t if necessary ([7096d27](https://github.com/mruby/mruby/commit/7096d27)) +- **mruby-time**: need to handle negative time_t ([b064d7e](https://github.com/mruby/mruby/commit/b064d7e)) + +# Changes in build system + +- Extended `rake install` task ([#5928](https://github.com/mruby/mruby/pull/5928))
+ **_NOTE_**: Due to this impact, executable files in the `mruby/bin/` directory by default are now symbolic links (batch files on Windows). + If previously relied on those executables, should be replaced with direct references to the entity created under the build directory (e.g. `mruby/build/host/bin/`). +- Encode and decode escape characters for presym ([#6011](https://github.com/mruby/mruby/pull/6011)) +- Rakefile: remove default build target directories in `deep_clean` ([#6032](https://github.com/mruby/mruby/pull/6032), [1e38569](https://github.com/mruby/mruby/commit/1e38569)) + +# Other breaking changes + +- `mrb_f_raise()` is now an internal function + ([#5923](https://github.com/mruby/mruby/pull/5923), [#6070](https://github.com/mruby/mruby/pull/6070)) +- `mrb_make_exception()` is now an internal function with different parameters + ([431f83e](https://github.com/mruby/mruby/commit/431f83e), [78137f3](https://github.com/mruby/mruby/commit/78137f3)) +- The `File#path` method no longer uses the `#to_path` method for implicit conversion + ([d86c4a7](https://github.com/mruby/mruby/commit/d86c4a7)) +- stop mrb isolation for each test file ([a20fbe5](https://github.com/mruby/mruby/commit/a20fbe5)) +- RBreak remembers the CI location ([#6103](https://github.com/mruby/mruby/pull/6103)) # Bugs Fixed -- [#5712](https://github.com/mruby/mruby/issues/5712) No "make install" -- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#\*\* is missing -- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code -- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error +- [#5932](https://github.com/mruby/mruby/issues/5932) How to create a block using the C API? mrb_yield keeps crashing! - [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed - [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable +- [#5946](https://github.com/mruby/mruby/pull/5946) Don't switch constant search path from modules to Object - [#5949](https://github.com/mruby/mruby/issues/5949) Caller appears to report wrong line when block passed and brackets omitted +- [0906cd7](https://github.com/mruby/mruby/commit/0906cd7) numeric.c: fix rounding function issues with big numbers - [#5974](https://github.com/mruby/mruby/issues/5974) Invalid escape sequences in gem_init.c on windows - [#5975](https://github.com/mruby/mruby/issues/5975) Equals comparison fails on extreme ends of 64-bit integers - [#5985](https://github.com/mruby/mruby/issues/5985) Sign extension with OP_LOADI32 in get_int_operand() - [#5986](https://github.com/mruby/mruby/issues/5986) Fix bugs in String#bytesplice - [#5987](https://github.com/mruby/mruby/issues/5987) ~(-1 << 64) is incorrect - [#5991](https://github.com/mruby/mruby/issues/5991) 'gets' method not working in mruby-3.2.0 +- [#5994](https://github.com/mruby/mruby/pull/5994) fix typo in mrbgems/mruby-io/src/io.c - [#5995](https://github.com/mruby/mruby/issues/5995) One seemingly unnecessary parameter is passed in the block parameters +- [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory +- [b47c8b7](https://github.com/mruby/mruby/commit/b47c8b7) gc.c (clear_all_old): fix a generational GC bug - [#6029](https://github.com/mruby/mruby/issues/6029) mruby build fails under mrbgems directory +- [a264965](https://github.com/mruby/mruby/commit/a264965) mruby-os-memsize/memsize.c: fix irep size calculation +- [3310e10](https://github.com/mruby/mruby/commit/3310e10) mruby-test/mrbgem.rake: fix mrb_state handling bug - [#6041](https://github.com/mruby/mruby/issues/6041) GC Performance may have degraded +- [#6044](https://github.com/mruby/mruby/issues/6044) Generated presym/table.h contains invalid characters - [#6051](https://github.com/mruby/mruby/issues/6051) Null pointer dereference in mrb_addrinfo_unix_path - [#6052](https://github.com/mruby/mruby/issues/6052) Null pointer dereference while handling the Proc class +- [#6055](https://github.com/mruby/mruby/pull/6055) Fix libmruby name for VisualC++ +- [#6060](https://github.com/mruby/mruby/issues/6060) SEGFAULT Issue Related to Fiber Usage in ngx_mruby Development +- [#6061](https://github.com/mruby/mruby/issues/6061) Performance issue in String#codepoints +- [#6064](https://github.com/mruby/mruby/issues/6064) MRUBY_PACKAGE_DIR does not always have a value. - [#6065](https://github.com/mruby/mruby/issues/6065) Null pointer dereference while handling the Proc class - [#6066](https://github.com/mruby/mruby/issues/6066) Null pointer dereference involving Struct.new() - [#6067](https://github.com/mruby/mruby/issues/6067) Null pointer dereference in mrb_string_value_cstr - [#6068](https://github.com/mruby/mruby/issues/6068) Stack overflow in mrb_vm_exec +- [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC +- [#6084](https://github.com/mruby/mruby/issues/6084) Incorrect symbolic sinks in binary built on Linux - [#6087](https://github.com/mruby/mruby/issues/6087) 'Remote branch HEAD not found in upstream origin' error on build - [#6089](https://github.com/mruby/mruby/issues/6089) binding.eval() handles def expressions differently from CRuby - [#6098](https://github.com/mruby/mruby/issues/6098) Fails to call superclass of wrapped method +- [#6099](https://github.com/mruby/mruby/issues/6099) `ensure` section is not executed if the function exits via a return in a proc - [#6108](https://github.com/mruby/mruby/issues/6108) VM crashes with break +- [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf +- [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails +- [#6126](https://github.com/mruby/mruby/pull/6126) Fixed return value of `OP_RETURN_BLK` called directly under C function - [#6134](https://github.com/mruby/mruby/issues/6134) String#unpack1 returns an array instead of a single string +- [#6136](https://github.com/mruby/mruby/pull/6136) Fixed when combined `mrb_fiber_resume()` and `Fiber#transfer` # Pull Requests (User Visible Ones) -- [#5870](https://github.com/mruby/mruby/pull/5870) Use OP_LOADINEG instead of OP_LOADI +- [#5517](https://github.com/mruby/mruby/pull/5517) Fixed local variables not separated between copied binding objects +- [#5902](https://github.com/mruby/mruby/pull/5902) Replace `MRB_NO_DIRECT_THREADING` with `MRB_USE_VM_SWITCH_DISPATCH` +- [#5923](https://github.com/mruby/mruby/pull/5923) Demotion `mrb_f_raise()` from `MRB_API` +- [#5928](https://github.com/mruby/mruby/pull/5928) Improved `rake install` +- [#5945](https://github.com/mruby/mruby/pull/5945) Avoid exposure for `REnv` objects +- [#5946](https://github.com/mruby/mruby/pull/5946) Don't switch constant search path from modules to Object - [#5966](https://github.com/mruby/mruby/pull/5966) Update default.gembox add mruby debugger mrdb - [#5979](https://github.com/mruby/mruby/pull/5979) Allow Class#allocate to be prohibited +- [#5981](https://github.com/mruby/mruby/pull/5981) `Kernel#binding` responds only to calls from Ruby - [#5989](https://github.com/mruby/mruby/pull/5989) Integrate mruby-binding-eval into mruby-eval - [#5961](https://github.com/mruby/mruby/pull/5961) Add Docker to build and run all mruby tests. Run pre-commit and generate YARD docs with Docker +- [#5994](https://github.com/mruby/mruby/pull/5994) fix typo in mrbgems/mruby-io/src/io.c - [#6008](https://github.com/mruby/mruby/pull/6008) Make "bintest" independent of directory - [#6009](https://github.com/mruby/mruby/pull/6009) Avoid adding /bintest which does not exist +- [#6011](https://github.com/mruby/mruby/pull/6011) Encode and decode escape characters for presym - [#6012](https://github.com/mruby/mruby/pull/6012) Allow tests to be disabled for specific gems; warn about disabled tests - [#6013](https://github.com/mruby/mruby/pull/6013) Fix Android toolchain +- [#6022](https://github.com/mruby/mruby/pull/6022) Build configuration for MS-DOS and DJGPP - [#6032](https://github.com/mruby/mruby/pull/6032) Rake: update task clean to remove bin and build folders - [#6045](https://github.com/mruby/mruby/pull/6045) Fixes escape sequence bug and enhancements in Presym scanning +- [#6054](https://github.com/mruby/mruby/pull/6054) Extends `bin/mruby-config` +- [#6055](https://github.com/mruby/mruby/pull/6055) Fix libmruby name for VisualC++ +- [#6070](https://github.com/mruby/mruby/pull/6070) Demotion mrb_f_raise() in kernel.c from MRB_API too - [#6076](https://github.com/mruby/mruby/pull/6076) Fixed unwinding block that could point to invalid PC - [#6081](https://github.com/mruby/mruby/pull/6081) Add "x" mode option for IO.open - [#6086](https://github.com/mruby/mruby/pull/6086) Add build config for Nintendo Wii - [#6097](https://github.com/mruby/mruby/pull/6097) Add a new mrb_fiber_new() with MRB_API +- [#6103](https://github.com/mruby/mruby/pull/6103) RBreak remembers the CI location +- [#6105](https://github.com/mruby/mruby/pull/6105) Implement `Fiber#to_s` method - [#6106](https://github.com/mruby/mruby/pull/6106) Ease fiber limitations - [#6118](https://github.com/mruby/mruby/pull/6118) Fixed IO#read with buf - [#6120](https://github.com/mruby/mruby/pull/6120) Set EBADF if check_file_descriptor() fails +- [#6122](https://github.com/mruby/mruby/pull/6122) Prohibit `Class#allocate` in a different way +- [#6123](https://github.com/mruby/mruby/pull/6123) Inherit `MRB_FL_UNDEF_ALLOCATE` in subclasses +- [#6125](https://github.com/mruby/mruby/pull/6125) Allow `OP_RETURN_BLK` to cross C boundaries +- [#6126](https://github.com/mruby/mruby/pull/6126) Fixed return value of `OP_RETURN_BLK` called directly under C function +- [#6130](https://github.com/mruby/mruby/pull/6130) `dreamcast_shelf build config`: complete overhaul +- [#6136](https://github.com/mruby/mruby/pull/6136) Fixed when combined `mrb_fiber_resume()` and `Fiber#transfer` From f8f3ff10fa0acb4579762dc2745ef66c123d204a Mon Sep 17 00:00:00 2001 From: John Bampton Date: Thu, 11 Jan 2024 03:17:23 +1000 Subject: [PATCH 048/117] pre-commit: add hook `detect-aws-credentials` https://github.com/pre-commit/pre-commit-hooks#detect-aws-credentials Another check or test we can have. "--allow-missing-credentials - Allow hook to pass when no credentials are detected." --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d344920fd..4f8b9c48e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,8 @@ repos: - id: check-shebang-scripts-are-executable - id: check-vcs-permalinks - id: check-yaml + - id: detect-aws-credentials + args: [--allow-missing-credentials] - id: detect-private-key - id: end-of-file-fixer - id: file-contents-sorter From e42f3b36f91c864138113ba7ead073b55d02293b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 11 Jan 2024 11:49:49 +0900 Subject: [PATCH 049/117] string.c (chars2bytes): simplify the condition to detect break --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 14f6433c4..085c2daa2 100644 --- a/src/string.c +++ b/src/string.c @@ -340,7 +340,7 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) } mrb_int len = (mrb_int)(p-p0); - if (idx > 0 || p > e) len++; + if (idx > 0) len++; return len; } From f646228dbe1a89ea7ea1e2d85a6c40446be1d491 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 11 Jan 2024 12:20:51 +0900 Subject: [PATCH 050/117] string.c (str_index_str_by_char): simplify using str_index_str() Instead of its own version of quick search, now we use str_index_str() and adjust character position. This change makes searching 4 times faster in some cases; ref #6143 --- src/string.c | 57 +++++++++------------------------------------------- 1 file changed, 9 insertions(+), 48 deletions(-) diff --git a/src/string.c b/src/string.c index 085c2daa2..63aa48371 100644 --- a/src/string.c +++ b/src/string.c @@ -387,61 +387,22 @@ char_backtrack(const char *ptr, const char *end) return end - 1; } -static mrb_int -str_index_str_by_char_search(mrb_state *mrb, const char *p, const char *pend, const char *s, const mrb_int slen, mrb_int off) -{ - /* Based on Quick Search algorithm (Boyer-Moore-Horspool algorithm) */ - - ptrdiff_t qstable[1 << CHAR_BIT]; - - /* Preprocessing */ - { - mrb_int i; - - for (i = 0; i < 1 << CHAR_BIT; i++) { - qstable[i] = slen; - } - for (i = 0; i < slen; i++) { - qstable[(unsigned char)s[i]] = slen - (i + 1); - } - } - - /* Searching */ - while (p < pend && pend - p >= slen) { - - if (memcmp(p, s, slen) == 0) { - return off; - } - - const char *pivot = p + qstable[(unsigned char)p[slen - 1]]; - if (pivot >= pend || pivot < p /* overflowed */) { return -1; } - - do { - p += mrb_utf8len(p, pend); - off++; - } while (p < pivot); - } - - return -1; -} - static mrb_int str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) { - const char *p = RSTRING_PTR(str); - const char *pend = p + RSTRING_LEN(str); - const char *s = RSTRING_PTR(sub); - const mrb_int slen = RSTRING_LEN(sub); - mrb_int off = pos; + const char *ptr = RSTRING_PTR(sub); + mrb_int len = RSTRING_LEN(sub); - for (; pos > 0; pos --) { - if (pend - p < 1) { return -1; } - p += mrb_utf8len(p, pend); + if (pos > 0) { + pos = chars2bytes(str, 0, pos); } - if (slen < 1) { return off; } + pos = mrb_str_index(mrb, str, ptr, len, pos); - return str_index_str_by_char_search(mrb, p, pend, s, slen, off); + if (pos > 0) { + pos = bytes2chars(str, pos); + } + return pos; } #else From fb8bc1954b805e57492266b0fa2f6c255901a52d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 11 Jan 2024 18:22:26 +0900 Subject: [PATCH 051/117] string.c: improve performance of chars2bytes/bytes2chars; ref #6143 --- src/string.c | 53 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/string.c b/src/string.c index 63aa48371..a26bad4a3 100644 --- a/src/string.c +++ b/src/string.c @@ -264,6 +264,18 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) } #ifdef MRB_UTF8_STRING + +#define NOASCII(c) ((c) & 0x80) + +static const char* +search_nonascii(const char* p, const char *e) +{ + for (; p < e; ++p) { + if (NOASCII(*p)) return p; + } + return e; +} + #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) extern const char mrb_utf8len_table[]; @@ -279,7 +291,6 @@ mrb_utf8len(const char* p, const char* e) if (len > e - p) return 1; switch (len) { case 0: - case 1: return 1; case 4: if (utf8_islead(p[3])) return 1; @@ -333,14 +344,29 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) const char *p0 = RSTRING_PTR(s) + off; const char *p = p0; const char *e = RSTRING_END(s); + mrb_int i = 0; - while (p < e && idx--) { - if ((*p & 0x80) == 0) p++; - else p += mrb_utf8len(p, e); + while (p 0) len++; + if (i Date: Sat, 13 Jan 2024 17:36:02 +0900 Subject: [PATCH 052/117] Enumerable#chunk implementation --- mrbgems/mruby-enum-ext/mrbgem.rake | 2 + mrbgems/mruby-enum-ext/mrblib/enum.rb | 68 +++++++++++++++++++++++++++ mrbgems/mruby-enum-ext/test/enum.rb | 49 +++++++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/mrbgems/mruby-enum-ext/mrbgem.rake b/mrbgems/mruby-enum-ext/mrbgem.rake index d5816b80f..9394bc514 100644 --- a/mrbgems/mruby-enum-ext/mrbgem.rake +++ b/mrbgems/mruby-enum-ext/mrbgem.rake @@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-enum-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'Enumerable module extension' + + spec.add_dependency 'mruby-enumerator', core: 'mruby-enumerator' end diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index 2c9e8d3a5..e3fa57aac 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -880,4 +880,72 @@ module Enumerable end result end + + ## + # call-seq: + # enum.chunk -> enumerator + # enum.chunk { |arr| block } -> enumerator + # + # Each element in the returned enumerator is a 2-element array consisting of: + # + # - A value returned by the block. + # - An array ("chunk") containing the element for which that value was returned, + # and all following elements for which the block returned the same value: + # + # So that: + # + # - Each block return value that is different from its predecessor + # begins a new chunk. + # - Each block return value that is the same as its predecessor + # continues the same chunk. + # + # Example: + # + # e = (0..10).chunk {|i| (i / 3).floor } # => # + # # The enumerator elements. + # e.next # => [0, [0, 1, 2]] + # e.next # => [1, [3, 4, 5]] + # e.next # => [2, [6, 7, 8]] + # e.next # => [3, [9, 10]] + # + # You can use the special symbol :_alone to force an element + # into its own separate chuck: + # + # a = [0, 0, 1, 1] + # e = a.chunk{|i| i.even? ? :_alone : true } + # e.to_a # => [[:_alone, [0]], [:_alone, [0]], [true, [1, 1]]] + # + # You can use the special symbol :_separator or +nil+ + # to force an element to be ignored (not included in any chunk): + # + # a = [0, 0, -1, 1, 1] + # e = a.chunk{|i| i < 0 ? :_separator : true } + # e.to_a # => [[true, [0, 0]], [true, [1, 1]]] + def chunk(&block) + return to_enum :chunk unless block + + enum = self + Enumerator.new do |y| + last_value, arr = nil, [] + enum.each do |element| + value = block.call(element) + case value + when :_alone + y.yield [last_value, arr] if arr.size > 0 + y.yield [value, [element]] + last_value, arr = nil, [] + when :_separator, nil + y.yield [last_value, arr] if arr.size > 0 + last_value, arr = nil, [] + when last_value + arr << element + else + raise 'symbols beginning with an underscore are reserved' if value.is_a?(Symbol) && value.to_s[0] == '_' + y.yield [last_value, arr] if arr.size > 0 + last_value, arr = value, [element] + end + end + y.yield [last_value, arr] if arr.size > 0 + end + end end diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb index 31181fe1a..759c0ead1 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -195,3 +195,52 @@ end assert("Enumerable#tally") do assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally) end + +assert("Enumerable#chunk") do + chunk = [1, 2, 3, 1, 2].chunk + assert_equal Enumerator, chunk.class + result = chunk.with_index { |elt, i| elt - i }.to_a + assert_equal [[1, [1, 2, 3]], [-2, [1, 2]]], result + + assert_equal Enumerator, [].chunk {}.class + + e = [1, 2, 3] + recorded = [] + e.chunk { |x| recorded << x }.to_a + assert_equal [1, 2, 3], recorded + + e = [1, 2, 3, 2, 3, 2, 1] + result = e.chunk { |x| x < 3 && 1 || 0 }.to_a + assert_equal [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]], result + + e = [1, 2, 3] + assert_equal [[1, 2], [3]], e.chunk { |x| x > 2 }.map(&:last) + + e = [1, 2, 3, 2, 1] + result = e.chunk { |x| x < 2 && :_alone }.to_a + assert_equal [[:_alone, [1]], [false, [2, 3, 2]], [:_alone, [1]]], result + + e = [[1, 2]] + inner_value = [] + e.chunk { |*x| inner_value << x }.to_a + assert_equal [[[1, 2]]], inner_value + + e = [1, 2, 3, 3, 2, 1] + result = e.chunk { |x| x == 2 ? :_separator : 1 }.to_a + assert_equal [[1, [1]], [1, [3, 3]], [1, [1]]], result + + e = [1, 2, 3, 2, 1] + result = e.chunk { |x| x == 2 ? nil : 1 }.to_a + assert_equal [[1, [1]], [1, [3]], [1, [1]]], result + + + e = [1, 2, 3, 2, 1] + assert_raise(RuntimeError) { e.chunk { |x| :_arbitrary }.to_a } + + e = [1, 2, 3] + assert_raise(ArgumentError) { e.chunk(1) {} } + + e = [1, 2, 3, 2, 1] + enum = e.chunk { |x| true } + assert_nil enum.size +end From c53d9a33fc37af716b3b65898de5346b3dd8132c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 12 Jan 2024 09:48:09 +0900 Subject: [PATCH 053/117] mruby-string-ext (mrb_valid_enc_p): simplify the code By using `mrb_utf8len` directly. If `len == 1` and `ch >= 0x80`, the character should be an invalid character. --- mrbgems/mruby-string-ext/src/string.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 79b4743ac..1209228c3 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -1339,19 +1339,9 @@ str_valid_enc_p(mrb_state *mrb, mrb_value str) const char *p = RSTR_PTR(s); const char *e = p + byte_len; while (p < e) { - mrb_int len = mrb_utf8len_table[(unsigned char)p[0] >> 3]; - if (len == 0 || len > e - p) - return mrb_false_value(); - switch (len) { - case 4: - if (utf8_islead(p[3])) return mrb_false_value(); - case 3: - if (utf8_islead(p[2])) return mrb_false_value(); - case 2: - if (utf8_islead(p[1])) return mrb_false_value(); - default: - break; - } + mrb_int len = mrb_utf8len(p, e); + + if (len == 1 && (*p & 0x80)) return mrb_false_value(); p += len; utf8_len++; } From 4f8fd23f7a358f55b9d52b43ba14f4ca64243afe Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 13 Jan 2024 23:00:13 +0900 Subject: [PATCH 054/117] mruby-string-ext (str_uminus): remove wrong document In mruby, deduplication of strings is not implemented (yet), so we have to remove the description from `String#-@` document. --- mrbgems/mruby-string-ext/src/string.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 1209228c3..ef4a23bb3 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -1304,10 +1304,6 @@ str_uplus(mrb_state *mrb, mrb_value str) * * Returns a frozen, possibly pre-existing copy of the string. * - * The returned \String will be deduplicated as long as it does not have - * any instance variables set on it and is not a String subclass. - * - * String#dedup is an alias for String#-@. */ static mrb_value str_uminus(mrb_state *mrb, mrb_value str) From 90fac467519fd8a6b303fe6ba6a003665d80d377 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 14 Jan 2024 23:00:43 +0900 Subject: [PATCH 055/117] mruby-bin-mruby: remove unnecessary condition --- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 10522011a..65be018fd 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -98,8 +98,8 @@ options_opt(struct options *opts) while (++opts->argv, --opts->argc) { opts->opt = *opts->argv; - /* empty || not start with `-` || `-` */ - if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL; + /* not start with `-` || `-` */ + if (opts->opt[0] != '-' || !opts->opt[1]) return NULL; if (opts->opt[1] == '-') { /* `--` */ From 9298dfb927a8853c0ce8a4f6bc77f09e4132cf35 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 15 Jan 2024 23:03:34 +0900 Subject: [PATCH 056/117] mruby-bin-mruby: reduce the scope of a local variable `c` --- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 65be018fd..a892254de 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -281,7 +281,6 @@ main(int argc, char **argv) int i; struct _args args; mrb_value ARGV; - mrb_ccontext *c; mrb_value v; if (mrb == NULL) { @@ -307,7 +306,7 @@ main(int argc, char **argv) mrb_define_global_const(mrb, "ARGV", ARGV); mrb_gv_set(mrb, mrb_intern_lit(mrb, "$DEBUG"), mrb_bool_value(args.debug)); - c = mrb_ccontext_new(mrb); + mrb_ccontext *c = mrb_ccontext_new(mrb); if (args.verbose) c->dump_result = TRUE; if (args.check_syntax) From 0e079fe946a23dcabdc8a19ebf011e9753e3cc2c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 15 Jan 2024 23:04:18 +0900 Subject: [PATCH 057/117] mruby-bin-mruby: reduce the scope of a loop variable `i` --- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index a892254de..36259609c 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -278,7 +278,6 @@ main(int argc, char **argv) { mrb_state *mrb = mrb_open(); int n = -1; - int i; struct _args args; mrb_value ARGV; mrb_value v; @@ -296,7 +295,7 @@ main(int argc, char **argv) else { int ai = mrb_gc_arena_save(mrb); ARGV = mrb_ary_new_capa(mrb, args.argc); - for (i = 0; i < args.argc; i++) { + for (int i = 0; i < args.argc; i++) { char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); if (utf8) { mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); @@ -323,7 +322,7 @@ main(int argc, char **argv) mrb_gv_set(mrb, mrb_intern_lit(mrb, "$0"), mrb_str_new_cstr(mrb, cmdline)); /* Load libraries */ - for (i = 0; i < args.libc; i++) { + for (int i = 0; i < args.libc; i++) { FILE *lfp = fopen(args.libv[i], "rb"); if (lfp == NULL) { fprintf(stderr, "%s: Cannot open library file: %s\n", *argv, args.libv[i]); From 6c2ed55077788dd10177c88b559d326d218e54ca Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 16 Jan 2024 12:28:32 +0900 Subject: [PATCH 058/117] mruby-bin-mruby: remove unused assignments --- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 36259609c..bf201deda 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -332,10 +332,10 @@ main(int argc, char **argv) } mrb_ccontext_filename(mrb, c, args.libv[i]); if (mrb_extension_p(args.libv[i])) { - v = mrb_load_irep_file_cxt(mrb, lfp, c); + mrb_load_irep_file_cxt(mrb, lfp, c); } else { - v = mrb_load_detect_file_cxt(mrb, lfp, c); + mrb_load_detect_file_cxt(mrb, lfp, c); } fclose(lfp); mrb_vm_ci_env_clear(mrb, mrb->c->cibase); From 5b76d2cbbe3d437583eb8a33b9119f5255fe8cf9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 16 Jan 2024 17:38:51 +0900 Subject: [PATCH 059/117] string.h: RSTR_ASCII_P(s) should always be true for non-UTF8 mode --- include/mruby/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mruby/string.h b/include/mruby/string.h index cd300f8bd..7e104c40a 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -85,7 +85,7 @@ struct RStringEmbed { # define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v) # define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src)) #else -# define RSTR_ASCII_P(s) (void)0 +# define RSTR_ASCII_P(s) (void)1 # define RSTR_SET_ASCII_FLAG(s) (void)0 # define RSTR_UNSET_ASCII_FLAG(s) (void)0 # define RSTR_WRITE_ASCII_FLAG(s, v) (void)0 From 57fd0edaa763de6208ea7d6a05205e3515b33f65 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 17 Jan 2024 23:15:46 +0900 Subject: [PATCH 060/117] mruby.h: rename ASCII flag to SINGLE_BYTE This flag means all the characters in the string can be represented by a single byte, i.e., the string does not contain any multi-byte character. Those characters are likely ASCII characters, but may be a part of broken UTF-8 sequence, so the term 'ASCII' is not sufficient. --- include/mruby/string.h | 23 ++++++++++---------- mrbgems/mruby-string-ext/src/string.c | 10 ++++----- src/string.c | 30 +++++++++++++-------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/mruby/string.h b/include/mruby/string.h index 7e104c40a..ac6740c5d 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -79,18 +79,19 @@ struct RStringEmbed { #define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE) #ifdef MRB_UTF8_STRING -# define RSTR_ASCII_P(s) ((s)->flags & MRB_STR_ASCII) -# define RSTR_SET_ASCII_FLAG(s) ((s)->flags |= MRB_STR_ASCII) -# define RSTR_UNSET_ASCII_FLAG(s) ((s)->flags &= ~MRB_STR_ASCII) -# define RSTR_WRITE_ASCII_FLAG(s, v) (RSTR_UNSET_ASCII_FLAG(s), (s)->flags |= v) -# define RSTR_COPY_ASCII_FLAG(dst, src) RSTR_WRITE_ASCII_FLAG(dst, RSTR_ASCII_P(src)) +# define RSTR_SINGLE_BYTE_P(s) ((s)->flags & MRB_STR_SINGLE_BYTE) +# define RSTR_SET_SINGLE_BYTE_FLAG(s) ((s)->flags |= MRB_STR_SINGLE_BYTE) +# define RSTR_UNSET_SINGLE_BYTE_FLAG(s) ((s)->flags &= ~MRB_STR_SINGLE_BYTE) +# define RSTR_WRITE_SINGLE_BYTE_FLAG(s, v) (RSTR_UNSET_SINGLE_BYTE_FLAG(s), (s)->flags |= v) +# define RSTR_COPY_SINGLE_BYTE_FLAG(dst, src) RSTR_WRITE_SINGLE_BYTE_FLAG(dst, RSTR_SINGLE_BYTE_P(src)) #else -# define RSTR_ASCII_P(s) (void)1 -# define RSTR_SET_ASCII_FLAG(s) (void)0 -# define RSTR_UNSET_ASCII_FLAG(s) (void)0 -# define RSTR_WRITE_ASCII_FLAG(s, v) (void)0 -# define RSTR_COPY_ASCII_FLAG(dst, src) (void)0 +# define RSTR_SINGLE_BYTE_P(s) (void)1 +# define RSTR_SET_SINGLE_BYTE_FLAG(s) (void)0 +# define RSTR_UNSET_SINGLE_BYTE_FLAG(s) (void)0 +# define RSTR_WRITE_SINGLE_BYTE_FLAG(s, v) (void)0 +# define RSTR_COPY_SINGLE_BYTE_FLAG(dst, src) (void)0 #endif +#define RSTR_SET_ASCII_FLAG(s) RSTR_SET_SINGLE_BYTE_FLAG(s) /** * Returns a pointer from a Ruby string @@ -108,7 +109,7 @@ struct RStringEmbed { #define MRB_STR_FSHARED 2 #define MRB_STR_NOFREE 4 #define MRB_STR_EMBED 8 /* type flags up to here */ -#define MRB_STR_ASCII 16 +#define MRB_STR_SINGLE_BYTE 16 #define MRB_STR_EMBED_LEN_SHIFT 6 #define MRB_STR_EMBED_LEN_BIT 5 #define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index ef4a23bb3..2f93e7ff4 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -53,7 +53,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) char utf8[4]; mrb_int len; mrb_value str; - uint32_t ascii_flag = 0; + uint32_t sb_flag = 0; if (cp < 0 || 0x10FFFF < cp) { mrb_raisef(mrb, E_RANGE_ERROR, "%v out of char range", num); @@ -61,7 +61,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) if (cp < 0x80) { utf8[0] = (char)cp; len = 1; - ascii_flag = MRB_STR_ASCII; + sb_flag = MRB_STR_SINGLE_BYTE; } else if (cp < 0x800) { utf8[0] = (char)(0xC0 | (cp >> 6)); @@ -82,7 +82,7 @@ int_chr_utf8(mrb_state *mrb, mrb_value num) len = 4; } str = mrb_str_new(mrb, utf8, len); - mrb_str_ptr(str)->flags |= ascii_flag; + mrb_str_ptr(str)->flags |= sb_flag; return str; } #endif @@ -1328,7 +1328,7 @@ str_valid_enc_p(mrb_state *mrb, mrb_value str) #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) struct RString *s = mrb_str_ptr(str); - if (RSTR_ASCII_P(s)) return mrb_true_value(); + if (RSTR_SINGLE_BYTE_P(s)) return mrb_true_value(); mrb_int byte_len = RSTR_LEN(s); mrb_int utf8_len = 0; @@ -1341,7 +1341,7 @@ str_valid_enc_p(mrb_state *mrb, mrb_value str) p += len; utf8_len++; } - if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s); + if (byte_len == utf8_len) RSTR_SET_SINGLE_BYTE_FLAG(s); #endif return mrb_true_value(); } diff --git a/src/string.c b/src/string.c index a26bad4a3..563af77ce 100644 --- a/src/string.c +++ b/src/string.c @@ -321,12 +321,12 @@ utf8_strlen(mrb_value str) struct RString *s = mrb_str_ptr(str); mrb_int byte_len = RSTR_LEN(s); - if (RSTR_ASCII_P(s)) { + if (RSTR_SINGLE_BYTE_P(s)) { return byte_len; } else { mrb_int utf8_len = mrb_utf8_strlen(RSTR_PTR(s), byte_len); - if (byte_len == utf8_len) RSTR_SET_ASCII_FLAG(s); + if (byte_len == utf8_len) RSTR_SET_SINGLE_BYTE_FLAG(s); return utf8_len; } } @@ -337,7 +337,7 @@ utf8_strlen(mrb_value str) static mrb_int chars2bytes(mrb_value s, mrb_int off, mrb_int idx) { - if (RSTR_ASCII_P(mrb_str_ptr(s))) { + if (RSTR_SINGLE_BYTE_P(mrb_str_ptr(s))) { return idx; } @@ -374,7 +374,7 @@ chars2bytes(mrb_value s, mrb_int off, mrb_int idx) static mrb_int bytes2chars(mrb_value s, mrb_int bi) { - if (RSTR_ASCII_P(mrb_str_ptr(s))) { + if (RSTR_SINGLE_BYTE_P(mrb_str_ptr(s))) { return bi; } @@ -552,7 +552,7 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) s->as.heap.ptr += (mrb_ssize)beg; s->as.heap.len = (mrb_ssize)len; } - RSTR_COPY_ASCII_FLAG(s, orig); + RSTR_COPY_SINGLE_BYTE_FLAG(s, orig); return mrb_obj_value(s); } @@ -635,7 +635,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) mrb_check_frozen(mrb, s1); if (s1 == s2) return mrb_obj_value(s1); - RSTR_COPY_ASCII_FLAG(s1, s2); + RSTR_COPY_SINGLE_BYTE_FLAG(s1, s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); } @@ -761,7 +761,7 @@ MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s) { mrb_str_modify_keep_ascii(mrb, s); - RSTR_UNSET_ASCII_FLAG(s); + RSTR_UNSET_SINGLE_BYTE_FLAG(s); } MRB_API mrb_value @@ -899,7 +899,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self) memcpy(p + n, p, len-n); } p[RSTR_LEN(str2)] = '\0'; - RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self)); + RSTR_COPY_SINGLE_BYTE_FLAG(str2, mrb_str_ptr(self)); return mrb_obj_value(str2); } @@ -1209,7 +1209,7 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) char buf[4]; /* `\x??` or UTF-8 character */ mrb_value result = mrb_str_new_lit(mrb, "\""); #ifdef MRB_UTF8_STRING - uint32_t ascii_flag = MRB_STR_ASCII; + uint32_t sb_flag = MRB_STR_SINGLE_BYTE; #endif p = RSTRING_PTR(str); pend = RSTRING_END(str); @@ -1221,7 +1221,7 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) if (clen > 1) { mrb_str_cat(mrb, result, p, clen); p += clen-1; - ascii_flag = 0; + sb_flag = 0; continue; } } @@ -1263,11 +1263,11 @@ str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) mrb_str_cat_lit(mrb, result, "\""); #ifdef MRB_UTF8_STRING if (inspect) { - mrb_str_ptr(str)->flags |= ascii_flag; - mrb_str_ptr(result)->flags |= ascii_flag; + mrb_str_ptr(str)->flags |= sb_flag; + mrb_str_ptr(result)->flags |= sb_flag; } else { - RSTR_SET_ASCII_FLAG(mrb_str_ptr(result)); + RSTR_SET_SINGLE_BYTE_FLAG(mrb_str_ptr(result)); } #endif @@ -1788,7 +1788,7 @@ mrb_str_byteindex_m(mrb_state *mrb, mrb_value str) static mrb_value mrb_str_index_m(mrb_state *mrb, mrb_value str) { - if (RSTR_ASCII_P(mrb_str_ptr(str))) { + if (RSTR_SINGLE_BYTE_P(mrb_str_ptr(str))) { return mrb_str_byteindex_m(mrb, str); } @@ -2059,7 +2059,7 @@ mrb_str_byterindex_m(mrb_state *mrb, mrb_value str) static mrb_value mrb_str_rindex_m(mrb_state *mrb, mrb_value str) { - if (RSTR_ASCII_P(mrb_str_ptr(str))) { + if (RSTR_SINGLE_BYTE_P(mrb_str_ptr(str))) { return mrb_str_byterindex_m(mrb, str); } From 6f0c34e04ec573f68b977e1be7cab8c645b199fd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 18 Jan 2024 22:53:46 +0900 Subject: [PATCH 061/117] mruby-string-ext: implement String#ascii_only? method --- mrbgems/mruby-string-ext/src/string.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 2f93e7ff4..82a52863e 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -1346,6 +1346,21 @@ str_valid_enc_p(mrb_state *mrb, mrb_value str) return mrb_true_value(); } +static mrb_value +str_ascii_only_p(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + const char *p = RSTR_PTR(s); + const char *e = p + RSTR_LEN(s); + + while (p < e) { + if (*p & 0x80) return mrb_false_value(); + p++; + } + RSTR_SET_SINGLE_BYTE_FLAG(mrb_str_ptr(str)); + return mrb_true_value(); +} + void mrb_mruby_string_ext_gem_init(mrb_state* mrb) { @@ -1384,6 +1399,7 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, s, "+@", str_uplus, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "-@", str_uminus, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "valid_encoding?", str_valid_enc_p, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "ascii_only?", str_ascii_only_p, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "__lines", str_lines, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "__codepoints", str_codepoints, MRB_ARGS_NONE()); From 1e9d69f89679435d8dc5f59d30d68f117b422821 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:59:43 +0000 Subject: [PATCH 062/117] build(deps): bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b95005f2d..6f92b31d5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -19,7 +19,7 @@ jobs: pip install pre-commit - name: Set PY run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} From 69cf074778f2e08c565f03e4251aaef38879ca69 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 19 Jan 2024 15:21:43 +0900 Subject: [PATCH 063/117] string.c (mrb_memsearch): move simple search from mrb_memsearch_qs() --- src/string.c | 61 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/string.c b/src/string.c index 563af77ce..7a0363b2e 100644 --- a/src/string.c +++ b/src/string.c @@ -454,39 +454,23 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) static inline mrb_int mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) { - if (n + m < MRB_QS_SHORT_STRING_LENGTH) { - const unsigned char *y = ys; - const unsigned char *ye = ys+n-m+1; + const unsigned char *y = ys; + ptrdiff_t qstable[256]; - for (;;) { - y = (const unsigned char*)memchr(y, xs[0], (size_t)(ye-y)); - if (y == NULL) return -1; - if (memcmp(xs, y, m) == 0) { - return (mrb_int)(y - ys); - } - y++; - } - return -1; - } - else { - const unsigned char *y = ys; - ptrdiff_t qstable[256]; - - /* Preprocessing */ - for (int i = 0; i < 256; i++) - qstable[i] = m + 1; - - const unsigned char *x = xs, *xe = xs + m; - for (; x < xe; x++) - qstable[*x] = xe - x; - - /* Searching */ - for (; y + m <= ys + n; y += qstable[y[m]]) { - if (*xs == *y && memcmp(xs, y, m) == 0) - return (mrb_int)(y - ys); - } - return -1; + /* Preprocessing */ + for (int i = 0; i < 256; i++) + qstable[i] = m + 1; + + const unsigned char *x = xs, *xe = xs + m; + for (; x < xe; x++) + qstable[*x] = xe - x; + + /* Searching */ + for (; y + m <= ys + n; y += qstable[y[m]]) { + if (*xs == *y && memcmp(xs, y, m) == 0) + return (mrb_int)(y - ys); } + return -1; } static mrb_int @@ -509,6 +493,21 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) else return -1; } + if (n + m < MRB_QS_SHORT_STRING_LENGTH) { + const unsigned char *ys = y0; + const unsigned char *y = ys; + const unsigned char *ye = y0+n-m+1; + + for (;;) { + y = (const unsigned char*)memchr(y, x[0], (size_t)(ye-ys)); + if (y == NULL) return -1; + if (memcmp(x, y, m) == 0) { + return (mrb_int)(y - ys); + } + y++; + } + return -1; + } return mrb_memsearch_qs((const unsigned char*)x0, m, (const unsigned char*)y0, n); } From f13101124c9806311219e5f805fc723dcdbc912c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 19 Jan 2024 18:24:34 +0900 Subject: [PATCH 064/117] string.c: add cast to remove warnings --- src/string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/string.c b/src/string.c index 7a0363b2e..e80f7fbff 100644 --- a/src/string.c +++ b/src/string.c @@ -494,9 +494,9 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) return -1; } if (n + m < MRB_QS_SHORT_STRING_LENGTH) { - const unsigned char *ys = y0; + const unsigned char *ys = (unsigned char*)y0; const unsigned char *y = ys; - const unsigned char *ye = y0+n-m+1; + const unsigned char *ye = ys+n-m+1; for (;;) { y = (const unsigned char*)memchr(y, x[0], (size_t)(ye-ys)); From 772f13520c089a2eb163f82587a31106834a7b02 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 09:44:47 +0900 Subject: [PATCH 065/117] Fixed buffer overflow in `mrb_memsearch()` --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index e80f7fbff..eb1ca78c3 100644 --- a/src/string.c +++ b/src/string.c @@ -499,7 +499,7 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) const unsigned char *ye = ys+n-m+1; for (;;) { - y = (const unsigned char*)memchr(y, x[0], (size_t)(ye-ys)); + y = (const unsigned char*)memchr(y, x[0], (size_t)(ye-y)); if (y == NULL) return -1; if (memcmp(x, y, m) == 0) { return (mrb_int)(y - ys); From 97203729a90cbeecd852ba208439d2fd78a0b27d Mon Sep 17 00:00:00 2001 From: buty4649 Date: Sat, 20 Jan 2024 11:47:37 +0900 Subject: [PATCH 066/117] Add Enumerable#grep_v to mruby-enum-ext --- mrbgems/mruby-enum-ext/mrblib/enum.rb | 11 +++++++++++ mrbgems/mruby-enum-ext/test/enum.rb | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index 2c9e8d3a5..28562a1b9 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -840,6 +840,17 @@ module Enumerable alias filter select + def grep_v(pattern, &block) + ary = [] + self.each{|*val| + sv = val.__svalue + unless pattern === sv + ary.push((block)? block.call(*val): sv) + end + } + ary + end + ## # call-seq: # enum.tally -> a_hash diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb index 31181fe1a..98ace670e 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -195,3 +195,10 @@ end assert("Enumerable#tally") do assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally) end + +assert("Enumerable#grep_v") do + a = [1, 2, 3, 4, 5, 0] + assert_equal [1, 5, 0], a.grep_v(2..4) + assert_equal [1, 2, 3, 4, 5, 0], a.grep_v(6..8) + assert_equal [2, 4, 6, 8, 10], a.grep_v(0) {|v| v * 2} +end From 35375257f6fbaf16d6c9a227255b2a238ee7e449 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 21:52:49 +0900 Subject: [PATCH 067/117] Remove unnecessary `Rational._new` method --- mrbgems/mruby-rational/src/rational.c | 42 --------------------------- 1 file changed, 42 deletions(-) diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 9bdea6957..2cfbfb35b 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -254,47 +254,6 @@ rational_new_f(mrb_state *mrb, mrb_float f0) } #endif -static mrb_value -rational_s_new(mrb_state *mrb, mrb_value self) -{ - mrb_int numerator, denominator; - -#ifdef MRB_NO_FLOAT - mrb_get_args(mrb, "ii", &numerator, &denominator); -#else - - mrb_value numv, denomv; - - mrb_get_args(mrb, "oo", &numv, &denomv); - if (mrb_integer_p(numv)) { - numerator = mrb_integer(numv); - - if (mrb_integer_p(denomv)) { - denominator = mrb_integer(denomv); - } - else { - mrb_float numf = (mrb_float)numerator; - mrb_float denomf = mrb_as_float(mrb, denomv); - - return rational_new_f(mrb, numf/denomf); - } - } - else { - mrb_float numf = mrb_as_float(mrb, numv); - mrb_float denomf; - - if (mrb_integer_p(denomv)) { - denomf = (mrb_float)mrb_integer(denomv); - } - else { - denomf = mrb_as_float(mrb, denomv); - } - return rational_new_f(mrb, numf/denomf); - } -#endif - return rational_new(mrb, numerator, denominator); -} - #ifndef MRB_NO_FLOAT static mrb_float rat_float(struct mrb_rational *p) @@ -771,7 +730,6 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) MRB_SET_INSTANCE_TT(rat, MRB_TT_RATIONAL); MRB_UNDEF_ALLOCATOR(rat); mrb_undef_class_method(mrb, rat, "new"); - mrb_define_class_method(mrb, rat, "_new", rational_s_new, MRB_ARGS_REQ(2)); mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE()); mrb_define_method(mrb, rat, "denominator", rational_denominator, MRB_ARGS_NONE()); #ifndef MRB_NO_FLOAT From 31119900890a6aa841a0e3a8a2abe957aa49cd1a Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 22:07:29 +0900 Subject: [PATCH 068/117] Introduce `mrb_obj_itself()` Some method definitions were changed to use this function. --- include/mruby.h | 2 ++ mrbgems/mruby-complex/src/complex.c | 8 +------- mrbgems/mruby-object-ext/src/object.c | 9 +++------ mrbgems/mruby-rational/src/rational.c | 8 +------- src/numeric.c | 24 +++++++++--------------- src/object.c | 6 ++++++ src/symbol.c | 10 +++------- 7 files changed, 25 insertions(+), 42 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index 4048edf69..828bb9d2e 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -798,6 +798,8 @@ MRB_API struct RClass * mrb_module_get_under_id(mrb_state *mrb, struct RClass *o MRB_API void mrb_notimplement(mrb_state*); /* a function to be replacement of unimplemented method */ MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value); +/* just return it self */ +MRB_API mrb_value mrb_obj_itself(mrb_state*, mrb_value); /** * Duplicate an object. diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index a2c579058..8aad4c000 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -149,12 +149,6 @@ mrb_complex_to_i(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, (mrb_int)p->real); } -static mrb_value -complex_to_c(mrb_state *mrb, mrb_value self) -{ - return self; -} - mrb_bool mrb_complex_eq(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -406,7 +400,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) mrb_define_method(mrb, comp, "imaginary", complex_imaginary, MRB_ARGS_NONE()); mrb_define_method(mrb, comp, "to_f", mrb_complex_to_f, MRB_ARGS_NONE()); mrb_define_method(mrb, comp, "to_i", mrb_complex_to_i, MRB_ARGS_NONE()); - mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE()); + mrb_define_method(mrb, comp, "to_c", mrb_obj_itself, MRB_ARGS_NONE()); mrb_define_method(mrb, comp, "+", complex_add, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "-", complex_sub, MRB_ARGS_REQ(1)); mrb_define_method(mrb, comp, "*", complex_mul, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c index f0b50bf13..62345810f 100644 --- a/mrbgems/mruby-object-ext/src/object.c +++ b/mrbgems/mruby-object-ext/src/object.c @@ -60,6 +60,8 @@ nil_to_i(mrb_state *mrb, mrb_value obj) } /* + * Document-method: Kernel#itself + * * call-seq: * obj.itself -> an_object * @@ -69,11 +71,6 @@ nil_to_i(mrb_state *mrb, mrb_value obj) * string.itself.object_id == string.object_id #=> true * */ -static mrb_value -f_itself(mrb_state *mrb, mrb_value self) -{ - return self; -} /* * call-seq: @@ -122,7 +119,7 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, n, "to_h", nil_to_h, MRB_ARGS_NONE()); mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb->kernel_module, "itself", f_itself, MRB_ARGS_NONE()); + mrb_define_method(mrb, mrb->kernel_module, "itself", mrb_obj_itself, MRB_ARGS_NONE()); mrb_define_method(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), "instance_exec", obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK()); } diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index 9bdea6957..358e24766 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -329,12 +329,6 @@ mrb_rational_to_i(mrb_state *mrb, mrb_value self) return mrb_int_value(mrb, p->numerator / p->denominator); } -static mrb_value -rational_to_r(mrb_state *mrb, mrb_value self) -{ - return self; -} - static mrb_value rational_negative_p(mrb_state *mrb, mrb_value self) { @@ -778,7 +772,7 @@ void mrb_mruby_rational_gem_init(mrb_state *mrb) mrb_define_method(mrb, rat, "to_f", mrb_rational_to_f, MRB_ARGS_NONE()); #endif mrb_define_method(mrb, rat, "to_i", mrb_rational_to_i, MRB_ARGS_NONE()); - mrb_define_method(mrb, rat, "to_r", rational_to_r, MRB_ARGS_NONE()); + mrb_define_method(mrb, rat, "to_r", mrb_obj_itself, MRB_ARGS_NONE()); mrb_define_method(mrb, rat, "negative?", rational_negative_p, MRB_ARGS_NONE()); mrb_define_method(mrb, rat, "==", rational_eq, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rat, "<=>", rational_cmp, MRB_ARGS_REQ(1)); diff --git a/src/numeric.c b/src/numeric.c index 743cdb3ae..6f5ad7308 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -744,18 +744,14 @@ flo_lshift(mrb_state *mrb, mrb_value x) /* 15.2.9.3.13 */ /* + * Document-method: Float#to_f + * * call-seq: * flt.to_f -> self * * As flt is already a float, returns +self+. */ -static mrb_value -flo_to_f(mrb_state *mrb, mrb_value num) -{ - return num; -} - /* 15.2.9.3.11 */ /* * call-seq: @@ -1105,19 +1101,17 @@ flo_abs(mrb_state *mrb, mrb_value num) /* 15.2.9.3.24 */ /* + * Document-method: Integer#to_i + * Document-method: Integer#to_int + * * call-seq: * int.to_i -> integer + * int.to_int -> integer * * As int is already an Integer, all these * methods simply return the receiver. */ -static mrb_value -int_to_i(mrb_state *mrb, mrb_value num) -{ - return num; -} - mrb_value mrb_int_mul(mrb_state *mrb, mrb_value x, mrb_value y) { @@ -2237,8 +2231,8 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method_id(mrb, integer, MRB_OPSYM(gt), num_gt, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, integer, MRB_OPSYM(ge), num_ge, MRB_ARGS_REQ(1)); - mrb_define_method_id(mrb, integer, MRB_SYM(to_i), int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ - mrb_define_method_id(mrb, integer, MRB_SYM(to_int), int_to_i, MRB_ARGS_NONE()); + mrb_define_method_id(mrb, integer, MRB_SYM(to_i), mrb_obj_itself, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ + mrb_define_method_id(mrb, integer, MRB_SYM(to_int), mrb_obj_itself, MRB_ARGS_NONE()); mrb_define_method_id(mrb, integer, MRB_OPSYM(add), int_add, MRB_ARGS_REQ(1)); /* 15.2.8.3.1 */ mrb_define_method_id(mrb, integer, MRB_OPSYM(sub), int_sub, MRB_ARGS_REQ(1)); /* 15.2.8.3.2 */ @@ -2301,7 +2295,7 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method_id(mrb, fl, MRB_SYM(floor), flo_floor, MRB_ARGS_OPT(1)); /* 15.2.9.3.10 */ mrb_define_method_id(mrb, fl, MRB_SYM_Q(infinite),flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */ mrb_define_method_id(mrb, fl, MRB_SYM(round), flo_round, MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */ - mrb_define_method_id(mrb, fl, MRB_SYM(to_f), flo_to_f, MRB_ARGS_NONE()); /* 15.2.9.3.13 */ + mrb_define_method_id(mrb, fl, MRB_SYM(to_f), mrb_obj_itself, MRB_ARGS_NONE()); /* 15.2.9.3.13 */ mrb_define_method_id(mrb, fl, MRB_SYM(to_i), flo_to_i, MRB_ARGS_NONE()); /* 15.2.9.3.14 */ mrb_define_method_id(mrb, fl, MRB_SYM(truncate), flo_truncate, MRB_ARGS_OPT(1)); /* 15.2.9.3.15 */ mrb_define_method_id(mrb, fl, MRB_SYM(divmod), flo_divmod, MRB_ARGS_REQ(1)); diff --git a/src/object.c b/src/object.c index f8e9c0b72..8fbcc0f57 100644 --- a/src/object.c +++ b/src/object.c @@ -649,3 +649,9 @@ mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2) if (mrb_class(mrb, obj1) != mrb_class(mrb, obj2)) return FALSE; return mrb_test(mrb_funcall_argv(mrb, obj1, MRB_SYM_Q(eql), 1, &obj2)); } + +MRB_API mrb_value +mrb_obj_itself(mrb_state *mrb, mrb_value self) +{ + return self; +} diff --git a/src/symbol.c b/src/symbol.c index 3f0ddb535..021b80003 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -441,6 +441,8 @@ sym_name(mrb_state *mrb, mrb_value vsym) /* 15.2.11.3.4 */ /* + * Document-method: Symbol#to_sym + * * call-seq: * sym.to_sym -> sym * sym.intern -> sym @@ -450,12 +452,6 @@ sym_name(mrb_state *mrb, mrb_value vsym) * in this case. */ -static mrb_value -sym_to_sym(mrb_state *mrb, mrb_value sym) -{ - return sym; -} - /* 15.2.11.3.5(x) */ /* * call-seq: @@ -696,7 +692,7 @@ mrb_init_symbol(mrb_state *mrb) mrb_define_method_id(mrb, sym, MRB_SYM(to_s), sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.3 */ mrb_define_method_id(mrb, sym, MRB_SYM(name), sym_name, MRB_ARGS_NONE()); - mrb_define_method_id(mrb, sym, MRB_SYM(to_sym), sym_to_sym, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ + mrb_define_method_id(mrb, sym, MRB_SYM(to_sym), mrb_obj_itself, MRB_ARGS_NONE()); /* 15.2.11.3.4 */ mrb_define_method_id(mrb, sym, MRB_SYM(inspect), sym_inspect, MRB_ARGS_NONE()); /* 15.2.11.3.5(x) */ mrb_define_method_id(mrb, sym, MRB_OPSYM(cmp), sym_cmp, MRB_ARGS_REQ(1)); } From 82312467d06b69c98d0df8931aaf43b18ffc16aa Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 22:20:20 +0900 Subject: [PATCH 069/117] Refer to `mrb->module_class` directly in `mrb_mruby_eval_gem_init()` --- mrbgems/mruby-eval/src/eval.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index fe1645822..db9b439bd 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -344,8 +344,8 @@ mrb_mruby_eval_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); - mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); - mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb->module_class, MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb->module_class, MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); struct RClass *binding = mrb_class_get_id(mrb, MRB_SYM(Binding)); mrb_define_method(mrb, binding, "eval", mrb_binding_eval, MRB_ARGS_ANY()); From 5caf8e14cf6d6c245839398faef56fa757aba43e Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 22:33:43 +0900 Subject: [PATCH 070/117] Retrieving the IO exception class with presym --- mrbgems/mruby-io/include/mruby/ext/io.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-io/include/mruby/ext/io.h b/mrbgems/mruby-io/include/mruby/ext/io.h index 13da769ce..a0f3a2e81 100644 --- a/mrbgems/mruby-io/include/mruby/ext/io.h +++ b/mrbgems/mruby-io/include/mruby/ext/io.h @@ -6,6 +6,7 @@ #define MRUBY_IO_H #include +#include #ifdef MRB_NO_STDIO # error IO and File conflicts 'MRB_NO_STDIO' in your build configuration @@ -63,8 +64,8 @@ struct mrb_io { #define MRB_O_DSYNC 0x00008000 #define MRB_O_RSYNC 0x00010000 -#define E_IO_ERROR (mrb_exc_get(mrb, "IOError")) -#define E_EOF_ERROR (mrb_exc_get(mrb, "EOFError")) +#define E_IO_ERROR mrb_exc_get_id(mrb, MRB_SYM(IOError)) +#define E_EOF_ERROR mrb_exc_get_id(mrb, MRB_SYM(EOFError)) int mrb_io_fileno(mrb_state *mrb, mrb_value io); From 464ac4581e9aa777065193f0f444598ceccb8a7d Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 20 Jan 2024 22:49:31 +0900 Subject: [PATCH 071/117] Make `MRuby::Gems::List#{each,<<}` method return `self` Returning internal objects is undesirable. --- lib/mruby/gem.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index 35aa2bd52..a2b649d71 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -372,6 +372,7 @@ module MRuby def each(&b) @ary.each(&b) + self end def [](name) @@ -384,6 +385,7 @@ module MRuby else # GEM was already added to this list end + self end def empty? From bf2db1ed2bf9f8f0ff734984178c73ef3418a26a Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 21 Jan 2024 10:59:06 +0900 Subject: [PATCH 072/117] Check `mrb_bigint_p()` before `mrb_integer()` --- src/numeric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/numeric.c b/src/numeric.c index 743cdb3ae..4ad523f22 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -1976,7 +1976,6 @@ MRB_API mrb_value mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base) { char buf[MRB_INT_BIT+1]; - mrb_int val = mrb_integer(x); if (base < 2 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %i", base); @@ -1986,6 +1985,7 @@ mrb_integer_to_str(mrb_state *mrb, mrb_value x, mrb_int base) return mrb_bint_to_s(mrb, x, base); } #endif + mrb_int val = mrb_integer(x); const char *p = mrb_int_to_cstr(buf, sizeof(buf), val, base); mrb_assert(p != NULL); mrb_value str = mrb_str_new_cstr(mrb, p); From d001974439ec2bde6e5ca48a1c776a69e727b3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=B9=96=E6=96=B0?= Date: Mon, 22 Jan 2024 18:26:01 +0900 Subject: [PATCH 073/117] Revert "Enumerable#chunk implementation" This reverts commit ebf86a24b058f9aa3f0b3765cb1bf3088005fcc0. --- mrbgems/mruby-enum-ext/mrbgem.rake | 2 - mrbgems/mruby-enum-ext/mrblib/enum.rb | 68 --------------------------- mrbgems/mruby-enum-ext/test/enum.rb | 49 ------------------- 3 files changed, 119 deletions(-) diff --git a/mrbgems/mruby-enum-ext/mrbgem.rake b/mrbgems/mruby-enum-ext/mrbgem.rake index 9394bc514..d5816b80f 100644 --- a/mrbgems/mruby-enum-ext/mrbgem.rake +++ b/mrbgems/mruby-enum-ext/mrbgem.rake @@ -2,6 +2,4 @@ MRuby::Gem::Specification.new('mruby-enum-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'Enumerable module extension' - - spec.add_dependency 'mruby-enumerator', core: 'mruby-enumerator' end diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index e3fa57aac..2c9e8d3a5 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -880,72 +880,4 @@ module Enumerable end result end - - ## - # call-seq: - # enum.chunk -> enumerator - # enum.chunk { |arr| block } -> enumerator - # - # Each element in the returned enumerator is a 2-element array consisting of: - # - # - A value returned by the block. - # - An array ("chunk") containing the element for which that value was returned, - # and all following elements for which the block returned the same value: - # - # So that: - # - # - Each block return value that is different from its predecessor - # begins a new chunk. - # - Each block return value that is the same as its predecessor - # continues the same chunk. - # - # Example: - # - # e = (0..10).chunk {|i| (i / 3).floor } # => # - # # The enumerator elements. - # e.next # => [0, [0, 1, 2]] - # e.next # => [1, [3, 4, 5]] - # e.next # => [2, [6, 7, 8]] - # e.next # => [3, [9, 10]] - # - # You can use the special symbol :_alone to force an element - # into its own separate chuck: - # - # a = [0, 0, 1, 1] - # e = a.chunk{|i| i.even? ? :_alone : true } - # e.to_a # => [[:_alone, [0]], [:_alone, [0]], [true, [1, 1]]] - # - # You can use the special symbol :_separator or +nil+ - # to force an element to be ignored (not included in any chunk): - # - # a = [0, 0, -1, 1, 1] - # e = a.chunk{|i| i < 0 ? :_separator : true } - # e.to_a # => [[true, [0, 0]], [true, [1, 1]]] - def chunk(&block) - return to_enum :chunk unless block - - enum = self - Enumerator.new do |y| - last_value, arr = nil, [] - enum.each do |element| - value = block.call(element) - case value - when :_alone - y.yield [last_value, arr] if arr.size > 0 - y.yield [value, [element]] - last_value, arr = nil, [] - when :_separator, nil - y.yield [last_value, arr] if arr.size > 0 - last_value, arr = nil, [] - when last_value - arr << element - else - raise 'symbols beginning with an underscore are reserved' if value.is_a?(Symbol) && value.to_s[0] == '_' - y.yield [last_value, arr] if arr.size > 0 - last_value, arr = value, [element] - end - end - y.yield [last_value, arr] if arr.size > 0 - end - end end diff --git a/mrbgems/mruby-enum-ext/test/enum.rb b/mrbgems/mruby-enum-ext/test/enum.rb index 759c0ead1..31181fe1a 100644 --- a/mrbgems/mruby-enum-ext/test/enum.rb +++ b/mrbgems/mruby-enum-ext/test/enum.rb @@ -195,52 +195,3 @@ end assert("Enumerable#tally") do assert_equal({"a"=>1, "b"=>2, "c"=>1}, ["a", "b", "c", "b"].tally) end - -assert("Enumerable#chunk") do - chunk = [1, 2, 3, 1, 2].chunk - assert_equal Enumerator, chunk.class - result = chunk.with_index { |elt, i| elt - i }.to_a - assert_equal [[1, [1, 2, 3]], [-2, [1, 2]]], result - - assert_equal Enumerator, [].chunk {}.class - - e = [1, 2, 3] - recorded = [] - e.chunk { |x| recorded << x }.to_a - assert_equal [1, 2, 3], recorded - - e = [1, 2, 3, 2, 3, 2, 1] - result = e.chunk { |x| x < 3 && 1 || 0 }.to_a - assert_equal [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]], result - - e = [1, 2, 3] - assert_equal [[1, 2], [3]], e.chunk { |x| x > 2 }.map(&:last) - - e = [1, 2, 3, 2, 1] - result = e.chunk { |x| x < 2 && :_alone }.to_a - assert_equal [[:_alone, [1]], [false, [2, 3, 2]], [:_alone, [1]]], result - - e = [[1, 2]] - inner_value = [] - e.chunk { |*x| inner_value << x }.to_a - assert_equal [[[1, 2]]], inner_value - - e = [1, 2, 3, 3, 2, 1] - result = e.chunk { |x| x == 2 ? :_separator : 1 }.to_a - assert_equal [[1, [1]], [1, [3, 3]], [1, [1]]], result - - e = [1, 2, 3, 2, 1] - result = e.chunk { |x| x == 2 ? nil : 1 }.to_a - assert_equal [[1, [1]], [1, [3]], [1, [1]]], result - - - e = [1, 2, 3, 2, 1] - assert_raise(RuntimeError) { e.chunk { |x| :_arbitrary }.to_a } - - e = [1, 2, 3] - assert_raise(ArgumentError) { e.chunk(1) {} } - - e = [1, 2, 3, 2, 1] - enum = e.chunk { |x| true } - assert_nil enum.size -end From ab21813100803ca94f9e18cbad3e2e2eb9dea15a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=9F=E6=B9=96=E6=96=B0?= Date: Mon, 22 Jan 2024 18:31:28 +0900 Subject: [PATCH 074/117] Move Enumerable#chunk to mruby-enumerator --- mrbgems/mruby-enumerator/mrblib/enumerator.rb | 68 +++++++++++++++++++ mrbgems/mruby-enumerator/test/enumerator.rb | 49 +++++++++++++ 2 files changed, 117 insertions(+) diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb index faaabf18a..44d84865a 100644 --- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -701,4 +701,72 @@ module Enumerable result end + + ## + # call-seq: + # enum.chunk -> enumerator + # enum.chunk { |arr| block } -> enumerator + # + # Each element in the returned enumerator is a 2-element array consisting of: + # + # - A value returned by the block. + # - An array ("chunk") containing the element for which that value was returned, + # and all following elements for which the block returned the same value: + # + # So that: + # + # - Each block return value that is different from its predecessor + # begins a new chunk. + # - Each block return value that is the same as its predecessor + # continues the same chunk. + # + # Example: + # + # e = (0..10).chunk {|i| (i / 3).floor } # => # + # # The enumerator elements. + # e.next # => [0, [0, 1, 2]] + # e.next # => [1, [3, 4, 5]] + # e.next # => [2, [6, 7, 8]] + # e.next # => [3, [9, 10]] + # + # You can use the special symbol :_alone to force an element + # into its own separate chuck: + # + # a = [0, 0, 1, 1] + # e = a.chunk{|i| i.even? ? :_alone : true } + # e.to_a # => [[:_alone, [0]], [:_alone, [0]], [true, [1, 1]]] + # + # You can use the special symbol :_separator or +nil+ + # to force an element to be ignored (not included in any chunk): + # + # a = [0, 0, -1, 1, 1] + # e = a.chunk{|i| i < 0 ? :_separator : true } + # e.to_a # => [[true, [0, 0]], [true, [1, 1]]] + def chunk(&block) + return to_enum :chunk unless block + + enum = self + Enumerator.new do |y| + last_value, arr = nil, [] + enum.each do |element| + value = block.call(element) + case value + when :_alone + y.yield [last_value, arr] if arr.size > 0 + y.yield [value, [element]] + last_value, arr = nil, [] + when :_separator, nil + y.yield [last_value, arr] if arr.size > 0 + last_value, arr = nil, [] + when last_value + arr << element + else + raise 'symbols beginning with an underscore are reserved' if value.is_a?(Symbol) && value.to_s[0] == '_' + y.yield [last_value, arr] if arr.size > 0 + last_value, arr = value, [element] + end + end + y.yield [last_value, arr] if arr.size > 0 + end + end end diff --git a/mrbgems/mruby-enumerator/test/enumerator.rb b/mrbgems/mruby-enumerator/test/enumerator.rb index 3e0c6c3be..4baf20c25 100644 --- a/mrbgems/mruby-enumerator/test/enumerator.rb +++ b/mrbgems/mruby-enumerator/test/enumerator.rb @@ -598,3 +598,52 @@ assert 'Enumerator.produce' do ], enum.to_a } end + +assert("Enumerable#chunk") do + chunk = [1, 2, 3, 1, 2].chunk + assert_equal Enumerator, chunk.class + result = chunk.with_index { |elt, i| elt - i }.to_a + assert_equal [[1, [1, 2, 3]], [-2, [1, 2]]], result + + assert_equal Enumerator, [].chunk {}.class + + e = [1, 2, 3] + recorded = [] + e.chunk { |x| recorded << x }.to_a + assert_equal [1, 2, 3], recorded + + e = [1, 2, 3, 2, 3, 2, 1] + result = e.chunk { |x| x < 3 && 1 || 0 }.to_a + assert_equal [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]], result + + e = [1, 2, 3] + assert_equal [[1, 2], [3]], e.chunk { |x| x > 2 }.map(&:last) + + e = [1, 2, 3, 2, 1] + result = e.chunk { |x| x < 2 && :_alone }.to_a + assert_equal [[:_alone, [1]], [false, [2, 3, 2]], [:_alone, [1]]], result + + e = [[1, 2]] + inner_value = [] + e.chunk { |*x| inner_value << x }.to_a + assert_equal [[[1, 2]]], inner_value + + e = [1, 2, 3, 3, 2, 1] + result = e.chunk { |x| x == 2 ? :_separator : 1 }.to_a + assert_equal [[1, [1]], [1, [3, 3]], [1, [1]]], result + + e = [1, 2, 3, 2, 1] + result = e.chunk { |x| x == 2 ? nil : 1 }.to_a + assert_equal [[1, [1]], [1, [3]], [1, [1]]], result + + + e = [1, 2, 3, 2, 1] + assert_raise(RuntimeError) { e.chunk { |x| :_arbitrary }.to_a } + + e = [1, 2, 3] + assert_raise(ArgumentError) { e.chunk(1) {} } + + e = [1, 2, 3, 2, 1] + enum = e.chunk { |x| true } + assert_nil enum.size +end From 4108b85c625570475313e130f6bc1132ccc9693b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 22 Jan 2024 07:46:31 +0900 Subject: [PATCH 075/117] string.c (search_nonascii): faster search using integer match If you define `SIMPLE_SEARCH_NONASCII`, you can use old, naive implementation of search_nonascii(). You may want to use the old one for code size constraint for example. --- src/string.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/string.c b/src/string.c index eb1ca78c3..688e5379f 100644 --- a/src/string.c +++ b/src/string.c @@ -267,6 +267,9 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) #define NOASCII(c) ((c) & 0x80) +#ifdef SIMPLE_SEARCH_NONASCII +/* the naive implementation. define SIMPLE_SEARCH_NONASCII, */ +/* if you need it for any constraint (e.g. code size). */ static const char* search_nonascii(const char* p, const char *e) { @@ -276,6 +279,69 @@ search_nonascii(const char* p, const char *e) return e; } +#else + +#ifdef MRB_64BIT +# define NONASCII_MASK 0x8080808080808080ULL +#else /* MRB_32BIT */ +# define NONASCII_MASK 0x80808080UL +#endif + +static const char* +search_nonascii(const char *p, const char *e) +{ + if (e - p >= sizeof(void*)) { + if ((uintptr_t)p % sizeof(void*)) { + int l = sizeof(void*) - (uintptr_t)p % sizeof(void*); + p += l; + switch (l) { +#ifdef MRB_64BIT + case 7: if (p[-7]&0x80) return p-7; + case 6: if (p[-6]&0x80) return p-6; + case 5: if (p[-5]&0x80) return p-5; + case 4: if (p[-4]&0x80) return p-4; +#endif + case 3: if (p[-3]&0x80) return p-3; + case 2: if (p[-2]&0x80) return p-2; + case 1: if (p[-1]&0x80) return p-1; + case 0: break; + } + } + + const uintptr_t *s = (uintptr_t*)p; + const uintptr_t *t = (uintptr_t*)(e - (sizeof(void*)-1)); + + for (;s < t; s++) { + if (*s & NONASCII_MASK) { + p = (const char*)s; + if (NOASCII(p[0])) return p+0; + if (NOASCII(p[1])) return p+1; + if (NOASCII(p[2])) return p+2; + if (NOASCII(p[3])) return p+3; + if (NOASCII(p[4])) return p+4; + if (NOASCII(p[5])) return p+5; + if (NOASCII(p[6])) return p+6; + if (NOASCII(p[7])) return p+7; + } + } + } + switch (e - p) { + default: +#ifdef MRB_64BIT + case 7: if (e[-7]&0x80) return e-7; + case 6: if (e[-6]&0x80) return e-6; + case 5: if (e[-5]&0x80) return e-5; + case 4: if (e[-4]&0x80) return e-4; +#endif + case 3: if (e[-3]&0x80) return e-3; + case 2: if (e[-2]&0x80) return e-2; + case 1: if (e[-1]&0x80) return e-1; + } + return e; +} + +#endif /* SIMPLE_SEARCH_NONASCII */ + #define utf8_islead(c) ((unsigned char)((c)&0xc0) != 0x80) extern const char mrb_utf8len_table[]; From fb2ebcde7cde872f2d90fe02b9bc7d6bbb8841f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 23 Jan 2024 08:55:53 +0900 Subject: [PATCH 076/117] string.c (search_nonascii): add faster search using SSE2 --- src/string.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/string.c b/src/string.c index 688e5379f..1130c1385 100644 --- a/src/string.c +++ b/src/string.c @@ -279,6 +279,45 @@ search_nonascii(const char* p, const char *e) return e; } +#elif defined(__SSE2__) +# include + +static inline const char * +search_nonascii(const char *p, const char *e) +{ + if (16 < e - p) { + if (!_mm_movemask_epi8(_mm_loadu_si128((__m128i const*)p))) { + const intptr_t lowbits = sizeof(__m128i) - 1; + const __m128i *s, *t; + s = (const __m128i*)(~lowbits & ((intptr_t)p + lowbits)); + t = (const __m128i*)(~lowbits & (intptr_t)e); + for (; s < t; ++s) { + if (_mm_movemask_epi8(_mm_load_si128(s))) + break; + } + p = (const char *)s; + } + } + switch (e - p) { + case 15: if (NOASCII(*p)) return p; ++p; + case 14: if (NOASCII(*p)) return p; ++p; + case 13: if (NOASCII(*p)) return p; ++p; + case 12: if (NOASCII(*p)) return p; ++p; + case 11: if (NOASCII(*p)) return p; ++p; + case 10: if (NOASCII(*p)) return p; ++p; + case 9: if (NOASCII(*p)) return p; ++p; + case 8: if (NOASCII(*p)) return p; ++p; + case 7: if (NOASCII(*p)) return p; ++p; + case 6: if (NOASCII(*p)) return p; ++p; + case 5: if (NOASCII(*p)) return p; ++p; + case 4: if (NOASCII(*p)) return p; ++p; + case 3: if (NOASCII(*p)) return p; ++p; + case 2: if (NOASCII(*p)) return p; ++p; + case 1: if (NOASCII(*p)) return p; + } + return e; +} + #else #ifdef MRB_64BIT From cf0cd6785c5df3c8c41ac4f3f018ee3c3084b6d1 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 23 Jan 2024 09:05:26 +0900 Subject: [PATCH 077/117] string.c: rename MRB_QS_SHORT_STRING_LENGTH The new name is MRB_SEARCH_SHORT_STRING_LENGTH since it's no longer used in the mrb_memsearch_qs(). FYI, 'qs' stands for 'quick search'. --- src/string.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/string.c b/src/string.c index 1130c1385..50090d2c5 100644 --- a/src/string.c +++ b/src/string.c @@ -285,20 +285,20 @@ search_nonascii(const char* p, const char *e) static inline const char * search_nonascii(const char *p, const char *e) { - if (16 < e - p) { + if (sizeof(__m128i) < e - p) { if (!_mm_movemask_epi8(_mm_loadu_si128((__m128i const*)p))) { const intptr_t lowbits = sizeof(__m128i) - 1; const __m128i *s, *t; s = (const __m128i*)(~lowbits & ((intptr_t)p + lowbits)); t = (const __m128i*)(~lowbits & (intptr_t)e); for (; s < t; ++s) { - if (_mm_movemask_epi8(_mm_load_si128(s))) - break; + if (_mm_movemask_epi8(_mm_load_si128(s))) break; } p = (const char *)s; } } switch (e - p) { + default: case 15: if (NOASCII(*p)) return p; ++p; case 14: if (NOASCII(*p)) return p; ++p; case 13: if (NOASCII(*p)) return p; ++p; @@ -313,7 +313,8 @@ search_nonascii(const char *p, const char *e) case 4: if (NOASCII(*p)) return p; ++p; case 3: if (NOASCII(*p)) return p; ++p; case 2: if (NOASCII(*p)) return p; ++p; - case 1: if (NOASCII(*p)) return p; + case 1: if (NOASCII(*p)) return p; ++p; + if (NOASCII(*p)) return p; } return e; } @@ -552,10 +553,6 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str((mrb), (str), (sub), (pos)) #endif -#ifndef MRB_QS_SHORT_STRING_LENGTH -#define MRB_QS_SHORT_STRING_LENGTH 2048 -#endif - static inline mrb_int mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) { @@ -578,6 +575,10 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr return -1; } +#ifndef MRB_SEARCH_SHORT_STRING_LENGTH +#define MRB_SEARCH_SHORT_STRING_LENGTH 2048 +#endif + static mrb_int mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) { @@ -598,7 +599,7 @@ mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) else return -1; } - if (n + m < MRB_QS_SHORT_STRING_LENGTH) { + if (n + m < MRB_SEARCH_SHORT_STRING_LENGTH) { const unsigned char *ys = (unsigned char*)y0; const unsigned char *y = ys; const unsigned char *ye = ys+n-m+1; From 68ab95ea571974ee9095634dd2eeac88bd63858c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 24 Jan 2024 22:32:23 +0900 Subject: [PATCH 078/117] string.c (mrb_memsearch): take `char*` instead of `void*` Avoid useless `void*`. --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 50090d2c5..cdd11c274 100644 --- a/src/string.c +++ b/src/string.c @@ -580,7 +580,7 @@ mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mr #endif static mrb_int -mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n) +mrb_memsearch(const char *x0, mrb_int m, const char *y0, mrb_int n) { const unsigned char *x = (const unsigned char*)x0, *y = (const unsigned char*)y0; From 08cd281200a16d9482b8c59860aca6e89f01247d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 25 Jan 2024 23:35:37 +0900 Subject: [PATCH 079/117] string.c (search_nonascii): skip alignment adjustment for some CPUs Some CPUs (e.g. x86) allow unaligned access to the memory. --- src/string.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/string.c b/src/string.c index cdd11c274..bbb6c2e15 100644 --- a/src/string.c +++ b/src/string.c @@ -327,10 +327,20 @@ search_nonascii(const char *p, const char *e) # define NONASCII_MASK 0x80808080UL #endif +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ + defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \ + defined(__mc68020__) +# define ALIGNED_WORD_ACCESS 0 +#else +# define ALIGNED_WORD_ACCESS 1 +#endif + static const char* search_nonascii(const char *p, const char *e) { if (e - p >= sizeof(void*)) { +#if ALIGNED_WORD_ACCESS if ((uintptr_t)p % sizeof(void*)) { int l = sizeof(void*) - (uintptr_t)p % sizeof(void*); p += l; @@ -347,6 +357,7 @@ search_nonascii(const char *p, const char *e) case 0: break; } } +#endif const uintptr_t *s = (uintptr_t*)p; const uintptr_t *t = (uintptr_t*)(e - (sizeof(void*)-1)); From 2943ca26859a9d533aef4a410bd39bbfe8511ccc Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 26 Jan 2024 23:57:25 +0900 Subject: [PATCH 080/117] string.c (mrb_memsearch_ss): faster integer-wise substring search The function is based on @WojciechMula's code from the repository https://github.com/WojciechMula/sse4-strstr.git Since it's licensed under 2 clause BSD, we updated LEGAL file too. --- LEGAL | 31 +++++++++++++++++++ src/string.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 107 insertions(+), 9 deletions(-) diff --git a/LEGAL b/LEGAL index 24c8dc670..116a218f6 100644 --- a/LEGAL +++ b/LEGAL @@ -4,10 +4,41 @@ LEGAL NOTICE INFORMATION All the files in this distribution are covered under the MIT license (see the file LICENSE) except some files mentioned below: +- src/string.c: mrb_memsearch_ss() is based on 2 clause BSD license code by Wojciech Muła (@WojciechMula) - src/readfloat.c: public domain by Yasuhiro Matsumoto (@mattn) - src/fmt_fp.c: public domain by Dave Hylands (@dhylands) - mrbgems/mruby-dir/src/Win/dirent.c: MIT-like license by Kevlin Henney +[src/string.c] +The implementation of mrb_memsearch_ss() is taken from +https://github.com/WojciechMula/sse4-strstr.git + +Copyright (c) 2008-2016, Wojciech Muła +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + [src/readfloat.c] strtod implementation. diff --git a/src/string.c b/src/string.c index bbb6c2e15..56a48f3c1 100644 --- a/src/string.c +++ b/src/string.c @@ -263,6 +263,15 @@ mrb_gc_free_str(mrb_state *mrb, struct RString *str) mrb_free(mrb, str->as.heap.ptr); } +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ + defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \ + defined(__mc68020__) +# define ALIGNED_WORD_ACCESS 0 +#else +# define ALIGNED_WORD_ACCESS 1 +#endif + #ifdef MRB_UTF8_STRING #define NOASCII(c) ((c) & 0x80) @@ -327,15 +336,6 @@ search_nonascii(const char *p, const char *e) # define NONASCII_MASK 0x80808080UL #endif -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ - defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \ - defined(__mc68020__) -# define ALIGNED_WORD_ACCESS 0 -#else -# define ALIGNED_WORD_ACCESS 1 -#endif - static const char* search_nonascii(const char *p, const char *e) { @@ -564,6 +564,70 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str((mrb), (str), (sub), (pos)) #endif +/* The function is taken from https://github.com/WojciechMula/sse4-strstr.git */ +/* The original source code is under 2 clause BSD license; see LEGAL file. */ +/* The modifications: + + * port from C++ to C + * takes unsigned char* + * returns mrb_int + * alignment adjustment added +*/ +static inline mrb_int +mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n) +{ +/* maximum pattern length */ +#define MAX_PATLEN 100 + +#ifdef MRB_64BIT +#define bitint uint64_t +#define MASK1 0x0101010101010101llu +#define MASK2 0x7f7f7f7f7f7f7f7fllu +#define MASK3 0x8080808080808080llu +#else +#define bitint uint32_t +#define MASK1 0x01010101lu +#define MASK2 0x7f7f7f7flu +#define MASK3 0x80808080lu +#endif + +#if ALIGNED_WORD_ACCESS + if ((uintptr_t)ys % sizeof(bitint)) { + int l = sizeof(bitint) - (bitint)ys % sizeof(bitint); + const unsigned char *p = (unsigned char*)memchr(ys, *xs, l); + if (p && (p - ys) < m) { + if (memcmp(p, xs, m) == 0) return (mrb_int)(p - ys); + ys = p; + } + } +#endif + + const bitint first = MASK1 * (uint8_t)xs[0]; + const bitint last = MASK1 * (uint8_t)xs[m-1]; + + bitint *s0 = (bitint*)(ys); + bitint *s1 = (bitint*)(ys+m-1); + + for (mrb_int i=0; i < n; i+=sizeof(bitint), s0++, s1++) { + const bitint eq = (*s0 ^ first) | (*s1 ^ last); + bitint zeros = ((~eq & MASK2) + MASK1) & (~eq & MASK3); + size_t j = 0; + + while (zeros) { + if (zeros & 0x80) { + const char* substr = (char*)s0 + j + 1; + if (memcmp(substr, xs + 1, m - 2) == 0) { + return i + j; + } + } + + zeros >>= 8; + j += 1; + } + } + return -1; +} + static inline mrb_int mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) { @@ -625,6 +689,9 @@ mrb_memsearch(const char *x0, mrb_int m, const char *y0, mrb_int n) } return -1; } + if (m <= MAX_PATLEN) { + return mrb_memsearch_ss((const unsigned char*)x0, m, (const unsigned char*)y0, n); + } return mrb_memsearch_qs((const unsigned char*)x0, m, (const unsigned char*)y0, n); } From 06d9a54760f61846d0d1c12a617c72cf79476abf Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 27 Jan 2024 00:01:47 +0900 Subject: [PATCH 081/117] string.c (mrb_memsearch): remove simple search and quick search Since mrb_memsearch_ss() is fast enough for most of the cases, we try to simplify the code. --- src/string.c | 49 +------------------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/string.c b/src/string.c index 56a48f3c1..5c3ef90cd 100644 --- a/src/string.c +++ b/src/string.c @@ -576,9 +576,6 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) static inline mrb_int mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n) { -/* maximum pattern length */ -#define MAX_PATLEN 100 - #ifdef MRB_64BIT #define bitint uint64_t #define MASK1 0x0101010101010101llu @@ -628,32 +625,6 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long return -1; } -static inline mrb_int -mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) -{ - const unsigned char *y = ys; - ptrdiff_t qstable[256]; - - /* Preprocessing */ - for (int i = 0; i < 256; i++) - qstable[i] = m + 1; - - const unsigned char *x = xs, *xe = xs + m; - for (; x < xe; x++) - qstable[*x] = xe - x; - - /* Searching */ - for (; y + m <= ys + n; y += qstable[y[m]]) { - if (*xs == *y && memcmp(xs, y, m) == 0) - return (mrb_int)(y - ys); - } - return -1; -} - -#ifndef MRB_SEARCH_SHORT_STRING_LENGTH -#define MRB_SEARCH_SHORT_STRING_LENGTH 2048 -#endif - static mrb_int mrb_memsearch(const char *x0, mrb_int m, const char *y0, mrb_int n) { @@ -674,25 +645,7 @@ mrb_memsearch(const char *x0, mrb_int m, const char *y0, mrb_int n) else return -1; } - if (n + m < MRB_SEARCH_SHORT_STRING_LENGTH) { - const unsigned char *ys = (unsigned char*)y0; - const unsigned char *y = ys; - const unsigned char *ye = ys+n-m+1; - - for (;;) { - y = (const unsigned char*)memchr(y, x[0], (size_t)(ye-y)); - if (y == NULL) return -1; - if (memcmp(x, y, m) == 0) { - return (mrb_int)(y - ys); - } - y++; - } - return -1; - } - if (m <= MAX_PATLEN) { - return mrb_memsearch_ss((const unsigned char*)x0, m, (const unsigned char*)y0, n); - } - return mrb_memsearch_qs((const unsigned char*)x0, m, (const unsigned char*)y0, n); + return mrb_memsearch_ss((const unsigned char*)x0, m, (const unsigned char*)y0, n); } static void From dee1ded7b5f047f08aa4cc9a71dcdf0d8c3e7fe9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 27 Jan 2024 06:23:16 +0900 Subject: [PATCH 082/117] string.c (mrb_memsearch_ss): support bigendians --- src/string.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 5c3ef90cd..d0805758a 100644 --- a/src/string.c +++ b/src/string.c @@ -572,6 +572,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) * takes unsigned char* * returns mrb_int * alignment adjustment added + * support bigendian CPU */ static inline mrb_int mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n) @@ -587,6 +588,15 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long #define MASK2 0x7f7f7f7flu #define MASK3 0x80808080lu #endif +#if defined(MRB_ENDIAN_BIG) +#ifdef MRB_64BIT +#define MASK4 0x8000000000000000llu +#else +#define MASK4 0x80000000 +#endif +#else +#define MASK4 0x80 +#endif #if ALIGNED_WORD_ACCESS if ((uintptr_t)ys % sizeof(bitint)) { @@ -611,14 +621,18 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long size_t j = 0; while (zeros) { - if (zeros & 0x80) { + if (zeros & MASK4) { const char* substr = (char*)s0 + j + 1; if (memcmp(substr, xs + 1, m - 2) == 0) { return i + j; } } +#if defined(MRB_ENDIAN_BIG) + zeros <<= 8; +#else zeros >>= 8; +#endif j += 1; } } From e859b430cc74ccc14ad3e97c4178c944dde55318 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 27 Jan 2024 11:59:29 +0900 Subject: [PATCH 083/117] fixup! string.c (search_nonascii): add faster search using SSE2 --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index d0805758a..3642dfbe6 100644 --- a/src/string.c +++ b/src/string.c @@ -294,7 +294,7 @@ search_nonascii(const char* p, const char *e) static inline const char * search_nonascii(const char *p, const char *e) { - if (sizeof(__m128i) < e - p) { + if (sizeof(__m128i) < (size_t)(e - p)) { if (!_mm_movemask_epi8(_mm_loadu_si128((__m128i const*)p))) { const intptr_t lowbits = sizeof(__m128i) - 1; const __m128i *s, *t; From 60dd6b55860a04dcb7fe3325fffb1fbd703e13b8 Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 29 Jan 2024 21:32:04 +0900 Subject: [PATCH 084/117] Allow to detect use-after-free after `mrb_irep_free()` for debugging Write invalid value to `irep` if `MRB_DEBUG` is defined by `MRuby::Build#enable_debug`. --- src/state.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/state.c b/src/state.c index ced96cb88..35ea71e2d 100644 --- a/src/state.c +++ b/src/state.c @@ -161,6 +161,9 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) } mrb_free(mrb, (void*)irep->lv); mrb_debug_info_free(mrb, irep->debug_info); +#ifdef MRB_DEBUG + memset(irep, -1, sizeof(*irep)); +#endif mrb_free(mrb, irep); } From d8e1aed6465b23b6b2f89386c3e524bdd49ff78b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 28 Jan 2024 23:35:46 +0900 Subject: [PATCH 085/117] string.c (search_nonascii): need not to check n>3 on 32bit platforms --- src/string.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/string.c b/src/string.c index 3642dfbe6..380a34c16 100644 --- a/src/string.c +++ b/src/string.c @@ -369,10 +369,12 @@ search_nonascii(const char *p, const char *e) if (NOASCII(p[1])) return p+1; if (NOASCII(p[2])) return p+2; if (NOASCII(p[3])) return p+3; +#ifdef MRB_64BIT if (NOASCII(p[4])) return p+4; if (NOASCII(p[5])) return p+5; if (NOASCII(p[6])) return p+6; if (NOASCII(p[7])) return p+7; +#endif } } } From be5448fd16128d92b73fb17c32e4c729e0b23f06 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 29 Jan 2024 22:17:04 +0900 Subject: [PATCH 086/117] string.c (mrb_memsearch): refactor m==1 (use memchr) case --- src/string.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/string.c b/src/string.c index 380a34c16..1c46a9843 100644 --- a/src/string.c +++ b/src/string.c @@ -654,12 +654,10 @@ mrb_memsearch(const char *x0, mrb_int m, const char *y0, mrb_int n) return 0; } else if (m == 1) { - const unsigned char *ys = (const unsigned char*)memchr(y, *x, n); + const unsigned char *p = (const unsigned char*)memchr(y, *x, n); - if (ys) - return (mrb_int)(ys - y); - else - return -1; + if (p) return (mrb_int)(p - y); + return -1; } return mrb_memsearch_ss((const unsigned char*)x0, m, (const unsigned char*)y0, n); } From 44a5882bc2fd070dc3fe34b2da779ec21dd2c98f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 30 Jan 2024 23:27:14 +0900 Subject: [PATCH 087/117] string.c (mrb_memsearch_ss): remove useless alignment adjustment Ref #6158 --- src/string.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/string.c b/src/string.c index 1c46a9843..bafb31a56 100644 --- a/src/string.c +++ b/src/string.c @@ -600,17 +600,6 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long #define MASK4 0x80 #endif -#if ALIGNED_WORD_ACCESS - if ((uintptr_t)ys % sizeof(bitint)) { - int l = sizeof(bitint) - (bitint)ys % sizeof(bitint); - const unsigned char *p = (unsigned char*)memchr(ys, *xs, l); - if (p && (p - ys) < m) { - if (memcmp(p, xs, m) == 0) return (mrb_int)(p - ys); - ys = p; - } - } -#endif - const bitint first = MASK1 * (uint8_t)xs[0]; const bitint last = MASK1 * (uint8_t)xs[m-1]; From 6ba65ea0f005a79916102827908dc776bb9e2a5e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 30 Jan 2024 23:54:31 +0900 Subject: [PATCH 088/117] string.c (mrb_memsearch_ss): update comment --- src/string.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/string.c b/src/string.c index bafb31a56..2bed98341 100644 --- a/src/string.c +++ b/src/string.c @@ -566,10 +566,9 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str((mrb), (str), (sub), (pos)) #endif -/* The function is taken from https://github.com/WojciechMula/sse4-strstr.git */ -/* The original source code is under 2 clause BSD license; see LEGAL file. */ +/* The function is taken from http://0x80.pl/articles/simd-strfind.html */ +/* The original source code is under 2-clause BSD license; see LEGAL file. */ /* The modifications: - * port from C++ to C * takes unsigned char* * returns mrb_int From 219cfd63e151360efe664728e3b5dbcf6e102d44 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 31 Jan 2024 07:42:52 +0900 Subject: [PATCH 089/117] string.c (mrb_memsearch_ss): update integer prefixes (LLU -> ULL) --- src/string.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/string.c b/src/string.c index 2bed98341..5044c1d50 100644 --- a/src/string.c +++ b/src/string.c @@ -580,20 +580,20 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long { #ifdef MRB_64BIT #define bitint uint64_t -#define MASK1 0x0101010101010101llu -#define MASK2 0x7f7f7f7f7f7f7f7fllu -#define MASK3 0x8080808080808080llu +#define MASK1 0x0101010101010101ull +#define MASK2 0x7f7f7f7f7f7f7f7full +#define MASK3 0x8080808080808080ull #else #define bitint uint32_t -#define MASK1 0x01010101lu -#define MASK2 0x7f7f7f7flu -#define MASK3 0x80808080lu +#define MASK1 0x01010101ul +#define MASK2 0x7f7f7f7ful +#define MASK3 0x80808080ul #endif #if defined(MRB_ENDIAN_BIG) #ifdef MRB_64BIT -#define MASK4 0x8000000000000000llu +#define MASK4 0x8000000000000000ull #else -#define MASK4 0x80000000 +#define MASK4 0x80000000ul #endif #else #define MASK4 0x80 From e61a2881a7c9adc895416fdd409e7362130198d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 31 Jan 2024 07:44:40 +0900 Subject: [PATCH 090/117] string.c (mrb_memsearch_ss): fix potential buffer overflow; fix #6158 - stop using `bigint*` - stop integer pointer dereferences - use `memcpy` to integer variables - add reminder search for shorter patterns --- src/string.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/string.c b/src/string.c index 5044c1d50..b7e182085 100644 --- a/src/string.c +++ b/src/string.c @@ -574,6 +574,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) * returns mrb_int * alignment adjustment added * support bigendian CPU + * fixed potential buffer overflow */ static inline mrb_int mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n) @@ -599,22 +600,33 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long #define MASK4 0x80 #endif +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + const bitint first = MASK1 * (uint8_t)xs[0]; const bitint last = MASK1 * (uint8_t)xs[m-1]; - bitint *s0 = (bitint*)(ys); - bitint *s1 = (bitint*)(ys+m-1); + const unsigned char *s0 = ys; + const unsigned char *s1 = ys+m-1; - for (mrb_int i=0; i < n; i+=sizeof(bitint), s0++, s1++) { - const bitint eq = (*s0 ^ first) | (*s1 ^ last); + const mrb_int lim = n - MAX(m, (mrb_int)sizeof(bitint)); + mrb_int i; + + for (i=0; i < lim; i+=sizeof(bitint)) { + bitint t0, t1; + + memcpy(&t0, s0+i, sizeof(bitint)); + memcpy(&t1, s1+i, sizeof(bitint)); + + const bitint eq = (t0 ^ first) | (t1 ^ last); bitint zeros = ((~eq & MASK2) + MASK1) & (~eq & MASK3); size_t j = 0; while (zeros) { if (zeros & MASK4) { - const char* substr = (char*)s0 + j + 1; - if (memcmp(substr, xs + 1, m - 2) == 0) { - return i + j; + const mrb_int idx = i + j; + const unsigned char* p = s0 + idx + 1; + if (memcmp(p, xs + 1, m - 2) == 0) { + return idx; } } @@ -623,9 +635,21 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long #else zeros >>= 8; #endif - j += 1; + j++; } } + + if (i+m < n) { + const unsigned char *p = s0; + const unsigned char *e = ys + n; + for (;p Date: Wed, 31 Jan 2024 15:06:04 +0900 Subject: [PATCH 091/117] string.c: remove unnecessary type casts We don't need `unsigned` for string pointers. --- src/string.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/string.c b/src/string.c index b7e182085..3ef547e36 100644 --- a/src/string.c +++ b/src/string.c @@ -577,7 +577,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) * fixed potential buffer overflow */ static inline mrb_int -mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long n) +mrb_memsearch_ss(const char *xs, long m, const char *ys, long n) { #ifdef MRB_64BIT #define bitint uint64_t @@ -605,8 +605,8 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long const bitint first = MASK1 * (uint8_t)xs[0]; const bitint last = MASK1 * (uint8_t)xs[m-1]; - const unsigned char *s0 = ys; - const unsigned char *s1 = ys+m-1; + const char *s0 = ys; + const char *s1 = ys+m-1; const mrb_int lim = n - MAX(m, (mrb_int)sizeof(bitint)); mrb_int i; @@ -624,7 +624,7 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long while (zeros) { if (zeros & MASK4) { const mrb_int idx = i + j; - const unsigned char* p = s0 + idx + 1; + const char* p = s0 + idx + 1; if (memcmp(p, xs + 1, m - 2) == 0) { return idx; } @@ -640,10 +640,10 @@ mrb_memsearch_ss(const unsigned char *xs, long m, const unsigned char *ys, long } if (i+m < n) { - const unsigned char *p = s0; - const unsigned char *e = ys + n; + const char *p = s0; + const char *e = ys + n; for (;p n) return -1; else if (m == n) { - return memcmp(x0, y0, m) == 0 ? 0 : -1; + return memcmp(x, y, m) == 0 ? 0 : -1; } else if (m < 1) { return 0; } else if (m == 1) { - const unsigned char *p = (const unsigned char*)memchr(y, *x, n); + const char *p = (const char*)memchr(y, *x, n); if (p) return (mrb_int)(p - y); return -1; } - return mrb_memsearch_ss((const unsigned char*)x0, m, (const unsigned char*)y0, n); + return mrb_memsearch_ss(x, m, y, n); } static void From d8144aef789d096af719136c0f29089575d370fe Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 31 Jan 2024 21:34:54 +0900 Subject: [PATCH 092/117] string.c: remove a comment regarding `unsigned char*` --- src/string.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/string.c b/src/string.c index 3ef547e36..5ce969474 100644 --- a/src/string.c +++ b/src/string.c @@ -570,7 +570,6 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) /* The original source code is under 2-clause BSD license; see LEGAL file. */ /* The modifications: * port from C++ to C - * takes unsigned char* * returns mrb_int * alignment adjustment added * support bigendian CPU From f8527f06709df046bf42fecf4aa9318a49301152 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 31 Jan 2024 21:36:05 +0900 Subject: [PATCH 093/117] string.c (mrb_memsearch_ss): update a comment regarding alignment issue --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 5ce969474..7d4810789 100644 --- a/src/string.c +++ b/src/string.c @@ -571,7 +571,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) /* The modifications: * port from C++ to C * returns mrb_int - * alignment adjustment added + * remove alignment issue * support bigendian CPU * fixed potential buffer overflow */ From cac698fe881ef24d07d59611a41485653247bec7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 31 Jan 2024 21:37:39 +0900 Subject: [PATCH 094/117] string.c (memsearch_swar): changed the function name For your information, SWAR stands for SIMD within a register. --- src/string.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/string.c b/src/string.c index 7d4810789..05fa1dbd0 100644 --- a/src/string.c +++ b/src/string.c @@ -566,8 +566,10 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) #define str_index_str_by_char(mrb, str, sub, pos) str_index_str((mrb), (str), (sub), (pos)) #endif -/* The function is taken from http://0x80.pl/articles/simd-strfind.html */ -/* The original source code is under 2-clause BSD license; see LEGAL file. */ +/* memsearch_swar (SWAR stands for SIMD within a register) */ +/* See https://en.wikipedia.org/wiki/SWAR */ +/* The function is taken from http://0x80.pl/articles/simd-strfind.html */ +/* The original source code is under 2-clause BSD license; see LEGAL file. */ /* The modifications: * port from C++ to C * returns mrb_int @@ -576,7 +578,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) * fixed potential buffer overflow */ static inline mrb_int -mrb_memsearch_ss(const char *xs, long m, const char *ys, long n) +memsearch_swar(const char *xs, long m, const char *ys, long n) { #ifdef MRB_64BIT #define bitint uint64_t @@ -668,7 +670,7 @@ mrb_memsearch(const char *x, mrb_int m, const char *y, mrb_int n) if (p) return (mrb_int)(p - y); return -1; } - return mrb_memsearch_ss(x, m, y, n); + return memsearch_swar(x, m, y, n); } static void From 9543cfa7ee5ff983aefc155537b9b933459aa11d Mon Sep 17 00:00:00 2001 From: dearblue Date: Wed, 31 Jan 2024 22:17:16 +0900 Subject: [PATCH 095/117] Fixed use-after-free by backtrace object The `MRB_TT_BACKTRACE` object has been added for the purpose. Previously, "use-after-free" could occur because the reference count in `backtrace_location::irep` was not incremented. fixed #6160 --- include/mruby/internal.h | 12 ++++++ include/mruby/value.h | 3 +- mrbgems/mruby-os-memsize/src/memsize.c | 4 ++ src/backtrace.c | 60 ++++++++++++-------------- src/gc.c | 19 ++++++++ 5 files changed, 64 insertions(+), 34 deletions(-) diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 37c6fa1f0..11b15d057 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -61,6 +61,18 @@ mrb_value mrb_exc_mesg_get(mrb_state *mrb, struct RException *exc); mrb_value mrb_f_raise(mrb_state*, mrb_value); mrb_value mrb_make_exception(mrb_state *mrb, mrb_value exc, mrb_value mesg); +struct RBacktrace { + MRB_OBJECT_HEADER; + size_t len; + struct mrb_backtrace_location *locations; +}; + +struct mrb_backtrace_location { + mrb_sym method_id; + int32_t idx; + const struct RProc *proc; +}; + /* gc */ void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); diff --git a/include/mruby/value.h b/include/mruby/value.h index 71cdaca35..16da2cbd4 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -159,7 +159,8 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000; f(MRB_TT_BREAK, struct RBreak, "break") \ f(MRB_TT_COMPLEX, struct RComplex, "Complex") \ f(MRB_TT_RATIONAL, struct RRational, "Rational") \ - f(MRB_TT_BIGINT, struct RBigint, "Integer") + f(MRB_TT_BIGINT, struct RBigint, "Integer") \ + f(MRB_TT_BACKTRACE, struct RBacktrace, "backtrace") enum mrb_vtype { #define MRB_VTYPE_DEFINE(tt, type, name) tt, diff --git a/mrbgems/mruby-os-memsize/src/memsize.c b/mrbgems/mruby-os-memsize/src/memsize.c index 10f77beea..8ffd313ed 100644 --- a/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mrbgems/mruby-os-memsize/src/memsize.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -167,6 +168,9 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_ISTRUCT: size += mrb_objspace_page_slot_size(); break; + case MRB_TT_BACKTRACE: + size += ((struct RBacktrace*)mrb_obj_ptr(obj))->len * sizeof(struct mrb_backtrace_location); + break; /* zero heap size types. * immediate VM stack values, contained within mrb_state, or on C stack */ case MRB_TT_TRUE: diff --git a/src/backtrace.c b/src/backtrace.c index 816b0e6db..ebdfb6f29 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -17,15 +17,7 @@ #include #include -struct backtrace_location { - mrb_sym method_id; - int32_t idx; - const mrb_irep *irep; -}; - -typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*, void*); - -static const mrb_data_type bt_type = { "Backtrace", mrb_free }; +typedef void (*each_backtrace_func)(mrb_state*, const struct mrb_backtrace_location*, void*); static uint32_t each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) @@ -33,7 +25,7 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * uint32_t n = 0; for (ptrdiff_t i=ciidx; i >= 0; i--) { - struct backtrace_location loc; + struct mrb_backtrace_location loc; mrb_callinfo *ci; const mrb_code *pc; @@ -41,22 +33,22 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * if (!ci->proc || MRB_PROC_CFUNC_P(ci->proc)) { if (!ci->mid) continue; - loc.irep = NULL; + loc.proc = NULL; } else { - loc.irep = ci->proc->body.irep; - if (!loc.irep) continue; - if (!loc.irep->debug_info) continue; + loc.proc = ci->proc; + if (!loc.proc->body.irep) continue; + if (!loc.proc->body.irep->debug_info) continue; if (mrb->c->cibase[i].pc) { pc = &mrb->c->cibase[i].pc[-1]; } else { continue; } - loc.idx = (uint32_t)(pc - loc.irep->iseq); + loc.idx = (uint32_t)(pc - loc.proc->body.irep->iseq); } loc.method_id = ci->mid; - if (loc.irep == NULL) { + if (loc.proc == NULL) { for (ptrdiff_t j=i-1; j >= 0; j--) { ci = &mrb->c->cibase[j]; @@ -74,8 +66,8 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * continue; } - loc.irep = irep; - loc.idx = (uint32_t)(pc - loc.irep->iseq); + loc.proc = ci->proc; + loc.idx = (uint32_t)(pc - irep->iseq); break; } } @@ -87,11 +79,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * static void pack_backtrace_i(mrb_state *mrb, - const struct backtrace_location *loc, + const struct mrb_backtrace_location *loc, void *data) { - struct backtrace_location **pptr = (struct backtrace_location**)data; - struct backtrace_location *ptr = *pptr; + struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; + struct mrb_backtrace_location *ptr = *pptr; *ptr = *loc; *pptr = ptr+1; @@ -100,7 +92,7 @@ pack_backtrace_i(mrb_state *mrb, static struct RObject* packed_backtrace(mrb_state *mrb) { - struct RData *backtrace; + struct RBacktrace *backtrace; ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase; if (ciidx >= mrb->c->ciend - mrb->c->cibase) @@ -108,16 +100,16 @@ packed_backtrace(mrb_state *mrb) /* count the number of backtraces */ int len = each_backtrace(mrb, ciidx, NULL, NULL); - backtrace = mrb_data_object_alloc(mrb, NULL, NULL, &bt_type); + backtrace = MRB_OBJ_ALLOC(mrb, MRB_TT_BACKTRACE, NULL); if (len > 0) { - void *ptr = mrb_malloc(mrb, len * sizeof(struct backtrace_location)); - backtrace->data = ptr; - backtrace->flags = len; + void *ptr = mrb_malloc(mrb, len * sizeof(struct mrb_backtrace_location)); + backtrace->locations = (struct mrb_backtrace_location*)ptr; + backtrace->len = len; each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); } else { - backtrace->data = NULL; - backtrace->flags = 0; + backtrace->locations = NULL; + backtrace->len = 0; } return (struct RObject*)backtrace; } @@ -146,7 +138,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) static struct RObject* mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { - const struct backtrace_location *bt; + const struct mrb_backtrace_location *bt; mrb_int n, i; int ai; @@ -155,19 +147,21 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0)); } if (backtrace->tt == MRB_TT_ARRAY) return backtrace; - bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, mrb_obj_value(backtrace), &bt_type); + mrb_assert(backtrace->tt == MRB_TT_BACKTRACE); + struct RBacktrace *btobj = (struct RBacktrace*)backtrace; + bt = btobj->locations; if (bt == NULL) goto empty_backtrace; - n = (mrb_int)backtrace->flags; + n = (mrb_int)btobj->len; if (n == 0) goto empty_backtrace; backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); ai = mrb_gc_arena_save(mrb); for (i = 0; i < n; i++) { - const struct backtrace_location *entry = &bt[i]; + const struct mrb_backtrace_location *entry = &bt[i]; mrb_value btline; int32_t lineno; const char *filename; - if (!mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { + if (!entry->proc || !mrb_debug_get_position(mrb, entry->proc->body.irep, entry->idx, &lineno, &filename)) { btline = mrb_str_new_lit(mrb, "(unknown):0"); } else if (lineno != -1) {//debug info was available diff --git a/src/gc.c b/src/gc.c index 39f63c62b..685f2b055 100644 --- a/src/gc.c +++ b/src/gc.c @@ -688,6 +688,15 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->backtrace); break; + case MRB_TT_BACKTRACE: + { + struct RBacktrace *bt = (struct RBacktrace*)obj; + for (size_t i = 0; i < bt->len; i++) { + mrb_gc_mark(mrb, (struct RBasic*)bt->locations[i].proc); + } + } + break; + default: break; } @@ -823,6 +832,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) break; #endif + case MRB_TT_BACKTRACE: + { + struct RBacktrace *bt = (struct RBacktrace*)obj; + mrb_free(mrb, bt->locations); + } + default: break; } @@ -969,6 +984,10 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) } break; + case MRB_TT_BACKTRACE: + children += ((struct RBacktrace*)obj)->len; + break; + default: break; } From a0bcf63bd53ec6bdce0d2cb07a4e41ac0fbb7bc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:23:26 +0000 Subject: [PATCH 096/117] build(deps): bump super-linter/super-linter from 5.7.2 to 6.0.0 Bumps [super-linter/super-linter](https://github.com/super-linter/super-linter) from 5.7.2 to 6.0.0. - [Release notes](https://github.com/super-linter/super-linter/releases) - [Changelog](https://github.com/super-linter/super-linter/blob/main/CHANGELOG.md) - [Commits](https://github.com/super-linter/super-linter/compare/v5.7.2...v6.0.0) --- updated-dependencies: - dependency-name: super-linter/super-linter dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/super-linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index d250a7f98..1f2004623 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -20,7 +20,7 @@ jobs: # Full git history is needed to get a proper list of changed files within `super-linter` fetch-depth: 0 - name: Lint Code Base - uses: super-linter/super-linter/slim@v5.7.2 + uses: super-linter/super-linter/slim@v6.0.0 env: ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true From 08c422c7ee83d293f4dcf06eb862ba77e3670546 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 2 Feb 2024 14:18:57 +0900 Subject: [PATCH 097/117] numeric.c (cmpnum): support fixnum cmp bignum; fix #6163 --- src/numeric.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/numeric.c b/src/numeric.c index 9a84fabd2..41951e6bc 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -2025,6 +2025,9 @@ cmpnum(mrb_state *mrb, mrb_value v1, mrb_value v2) if (mrb_bigint_p(v1)) { return mrb_bint_cmp(mrb, v1, v2); } + if (mrb_bigint_p(v2)) { + return mrb_bint_cmp(mrb, mrb_bint_new_int(mrb, mrb_integer(v1)), v2); + } #endif #ifdef MRB_NO_FLOAT From 8e04e76325dc3d33a0ad663663d536b92f26d465 Mon Sep 17 00:00:00 2001 From: John Bampton Date: Fri, 2 Feb 2024 15:50:44 +1000 Subject: [PATCH 098/117] super-linter: remove `ERROR_ON_MISSING_EXEC_BIT` check https://github.com/super-linter/super-linter/releases/tag/v6.0.0 https://github.com/super-linter/super-linter/pull/5120 --- .github/workflows/super-linter.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 1f2004623..054b12f14 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -22,7 +22,6 @@ jobs: - name: Lint Code Base uses: super-linter/super-linter/slim@v6.0.0 env: - ERROR_ON_MISSING_EXEC_BIT: true VALIDATE_BASH: true # VALIDATE_BASH_EXEC: true # VALIDATE_EDITORCONFIG: true From 2f63b49542a1956f1ba20610862fdddca5bb9d47 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 4 Feb 2024 16:46:09 +0900 Subject: [PATCH 099/117] backtrace.c: use `mrb_irep` references instead of `struct RProc` To reduce GC burden (no mark needed). We use `mrb_irep_incref()` and `mrb_irep_decref()` instead to track irep memory usage; ref #6161 --- include/mruby/internal.h | 2 +- src/backtrace.c | 19 +++++++++++-------- src/gc.c | 12 +++--------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/mruby/internal.h b/include/mruby/internal.h index 11b15d057..a2948961a 100644 --- a/include/mruby/internal.h +++ b/include/mruby/internal.h @@ -70,7 +70,7 @@ struct RBacktrace { struct mrb_backtrace_location { mrb_sym method_id; int32_t idx; - const struct RProc *proc; + const mrb_irep *irep; }; /* gc */ diff --git a/src/backtrace.c b/src/backtrace.c index ebdfb6f29..f4ec6999a 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -33,22 +33,22 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * if (!ci->proc || MRB_PROC_CFUNC_P(ci->proc)) { if (!ci->mid) continue; - loc.proc = NULL; + loc.irep = NULL; } else { - loc.proc = ci->proc; - if (!loc.proc->body.irep) continue; - if (!loc.proc->body.irep->debug_info) continue; + loc.irep = ci->proc->body.irep; + if (!loc.irep) continue; + if (!loc.irep->debug_info) continue; if (mrb->c->cibase[i].pc) { pc = &mrb->c->cibase[i].pc[-1]; } else { continue; } - loc.idx = (uint32_t)(pc - loc.proc->body.irep->iseq); + loc.idx = (uint32_t)(pc - loc.irep->iseq); } loc.method_id = ci->mid; - if (loc.proc == NULL) { + if (loc.irep == NULL) { for (ptrdiff_t j=i-1; j >= 0; j--) { ci = &mrb->c->cibase[j]; @@ -66,7 +66,7 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * continue; } - loc.proc = ci->proc; + loc.irep = irep; loc.idx = (uint32_t)(pc - irep->iseq); break; } @@ -85,6 +85,9 @@ pack_backtrace_i(mrb_state *mrb, struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; struct mrb_backtrace_location *ptr = *pptr; + if (loc->irep) { + mrb_irep_incref(mrb, (mrb_irep*)loc->irep); + } *ptr = *loc; *pptr = ptr+1; } @@ -161,7 +164,7 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) int32_t lineno; const char *filename; - if (!entry->proc || !mrb_debug_get_position(mrb, entry->proc->body.irep, entry->idx, &lineno, &filename)) { + if (!entry->irep || !mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { btline = mrb_str_new_lit(mrb, "(unknown):0"); } else if (lineno != -1) {//debug info was available diff --git a/src/gc.c b/src/gc.c index 685f2b055..63d3f1678 100644 --- a/src/gc.c +++ b/src/gc.c @@ -688,15 +688,6 @@ gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) mrb_gc_mark(mrb, (struct RBasic*)((struct RException*)obj)->backtrace); break; - case MRB_TT_BACKTRACE: - { - struct RBacktrace *bt = (struct RBacktrace*)obj; - for (size_t i = 0; i < bt->len; i++) { - mrb_gc_mark(mrb, (struct RBasic*)bt->locations[i].proc); - } - } - break; - default: break; } @@ -835,6 +826,9 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) case MRB_TT_BACKTRACE: { struct RBacktrace *bt = (struct RBacktrace*)obj; + for (size_t i = 0; i < bt->len; i++) { + mrb_irep_decref(mrb, (mrb_irep*)bt->locations[i].irep); + } mrb_free(mrb, bt->locations); } From f04a729dc93f6f34bc6aec019bdfd820ff32f1a9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 4 Feb 2024 17:06:05 +0900 Subject: [PATCH 100/117] gc.c (obj_free): check if irep is NULL before mrb_irep_decref(); #6161 --- src/gc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gc.c b/src/gc.c index 63d3f1678..a39d4e47f 100644 --- a/src/gc.c +++ b/src/gc.c @@ -827,7 +827,9 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) { struct RBacktrace *bt = (struct RBacktrace*)obj; for (size_t i = 0; i < bt->len; i++) { - mrb_irep_decref(mrb, (mrb_irep*)bt->locations[i].irep); + const mrb_irep *irep = bt->locations[i].irep; + if (irep == NULL) continue; + mrb_irep_decref(mrb, (mrb_irep*)irep); } mrb_free(mrb, bt->locations); } From dde5fe3a60e15fe76ef89f40b97de61c69e5ff2d Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 4 Feb 2024 21:55:53 +0900 Subject: [PATCH 101/117] Reduce `RVALUE` related pointer casts. --- src/gc.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/gc.c b/src/gc.c index a39d4e47f..4aa425ba2 100644 --- a/src/gc.c +++ b/src/gc.c @@ -107,9 +107,11 @@ */ +typedef struct RVALUE RVALUE; + struct free_obj { MRB_OBJECT_HEADER; - struct RBasic *next; + RVALUE *next; }; struct RVALUE_initializer { @@ -117,7 +119,7 @@ struct RVALUE_initializer { char padding[sizeof(void*) * 4 - sizeof(uint32_t)]; }; -typedef struct { +struct RVALUE { union { struct RVALUE_initializer init; /* must be first member to ensure initialization */ struct free_obj free; @@ -136,7 +138,7 @@ typedef struct { struct RException exc; struct RBreak brk; } as; -} RVALUE; +}; #ifdef GC_DEBUG #define DEBUG(x) (x) @@ -149,7 +151,7 @@ typedef struct { #endif typedef struct mrb_heap_page { - struct RBasic *freelist; + RVALUE *freelist; struct mrb_heap_page *next; struct mrb_heap_page *free_next; mrb_bool old:1; @@ -301,12 +303,12 @@ add_heap(mrb_state *mrb, mrb_gc *gc) { mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); RVALUE *p, *e; - struct RBasic *prev = NULL; + RVALUE *prev = NULL; for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt = MRB_TT_FREE; p->as.free.next = prev; - prev = &p->as.basic; + prev = p; } page->freelist = prev; @@ -498,19 +500,19 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) add_heap(mrb, gc); } - struct RBasic *p = gc->free_heaps->freelist; - gc->free_heaps->freelist = ((struct free_obj*)p)->next; + RVALUE *p = gc->free_heaps->freelist; + gc->free_heaps->freelist = p->as.free.next; if (gc->free_heaps->freelist == NULL) { gc->free_heaps = gc->free_heaps->free_next; } gc->live++; - gc_protect(mrb, gc, p); - *(RVALUE*)p = RVALUE_zero; - p->tt = ttype; - p->c = cls; - paint_partial_white(gc, p); - return p; + gc_protect(mrb, gc, &p->as.basic); + *p = RVALUE_zero; + p->as.basic.tt = ttype; + p->as.basic.c = cls; + paint_partial_white(gc, &p->as.basic); + return &p->as.basic; } static inline void @@ -1095,7 +1097,7 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) obj_free(mrb, &p->as.basic, FALSE); if (p->as.basic.tt == MRB_TT_FREE) { p->as.free.next = page->freelist; - page->freelist = (struct RBasic*)p; + page->freelist = p; freed++; } else { From 84fbe63457a126c56afbd5eddc5098661390974d Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 4 Feb 2024 21:55:54 +0900 Subject: [PATCH 102/117] Change the `end` parameter of `obj_free()` to a boolean type The caller is a boolean value from the first. --- src/gc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gc.c b/src/gc.c index a39d4e47f..9244af2e8 100644 --- a/src/gc.c +++ b/src/gc.c @@ -345,7 +345,7 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc) #endif } -static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); +static void obj_free(mrb_state *mrb, struct RBasic *obj, mrb_bool end); static void free_heap(mrb_state *mrb, mrb_gc *gc) @@ -704,7 +704,7 @@ mrb_gc_mark(mrb_state *mrb, struct RBasic *obj) } static void -obj_free(mrb_state *mrb, struct RBasic *obj, int end) +obj_free(mrb_state *mrb, struct RBasic *obj, mrb_bool end) { DEBUG(fprintf(stderr, "obj_free(%p,tt=%d)\n",obj,obj->tt)); switch (obj->tt) { From 8f14785f10988095a95ff1ac56ba215e8017d4e4 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 4 Feb 2024 21:55:54 +0900 Subject: [PATCH 103/117] Stop pseudo flexible array in `mrb_heap_page` For reference, the flexible array was introduced by commit 3ab2f9371e60039936356afaee9f509d782259fd (#2997). Subsequently changed for compatibility with C++ by commit 24939723d77291152298acc2fb6415b3d1fe2c24 (#5596). --- src/gc.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/gc.c b/src/gc.c index a39d4e47f..b5abd76a6 100644 --- a/src/gc.c +++ b/src/gc.c @@ -153,8 +153,7 @@ typedef struct mrb_heap_page { struct mrb_heap_page *next; struct mrb_heap_page *free_next; mrb_bool old:1; - /* Flexible array members are not C++ compatible */ - /* void* objects[]; */ + RVALUE objects[MRB_HEAP_PAGE_SIZE]; } mrb_heap_page; #define GC_STEP_SIZE 1024 @@ -181,12 +180,6 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); #define other_white_part(s) ((s)->current_white_part ^ GC_WHITES) #define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE) -/* We have removed `objects[]` from `mrb_heap_page` since it was not C++ - * compatible. Using array index to get pointer after structure instead. */ - -/* #define objects(p) ((RVALUE*)p->objects) */ -#define objects(p) ((RVALUE*)&p[1]) - mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); MRB_API void* @@ -279,7 +272,7 @@ heap_p(mrb_gc *gc, struct RBasic *object) while (page) { RVALUE *p; - p = objects(page); + p = page->objects; if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE - 1].as.basic) { return TRUE; } @@ -299,11 +292,11 @@ mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) static void add_heap(mrb_state *mrb, mrb_gc *gc) { - mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); + mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page)); RVALUE *p, *e; struct RBasic *prev = NULL; - for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; pobjects, e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt = MRB_TT_FREE; p->as.free.next = prev; prev = &p->as.basic; @@ -357,7 +350,7 @@ free_heap(mrb_state *mrb, mrb_gc *gc) while (page) { tmp = page; page = page->next; - for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; pobjects, e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt != MRB_TT_FREE) obj_free(mrb, &p->as.basic, TRUE); } @@ -1079,7 +1072,7 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) size_t tried_sweep = 0; while (page && (tried_sweep < limit)) { - RVALUE *p = objects(page); + RVALUE *p = page->objects; RVALUE *e = p + MRB_HEAP_PAGE_SIZE; size_t freed = 0; mrb_bool dead_slot = TRUE; @@ -1539,7 +1532,7 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, while (page != NULL) { RVALUE *p; - p = objects(page); + p = page->objects; for (int i=0; i < MRB_HEAP_PAGE_SIZE; i++) { if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) return; From 0fe95d6c81300b5a8681badcdae46a85f6e7033e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 5 Feb 2024 21:28:11 +0900 Subject: [PATCH 104/117] mruby-pack (mrb_pack_pack): avoid integer overflow `int` (32bit integer) may be too small on 64bit platforms. --- mrbgems/mruby-pack/src/pack.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mrbgems/mruby-pack/src/pack.c b/mrbgems/mruby-pack/src/pack.c index 743b8663b..8f61b0bb7 100644 --- a/mrbgems/mruby-pack/src/pack.c +++ b/mrbgems/mruby-pack/src/pack.c @@ -1495,19 +1495,17 @@ static mrb_value mrb_pack_pack(mrb_state *mrb, mrb_value ary) { mrb_value o, result; - mrb_int aidx; struct tmpl tmpl; - int count; + enum pack_type type; + int count, size; unsigned int flags; enum pack_dir dir; - enum pack_type type; - int ridx, size; prepare_tmpl(mrb, &tmpl); result = mrb_str_new(mrb, NULL, 128); /* allocate initial buffer */ - aidx = 0; - ridx = 0; + mrb_int aidx = 0; + mrb_int ridx = 0; while (has_tmpl(&tmpl)) { dir = read_tmpl(mrb, &tmpl, &type, &size, &count, &flags); From b67cea4442e06467127cbb2949f40c180a5f94b5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 6 Feb 2024 22:35:24 +0900 Subject: [PATCH 105/117] backtrace.c (pack_backtrace_i): avoid infinite loop; ref #6161 When irep->refcnt reaches UINT16_MAX, mrb_irep_incref() raises exception but the function pack_backtrace_i() is called from mrb_exc_raise() thus causes the infinite loop problem. So this is a hack-ish workaround by making irep reference to NULL if refcnt reaches the maximum count. Probably we will address this issue again to make it better. --- src/backtrace.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index f4ec6999a..a98b80004 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -85,10 +85,15 @@ pack_backtrace_i(mrb_state *mrb, struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; struct mrb_backtrace_location *ptr = *pptr; - if (loc->irep) { - mrb_irep_incref(mrb, (mrb_irep*)loc->irep); - } *ptr = *loc; + if (ptr->irep) { + if (ptr->irep->refcnt == UINT16_MAX) { + ptr->irep = NULL; + } + else { + mrb_irep_incref(mrb, (mrb_irep*)ptr->irep); + } + } *pptr = ptr+1; } From 0a112154522c26abf4f1be4cd8c1aa07364926b5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 7 Feb 2024 17:32:58 +0900 Subject: [PATCH 106/117] backtrace.c (packed_backtrace): avoid calling each_backtrace() twice Since the length of the backtrace is at most `ciidx + 1` we can avoid the first call of each_backtrace(). --- src/backtrace.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index a98b80004..83a5180ee 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -106,19 +106,14 @@ packed_backtrace(mrb_state *mrb) if (ciidx >= mrb->c->ciend - mrb->c->cibase) ciidx = mrb->c->ciend - mrb->c->cibase; /* ciidx is broken... */ - /* count the number of backtraces */ - int len = each_backtrace(mrb, ciidx, NULL, NULL); + ptrdiff_t len = ciidx + 1; + backtrace = MRB_OBJ_ALLOC(mrb, MRB_TT_BACKTRACE, NULL); - if (len > 0) { - void *ptr = mrb_malloc(mrb, len * sizeof(struct mrb_backtrace_location)); - backtrace->locations = (struct mrb_backtrace_location*)ptr; - backtrace->len = len; - each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); - } - else { - backtrace->locations = NULL; - backtrace->len = 0; - } + + void *ptr = mrb_malloc(mrb, len * sizeof(struct mrb_backtrace_location)); + backtrace->locations = (struct mrb_backtrace_location*)ptr; + backtrace->len = each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + return (struct RObject*)backtrace; } From 60919807e5846088abc3353f610ae4a5b31c94bd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 7 Feb 2024 17:34:33 +0900 Subject: [PATCH 107/117] backtrace.c (each_backtrace): make return type to `size_t` --- src/backtrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 83a5180ee..291b20893 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -19,10 +19,10 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct mrb_backtrace_location*, void*); -static uint32_t +static size_t each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { - uint32_t n = 0; + size_t n = 0; for (ptrdiff_t i=ciidx; i >= 0; i--) { struct mrb_backtrace_location loc; From 432caf0670687bb1b8d45489305e5bdd398af951 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 8 Feb 2024 23:22:48 +0900 Subject: [PATCH 108/117] backtrace.c (pack_backtrace): refactor the function that called once --- src/backtrace.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 291b20893..441159a5e 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -17,10 +17,28 @@ #include #include -typedef void (*each_backtrace_func)(mrb_state*, const struct mrb_backtrace_location*, void*); +static void +pack_backtrace_i(mrb_state *mrb, + const struct mrb_backtrace_location *loc, + void *data) +{ + struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; + struct mrb_backtrace_location *ptr = *pptr; + + *ptr = *loc; + if (ptr->irep) { + if (ptr->irep->refcnt == UINT16_MAX) { + ptr->irep = NULL; + } + else { + mrb_irep_incref(mrb, (mrb_irep*)ptr->irep); + } + } + *pptr = ptr+1; +} static size_t -each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) +pack_backtrace(mrb_state *mrb, ptrdiff_t ciidx, void *data) { size_t n = 0; @@ -71,32 +89,12 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void * break; } } - if (func) func(mrb, &loc, data); + pack_backtrace_i(mrb, &loc, data); n++; } return n; } -static void -pack_backtrace_i(mrb_state *mrb, - const struct mrb_backtrace_location *loc, - void *data) -{ - struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; - struct mrb_backtrace_location *ptr = *pptr; - - *ptr = *loc; - if (ptr->irep) { - if (ptr->irep->refcnt == UINT16_MAX) { - ptr->irep = NULL; - } - else { - mrb_irep_incref(mrb, (mrb_irep*)ptr->irep); - } - } - *pptr = ptr+1; -} - static struct RObject* packed_backtrace(mrb_state *mrb) { @@ -112,7 +110,7 @@ packed_backtrace(mrb_state *mrb) void *ptr = mrb_malloc(mrb, len * sizeof(struct mrb_backtrace_location)); backtrace->locations = (struct mrb_backtrace_location*)ptr; - backtrace->len = each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); + backtrace->len = pack_backtrace(mrb, ciidx, &ptr); return (struct RObject*)backtrace; } From 874f1e0138a72bd7dda30c66d3a1b1789b778808 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 8 Feb 2024 23:41:22 +0900 Subject: [PATCH 109/117] backtrace.c (copy_location): rename some function and arguments --- src/backtrace.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 441159a5e..604a9c84c 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -18,27 +18,24 @@ #include static void -pack_backtrace_i(mrb_state *mrb, +copy_backtrace(mrb_state *mrb, const struct mrb_backtrace_location *loc, - void *data) + struct mrb_backtrace_location *ptr, + size_t n) { - struct mrb_backtrace_location **pptr = (struct mrb_backtrace_location**)data; - struct mrb_backtrace_location *ptr = *pptr; - - *ptr = *loc; - if (ptr->irep) { - if (ptr->irep->refcnt == UINT16_MAX) { - ptr->irep = NULL; + ptr[n] = *loc; + if (loc->irep) { + if (loc->irep->refcnt == UINT16_MAX) { + ptr[n].irep = NULL; } else { - mrb_irep_incref(mrb, (mrb_irep*)ptr->irep); + mrb_irep_incref(mrb, (mrb_irep*)loc->irep); } } - *pptr = ptr+1; } static size_t -pack_backtrace(mrb_state *mrb, ptrdiff_t ciidx, void *data) +pack_backtrace(mrb_state *mrb, ptrdiff_t ciidx, struct mrb_backtrace_location *ptr) { size_t n = 0; @@ -89,7 +86,7 @@ pack_backtrace(mrb_state *mrb, ptrdiff_t ciidx, void *data) break; } } - pack_backtrace_i(mrb, &loc, data); + copy_backtrace(mrb, &loc, ptr, n); n++; } return n; @@ -110,7 +107,7 @@ packed_backtrace(mrb_state *mrb) void *ptr = mrb_malloc(mrb, len * sizeof(struct mrb_backtrace_location)); backtrace->locations = (struct mrb_backtrace_location*)ptr; - backtrace->len = pack_backtrace(mrb, ciidx, &ptr); + backtrace->len = pack_backtrace(mrb, ciidx, backtrace->locations); return (struct RObject*)backtrace; } From 868aeaf48c07479c0a33fb74b8886ae5bd6095f9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 9 Feb 2024 18:52:44 +0900 Subject: [PATCH 110/117] string.c (memsearch_swar): fixed a buffer overflow --- src/string.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/string.c b/src/string.c index 05fa1dbd0..19b5f9f39 100644 --- a/src/string.c +++ b/src/string.c @@ -644,8 +644,9 @@ memsearch_swar(const char *xs, long m, const char *ys, long n) const char *p = s0; const char *e = ys + n; for (;p Date: Fri, 9 Feb 2024 19:09:01 +0900 Subject: [PATCH 111/117] string.c (memsearch_swar): fixed a buffer overflow --- src/string.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/string.c b/src/string.c index 19b5f9f39..e214ad4c2 100644 --- a/src/string.c +++ b/src/string.c @@ -601,15 +601,13 @@ memsearch_swar(const char *xs, long m, const char *ys, long n) #define MASK4 0x80 #endif -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - const bitint first = MASK1 * (uint8_t)xs[0]; const bitint last = MASK1 * (uint8_t)xs[m-1]; const char *s0 = ys; const char *s1 = ys+m-1; - const mrb_int lim = n - MAX(m, (mrb_int)sizeof(bitint)); + const mrb_int lim = n - m - (mrb_int)sizeof(bitint); mrb_int i; for (i=0; i < lim; i+=sizeof(bitint)) { @@ -620,9 +618,9 @@ memsearch_swar(const char *xs, long m, const char *ys, long n) const bitint eq = (t0 ^ first) | (t1 ^ last); bitint zeros = ((~eq & MASK2) + MASK1) & (~eq & MASK3); - size_t j = 0; - while (zeros) { + + for (size_t j = 0; zeros; j++) { if (zeros & MASK4) { const mrb_int idx = i + j; const char* p = s0 + idx + 1; @@ -636,7 +634,6 @@ memsearch_swar(const char *xs, long m, const char *ys, long n) #else zeros >>= 8; #endif - j++; } } From 01ff7fbf0ae2c042093d423fc50f4ffff4b748a3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 10 Feb 2024 17:05:55 +0900 Subject: [PATCH 112/117] Update mruby3.3.md --- NEWS | 3 +++ doc/mruby3.3.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/NEWS b/NEWS index 4c5900b1e..7144b3a86 100644 --- a/NEWS +++ b/NEWS @@ -100,6 +100,9 @@ NEWS # Bugs Fixed +- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#\*\* is missing +- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code +- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error - [#5932](https://github.com/mruby/mruby/issues/5932) How to create a block using the C API? mrb_yield keeps crashing! - [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed - [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable diff --git a/doc/mruby3.3.md b/doc/mruby3.3.md index 560b6f02e..eec7732fb 100644 --- a/doc/mruby3.3.md +++ b/doc/mruby3.3.md @@ -97,6 +97,9 @@ # Bugs Fixed +- [#5724](https://github.com/mruby/mruby/issues/5724) Rational#\*\* is missing +- [#5725](https://github.com/mruby/mruby/issues/5725) weird const_missing exceptions in mrblib code +- [#5789](https://github.com/mruby/mruby/issues/5789) No memory release of backtrace information due to stack error - [#5932](https://github.com/mruby/mruby/issues/5932) How to create a block using the C API? mrb_yield keeps crashing! - [#5943](https://github.com/mruby/mruby/issues/5943) TCPSocket#write is failed - [#5944](https://github.com/mruby/mruby/issues/5944) Behavior of calling method with a hash variable From a3da9c1da3bcdc02a1827bb1f43aa0bb499cf467 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 11 Feb 2024 23:53:31 +0900 Subject: [PATCH 113/117] AUTHORS: update entries [ci skip] --- AUTHORS | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index d21c88a0c..3464d3671 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,10 @@ # Authors of mruby (mruby developers) -## The List of Contributors sorted by number of commits (as of 2023-12-28 67cb987) +## The List of Contributors sorted by number of commits (as of 2024-02-10 d2af9da) - 9477 Yukihiro "Matz" Matsumoto (@matz)* + 9592 Yukihiro "Matz" Matsumoto (@matz)* 586 KOBAYASHI Shuji (@shuujii) - 533 dearblue (@dearblue)* + 547 dearblue (@dearblue)* 378 Daniel Bovensiepen (@bovi)* 346 Takeshi Watanabe (@take-cheeze)* 334 Masaki Muranaka (@monaka) @@ -12,7 +12,7 @@ 234 Jun Hiroe (@suzukaze) 220 Cremno (@cremno)* 209 Yuki Kurihara (@ksss)+ - 166 John Bampton (@jbampton) + 170 John Bampton (@jbampton) 151 Yasuhiro Matsumoto (@mattn)* 113 Carson McDonald (@carsonmcdonald) 103 Tomasz Dąbrowski (@dabroz)* @@ -156,6 +156,7 @@ 3 bamchoh (@bamchoh) 3 sasaki takeru (@takeru) 3 windwiny (@windwiny) + 3 星湖新 (@hoshiumiarata) 2 Akira Moroo (@retrage) 2 Artur K (@nemerle) 2 Christian Mauceri (@mauceri) @@ -290,6 +291,7 @@ 1 Yusuke Tanaka (@csouls) 1 alpha.netzilla (@alpha-netzilla) 1 arton (@arton) + 1 buty4649 (@buty4649) 1 duangsuse (@duangsuse) 1 fl0l0u (@fl0l0u) 1 hhc0null (@hhc0null) From f285420653a5f6953227077bc1819e792c7ef2e4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 12 Feb 2024 23:41:50 +0900 Subject: [PATCH 114/117] backtrace.c (decode_location): decode packed backtrace location on demand. --- src/backtrace.c | 64 +++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 604a9c84c..24623df10 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -133,45 +133,47 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) mrb_gc_arena_restore(mrb, ai); } +static mrb_value +decode_location(mrb_state *mrb, const struct mrb_backtrace_location *entry) +{ + mrb_value btline; + int32_t lineno; + const char *filename; + + if (!entry->irep || !mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { + btline = mrb_str_new_lit(mrb, "(unknown):0"); + } + else if (lineno != -1) {//debug info was available + btline = mrb_format(mrb, "%s:%d", filename, (int)lineno); + } + else { //all that was left was the stack frame + btline = mrb_format(mrb, "%s:0", filename); + } + if (entry->method_id != 0) { + mrb_str_cat_lit(mrb, btline, ":in "); + mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); + } + return btline; +} + static struct RObject* mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) { - const struct mrb_backtrace_location *bt; - mrb_int n, i; - int ai; - if (backtrace == NULL) { - empty_backtrace: return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0)); } if (backtrace->tt == MRB_TT_ARRAY) return backtrace; - mrb_assert(backtrace->tt == MRB_TT_BACKTRACE); - struct RBacktrace *btobj = (struct RBacktrace*)backtrace; - bt = btobj->locations; - if (bt == NULL) goto empty_backtrace; - n = (mrb_int)btobj->len; - if (n == 0) goto empty_backtrace; - backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); - ai = mrb_gc_arena_save(mrb); - for (i = 0; i < n; i++) { - const struct mrb_backtrace_location *entry = &bt[i]; - mrb_value btline; - int32_t lineno; - const char *filename; - if (!entry->irep || !mrb_debug_get_position(mrb, entry->irep, entry->idx, &lineno, &filename)) { - btline = mrb_str_new_lit(mrb, "(unknown):0"); - } - else if (lineno != -1) {//debug info was available - btline = mrb_format(mrb, "%s:%d", filename, (int)lineno); - } - else { //all that was left was the stack frame - btline = mrb_format(mrb, "%s:0", filename); - } - if (entry->method_id != 0) { - mrb_str_cat_lit(mrb, btline, ":in "); - mrb_str_cat_cstr(mrb, btline, mrb_sym_name(mrb, entry->method_id)); - } + mrb_assert(backtrace->tt == MRB_TT_BACKTRACE); + + struct RBacktrace *bt = (struct RBacktrace*)backtrace; + mrb_int n = bt ? (mrb_int)bt->len : 0; + const struct mrb_backtrace_location *loc = bt->locations; + + backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); + int ai = mrb_gc_arena_save(mrb); + for (mrb_int i = 0; i < n; i++) { + mrb_value btline = decode_location(mrb, &loc[i]); mrb_ary_push(mrb, mrb_obj_value(backtrace), btline); mrb_gc_arena_restore(mrb, ai); } From 441de05376676e43069b2d411f72efede0794060 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 13 Feb 2024 11:05:27 +0900 Subject: [PATCH 115/117] error.h: use RBasic instead of RObject for generic objects RObject is type for objects with instance variables. For generic objects, use RBasic. --- include/mruby/error.h | 4 ++-- src/backtrace.c | 38 +++++++++++++++++++------------------- src/error.c | 4 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/mruby/error.h b/include/mruby/error.h index ee6fe8ffc..e8c63dc3e 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -17,8 +17,8 @@ MRB_BEGIN_DECL struct RException { MRB_OBJECT_HEADER; struct iv_tbl *iv; - struct RObject *mesg; // NULL or probably RString - struct RObject *backtrace; // NULL, RArray or RData + struct RBasic *mesg; // NULL or probably RString + struct RBasic *backtrace; // NULL, RArray or RData }; /* error that should terminate execution */ diff --git a/src/backtrace.c b/src/backtrace.c index 24623df10..3c53efda8 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -92,7 +92,7 @@ pack_backtrace(mrb_state *mrb, ptrdiff_t ciidx, struct mrb_backtrace_location *p return n; } -static struct RObject* +static struct RBasic* packed_backtrace(mrb_state *mrb) { struct RBacktrace *backtrace; @@ -109,15 +109,15 @@ packed_backtrace(mrb_state *mrb) backtrace->locations = (struct mrb_backtrace_location*)ptr; backtrace->len = pack_backtrace(mrb, ciidx, backtrace->locations); - return (struct RObject*)backtrace; + return (struct RBasic*)backtrace; } static void -store_backtrace(mrb_state *mrb, mrb_value exc, struct RObject *backtrace) +store_backtrace(mrb_state *mrb, mrb_value exc, struct RBasic *backtrace) { struct RException *e = mrb_exc_ptr(exc); e->backtrace = backtrace; - mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)backtrace); + mrb_field_write_barrier(mrb, (struct RBasic*)e, backtrace); } void @@ -128,7 +128,7 @@ mrb_keep_backtrace(mrb_state *mrb, mrb_value exc) if (mrb->c->ci == NULL) return; if (mrb_exc_ptr(exc)->backtrace) return; ai = mrb_gc_arena_save(mrb); - struct RObject *backtrace = packed_backtrace(mrb); + struct RBasic *backtrace = packed_backtrace(mrb); store_backtrace(mrb, exc, backtrace); mrb_gc_arena_restore(mrb, ai); } @@ -156,11 +156,11 @@ decode_location(mrb_state *mrb, const struct mrb_backtrace_location *entry) return btline; } -static struct RObject* -mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) +static struct RBasic* +mrb_unpack_backtrace(mrb_state *mrb, struct RBasic *backtrace) { if (backtrace == NULL) { - return mrb_obj_ptr(mrb_ary_new_capa(mrb, 0)); + return mrb_basic_ptr(mrb_ary_new_capa(mrb, 0)); } if (backtrace->tt == MRB_TT_ARRAY) return backtrace; @@ -170,7 +170,7 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) mrb_int n = bt ? (mrb_int)bt->len : 0; const struct mrb_backtrace_location *loc = bt->locations; - backtrace = mrb_obj_ptr(mrb_ary_new_capa(mrb, n)); + backtrace = mrb_basic_ptr(mrb_ary_new_capa(mrb, n)); int ai = mrb_gc_arena_save(mrb); for (mrb_int i = 0; i < n; i++) { mrb_value btline = decode_location(mrb, &loc[i]); @@ -184,7 +184,7 @@ mrb_unpack_backtrace(mrb_state *mrb, struct RObject *backtrace) mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc) { - struct RObject *backtrace = mrb_exc_ptr(exc)->backtrace; + struct RBasic *backtrace = mrb_exc_ptr(exc)->backtrace; if (backtrace == NULL) { return mrb_nil_value(); } @@ -206,16 +206,16 @@ mrb_get_backtrace(mrb_state *mrb) #ifndef MRB_NO_STDIO static void -print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RBasic *bt) { - mrb_int i; + struct RArray *backtrace = (struct RArray*)bt; mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); - mrb_value *loc, mesg; if (n != 0) { - if (n > 1) { - fputs("trace (most recent call last):\n", stderr); - } + mrb_value *loc; + mrb_int i; + + fputs("trace (most recent call last):\n", stderr); for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { if (mrb_string_p(*loc)) { fprintf(stderr, "\t[%d] ", (int)i); @@ -237,7 +237,7 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, struct RArray *backtrace) fwrite(nomem, sizeof(nomem)-1, 1, stderr); } else { - mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); + mrb_value mesg = mrb_exc_inspect(mrb, mrb_obj_value(exc)); fwrite(RSTRING_PTR(mesg), RSTRING_LEN(mesg), 1, stderr); fputc('\n', stderr); } @@ -255,9 +255,9 @@ mrb_print_backtrace(mrb_state *mrb) return; } - struct RObject *backtrace = ((struct RException*)mrb->exc)->backtrace; + struct RBasic *backtrace = ((struct RException*)mrb->exc)->backtrace; if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); - print_backtrace(mrb, mrb->exc, (struct RArray*)backtrace); + print_backtrace(mrb, mrb->exc, backtrace); } #else MRB_API void diff --git a/src/error.c b/src/error.c index c91725283..63c104c77 100644 --- a/src/error.c +++ b/src/error.c @@ -24,7 +24,7 @@ mrb_exc_mesg_set(mrb_state *mrb, struct RException *exc, mrb_value mesg) if (!mrb_string_p(mesg)) { mesg = mrb_obj_as_string(mrb, mesg); } - exc->mesg = mrb_obj_ptr(mesg); + exc->mesg = mrb_basic_ptr(mesg); mrb_field_write_barrier_value(mrb, (struct RBasic*)exc, mesg); } @@ -160,7 +160,7 @@ set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace) p++; } } - mrb_exc_ptr(exc)->backtrace = mrb_obj_ptr(backtrace); + mrb_exc_ptr(exc)->backtrace = mrb_basic_ptr(backtrace); mrb_field_write_barrier_value(mrb, mrb_basic_ptr(exc), backtrace); } From 6810423da121b776ed4ff500c08f1431cefc740e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 13 Feb 2024 16:18:14 +0900 Subject: [PATCH 116/117] backtrace.c (mrb_print_backtrace): avoid backtrace to array conversion Made print_backtrace() to support both array form and packed backtrace form, so that we can avoid allocating an array. --- src/backtrace.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/backtrace.c b/src/backtrace.c index 3c53efda8..636e3ce2c 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -206,25 +206,40 @@ mrb_get_backtrace(mrb_state *mrb) #ifndef MRB_NO_STDIO static void -print_backtrace(mrb_state *mrb, struct RObject *exc, struct RBasic *bt) +print_backtrace(mrb_state *mrb, struct RObject *exc, struct RBasic *ptr) { - struct RArray *backtrace = (struct RArray*)bt; - mrb_int n = (backtrace ? ARY_LEN(backtrace) : 0); + struct RArray *ary = NULL; + struct RBacktrace *bt = NULL; + mrb_int n = 0; + + if (ptr) { + if (ptr->tt == MRB_TT_ARRAY) { + ary = (struct RArray*)ptr; + n = ARY_LEN(ary); + } + else { + bt = (struct RBacktrace*)ptr; + n = (mrb_int)bt->len; + } + } if (n != 0) { - mrb_value *loc; - mrb_int i; + mrb_value btline; fputs("trace (most recent call last):\n", stderr); - for (i=n-1,loc=&ARY_PTR(backtrace)[i]; i>0; i--,loc--) { - if (mrb_string_p(*loc)) { + for (mrb_int i=n-1; i>0; i--) { + if (ary) btline = ARY_PTR(ary)[i]; + else btline = decode_location(mrb, &bt->locations[i]); + if (mrb_string_p(btline)) { fprintf(stderr, "\t[%d] ", (int)i); - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + fwrite(RSTRING_PTR(btline), (int)RSTRING_LEN(btline), 1, stderr); fputc('\n', stderr); } } - if (mrb_string_p(*loc)) { - fwrite(RSTRING_PTR(*loc), (int)RSTRING_LEN(*loc), 1, stderr); + if (ary) btline = ARY_PTR(ary)[0]; + else btline = decode_location(mrb, &bt->locations[0]); + if (mrb_string_p(btline)) { + fwrite(RSTRING_PTR(btline), (int)RSTRING_LEN(btline), 1, stderr); fputs(": ", stderr); } } @@ -256,7 +271,6 @@ mrb_print_backtrace(mrb_state *mrb) } struct RBasic *backtrace = ((struct RException*)mrb->exc)->backtrace; - if (backtrace && backtrace->tt != MRB_TT_ARRAY) backtrace = mrb_unpack_backtrace(mrb, backtrace); print_backtrace(mrb, mrb->exc, backtrace); } #else From 9c840a68e212fb54136b67711daff331435c1ce7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 13 Feb 2024 22:36:03 +0900 Subject: [PATCH 117/117] string.c (memsearch_swar): boundary check by the latest position --- src/string.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/string.c b/src/string.c index e214ad4c2..780ab4e5e 100644 --- a/src/string.c +++ b/src/string.c @@ -578,7 +578,7 @@ str_index_str_by_char(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos) * fixed potential buffer overflow */ static inline mrb_int -memsearch_swar(const char *xs, long m, const char *ys, long n) +memsearch_swar(const char *xs, mrb_int m, const char *ys, mrb_int n) { #ifdef MRB_64BIT #define bitint uint64_t @@ -641,9 +641,9 @@ memsearch_swar(const char *xs, long m, const char *ys, long n) const char *p = s0; const char *e = ys + n; for (;p