Commit Graph

18642 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto f7d7bbef43 array.c: add string-specialized fast path for Array#sort!
when all elements are plain String (not subclass) and no block is
given, use specialized sort that calls mrb_str_cmp() directly,
bypassing sort_cmp overhead (GC arena, type dispatch, array
modification check).

includes subclass check to ensure String#<=> is not overridden.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:27 +09:00
Yukihiro "Matz" Matsumoto 5364c4167e array.c: add integer-specialized fast path for Array#sort!
when all elements are integers and no block is given, use
specialized heapify/insertion_sort that compare mrb_int values
directly, bypassing sort_cmp entirely. this eliminates per-comparison
overhead of GC arena save/restore, type checking, and array
modification checks.

the pre-scan to detect all-integer arrays is O(n), negligible
compared to O(n log n) sort. non-integer and block sorts are
unaffected.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto 02bb943960 array.c: optimize heap sort with hole-style sift-down and Floyd's method
two improvements to Array#sort!'s heap sort:

1. hole-style sift-down: save root value, move larger children up
   one at a time, write saved value once at the end. reduces
   assignments from 3 per level (swap) to 1 per level (move).

2. Floyd's bottom-up heap deletion: during extraction phase, sift
   the hole down to a leaf using only child-child comparisons
   (~1 comparison per level), then sift up to find the correct
   position. this reduces average comparisons from ~2 log n to
   ~log n per extraction, nearly halving the total comparison
   count for the sort.

both changes preserve O(n log n) worst case and O(1) extra space.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto e292d7a6c4 symbol.c: implement lazy symbol GC (mark-sweep)
when dynamic symbol count reaches MRB_SYMBOL_MAX, run a mark-sweep
pass over all live objects to identify referenced symbols. sweep
unreferenced dynamic symbols, freeing their individually-allocated
string data and marking symtbl slots as tombstones.

mark phase traverses:
- all heap objects (method tables, IV tables, arrays, hashes, envs)
- VM stack values (MRB_TT_SYMBOL)
- call stack method IDs (ci->mid)
- root and current context

after sweep, rebuild hash table to maintain valid collision chains.

this completes the A+ symbol GC plan: the limit acts as a GC
trigger rather than a hard cap. unreferenced DoS symbols are
reclaimed, allowing legitimate code to continue.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto cb64a0b4a4 symbol.c: use individual malloc for dynamic symbol strings
dynamic symbols (created via to_sym, send, etc.) now use
mrb_malloc() instead of sym_pool_alloc(). this makes them
individually freeable by future symbol GC.

static symbols (presym, mrb_intern_static, literals) continue
to use the pool allocator for compact storage.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto afc0753c1d symbol.c: add dynamic symbol limit (MRB_SYMBOL_MAX)
track dynamic (runtime-created) symbols separately from presyms,
inline symbols, and static C API symbols. raise RuntimeError when
the dynamic symbol count exceeds MRB_SYMBOL_MAX (default 4096).

this prevents DoS attacks via unbounded symbol creation (e.g.
"str".to_sym in a loop). presyms and inline symbols are not
counted toward the limit.

infrastructure for future symbol GC: sym_flags array tracks
per-symbol metadata (SYM_FL_DYNAMIC flag).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto 3f8e13da6f codegen.c: consolidate while/until loop codegen
merge codegen_while/codegen_until into codegen_loop, and
codegen_while_mod/codegen_until_mod into codegen_loop_mod.
each pair differed only in swapped constant-condition checks
(true_always/false_always) and jump opcode (OP_JMPNOT/OP_JMPIF).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:26 +09:00
Yukihiro "Matz" Matsumoto 65e24f4083 codegen.c: consolidate codegen_dot2/codegen_dot3 into codegen_range
the two functions differed only in OP_RANGE_INC vs OP_RANGE_EXC.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:25 +09:00
Yukihiro "Matz" Matsumoto 0b79c70935 dump.c: consolidate error handling in mrb_dump_irep_cfunc()
replace four repeated `mrb_free(mrb, bin); return MRB_DUMP_WRITE_FAULT`
sequences with a single goto-based cleanup path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:25 +09:00
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 0f47249963 class.c: clear const cache on include/prepend
mrb_include_module() and mrb_prepend_module() did not invalidate
the constant cache. stale cache entries caused incorrect constant
resolution after include changed the ancestor chain.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:25 +09:00
Yukihiro "Matz" Matsumoto 3b85d48f89 class.c: fix module/class reopening via include
mrb_vm_define_module() and mrb_vm_define_class() incorrectly
reopened modules/classes accessible through include rather than
creating new ones. CRuby only reopens modules directly defined
on the outer scope.

the internal define_module()/define_class() use
mrb_const_defined_at() which walks ancestors for Object class.
bypass them and create modules/classes directly in the VM path.

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 d2caa144be cdump.c: consolidate sym_name_with_*_p into sym_name_with_suffix_p
three functions differed only in the trailing character check ('=',
'?', '!'). replace with a single parameterized function.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto f1a6274c34 vm.c: extract vm_call_proc() to consolidate OP_CALL and OP_BLKCALL
both opcodes share identical proc dispatch logic (alias resolution,
callinfo setup, cfunc/irep branching). the only difference is how
nargs is computed (ci_bidx vs operand b).

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 6a6e2b48ac vm.c: replace mrb_funcall_argv() with goto L_SEND_SYM in OP_MATHILV
avoid re-entrant VM call from C; use the same dispatch pattern as
OP_MATH and OP_MATHI for consistency.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 82bb954c23 vm.c: extract vm_define_method() to consolidate OP_TDEF and OP_SDEF
Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 309f450bab gc.c: use actual work done for debt repayment in incremental step
Decrement gc_debt by the actual number of objects processed
instead of the fixed GC_STEP_SIZE. This makes step_ratio
directly affect debt repayment: larger steps repay more debt,
naturally reducing GC invocation frequency.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 851da984b4 gc.c: use :debt instead of :threshold in GC.stat
Expose gc_debt directly as :debt in GC.stat without sign negation.
The debt model has no threshold ceiling, so :threshold was a
misleading name. Negative debt means credit, positive means GC
is behind on collection work.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:24 +09:00
Yukihiro "Matz" Matsumoto 4d03f40204 doc/internal/gc.md: update for debt model and new tuning parameters
Document the debt-based GC trigger model, malloc threshold,
step limit, GC.stat, and tuning guide.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:23 +09:00
Yukihiro "Matz" Matsumoto 878ecd9b09 gc.c: expose negated gc_debt as :threshold in GC.stat
Use -gc_debt as the :threshold key in GC.stat for familiarity.
Positive means credit remaining, negative means GC is overdue.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:23 +09:00
Yukihiro "Matz" Matsumoto f0b3fdfb14 gc.c: replace threshold model with debt-based GC trigger
Replace the threshold-based GC trigger (gc->threshold vs gc->live)
with a debt model (gc->gc_debt). Each allocation increments debt;
each GC step decrements by GC_STEP_SIZE. When a cycle completes,
credit is proportional to live_after_mark * interval_ratio, giving
a natural feedback loop that adapts to allocation rate.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:23 +09:00
Yukihiro "Matz" Matsumoto 4b866a84da gc.c: add step_limit and malloc_threshold for GC tuning
GC.step_limit caps the per-step work in incremental GC,
enabling more predictable pause times for real-time use.
GC.malloc_threshold triggers GC based on allocation bytes,
addressing memory pressure from large buffers.
Both default to 0 (disabled), preserving existing behavior.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:23 +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 cfa422b872 gc.c: mark leaf objects directly without gray stack
Leaf types (String, Integer, BigInt, Complex, CPTR) have no children
besides their class pointer. Mark them black immediately in
mrb_gc_mark() instead of pushing to the gray stack, reducing gray
stack pressure and overflow frequency.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 60cde305c1 gc.c: implement GC.stat method
Return a Hash with GC statistics: live, threshold, state,
generational, full. When MRB_GC_STATS is defined, also includes
total, minor, major counters.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 52fb294172 gc.c: add optional GC statistics counters
Add gc_total_count, minor_gc_count, major_gc_count (uint32_t) to
mrb_gc, guarded by MRB_GC_STATS. Zero cost when disabled.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 78658d67e1 vm.c: extract OP_GETIDX, OP_GETIDX0, OP_SETIDX, OP_DIV into static helpers
Phase 2 of opcode handler extraction. these opcodes use
L_SEND_SYM/L_SENDB_SYM fallback for generic method dispatch when
the fast path (Array/Hash/String/Integer/Float) does not apply.
add VM_SEND_SYM and VM_SENDB_SYM return codes. move TYPES2 macro
to file scope for use by vm_op_div.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:22 +09:00
Yukihiro "Matz" Matsumoto 95bfa86160 vm.c: extract OP_ENTER, OP_ARGARY, OP_BLKPUSH into static helpers
extract the three largest self-contained opcode handlers from the
mrb_vm_exec() dispatch loop into static functions. add
__attribute__((flatten)) to mrb_vm_exec() so that the compiler
inlines them back, producing identical binary output while keeping
the source clean.

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 3d53864991 fp_uscale.c: add shortest representation for Float#to_s
Use uscale-based shortest() to compute the minimal decimal string
that uniquely identifies each double. This guarantees perfect
round-trip (parse(to_s(x)) == x) while keeping output concise
(e.g. 0.1 prints as "0.1", not "0.10000000000000001").

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 9ff1aa9d55 fp_uscale.c: replace fmt_fp.c and readfloat.c with uscale algorithm
Replace separate float formatting (fmt_fp.c) and parsing (readfloat.c)
implementations with a unified fp_uscale.c using 128-bit unrounded
scaling. Both mrb_format_float() and mrb_read_float() now share a
single pow10 table and uscale() primitive for decimal/binary conversion.

This fixes subnormal parsing accuracy (old code returned 0.0 for the
smallest subnormals) and corrects %.2f rounding for values like
12345.125. Table size grows from ~5KB to ~11KB in .rodata.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 50bc8c6136 vm.c: replace constant cache generation counter with direct invalidation
Remove the per-entry generation field and per-state generation
counter. Invalidation now clears entries directly, removing one
comparison from every OP_GETCONST hot path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto d0d2c3072c class.c: use 2-way set-associative method cache
Right-shift class pointer by 4 before hashing to remove
always-zero alignment bits, improving hash distribution.
Organize 256 cache entries as 128 sets x 2 ways to reduce
conflict misses when multiple methods share a hash bucket.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:21 +09:00
Yukihiro "Matz" Matsumoto 7675601b92 vm.c: add constant lookup cache with generation counter
Cache OP_GETCONST results in a global direct-mapped cache (64 entries)
keyed by (irep, sym). Invalidate all entries via a generation counter
bumped on mrb_const_set(), mrb_const_remove(), and
mrb_define_const_id(). ~10% faster on constant-heavy code; disabled
with MRB_NO_CONST_CACHE.

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-23 19:25:20 +09:00
Yukihiro "Matz" Matsumoto b2d935b6d3 Merge pull request #6803 from saeki-mototsune/fix_psp_build_config 2026-04-23 19:24:10 +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 8996152365 Merge pull request #6786 from dearblue/sysfail 2026-04-23 19:15:38 +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
Yukihiro "Matz" Matsumoto 05f7236586 Merge pull request #6805 from mruby/dependabot/github_actions/github-actions-dependencies-f3e34333ea 2026-04-23 16:01:46 +09:00
Yukihiro "Matz" Matsumoto d359182b47 Merge pull request #6804 from mruby/dependabot/bundler/bundler-dependencies-39953ac9c0 2026-04-23 15:52:01 +09:00
dependabot[bot] ccd661b429 build(deps): bump github/codeql-action
Bumps the github-actions-dependencies group with 1 update: [github/codeql-action](https://github.com/github/codeql-action).


Updates `github/codeql-action` from 4.35.1 to 4.35.2
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v4.35.1...v4.35.2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-22 14:54:14 +00:00
dependabot[bot] aea5d584f0 build(deps): bump rake in the bundler-dependencies group
Bumps the bundler-dependencies group with 1 update: [rake](https://github.com/ruby/rake).


Updates `rake` from 13.3.1 to 13.4.1
- [Release notes](https://github.com/ruby/rake/releases)
- [Changelog](https://github.com/ruby/rake/blob/master/History.rdoc)
- [Commits](https://github.com/ruby/rake/compare/v13.3.1...v13.4.1)

---
updated-dependencies:
- dependency-name: rake
  dependency-version: 13.4.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: bundler-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-21 14:53:28 +00:00
SaekiMototsune 08b6d2ecd0 Disable some gems on build_config for playstationportable 2026-04-21 18:50:14 +09:00
Yukihiro "Matz" Matsumoto f469e7567a Merge pull request #6801 from mruby/dependabot/github_actions/github-actions-dependencies-9527efa922 2026-04-21 08:34:06 +09:00