Commit Graph

5770 Commits

Author SHA1 Message Date
dearblue cf20687ee7 mruby-eval: unify f_instance_eval and f_class_eval
Their bodies were nearly identical: same argument parsing,
same proc creation, same target-class plumbing. The only
differences are which method to delegate to in the block-given
case (mrb_obj_instance_eval vs. mrb_mod_module_eval) and
which class to use as the target (singleton vs. self-as-class).

Extract the shared logic into object_eval(self, class_eval).
The two top-level dispatchers become one-line wrappers.

Closes #6579, picked from PR by dearblue.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-08 11:51:25 +09:00
Yukihiro "Matz" Matsumoto 817ec1bd90 Merge pull request #6580 from dearblue/File.basename
Improve `File.basename`
2026-05-08 11:41:36 +09:00
Yukihiro "Matz" Matsumoto bf0915dd03 Merge pull request #6817 from dearblue/array-ext
Integrate `Array#{permutation,combination}` into `Array#__combination`
2026-05-08 10:56:42 +09:00
Yukihiro "Matz" Matsumoto 91b60802db mruby-regexp: cap character class count and free named_captures
Two related bugs uncovered by OSS-Fuzz testcase 6692915710853120:

1. add_class allowed unbounded growth of c->classes. Class IDs are
   stored in re_inst.a (uint8_t), so any ID >= 256 silently aliases
   another class via the cast at emit sites. Worse, c->class_capa
   (uint16_t) overflows on doubling past 32768 -> 0, then
   mrb_realloc(..., 0) returns NULL, and the next memset(&c->classes[id])
   segfaults at NULL+offset. Cap with RE_MAX_CLASSES = 256 (the encoding
   limit) and raise via compile_error past that.

2. Once the crash is fixed, the testcase exposes a leak of
   c->named_captures: compile_error frees c->code, c->classes, and
   c->stripped (commit 3f321f09bc) but missed named_captures. Add it
   to the same cleanup block.

Reported by OSS-Fuzz (clusterfuzz testcase 6692915710853120).

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-08 10:32:03 +09:00
Yukihiro "Matz" Matsumoto 28624ecfd8 mruby-regexp: cap {n}/{n,m} quantifiers to prevent overflow
parse_quantifier read digits via min = min * 10 + d with no upper
bound, allowing patterns like /a{1111558833}/ to overflow int and
trigger signed-integer-overflow UB. Even without UB, the value
flows into compile_quantified's emit loop where it would attempt
to emit a billion copies of the atom.

Add RE_MAX_REPEAT = 32768 (the largest value that still fits in
re_inst.offset, the uint16_t jump field) and reject quantifiers
beyond that during parsing via compile_error. Apply the same cap
to the max field.

Reported by OSS-Fuzz (clusterfuzz testcase 6152367367323648).

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-07 16:25:12 +09:00
Yukihiro "Matz" Matsumoto f267925d45 mruby-socket: translate Winsock errors to errno on Windows
Winsock APIs (socket, bind, connect, accept, recv, send, ...) report
errors via WSAGetLastError() and do not set errno, so mrb_sys_fail
on Windows was reading a stale or zero errno. Result: every socket
failure raised SystemCallError with errno 0 ("Success") instead of
the appropriate Errno::* class.

Add mrb_hal_socket_set_errno_from_last_error() to the HAL:
- POSIX: no-op (failed calls already set errno)
- Windows: maps WSAGetLastError() to a POSIX errno via wsa_to_errno()
  with 32 cases covering the common Winsock error codes; unmapped
  codes fall back to EIO. Each case is #ifdef-guarded against older
  MSVC CRTs that lack a particular Exxx.

In src/socket.c, route the 22 socket-API failure sites through a new
sock_sys_fail() helper that calls the HAL translator before
mrb_sys_fail. Also fix mrb_hal_socket_set_nonblock() on Windows,
which was returning -1 without setting errno after ioctlsocket
failure.

POSIX behavior unchanged (verified: TCPSocket connect refused ->
Errno::ECONNREFUSED, bind to privileged port -> Errno::EACCES, bad
sockopt -> Errno::EOPNOTSUPP).

Closes #6819, reported by Asmod4n.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-07 11:01:46 +09:00
dearblue 3db11cef09 Integrate Array#{permutation,combination} into Array#__combination
Compared to a pure Ruby implementation, this results in faster performance, eliminates recursive calls, and removes the creation of intermediate objects.

The "permutation" implementation in `ary_combination_next()` is slow for C.
However, it does not require a heap other than the index array.
2026-05-06 18:27:16 +09:00
dearblue e7a375d4be Preparations for integrating the implementation of Array#{permutation,combination}
- Modify the `mrb_combination_state` structure to accommodate feature extensions
  - Rename `Array#__repeated_combination` to `__combination`
  - Consolidate integer checks for arguments into `__combination`
  - Since checking for integer types using both `__to_int` and `0 <=>` is redundant, use only `__to_int`
  - Since `__combination` now accepts symbols instead of booleans, the call to `to_enum` has also been consolidated
2026-05-06 18:27:16 +09:00
dearblue a8c841433f Rename the members of the mrb_combination_state structure
Since these are expressed as "nPk" or "nCk" in mathematics, rename `n` to `k` and `array_size` to `n`.
Additionally, rename the parameters `#__repeated_combination` and `#__combination_init` from `n` to `k`.

However, the parameter `n` in `#repeated_permutation` and `#repeated_combination` remains unchanged to align with CRuby.
2026-05-05 22:25:26 +09:00
Yukihiro "Matz" Matsumoto 3f321f09bc mruby-regexp: fix leak and UAF on compile error paths
compile_error is the chokepoint for all regex-compile errors;
mrb_raisef longjmps out of re_compile, abandoning the stack-local
re_compiler struct. Three connected bugs:

1. Memory leak: c->code and c->classes (grown by emit/add_class
   via mrb_realloc) were never freed before raising, leaking on
   any compile error like /[/. c->stripped was already cleaned up
   here for the same reason; the other two buffers were missed.

2. Use-after-free: c->src aliases c->stripped when RE_FLAG_EXTENDED
   is set, but the original code freed c->stripped before passing
   c->src to mrb_raisef's "%s" formatter. Format the message into
   an mrb_value first (mruby's GC-managed string survives the
   longjmp), then free, then raise.

3. Heap-buffer-overflow: strip_extended returns a non-NUL-terminated
   buffer of size len. Even with format-before-free, "%s" called
   strlen and read past the buffer end. Use mruby's %l directive
   which takes an explicit (char*, size_t) and avoids strlen.

Reported by OSS-Fuzz (clusterfuzz testcase 5394267353972736).

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-05 09:31:38 +09:00
Yukihiro "Matz" Matsumoto 479af5c1bd mruby-regexp: bounds-check non-ASCII RE_CHAR in first_set_walk
The first-byte bitmap (bm[16]) is intentionally ASCII-only
(include/re_internal.h:75 documents it as 128 bits / ASCII), and
the matcher at re_exec.c:39 short-circuits for bytes >= 128. But
first_set_walk's RE_CHAR case wrote bm[a >> 3] without checking
a, overflowing the 16-byte stack buffer for any pattern
containing a byte >= 128.

When a >= 128, return FALSE so compute_first_set marks the filter
unusable, matching the bail-out pattern already used for RE_NCLASS
and RE_ANY. The pattern still compiles and matches; only the
first-byte optimization is skipped.

Reported by OSS-Fuzz (clusterfuzz testcase 4909069193510912).

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-03 22:43:22 +09:00
Yukihiro "Matz" Matsumoto c24d01c6fa Merge pull request #6776 from dearblue/array-combination.3
Return nil if a number less than 1 is passed to `Array#__combination_init`
2026-05-02 23:41:04 +09:00
dearblue 525ab7a800 Return nil if a number less than 1 is passed to Array#__combination_init
This simplifies the subsequent processing.
2026-05-02 22:16:56 +09:00
dearblue a98c6b62ea Don't use #puts in bintest for "mruby-bin-mrb"
Since `Kernel#puts` is undefined in unit tests, using `Kernel#print` is required.
Previously, for example, running `rake test` with the following build configuration caused the tests to fail.

```ruby
MRuby::Build.new do
  toolchain
  enable_debug
  enable_test
  enable_bintest
  gem core: "mruby-bin-mrb"
end
```
2026-05-02 20:52:00 +09:00
Yukihiro "Matz" Matsumoto 7dfd560df8 mruby-io: cap puts recursion depth to prevent C stack overflow
io_puts_ary recursed unconditionally on nested arrays. For cyclic
arrays (a = []; a << a; puts a) or pathologically deep arrays,
this caused a C stack overflow.

Add a depth cap (IO_PUTS_MAX_DEPTH = 16); on overflow, write
"[...]\n" and return, matching CRuby's behavior on cycles. The
pattern mirrors mruby-set's MAX_NESTED_DEPTH for the same problem
shape (pure C recursion not dispatched as a Ruby method).

Reported by OSS-Fuzz (clusterfuzz testcase 6233530857488384).

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-02 11:27:01 +09:00
Yukihiro "Matz" Matsumoto e4cd7e6daf mruby-compiler: place newline before else
The mruby C style places `else` on its own line. Reformat the
remaining `} else if (...)` occurrence in the C action block of
NODE_SYMBOLS dump.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-28 12:56:25 +09:00
Yukihiro "Matz" Matsumoto 16f1f4418a mruby-bigint: place newline before else
The mruby C style places `else` on its own line. Reformat the
remaining `} else {` occurrences.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-28 12:56:25 +09:00
Yukihiro "Matz" Matsumoto 1702b89c25 Merge pull request #6787 from dearblue/sprintf 2026-04-28 12:56:07 +09:00
Yukihiro "Matz" Matsumoto 06d236d535 mruby-bin-config: register installer in products instead of bins
`build.bins` is for compiled binaries with bare names; entries are
fed through `exefile()` in `tasks/bin.rake`, which appends
`exts.executable` (e.g. `.exe`) when no extension is present.

When `ENV['OS']` is not `Windows_NT` but the toolchain has
`exts.executable=".exe"` (e.g. cross builds, or environments where
`OS` is unset under visualcpp), `mruby-bin-config` ended up with a
file task at `.../mruby-config` while rake asked for
`.../mruby-config.exe`, aborting with "Don't know how to build task".

Skip the `bins` path and call `build.define_installer` directly with
`mruby_config_path`, mirroring the existing `iscross` branch. The
file task path now always matches the script content's extension
(`.bat` on Windows, no extension elsewhere).

close #6807, reported by UENO, M. (@eunos-1128).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-25 19:57:44 +09:00
Yukihiro "Matz" Matsumoto 550be1445f Revert "mruby-socket: add temporary getaddrinfo diagnostic for Windows CI"
This reverts commit a69d12aa54.

The diagnostic served its purpose: it isolated the failure to
Winsock's getaddrinfo for the "localhost" hostname. The permanent
fix (skip guard) is now in place, so remove the temporary probe.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-24 08:19:04 +09:00
Yukihiro "Matz" Matsumoto 57ca531f76 mruby-socket: skip localhost-dependent addrinfo tests on Windows
Addrinfo.getaddrinfo("localhost", ...) and Addrinfo.foreach("localhost",
...) crash on GitHub Actions Windows runners (Windows Server 2022 and
2025, both mingw-gcc and MSVC). Diagnostic showed 127.0.0.1 as a
numeric literal resolves fine via Winsock getaddrinfo, but "localhost"
as a hostname returns WSAHOST_NOT_FOUND under every address family
(AF_INET, AF_INET6, AF_UNSPEC, nil). PowerShell Resolve-DnsName on
the same runner succeeds, so the failure is Winsock-specific rather
than OS-level. Earlier workarounds (Dnscache service start, hosts
file append) had no effect.

Skip both tests on Windows with the existing SocketTest.win? guard,
matching the pattern already used for Addrinfo.unix and
Addrinfo#afamily. Linux and macOS coverage is unaffected.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-24 08:18:41 +09:00
Yukihiro "Matz" Matsumoto a69d12aa54 mruby-socket: add temporary getaddrinfo diagnostic for Windows CI
Addrinfo.getaddrinfo("localhost", 53, AF_INET, SOCK_STREAM) crashes
on GitHub Actions Windows runners with WSAHOST_NOT_FOUND, while the
same call works on Linux and macOS. Earlier hypotheses (winsock link
missing; hosts file not populated) have been ruled out on CI.

Probe five variants in one run to isolate the failing condition:
numeric literal 127.0.0.1, localhost with AF_UNSPEC, localhost with
nil family, localhost with AF_INET6, and the original AF_INET path.
Results go to stdout via puts so they are visible in CI logs. This
commit is temporary and will be reverted once the real fix lands.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-24 01:20:15 +09:00
Yukihiro "Matz" Matsumoto 2ff6563484 mruby-task: restore Windows link library dropped during HAL migration
Commit be6413f0d86a ("mruby-task: migrate HAL to ports/ directories")
moved the Windows HAL source into mruby-task/ports/win/ but dropped
the linker.libraries declaration that previously lived in
hal-win-task/mrbgem.rake. Both mingw and MSVC builds now fail to link
task_hal.o/obj with undefined references to timeBeginPeriod,
timeEndPeriod, timeSetEvent, and timeKillEvent. Re-declare winmm
under a for_windows? guard.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 23:16:21 +09:00
Yukihiro "Matz" Matsumoto 3f27eac308 mruby-io: restore Windows link library dropped during HAL migration
Commit 9965f11cfe1c ("mruby-io: migrate HAL to ports/ directories")
moved the Windows HAL source into mruby-io/ports/win/ but dropped the
linker.libraries declaration that previously lived in
hal-win-io/mrbgem.rake. Both mingw and MSVC builds now fail to link
with undefined references to closesocket, WSAStartup, WSACleanup,
select, and WSAGetLastError referenced from io.c and io_hal.c.
Re-declare ws2_32 under a for_windows? guard.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 23:16:11 +09:00
Yukihiro "Matz" Matsumoto 22df8d61be mruby-socket: restore Windows link libraries dropped during HAL migration
Commit d9e107c801 ("mruby-socket: migrate HAL to ports/ directories")
moved the Windows HAL source into mruby-socket/ports/win/ but dropped
the linker.libraries declarations that previously lived in
hal-win-socket/mrbgem.rake. Both mingw and MSVC builds now fail to
link with undefined references to WSAStartup, socket, send, and other
Winsock APIs. Re-declare wsock32 and ws2_32 under a for_windows? guard.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 23:16:02 +09:00
Yukihiro "Matz" Matsumoto ad8fc7d918 mruby-bigint: add multi-precision gcd tests
Cover zero operands, power-of-2 fast path, negative operands,
balanced multi-limb pairs with a shared Fibonacci factor, highly
unbalanced pairs (to exercise the Euclidean fallback), and
Fibonacci neighbors (always coprime). Declare a test dependency
on mruby-numeric-ext since Integer#gcd is defined there.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 22:56:44 +09:00
Yukihiro "Matz" Matsumoto 8e91554c6d mruby-bigint: rewrite mpz_gcd main loop as binary Stein algorithm
Replace the classical Euclidean main loop (mpz_mod per iteration)
with Stein's binary GCD: subtract + factor out trailing 2s on
odd-maintained operands. Keep an mpz_mod fallback for heavily
unbalanced pairs (the smaller operand has at least two fewer limbs)
where one long division replaces many Stein subtracts.

The old loop allocated a temporary mpz_t every iteration to hold the
mod result; the Stein loop is allocation-free thanks to the in-place
paths in mpz_sub and mpz_div_2exp. This matches the "memory first"
priority and also happens to be faster on typical inputs because
mpz_mod's setup cost dominates when the quotient is small (the
classical Fibonacci-neighbor worst case).

Also add a small mpz_swap helper used by the new loop.

Benchmark (bin/mruby benchmark/bm_bigint_gcd.rb, median of 3):

  case                       before    after    ratio
  single-limb                 42 ms    50 ms    1.19  (fast-path
                                                      unchanged;
                                                      noise)
  fib(200) vs fib(201)        82 ms    23 ms    0.28
  balanced ~700-bit shared    46 ms    32 ms    0.70
  unbalanced big vs small     35 ms    28 ms    0.80
  power-of-2 path             38 ms    42 ms    1.11  (fast-path
                                                      unchanged;
                                                      noise)
  balanced ~2800-bit shared   19 ms    15 ms    0.79

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 22:52:05 +09:00
Yukihiro "Matz" Matsumoto ec55e0d0f1 mruby-bigint: correct mpz_gcd comment to describe hybrid behavior
The preceding comment claimed "Binary GCD (Stein's algorithm)",
but the multi-limb main loop is classical Euclidean using mpz_mod.
Only the prelude (factoring out common 2s, single-limb and
power-of-2 fast paths) is Stein-flavored. Describe what the code
actually does so readers are not misled.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 22:36:18 +09:00
Yukihiro "Matz" Matsumoto 81bcd4e931 mruby-bigint: simplify MPZ_CTX_INIT with positional initializer
Per gemini-code-assist review on #6791: replace member-by-member
assignment with C89/C++98-style positional aggregate initialization,
keeping the macro a single declaration and matching the existing
pool_storage initializer style in the same macro.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:39 +09:00
Yukihiro "Matz" Matsumoto 449040400a mruby-regexp: keep MatchData source/regexp GC-reachable
The mrb_match_data struct stores `source` and `regexp` as plain
mrb_value members of a C-allocated struct, which the GC does not
scan.  Under MRB_GC_STRESS the source string could be collected
while the MatchData was still alive, causing md[0] to read freed
memory (observed as "\xff\xff\xff").

Also stash source and regexp as instance variables on the MatchData
object so they remain reachable via the object's iv_tbl during GC.
The C struct members continue to provide fast direct access, and
no other call sites need to change.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:39 +09:00
Yukihiro "Matz" Matsumoto 909f5a070f hw-adc: add ADC peripheral gem for embedded platforms
Add hw-adc gem with analog-to-digital conversion support:
- Common Ruby API with read, read_raw, and read_voltage
- ports/esp32/ using ESP-IDF ADC oneshot driver
- ports/rp2040/ using Pico SDK ADC hardware

Based on picoruby-adc by HASUMI Hitoshi.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:38 +09:00
Yukihiro "Matz" Matsumoto ce4bc77aaf hw-pwm: add PWM peripheral gem for embedded platforms
Add hw-pwm gem with pulse width modulation support:
- Common Ruby API with frequency, duty, period_us, pulse_width_us
- ports/esp32/ using LEDC peripheral
- ports/rp2040/ using Pico SDK PWM hardware

Based on picoruby-pwm by HASUMI Hitoshi.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:38 +09:00
Yukihiro "Matz" Matsumoto 5931a96a17 hw-spi: add SPI peripheral gem for embedded platforms
Add hw-spi gem with SPI communication support:
- Common Ruby API with write, read, and full-duplex transfer
- ports/esp32/ using ESP-IDF SPI master driver
- ports/rp2040/ using Pico SDK

Based on picoruby-spi by HASUMI Hitoshi.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:38 +09:00
Yukihiro "Matz" Matsumoto be6413f0d8 mruby-task: migrate HAL to ports/ directories
Move hal-posix-task and hal-win-task into
mruby-task/ports/posix/ and mruby-task/ports/win/.
Remove HAL auto-detection logic from mrbgem.rake. Update
cosmopolitan.rb to use conf.ports :posix instead of explicit
hal-* gem references.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto d9e107c801 mruby-socket: migrate HAL to ports/ directories
Move hal-posix-socket and hal-win-socket into
mruby-socket/ports/posix/ and mruby-socket/ports/win/.
Remove HAL auto-detection logic from mrbgem.rake.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto 886bf270f0 mruby-dir: migrate HAL to ports/ directories
Move hal-posix-dir and hal-win-dir into mruby-dir/ports/posix/
and mruby-dir/ports/win/. Remove HAL auto-detection logic from
mrbgem.rake.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto 9965f11cfe mruby-io: migrate HAL to ports/ directories
Move hal-posix-io and hal-win-io into mruby-io/ports/posix/ and
mruby-io/ports/win/. Platform sources are now compiled
automatically based on conf.ports setting. Remove HAL
auto-detection logic from mrbgem.rake.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto a8c82b506f hw-uart: consolidate platform gems into ports/ directories
Move hw-esp32-uart and hw-rp2040-uart into hw-uart/ports/esp32/
and hw-uart/ports/rp2040/ using the new ports build system.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto 53a43e9d36 hw-gpio: consolidate platform gems into ports/ directories
Move hw-esp32-gpio and hw-rp2040-gpio into hw-gpio/ports/esp32/
and hw-gpio/ports/rp2040/ using the new ports build system.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:37 +09:00
Yukihiro "Matz" Matsumoto b8eccc7a38 hw-i2c: consolidate platform gems into ports/ directories
Move hw-esp32-i2c and hw-rp2040-i2c into hw-i2c/ports/esp32/
and hw-i2c/ports/rp2040/ using the new ports build system.
Platform sources are now compiled automatically based on
conf.ports setting. Separate platform gems are no longer needed.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:36 +09:00
Yukihiro "Matz" Matsumoto 2b5a389de3 hw-uart: add UART peripheral gems for embedded platforms
Add three new gems for UART serial communication:
- hw-uart: common Ruby API, C bindings, ring buffer, and HAL header
- hw-esp32-uart: ESP32 HAL using ESP-IDF UART driver with FreeRTOS
  RX task
- hw-rp2040-uart: RP2040 HAL using Pico SDK with IRQ-driven RX

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:36 +09:00
Yukihiro "Matz" Matsumoto bdc3a65601 mruby-io: call mrb_hal_io_init/final from gem_init/gem_final
The HAL init/final functions were defined in hal-posix-io and
hal-win-io but never called. On Windows, hal-win-io performs
WSAStartup/WSACleanup in these functions, which was not being
invoked by mruby-io unlike other HAL gems (dir, socket, task).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:36 +09:00
Yukihiro "Matz" Matsumoto 0ff41e4e28 hw-gpio: add GPIO peripheral gems for embedded platforms
Add three new gems for GPIO pin control:
- hw-gpio: common Ruby API, C bindings, and HAL header
- hw-esp32-gpio: ESP32 HAL using ESP-IDF GPIO driver
- hw-rp2040-gpio: RP2040 HAL using Pico SDK

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:36 +09:00
Yukihiro "Matz" Matsumoto 1ed52461e8 hw-i2c: add I2C peripheral gems for embedded platforms
Add three new gems for I2C communication:
- hw-i2c: common Ruby API, C bindings, and HAL header
- hw-esp32-i2c: ESP32 HAL using ESP-IDF I2C master driver
- hw-rp2040-i2c: RP2040 HAL using Pico SDK

The HAL API provides init, read, write, and atomic write_read
(repeated START) operations. Platform gems depend on hw-i2c
and are only compiled when explicitly included in build config.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto 416793db3d mruby-sprintf: use mrb_uint cast instead of uint64_t
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto 6f202d6c2b mruby-io: use mrb_int consistently in IO HAL interface
Replace all int64_t, uint64_t, uint32_t, and int32_t with mrb_int
in the HAL struct, timeval, and function signatures. All values
originate from or end up as mrb_int at the Ruby layer. Also removes
dead overflow checks in callers and the stdint.h dependency from
io_hal.h.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto ad1fd9285c mirb.c: add fileno() to _fileno() mapping for MSVC
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto 29f84030ca bigint.c: fix signed/unsigned comparison warning in base conversion
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto b70c393039 mruby-io: use mrb_int for mrb_hal_io_readlink() return type
int64_t was unnecessary; readlink(2) returns ssize_t (bounded by
PATH_MAX), and the Windows HAL just raises NotImplementedError.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:35 +09:00
Yukihiro "Matz" Matsumoto 726d8febf3 mruby-regexp: cache Pike VM state in pattern to avoid per-exec malloc
Pre-allocate visited array and thread lists at compile time and
reuse them across re_exec calls. A cache_in_use flag detects
re-entrancy and falls back to malloc when needed.

Eliminates 3 malloc + 3 free per NFA execution for the common
non-re-entrant case. Combined with the literal fast path, brings
literal match? from 4.7x to 2.5x vs CRuby.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:34 +09:00