Commit Graph

5679 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto 16fbd56e4b mruby-task: extract task_create_common() from Task.new and mrb_create_task()
both functions shared identical task allocation, context
initialization, queue insertion, and priority preemption logic.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:25 +09:00
Yukihiro "Matz" Matsumoto f3cd991771 mruby-enum-lazy: add Enumerator::Lazy#tap_each
add tap_each method that yields each element for side effects
(e.g. logging, debugging) and passes it through unmodified.
see https://bugs.ruby-lang.org/issues/21520

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:25 +09:00
Yukihiro "Matz" Matsumoto 9a736d6609 mruby-bin-mrb: remove mruby-compiler dependency from runtime executor
mrb_ccontext functions are implemented in mruby-compiler (y.tab.c),
causing linker errors when the compiler is excluded from the build.
Replace with mrb_load_irep_file() which is in core (src/load.c).
Also fix incorrect *argv in error message and remove dead fname field.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:23 +09:00
Yukihiro "Matz" Matsumoto eb8c177824 mruby-bin-mrb: add compiler-free runtime executor gem
The `mrb` command executes only precompiled RiteBinary (.mrb) files
without depending on mruby-compiler. This enables smaller binaries
for embedded deployments where scripts are precompiled on a
development machine.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 5148062516 mruby-env: add README.md
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 3272955bf1 mruby-env: add ENV object for environment variable access
ENV is a plain Object with singleton methods and Enumerable,
matching CRuby's behavior. C methods wrap getenv/setenv/unsetenv
with platform support for POSIX, macOS, and Windows.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 36dd668f73 Merge pull request #6799 from dearblue/mrb_state 2026-04-23 19:20:43 +09:00
Yukihiro "Matz" Matsumoto 7365ed526b Merge pull request #6785 from khasinski/cfunc-proc-aspec 2026-04-23 19:11:35 +09:00
Yukihiro "Matz" Matsumoto 7a14bad5ea Merge pull request #6777 from dearblue/array-combination.4 2026-04-23 18:59:05 +09:00
Yukihiro "Matz" Matsumoto bfc1f37b91 Merge pull request #6775 from dearblue/array-combination.2 2026-04-23 18:56:46 +09:00
Yukihiro "Matz" Matsumoto 7eab8302b0 Merge pull request #6774 from dearblue/array-combination.1 2026-04-23 18:49:28 +09:00
dearblue 0d00743a5f Define the typedef for mrb_state earlier
This improves consistency with other definitions.
2026-04-19 21:17:18 +09:00
Yukihiro "Matz" Matsumoto 617a55b775 mruby-bigint: avoid C99 compound literal in MPZ_CTX_INIT
MPZ_CTX_INIT used a compound literal with designated initializers:

  mpz_ctx_t ctx##_struct = ((mpz_ctx_t){.mrb = ..., .pool = ...});

Both features are C99-only, and are not accepted by legacy C++
compilers (notably gcc 4.x) when mruby is pulled into a C++
translation unit via the -cxx.cxx wrapper.

Replace with plain member assignment so the macro expands to code
that is valid under C89/C++98 as well.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-15 09:01:19 +09:00
Chris Hasiński 55f0228bf8 Store compressed aspec on cfunc RProc for correct arity/parameters
Compress the 24-bit aspec into 13 free flag bits on RProc (bits 0-6
and 14-19) when wrapping cfunc methods. Field widths: req/opt 3 bits
(max 7), post/key 2 bits (max 3), rest/kdict/block 1 bit each. Values
exceeding the compressed range are clamped and rest is forced to 1.

This enables Proc#arity and Proc#parameters to return correct results
for cfunc-backed Procs (e.g. from Method#to_proc) with zero memory
overhead -- no struct change needed.

Closes #6764
2026-04-13 13:11:27 +02:00
Yukihiro "Matz" Matsumoto 48fc4220d3 Merge pull request #6781 from mruby/fix/sprintf-uaf 2026-04-11 16:33:05 +09:00
Yukihiro "Matz" Matsumoto 59552ecb8e mruby-sprintf: protect format string from mutation during callbacks
mrb_str_format captured raw C pointers (p, end) into the format
string's buffer before the main loop. The %s and %p specifiers call
to_s and inspect, which can invoke Ruby code that mutates the format
string via String#replace, freeing or reallocating its buffer. The
loop then continued iterating with dangling pointers, reading freed
memory and potentially leaking adjacent heap contents into the result.

Duplicate the format string with mrb_str_dup() before the loop. This
is O(1) because mrb_str_dup shares the underlying buffer; if the
original is later mutated via String#replace, str_replace decrements
the shared refcount, leaving our duplicate's buffer intact.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-10 14:51:59 +09:00
Yukihiro "Matz" Matsumoto af6f23ddb3 mruby-string-ext: fix String#prepend with self-referencing arguments
String#prepend(s, s) read RSTRING_LEN(argv[i]) in the copy loop after
mrb_str_resize had already updated the receiver's length, causing the
memcpy to write past the allocated buffer.

Detect self-references with mrb_obj_eq() and read from the memmoved
original data at p + total_prepend_len using the captured self_len.
This also handles mixed cases like s.prepend("X", s) where earlier
writes would otherwise corrupt the source of later reads.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-10 14:44:46 +09:00
dearblue d246ac6c8a Make Array#__combination_next return an array of elements
Since the main processing will be completed on the C side, the Ruby side will simply call the block.
2026-04-08 22:29:56 +09:00
dearblue 5e3e982442 Improve the calculation of the next index for Array#__combination_next
When the index wraps around, the lower index becomes a fixed value.
2026-04-08 22:16:59 +09:00
dearblue 3a9ef9d27e Avoid using the deprecated function mrb_data_check_and_get()
The "d" directive in `mrb_get_args()` can be used as an alternative.
Furthermore, NULL checking is unnecessary for the following reasons:
  - Incomplete objects from `ary_combination_init()` are not passed to the caller and are garbage collected when `ObjectSpace.each_object` is called, so they are never retrieved
  - Even if `state.clone` is called, the `RData::type` of the cloned object is set to NULL, so it is rejected by `mrb_get_args()`
2026-04-08 21:10:45 +09:00
Yukihiro "Matz" Matsumoto 0cc4caad2b Merge pull request #6769 from khasinski/fix-socket-recvfrom-nonblock 2026-04-01 09:23:00 +09:00
Chris Hasiński b85c520843 Remove stale self-corruption workaround in recvfrom_nonblock
The s = self workaround and XXX comment in recvfrom_nonblock date back
to the initial import of mruby-socket. The underlying bug where self
became a SystemcallException inside ensure blocks has since been fixed.

Verified that self correctly refers to the socket object in ensure
blocks after exceptions from recvfrom.
2026-03-30 22:14:26 +02:00
Yukihiro "Matz" Matsumoto 919cbd8fea mruby-compiler: allow compound statement in tLPAREN_ARG
Change the grammar rule for tLPAREN_ARG from accepting only a
single stmt to accepting compstmt. This allows compound
statements with semicolons inside parenthesized arguments when
the parenthesis is preceded by a space, e.g., `p (f1; f2)`.

This matches the behavior of CRuby 3.3+.

Fixes #6766.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-30 07:06:30 +09:00
Chris Hasiński 8f71887e46 Improve flat_map test descriptions for clarity 2026-03-28 23:14:46 +01:00
Chris Hasiński 3f52ef6cfc Fix Lazy#flat_map to handle non-enumerable block return values
When the block passed to Lazy#flat_map returns a non-enumerable value
(e.g. an Integer), mruby raised NoMethodError because it unconditionally
called #each on the result. CRuby yields non-enumerable values directly.

Use respond_to?(:each) to match CRuby behavior: iterate enumerable
results, yield non-enumerable results as-is.
2026-03-28 22:59:11 +01:00
Yukihiro "Matz" Matsumoto e8c5e7c0cd mruby-test: write generated C files atomically to avoid race condition
With `rake -m`, the C compiler can start reading a partially-written
gem_test.c before generation completes. Write to a .tmp file first,
then rename to the final path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-25 15:32:36 +09:00
dearblue 6c4a8c09db Define mrb_bigint_p() always.
Define the `mrb_bigint_p()` macro function, which returns false if `MRB_USE_BIGINT` is undefined.
2026-03-24 22:16:15 +09:00
dearblue 2135088ada Avoid the impact of object modifications caused by calls to mrb_vm_exec()
Several methods defined in mruby-array-ext are written in C and may call `mrb_vm_exec()`.
If array objects are modified on the Ruby side, problems may arise in subsequent processing.

  - Using objects that have been removed from the array and garbage collected
  - Using pointers or array lengths that have become invalid due to changes to the array object
  - Modifying the contents of a shared array object directly

ref: https://github.com/mruby/mruby/issues/6662
2026-03-22 23:05:37 +09:00
dearblue 98d763603c Further optimize Array#product
Replace `__product_group` method with `__product_generate` and `__product_next`.
This change eliminates the need for Ruby to perform internal state calculations, allowing it to simply receive the results.
2026-03-20 21:13:52 +09:00
Yukihiro "Matz" Matsumoto 01ce2f8c71 Merge pull request #6747 from katafrakt/handle-hash-default-arg 2026-03-20 16:44:27 +09:00
dearblue 8441eaf633 Fixed "Out-of-bounds Read" and "Divide-by-Zero" in ary_product_group()
Reproduction:

  - Out-of-bounds Read

    ```console
    % build/host/bin/mruby -e '([nil] * 256).__product_group([[nil] * 256], 1 << 32, 256)'
    zsh: segmentation fault (core dumped)  build/host/bin/mruby -e
    ```

  - Divide-by-Zero

    ```console
    % build/host/bin/mruby -e '([nil] * 256).__product_group([[]], 1 << 32, 256)'
    zsh: floating point exception (core dumped)  build/host/bin/mruby -e '([nil] * 256).__product_group([[]], 1 << 32, 256)'
    ```
2026-03-19 23:11:06 +09:00
Paweł Świątkowski 13d9d770fc Correctly handle empty hash as default named argument
```
def func(arg: {})
  p arg
end
```

This used to work in earlier mruby versions, but broke somewhere recently.
2026-03-18 08:53:20 +01:00
Yukihiro "Matz" Matsumoto d8de35b635 codegen.c: raise NoMatchingPatternError in case/in without else
case/in without else clause now raises NoMatchingPatternError
when no pattern matches, matching CRuby behavior. Fixes #6741.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-12 14:28:17 +09:00
Yukihiro "Matz" Matsumoto 62cf0dc17a codegen.c: chunk %w() and %i() literals to reduce register pressure
Apply the same chunking strategy used for regular array literals
to %w() and %i() literal arrays in gen_literal_array(). Fixes #6740.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-12 12:12:50 +09:00
Yukihiro "Matz" Matsumoto cfc83bb6ac Merge pull request #6734 from mruby/fix/array-chunking 2026-03-10 17:01:28 +09:00
Yukihiro "Matz" Matsumoto f98d6414dc codegen.c: chunk array literals at 64 elements to reduce register pressure
Array literals were being built by loading all elements into registers
before constructing the array, requiring nregs proportional to the array
size (e.g. nregs=99 for 100 elements). This exceeds mruby/c's register
limit. Restore 3.4-era chunking at GEN_LIT_ARY_MAX (64) elements.

fixes mruby/mruby#6731

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-09 16:50:59 +09:00
Yukihiro "Matz" Matsumoto 8956c5abb5 mruby.h: include mruby/presym.h for all source files
Since presym is now mandatory, mruby.h includes presym.h so that
MRB_SYM() macros are available everywhere without explicit include.
Remove redundant #include <mruby/presym.h> from all source files.

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-09 16:50:58 +09:00
Yukihiro "Matz" Matsumoto 59e1fe29d6 mrbconf.h: rename MRB_WORDBOX_NO_FLOAT_TRUNCATE to MRB_WORDBOX_NO_INLINE_FLOAT
The old name referred to "truncation" of float precision, which no
longer happens with rotation encoding. The new name describes the
actual behavior: disabling inline float encoding in word boxing.
The old name is kept as an obsolete alias for backward compatibility.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-27 10:30:01 +09:00
Yukihiro "Matz" Matsumoto 9e0eec3974 mruby-compiler: fix MRB_NO_STDIO build in codegen_pattern()
remove snprintf() call that requires <stdio.h>, which is unavailable
with MRB_NO_STDIO; use a static error message consistent with other
codegen_error() calls.

Fixes #6724.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-25 15:11:27 +09:00
Yukihiro "Matz" Matsumoto b9007a8f0a cmdprint.c: extract next_print_no() helper
Consolidate the duplicated print_no increment-and-wrap logic
from dbgcmd_print() and dbgcmd_info_local() into a single
next_print_no() function.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:05:02 +09:00
Yukihiro "Matz" Matsumoto d3dfe83aa1 apibreak.c: simplify get_break_index()
Return directly from the loop instead of using a hit flag
and separate index variable.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:04:25 +09:00
Yukihiro "Matz" Matsumoto e35c011537 cmdmisc.c: extract parse_file_line_spec() from parse_listcmd_args()
Flatten 4-level nested parsing of list command arguments into
a separate parse_file_line_spec() function.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:03:59 +09:00
Yukihiro "Matz" Matsumoto 1d52c7a3dd mrdb.c: extract check_breakpoint_hit() from mrb_code_fetch_hook()
Combine method and line breakpoint checks into a single
check_breakpoint_hit() helper, simplifying the DBG_RUN case.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:03:28 +09:00
Yukihiro "Matz" Matsumoto 8702244a42 mrdb.c: decompose parse_command() into lookup helpers
Extract find_command_by_word1() and find_command_by_words()
from parse_command(), separating command-table lookup from
tokenization logic.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:02:47 +09:00
Yukihiro "Matz" Matsumoto eedc95460c mruby-bin-debugger: extract raise_debugger_exception() helper
Both dbgcmd_run() and dbgcmd_quit() defined an exception class
and raised it with identical code. Add a shared static inline
helper in mrdb.h.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:02:11 +09:00
Yukihiro "Matz" Matsumoto 811741eb8e cmdbreak.c: unify delete/enable/disable via dbgcmd_set_breakpoint()
The three commands shared identical dispatch logic. Extract a
shared dbgcmd_set_breakpoint() that takes function pointers,
reducing each command to a one-line wrapper.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:01:19 +09:00
Yukihiro "Matz" Matsumoto 2c21e1a959 apibreak.c: extract alloc_breakpoint() helper
Extract common breakpoint slot allocation logic from
mrb_debug_set_break_line() and mrb_debug_set_break_method()
into a shared alloc_breakpoint() helper.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-24 09:00:49 +09:00
Yukihiro "Matz" Matsumoto 9a0e8e33ed mirb: use ISSPACE/ISALNUM from mruby.h, remove stale ctype.h
Remove redundant local ISSPACE/ISALNUM definitions from
mirb_completion.c and unused ctype.h includes from both
mirb_completion.c and mirb.c. The locale-independent macros
from mruby.h are already available via <mruby.h>.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 15:49:36 +09:00
Yukihiro "Matz" Matsumoto 48c38c822f mirb_editor.c: table-drive block keywords in calc_indent_level()
Replace the strncmp() if-else chain for block-opening and closing
keywords with a data-driven indent_table, matching the existing
dedent_table pattern. Also use mirb_is_word_char() for the word
boundary check.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 15:46:28 +09:00
Yukihiro "Matz" Matsumoto f3dc8d4ae3 mirb_buffer.c: extract buffer_join_line_up() helper
Replace duplicate line-joining logic in mirb_buffer_delete_back()
and mirb_buffer_delete_forward() with a shared helper that appends
a line's content to the previous line, then removes it.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-23 15:35:09 +09:00