Commit Graph

18392 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto b460554d33 vm.c: generalize pre-dispatch argument count check for C methods
Replace check_method_noarg() with check_argument_count() that validates
min <= argc <= max using the full aspec stored in mrb_method_t.flags.
This catches ArgumentError earlier at dispatch time, before entering
the C function.

The old check only handled the special case of aspec==0 (NOARG).
The new check extracts REQ, OPT, REST, POST, KEY, and KDICT from
the aspec and validates accordingly. Keyword hash is counted as
a positional arg only when the method doesn't accept keywords.

Remove MRB_METHOD_NOARG_P macro from proc.h (subsumed by aspec check).
Fix 15 incorrect aspec declarations across the codebase that were
exposed by the stricter enforcement.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 14:25:48 +09:00
Yukihiro "Matz" Matsumoto 4a097525df proc.h: unify method flag layout; eliminate aspec shifting
Move MRB_METHOD_FUNC_FL to bit 24 and visibility flags to
bits 25-26 so that MRB_ARGS_*() values (bits 0-23) can be
stored directly without shifting. This makes MRB_MT_PRIVATE
and MRB_METHOD_PRIVATE_FL the same value, eliminating the
dual-constant confusion and simplifying the MRB_MT_ENTRY()
macro to a single OR operation.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 13:49:17 +09:00
Yukihiro "Matz" Matsumoto ada229d2b0 proc.h: remove MRB_METHOD_NOARG flag; derive from aspec
The NOARG flag (bit 2) is now redundant since the full aspec is
stored in bits 4+ of the flags field. Replace the dedicated bit
check with aspec==0 check. Store aspec in define_method_id() for
dynamically defined methods too.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 11:51:59 +09:00
Yukihiro "Matz" Matsumoto 483c155a41 class.c: store aspec in ROM method table entries
Restore MRB_ARGS_* argument specs and ISO section comments to all
709 ROM method table entries. The aspec is encoded in bits 4-27 of
the flags field; MRB_MT_NOARG is now auto-derived from aspec==0.

Add MRB_MT_ENTRY_PRIVATE() macro for private methods (53 entries)
and MRB_MT_ASPEC() accessor for extracting aspec from flags.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 11:44:28 +09:00
Yukihiro "Matz" Matsumoto 20b9002214 class.c: merge conditional methods into ROM tables
Move conditional mrb_define_method_id() calls into ROM entry
arrays using #ifdef guards. With linear search, sizeof in
MRB_MT_ROM_TAB() adjusts automatically after preprocessing.

Cross-class ROM tables (methods a gem defines on a class it does
not own) are reverted to mrb_define_method_id(). Multiple gems
should not add ROM table layers to the same class; each layer
costs a 16-byte mrb_mt_tbl struct in RAM and deepens the lookup
chain. Use mrb_define_method_id() for cross-class methods.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 11:05:03 +09:00
Yukihiro "Matz" Matsumoto 8adba34bd9 class.c: auto-set MRB_MT_FUNC in MRB_MT_ENTRY macro
Since ROM table entries are always C functions, have the
MRB_MT_ENTRY() macro set MRB_MT_FUNC automatically. This
simplifies entry definitions across all 32 source files.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 10:37:06 +09:00
Yukihiro "Matz" Matsumoto 0fab703028 class.c: use linear search for method tables; make ROM entries const
Replace binary search with linear scan in mt_get(), mt_put(),
mt_del(), mt_chain_has(), and mrb_mt_foreach(). The method cache
makes repeated lookups O(1), so linear scan on cache misses is
acceptable.

This removes the sorting requirement, allowing ROM entry arrays
to be declared const. On embedded systems, const static data
resides in flash/ROM instead of RAM, saving ~8.4KB for ~700
method entries on 32-bit MCUs.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 08:26:05 +09:00
Yukihiro "Matz" Matsumoto ce8ce3f96d class.c: separate flags from symbol key in mrb_mt_entry
Add a dedicated uint32_t flags field to mrb_mt_entry instead of
packing flags into the lower bits of mrb_sym via MRB_MT_KEY().
The key field now stores the pure symbol ID with no shift.

On 64-bit, the flags field fills the alignment gap after mrb_sym,
so entry size remains 16 bytes (zero overhead). On 32-bit, entry
size grows from 8 to 12 bytes.

This eliminates the risk of symbol ID overflow from the 4-bit
shift, and the flags field can later store aspec (MRB_ARGS_*)
information that was previously discarded.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-20 07:57:02 +09:00
Yukihiro "Matz" Matsumoto bde2202100 class.c: refactor ROM method tables to array-of-structs layout
Replace the parallel-arrays (struct-of-arrays) ROM method table
layout with an array-of-structs layout where each mrb_mt_entry
bundles its function pointer and symbol key together.

New MRB_MT_ENTRY() and MRB_MT_ROM_TAB() macros simplify ROM table
definitions from a 3-part pattern (SIZE define + anonymous struct +
mrb_mt_tbl) to a 2-part pattern (entries array + mrb_mt_tbl).

Internal mt_* functions in class.c are simplified: single memmove/
memcpy operations replace paired key+value operations.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 23:59:30 +09:00
Yukihiro "Matz" Matsumoto cfd9214b3d class.c: add MRB_MT_FROZEN_BIT for method table layers
When mrb_mt_init_rom() is called on a class that already has a
mutable method table (from prior mrb_define_method_id() calls),
the mutable top layer is now frozen in place instead of being
left as a writable layer that wastes RAM on embedded systems.

The frozen bit (bit 29 of alloc field) marks heap-allocated
method table layers as temporarily immutable. Unlike the
readonly bit (bit 30, for true ROM), frozen layers are
automatically unfrozen when methods are later added via
mrb_define_method_raw() or removed via mrb_remove_method().
This preserves the c->mt pointer, which is critical because
iclasses (from module inclusion) hold a copy of it.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 23:25:16 +09:00
Yukihiro "Matz" Matsumoto a208440c4f numeric.c: fix SEGV in int_divmod when argument is not numeric
int_divmod passed an integer mrb_value directly to flo_divmod, which
used mrb_float() to extract the value. In word boxing mode, this caused
a misaligned pointer dereference. Use mrb_ensure_float_type() to safely
convert the integer to float before passing to flo_divmod.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 20:31:45 +09:00
Yukihiro "Matz" Matsumoto a1ee420aea test/t/syntax.rb: add test for &nil in formal parameters
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 17:26:04 +09:00
Yukihiro "Matz" Matsumoto b07518e85c parse.y: implement &nil in formal parameters
`&nil` is recently introduced in CRuby to explicitly declare that
a method does not accept a block. When a block is passed,
ArgumentError "no block accepted" is raised. This is analogous to
`**nil` for keyword arguments.

The noblock flag is encoded in bit 23 of OP_ENTER's aspec operand
(24=n1:m5:o5:r1:m5:k5:d1:b1), avoiding the need for a new opcode.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 16:54:17 +09:00
Yukihiro "Matz" Matsumoto 337cf4bfd5 etc.c: fix undefined behavior in WORDBOX_FLOAT_ADDEND
Left-shifting a negative int64_t is undefined behavior in C.
Cast to uint64_t before the shift to produce the same bit pattern
using well-defined unsigned arithmetic.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 15:44:54 +09:00
Yukihiro "Matz" Matsumoto 0ed26f8352 class.c: rename mt_/MT_ to mrb_mt_/MRB_MT_ for non-static identifiers
Follow mruby's naming convention: non-static types, macros, and
functions use the mrb_/MRB_ prefix. Renamed:
- union mt_ptr -> union mrb_mt_ptr
- mt_tbl -> mrb_mt_tbl
- MT_KEY(), MT_FUNC, MT_NOARG, MT_PUBLIC, MT_PRIVATE -> MRB_MT_*
- MT_KEY_SHIFT, MT_READONLY_BIT, MT_REMOVED_P -> MRB_MT_*
- mt_init_rom() -> mrb_mt_init_rom()
File-local static functions and macros in class.c are unchanged.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 15:22:55 +09:00
Yukihiro "Matz" Matsumoto 494d55c9f7 class.c: use tombstone for remove_method with ROM method tables
Previously, removing a ROM method required flattening all chain layers
into a single mutable table. This was O(n) and allocated RAM for all
previously-ROM methods.

Use a tombstone marker (MT_FUNC flag with func=NULL) instead. The
mt_get() lookup treats this as "not found" and stops the chain walk,
hiding the ROM entry while allowing superclass lookup.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 14:57:50 +09:00
Yukihiro "Matz" Matsumoto 16fb8a6b08 doc: add ROM method table guide
Comprehensive documentation covering architecture, definition
format, flags, extension gem usage, conditional methods, runtime
behavior (COW, method removal, GC), and conversion guide.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 14:38:29 +09:00
Yukihiro "Matz" Matsumoto bcc585a80f presym.h: merge enable.h into presym.h
Since disable.h was removed, enable.h was the only remaining
dispatch target from presym.h. Inline its contents into presym.h
and delete the now-redundant enable.h. Also define _2 backward
compatibility macros in terms of the standard macros.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 14:24:27 +09:00
Yukihiro "Matz" Matsumoto dcd77f1efd mruby-compiler: replace MRB_SYM_2() with MRB_SYM() macros
The _2 suffix variants accept an mrb_state* parameter that is
always ignored with presym enabled. Replace all uses in codegen.c,
parse.y, and y.tab.c with the standard macros. The _2 macro
definitions are kept in presym headers for backward compatibility.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 14:14:40 +09:00
Yukihiro "Matz" Matsumoto bd4f380178 build system: remove dead presym_enabled? checks
Since presym is now always enabled, the @enable_presym flag,
presym_enabled? method, and all conditional branches guarding
presym-specific code paths are dead code. Remove them and
simplify the affected build logic.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 14:10:02 +09:00
Yukihiro "Matz" Matsumoto 5829ca60b6 doc: update presym documentation
Remove references to conf.disable_presym and MRB_NO_PRESYM.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:18:00 +09:00
Yukihiro "Matz" Matsumoto f86caf9e14 mruby-errno: remove MRB_NO_PRESYM fallback code
Simplify struct layouts and macros to use presym-only path.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:51 +09:00
Yukihiro "Matz" Matsumoto 52c71f5b99 mrbgems: remove MRB_NO_PRESYM guards from additional gems
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:43 +09:00
Yukihiro "Matz" Matsumoto 9fbc11c6d0 mrbgems: remove MRB_NO_PRESYM guards from core extension gems
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:34 +09:00
Yukihiro "Matz" Matsumoto 03be6af0b9 src: remove MRB_NO_PRESYM guards from core source files
Presym is now always enabled. Remove #ifndef MRB_NO_PRESYM
guards and their #else fallback branches from all core files.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:24 +09:00
Yukihiro "Matz" Matsumoto 81689045a6 presym.h: remove MRB_NO_PRESYM dispatch and delete disable.h
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:15 +09:00
Yukihiro "Matz" Matsumoto eccfe52612 build system: always enable presym for mrbc build
Remove disable_presym from mrbc_build and cross-build fallback.
Add explicit object file dependencies on presym headers in
presym.rake to prevent compilation before headers are generated.

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 12:17:02 +09:00
Yukihiro "Matz" Matsumoto cf52364c43 mruby-kernel-ext: ROM method table for Kernel extensions (7 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:39 +09:00
Yukihiro "Matz" Matsumoto 4448b5e227 mruby-random: ROM method tables for Random/Kernel/Array (9 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:37 +09:00
Yukihiro "Matz" Matsumoto 7e83c0e974 mruby-complex: ROM method tables for Complex/NilClass/Kernel
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:34 +09:00
Yukihiro "Matz" Matsumoto 3a7e0e9d82 mruby-rational: ROM method tables for Rational/Integer/NilClass/Kernel
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:33 +09:00
Yukihiro "Matz" Matsumoto 3041dda976 mruby-struct: ROM method table for Struct class (15 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:32 +09:00
Yukihiro "Matz" Matsumoto 653bf360bc mruby-socket: ROM method tables for Socket classes
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:30 +09:00
Yukihiro "Matz" Matsumoto 067f123193 mruby-method: ROM method tables for Method/UnboundMethod classes
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:28 +09:00
Yukihiro "Matz" Matsumoto 08e800e43e mruby-metaprog: ROM method tables for metaprogramming extensions
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:26 +09:00
Yukihiro "Matz" Matsumoto ba0f450fb4 mruby-io: ROM method tables for IO and File classes
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:24 +09:00
Yukihiro "Matz" Matsumoto ae41bb332a mruby-set: ROM method table for Set class (43 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:23 +09:00
Yukihiro "Matz" Matsumoto f46d77dcf0 mruby-time: ROM method table for Time class
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-19 09:39:19 +09:00
Yukihiro "Matz" Matsumoto f0a4820d44 mruby-symbol-ext: ROM method table for Symbol extensions (2 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:44:30 +09:00
Yukihiro "Matz" Matsumoto 4f167f55f7 mruby-range-ext: ROM method table for Range extensions (3 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:44:29 +09:00
Yukihiro "Matz" Matsumoto 63df017ff6 mruby-object-ext: ROM method tables for NilClass/Kernel/BasicObject extensions (5 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:44:27 +09:00
Yukihiro "Matz" Matsumoto b52d3936e6 mruby-numeric-ext: ROM method table for Integer extensions (9 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:44:25 +09:00
Yukihiro "Matz" Matsumoto 0ac01f23ba mruby-hash-ext: ROM method table for Hash extensions (6 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:44:23 +09:00
Yukihiro "Matz" Matsumoto 532ab1a74a mruby-proc-ext: ROM method tables for Proc/Kernel extensions (6 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:41:20 +09:00
Yukihiro "Matz" Matsumoto 51d0bfa1fc mruby-class-ext: ROM method tables for Module/Class extensions (11 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:41:18 +09:00
Yukihiro "Matz" Matsumoto 6b66f99c6b mruby-array-ext: ROM method table for Array extensions (29 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:41:10 +09:00
Yukihiro "Matz" Matsumoto d95d71fb8b mruby-string-ext: ROM method table for String/Integer extensions (54 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:38:51 +09:00
Yukihiro "Matz" Matsumoto 2c2e38cceb proc.c: ROM method table for Proc class (5 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:30:53 +09:00
Yukihiro "Matz" Matsumoto 6cf02c26b9 error.c: ROM method table for Exception class (7 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:30:51 +09:00
Yukihiro "Matz" Matsumoto c679c2762d symbol.c: ROM method table for Symbol class (6 methods)
Co-authored-by: Claude <noreply@anthropic.com>
2026-02-18 16:30:49 +09:00