From 71cb3c2e3af6cf9f131c4b91186821bbe0fd40d4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 20 Feb 2026 22:24:31 +0900 Subject: [PATCH] class.c: allocate ROM table wrappers per mrb_state ROM method tables used static mrb_mt_tbl variables shared across the process. The next pointer in each wrapper was mutated by mrb_mt_init_rom(), causing cross-state contamination when multiple mrb_state instances existed. Allocate mrb_mt_tbl wrappers per-state via mrb_malloc(). The const mrb_mt_entry[] arrays remain static and shared. Wrappers are tracked in mrb->rom_mt and freed at mrb_close(). Remove MRB_MT_ROM_TAB macro; add MRB_MT_INIT_ROM macro that auto-computes size and calls the new mrb_mt_init_rom(). Co-authored-by: Claude --- doc/guides/rom-method-table.md | 87 +++++++++++---------- include/mruby.h | 2 + include/mruby/class.h | 22 +++--- mrbgems/mruby-array-ext/src/array.c | 3 +- mrbgems/mruby-class-ext/src/class.c | 6 +- mrbgems/mruby-complex/src/complex.c | 3 +- mrbgems/mruby-hash-ext/src/hash_ext.c | 3 +- mrbgems/mruby-io/src/file.c | 3 +- mrbgems/mruby-io/src/io.c | 3 +- mrbgems/mruby-kernel-ext/src/kernel.c | 3 +- mrbgems/mruby-metaprog/src/metaprog.c | 6 +- mrbgems/mruby-method/src/method.c | 6 +- mrbgems/mruby-numeric-ext/src/numeric_ext.c | 3 +- mrbgems/mruby-object-ext/src/object.c | 6 +- mrbgems/mruby-proc-ext/src/proc.c | 3 +- mrbgems/mruby-random/src/random.c | 3 +- mrbgems/mruby-range-ext/src/range.c | 3 +- mrbgems/mruby-rational/src/rational.c | 3 +- mrbgems/mruby-set/src/set.c | 3 +- mrbgems/mruby-socket/src/socket.c | 12 +-- mrbgems/mruby-string-ext/src/string.c | 3 +- mrbgems/mruby-struct/src/struct.c | 3 +- mrbgems/mruby-symbol-ext/src/symbol.c | 3 +- mrbgems/mruby-time/src/time.c | 3 +- src/array.c | 3 +- src/class.c | 39 ++++++--- src/error.c | 3 +- src/hash.c | 3 +- src/kernel.c | 3 +- src/numeric.c | 9 +-- src/object.c | 9 +-- src/proc.c | 3 +- src/range.c | 3 +- src/state.c | 12 +++ src/string.c | 3 +- src/symbol.c | 3 +- 36 files changed, 142 insertions(+), 146 deletions(-) diff --git a/doc/guides/rom-method-table.md b/doc/guides/rom-method-table.md index 3a694dff1..51769180a 100644 --- a/doc/guides/rom-method-table.md +++ b/doc/guides/rom-method-table.md @@ -61,16 +61,24 @@ Entries are searched linearly, so source code order does not matter. The method cache makes repeated lookups O(1), so the linear scan only occurs on cache misses. +### Per-State Wrappers + +The `const mrb_mt_entry[]` arrays are truly static and shared across +the process. However, the `mrb_mt_tbl` wrapper (which carries the +`next` pointer for chaining) is heap-allocated per `mrb_state` by +`MRB_MT_INIT_ROM()`. This allows multiple `mrb_state` instances in +the same process to each have independent method table chains, even +when linking to the same const entries. + ## How to Define a ROM Method Table ### Step 1: Define the Static Data -Include `` (which provides `mrb_mt_entry`, -`mrb_mt_tbl`, `MRB_MT_ENTRY()`, `MRB_MT_ROM_TAB()`, and flag -constants) and define the ROM entries: +Include `` (which provides `mrb_mt_entry`, +`MRB_MT_ENTRY()`, and flag constants) and define the ROM entries: ```c -#include +#include #include static const mrb_mt_entry my_rom_entries[] = { @@ -78,25 +86,24 @@ static const mrb_mt_entry my_rom_entries[] = { MRB_MT_ENTRY(my_method_b, MRB_SYM(method_b), MRB_ARGS_NONE()), MRB_MT_ENTRY(my_method_eq, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl my_rom_mt = MRB_MT_ROM_TAB(my_rom_entries); ``` ### Step 2: Register in the Init Function Replace `mrb_define_method_id()` calls with a single -`mrb_mt_init_rom()` call: +`MRB_MT_INIT_ROM()` call: ```c void mrb_mruby_mygem_gem_init(mrb_state *mrb) { struct RClass *c = mrb_define_class_id(mrb, MRB_SYM(MyClass), mrb->object_class); - mrb_mt_init_rom(c, &my_rom_mt); + MRB_MT_INIT_ROM(mrb, c, my_rom_entries); } ``` -`mrb_mt_init_rom()` pushes the ROM layer onto the class's method -table chain. +`MRB_MT_INIT_ROM()` allocates a per-state wrapper and pushes the ROM +layer onto the class's method table chain. ### Step 3: Verify @@ -107,7 +114,7 @@ to Ruby code. ### Data Types -Defined in `include/mruby/internal.h`: +Defined in `include/mruby/class.h`: ```c union mrb_mt_ptr { @@ -140,11 +147,10 @@ typedef struct mrb_mt_tbl { /* Extract aspec from combined flags */ #define MRB_MT_ASPEC(flags) ((mrb_aspec)((flags) & 0xffffff)) -/* ROM table initializer (auto-computes size from entries array) */ -#define MRB_MT_ROM_TAB(entries) { \ - (int)(sizeof(entries)/sizeof(entries[0])), \ - (int)(sizeof(entries)/sizeof(entries[0])) | MRB_MT_READONLY_BIT, \ - (mrb_mt_entry*)(entries), NULL } +/* Allocate a per-state ROM wrapper and push onto class method chain */ +#define MRB_MT_INIT_ROM(mrb, cls, entries) \ + mrb_mt_init_rom(mrb, cls, entries, \ + (int)(sizeof(entries)/sizeof(entries[0]))) ``` ### Flags @@ -190,13 +196,15 @@ MRB_IVSYM(name) /* @name */ ### API ```c -void mrb_mt_init_rom(struct RClass *c, mrb_mt_tbl *rom); +void mrb_mt_init_rom(mrb_state *mrb, struct RClass *c, + const mrb_mt_entry *entries, int size); ``` -Pushes the ROM layer onto the class's method table chain. The -readonly flag is already set by `MRB_MT_ROM_TAB()`. Multiple calls -push additional layers, which is how extension gems add methods to -core classes. +Allocates a per-state `mrb_mt_tbl` wrapper for the const entries and +pushes it onto the class's method table chain. The wrapper is tracked +in `mrb->rom_mt` and freed at `mrb_close()`. Use the `MRB_MT_INIT_ROM` +macro to auto-compute the size. Multiple calls push additional layers, +which is how extension gems add methods to core classes. ## Entry Correspondence @@ -219,7 +227,7 @@ static const mrb_mt_entry str_rom_entries[] = { Methods that depend on build configuration (e.g., `MRB_NO_FLOAT`) can use `#ifdef` directly inside the ROM entries array. The `sizeof` in -`MRB_MT_ROM_TAB()` automatically adjusts to the number of entries +`MRB_MT_INIT_ROM()` automatically adjusts to the number of entries that survive preprocessing: ```c @@ -230,7 +238,6 @@ static const mrb_mt_entry integer_rom_entries[] = { MRB_MT_ENTRY(int_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), #endif }; -static mrb_mt_tbl integer_rom_mt = MRB_MT_ROM_TAB(integer_rom_entries); ``` For conditional methods on a **different class**, use a separate ROM @@ -239,13 +246,12 @@ table wrapped in the `#ifdef`: ```c #ifndef MRB_NO_FLOAT static const mrb_mt_entry float_rom_entries[] = { ... }; -static mrb_mt_tbl float_rom_mt = MRB_MT_ROM_TAB(float_rom_entries); #endif void mrb_init_numeric(mrb_state *mrb) { - mrb_mt_init_rom(integer, &integer_rom_mt); + MRB_MT_INIT_ROM(mrb, integer, integer_rom_entries); #ifndef MRB_NO_FLOAT - mrb_mt_init_rom(fl, &float_rom_mt); + MRB_MT_INIT_ROM(mrb, fl, float_rom_entries); #endif } ``` @@ -253,19 +259,18 @@ void mrb_init_numeric(mrb_state *mrb) { ## Extension Gems Extension gems use exactly the same pattern. Since gems are -initialized after core, calling `mrb_mt_init_rom()` pushes the gem's +initialized after core, calling `MRB_MT_INIT_ROM()` pushes the gem's ROM layer in front of the core ROM layer: ```c /* mrbgems/mruby-string-ext/src/string.c */ static const mrb_mt_entry string_ext_rom_entries[] = { ... }; -static mrb_mt_tbl string_ext_rom_mt = MRB_MT_ROM_TAB(string_ext_rom_entries); void mrb_mruby_string_ext_gem_init(mrb_state *mrb) { struct RClass *s = mrb->string_class; - mrb_mt_init_rom(s, &string_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, s, string_ext_rom_entries); } ``` @@ -282,8 +287,8 @@ A gem may also define ROM tables for multiple classes: ```c void mrb_mruby_mygem_gem_init(mrb_state *mrb) { - mrb_mt_init_rom(mrb->string_class, &string_mygem_rom_mt); - mrb_mt_init_rom(mrb->integer_class, &integer_mygem_rom_mt); + MRB_MT_INIT_ROM(mrb, mrb->string_class, string_mygem_rom_entries); + MRB_MT_INIT_ROM(mrb, mrb->integer_class, integer_mygem_rom_entries); } ``` @@ -303,10 +308,10 @@ Some methods must remain as `mrb_define_method_id()` calls: - **Cross-class methods** (methods on a class the gem does not own): Each ROM table adds a 16-byte `mrb_mt_tbl` layer to the target class's chain. For 1-2 methods, this overhead exceeds the savings. - Use `mrb_define_method_id()` instead — cross-class methods share + Use `mrb_define_method_id()` instead -- cross-class methods share the target class's existing mutable layer. -These methods are added after `mrb_mt_init_rom()` and go into the +These methods are added after `MRB_MT_INIT_ROM()` and go into the mutable layer that sits in front of the ROM chain. ## Runtime Behavior @@ -351,12 +356,13 @@ data is copied. ROM layers are skipped during GC mark and sweep phases. Only mutable layers are scanned for live RProc references and freed when the class -is collected. This reduces GC overhead. +is collected. ROM wrappers are freed at `mrb_close()` via the +`mrb->rom_mt` tracking list. ### Memory Measurement -`mrb_class_mt_memsize()` reports only mutable layer memory. ROM layers -are not counted since they do not consume heap memory. +`mrb_class_mt_memsize()` reports only mutable layer memory. ROM +wrappers are tracked separately and not counted per-class. ## Converting Existing Code @@ -374,14 +380,12 @@ To convert existing `mrb_define_method_id()` calls to a ROM table: - For private methods, OR `MRB_MT_PRIVATE` into the aspec: `MRB_MT_ENTRY(func, sym, aspec | MRB_MT_PRIVATE)` -4. **Create** the table with `MRB_MT_ROM_TAB(entries)`. +4. **Replace** the calls with `MRB_MT_INIT_ROM(mrb, c, entries)`. -5. **Replace** the calls with `mrb_mt_init_rom(c, &my_rom_mt)`. - -6. **Keep** any methods that cannot be converted (see above) as +5. **Keep** any methods that cannot be converted (see above) as individual `mrb_define_method_id()` calls after the ROM init. -7. **Build and test**: `rake CONFIG=host-debug -j24 all test:run:serial` +6. **Build and test**: `rake CONFIG=host-debug -j24 all test:run:serial` ### Before @@ -402,10 +406,9 @@ static const mrb_mt_entry foo_rom_entries[] = { MRB_MT_ENTRY(foo_baz, MRB_SYM(baz), MRB_ARGS_NONE()), MRB_MT_ENTRY(foo_eq, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl foo_rom_mt = MRB_MT_ROM_TAB(foo_rom_entries); void mrb_mruby_foo_gem_init(mrb_state *mrb) { struct RClass *foo = mrb_define_class_id(mrb, MRB_SYM(Foo), mrb->object_class); - mrb_mt_init_rom(foo, &foo_rom_mt); + MRB_MT_INIT_ROM(mrb, foo, foo_rom_entries); } ``` diff --git a/include/mruby.h b/include/mruby.h index 0e26d972f..6ca2760b5 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -323,6 +323,8 @@ typedef struct mrb_state { struct RObject *arena_err; /* pre-allocated arena overflow error */ #endif + struct mrb_mt_rom_list *rom_mt; /* heap-allocated ROM wrappers (freed at close) */ + void *ud; /* auxiliary data */ #ifdef MRB_FIXED_STATE_ATEXIT_STACK diff --git a/include/mruby/class.h b/include/mruby/class.h index 266cb1199..fdac8ef9f 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -131,14 +131,6 @@ typedef struct mrb_mt_tbl { { { .func = (fn) }, (sym), (flags) | MRB_MT_FUNC } #define MRB_MT_ASPEC(flags) ((mrb_aspec)((flags) & 0xffffff)) -/* ROM table initializer from const entries array (auto-computes size). - Casts away const because mrb_mt_tbl.ptr is shared with mutable layers; - the MRB_MT_READONLY_BIT prevents writes. */ -#define MRB_MT_ROM_TAB(entries) { \ - (int)(sizeof(entries)/sizeof(entries[0])), \ - (int)(sizeof(entries)/sizeof(entries[0])) | MRB_MT_READONLY_BIT, \ - (mrb_mt_entry*)(entries), NULL } - /* "removed" tombstone: MRB_MT_FUNC flag set with NULL function pointer. This combination never occurs naturally (C functions are never NULL). Unlike undef (proc=NULL without MRB_MT_FUNC), a removed marker makes @@ -146,7 +138,19 @@ typedef struct mrb_mt_tbl { allowing superclass lookup. */ #define MRB_MT_REMOVED_P(e) (((e).flags&MRB_MT_FUNC) && (e).val.func==NULL) -void mrb_mt_init_rom(struct RClass *c, mrb_mt_tbl *rom); +/* Singly-linked list node for tracking heap-allocated ROM wrappers. */ +struct mrb_mt_rom_list { + mrb_mt_tbl *tbl; + struct mrb_mt_rom_list *next; +}; + +/* Allocate a per-state ROM layer wrapping the const entries array, + and push it onto the class's method table chain. */ +void mrb_mt_init_rom(mrb_state *mrb, struct RClass *c, + const mrb_mt_entry *entries, int size); +#define MRB_MT_INIT_ROM(mrb, cls, entries) \ + mrb_mt_init_rom(mrb, cls, entries, \ + (int)(sizeof(entries)/sizeof(entries[0]))) MRB_END_DECL diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index a60641f63..aa9467714 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -1568,14 +1568,13 @@ static const mrb_mt_entry array_ext_rom_entries[] = { MRB_MT_ENTRY(ary_combination_init, MRB_SYM(__combination_init), MRB_ARGS_REQ(2)), MRB_MT_ENTRY(ary_combination_next, MRB_SYM(__combination_next), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl array_ext_rom_mt = MRB_MT_ROM_TAB(array_ext_rom_entries); void mrb_mruby_array_ext_gem_init(mrb_state* mrb) { struct RClass * a = mrb->array_class; - mrb_mt_init_rom(a, &array_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, a, array_ext_rom_entries); } void diff --git a/mrbgems/mruby-class-ext/src/class.c b/mrbgems/mruby-class-ext/src/class.c index f58605d1c..c95253872 100644 --- a/mrbgems/mruby-class-ext/src/class.c +++ b/mrbgems/mruby-class-ext/src/class.c @@ -346,13 +346,11 @@ static const mrb_mt_entry mod_ext_rom_entries[] = { MRB_MT_ENTRY(mod_name, MRB_SYM(name), MRB_ARGS_NONE()), MRB_MT_ENTRY(mod_singleton_class_p, MRB_SYM_Q(singleton_class), MRB_ARGS_NONE()), }; -static mrb_mt_tbl mod_ext_rom_mt = MRB_MT_ROM_TAB(mod_ext_rom_entries); static const mrb_mt_entry cls_ext_rom_entries[] = { MRB_MT_ENTRY(class_attached_object, MRB_SYM(attached_object), MRB_ARGS_NONE()), MRB_MT_ENTRY(class_subclasses, MRB_SYM(subclasses), MRB_ARGS_NONE()), }; -static mrb_mt_tbl cls_ext_rom_mt = MRB_MT_ROM_TAB(cls_ext_rom_entries); /* * Initialize the mruby-class-ext gem. @@ -369,8 +367,8 @@ mrb_mruby_class_ext_gem_init(mrb_state *mrb) struct RClass *mod = mrb->module_class; struct RClass *cls = mrb->class_class; - mrb_mt_init_rom(mod, &mod_ext_rom_mt); - mrb_mt_init_rom(cls, &cls_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, mod, mod_ext_rom_entries); + MRB_MT_INIT_ROM(mrb, cls, cls_ext_rom_entries); } void diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c index 04ac54294..3caf3a72b 100644 --- a/mrbgems/mruby-complex/src/complex.c +++ b/mrbgems/mruby-complex/src/complex.c @@ -573,7 +573,6 @@ static const mrb_mt_entry complex_rom_entries[] = { MRB_MT_ENTRY(complex_hash, MRB_SYM(hash), MRB_ARGS_NONE()), MRB_MT_ENTRY(complex_pow, MRB_OPSYM(pow), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl complex_rom_mt = MRB_MT_ROM_TAB(complex_rom_entries); void mrb_mruby_complex_gem_init(mrb_state *mrb) { @@ -587,7 +586,7 @@ void mrb_mruby_complex_gem_init(mrb_state *mrb) mrb_define_class_method_id(mrb, comp, MRB_SYM(rectangular), complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_class_method_id(mrb, comp, MRB_SYM(rect), complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); - mrb_mt_init_rom(comp, &complex_rom_mt); + MRB_MT_INIT_ROM(mrb, comp, complex_rom_entries); mrb_define_method_id(mrb, mrb->nil_class, MRB_SYM(to_c), nil_to_c, MRB_ARGS_NONE()); mrb_define_private_method_id(mrb, mrb->kernel_module, MRB_SYM(Complex), complex_s_rect, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); } diff --git a/mrbgems/mruby-hash-ext/src/hash_ext.c b/mrbgems/mruby-hash-ext/src/hash_ext.c index cde36839e..2aac680d1 100644 --- a/mrbgems/mruby-hash-ext/src/hash_ext.c +++ b/mrbgems/mruby-hash-ext/src/hash_ext.c @@ -375,7 +375,6 @@ static const mrb_mt_entry hash_ext_rom_entries[] = { MRB_MT_ENTRY(hash_key, MRB_SYM(key), MRB_ARGS_REQ(1)), MRB_MT_ENTRY(hash_merge, MRB_SYM(__merge), MRB_ARGS_ANY()), }; -static mrb_mt_tbl hash_ext_rom_mt = MRB_MT_ROM_TAB(hash_ext_rom_entries); void mrb_mruby_hash_ext_gem_init(mrb_state *mrb) @@ -383,7 +382,7 @@ mrb_mruby_hash_ext_gem_init(mrb_state *mrb) struct RClass *h; h = mrb->hash_class; - mrb_mt_init_rom(h, &hash_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, h, hash_ext_rom_entries); mrb_define_class_method_id(mrb, h, MRB_OPSYM(aref), hash_s_create, MRB_ARGS_ANY()); } diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index 52cf359f5..f146233f3 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -1130,7 +1130,6 @@ static const mrb_mt_entry file_rom_entries[] = { MRB_MT_ENTRY(mrb_file_size, MRB_SYM(size), MRB_ARGS_NONE()), MRB_MT_ENTRY(mrb_file_truncate, MRB_SYM(truncate), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl file_rom_mt = MRB_MT_ROM_TAB(file_rom_entries); void mrb_init_file(mrb_state *mrb) @@ -1156,7 +1155,7 @@ mrb_init_file(mrb_state *mrb) mrb_define_class_method_id(mrb, file, MRB_SYM_Q(absolute_path), mrb_file_absolute_path_p, MRB_ARGS_REQ(1)); mrb_define_class_method_id(mrb, file, MRB_SYM(expand_path), mrb_file_expand_path, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); - mrb_mt_init_rom(file, &file_rom_mt); + MRB_MT_INIT_ROM(mrb, file, file_rom_entries); struct RClass *cnst = mrb_define_module_under_id(mrb, file, MRB_SYM(Constants)); mrb_define_const_id(mrb, cnst, MRB_SYM(LOCK_SH), mrb_fixnum_value(LOCK_SH)); diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index aacc8cd0e..6b161c936 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -2235,7 +2235,6 @@ static const mrb_mt_entry io_rom_entries[] = { MRB_MT_ENTRY(io_getbyte, MRB_SYM(getbyte), MRB_ARGS_NONE()), MRB_MT_ENTRY(io_readbyte, MRB_SYM(readbyte), MRB_ARGS_NONE()), }; -static mrb_mt_tbl io_rom_mt = MRB_MT_ROM_TAB(io_rom_entries); void mrb_init_io(mrb_state *mrb) @@ -2253,7 +2252,7 @@ mrb_init_io(mrb_state *mrb) mrb_define_class_method_id(mrb, io, MRB_SYM(_pipe), io_s_pipe, MRB_ARGS_NONE()); #endif - mrb_mt_init_rom(io, &io_rom_mt); + MRB_MT_INIT_ROM(mrb, io, io_rom_entries); mrb_define_const_id(mrb, io, MRB_SYM(SEEK_SET), mrb_fixnum_value(SEEK_SET)); mrb_define_const_id(mrb, io, MRB_SYM(SEEK_CUR), mrb_fixnum_value(SEEK_CUR)); diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index d55ec440c..d9ea0e315 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -301,14 +301,13 @@ static const mrb_mt_entry kernel_ext_rom_entries[] = { #endif MRB_MT_ENTRY(mrb_f_hash, MRB_SYM(Hash), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), }; -static mrb_mt_tbl kernel_ext_rom_mt = MRB_MT_ROM_TAB(kernel_ext_rom_entries); void mrb_mruby_kernel_ext_gem_init(mrb_state *mrb) { struct RClass *krn = mrb->kernel_module; - mrb_mt_init_rom(krn, &kernel_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, krn, kernel_ext_rom_entries); } void diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index ae1cc0c5c..79b2ae46d 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -703,7 +703,6 @@ static const mrb_mt_entry metaprog_krn_rom_entries[] = { MRB_MT_ENTRY(mrb_f_send, MRB_SYM(send), MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()), /* 15.3.1.3.44 */ MRB_MT_ENTRY(mrb_f_public_send, MRB_SYM(public_send), MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()), }; -static mrb_mt_tbl metaprog_krn_rom_mt = MRB_MT_ROM_TAB(metaprog_krn_rom_entries); static const mrb_mt_entry metaprog_mod_rom_entries[] = { MRB_MT_ENTRY(mrb_mod_class_variables, MRB_SYM(class_variables), MRB_ARGS_OPT(1)), /* 15.2.2.4.19 */ @@ -721,7 +720,6 @@ static const mrb_mt_entry metaprog_mod_rom_entries[] = { MRB_MT_ENTRY(mrb_f_nil, MRB_SYM(method_removed), MRB_ARGS_REQ(1)), MRB_MT_ENTRY(mrb_mod_constants, MRB_SYM(constants), MRB_ARGS_OPT(1)), /* 15.2.2.4.24 */ }; -static mrb_mt_tbl metaprog_mod_rom_mt = MRB_MT_ROM_TAB(metaprog_mod_rom_entries); void mrb_mruby_metaprog_gem_init(mrb_state* mrb) @@ -729,8 +727,8 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb) struct RClass *krn = mrb->kernel_module; struct RClass *mod = mrb->module_class; - mrb_mt_init_rom(krn, &metaprog_krn_rom_mt); - mrb_mt_init_rom(mod, &metaprog_mod_rom_mt); + MRB_MT_INIT_ROM(mrb, krn, metaprog_krn_rom_entries); + MRB_MT_INIT_ROM(mrb, mod, metaprog_mod_rom_entries); mrb_define_class_method_id(mrb, mod, MRB_SYM(constants), mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */ mrb_define_class_method_id(mrb, mod, MRB_SYM(nesting), mrb_mod_s_nesting, MRB_ARGS_NONE()); /* 15.2.2.3.2 */ } diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c index 692ccddb1..69dcdedfc 100644 --- a/mrbgems/mruby-method/src/method.c +++ b/mrbgems/mruby-method/src/method.c @@ -846,7 +846,6 @@ static const mrb_mt_entry method_ubm_rom_entries[] = { MRB_MT_ENTRY(method_owner, MRB_SYM(owner), MRB_ARGS_NONE()), MRB_MT_ENTRY(method_name, MRB_SYM(name), MRB_ARGS_NONE()), }; -static mrb_mt_tbl method_ubm_rom_mt = MRB_MT_ROM_TAB(method_ubm_rom_entries); static const mrb_mt_entry method_mtd_rom_entries[] = { MRB_MT_ENTRY(method_eql, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), @@ -864,7 +863,6 @@ static const mrb_mt_entry method_mtd_rom_entries[] = { MRB_MT_ENTRY(method_receiver, MRB_SYM(receiver), MRB_ARGS_NONE()), MRB_MT_ENTRY(method_name, MRB_SYM(name), MRB_ARGS_NONE()), }; -static mrb_mt_tbl method_mtd_rom_mt = MRB_MT_ROM_TAB(method_mtd_rom_entries); void mrb_mruby_method_gem_init(mrb_state* mrb) @@ -875,12 +873,12 @@ mrb_mruby_method_gem_init(mrb_state* mrb) MRB_SET_INSTANCE_TT(unbound_method, MRB_TT_OBJECT); MRB_UNDEF_ALLOCATOR(unbound_method); mrb_undef_class_method_id(mrb, unbound_method, MRB_SYM(new)); - mrb_mt_init_rom(unbound_method, &method_ubm_rom_mt); + MRB_MT_INIT_ROM(mrb, unbound_method, method_ubm_rom_entries); MRB_SET_INSTANCE_TT(method, MRB_TT_OBJECT); MRB_UNDEF_ALLOCATOR(method); mrb_undef_class_method_id(mrb, method, MRB_SYM(new)); - mrb_mt_init_rom(method, &method_mtd_rom_mt); + MRB_MT_INIT_ROM(mrb, method, method_mtd_rom_entries); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(method), mrb_kernel_method, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(singleton_method), mrb_kernel_singleton_method, MRB_ARGS_REQ(1)); mrb_define_method_id(mrb, mrb->module_class, MRB_SYM(instance_method), mrb_module_instance_method, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 23c359c5f..0a0ad174f 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -491,7 +491,6 @@ static const mrb_mt_entry integer_ext_rom_entries[] = { MRB_MT_ENTRY(int_gcd, MRB_SYM(gcd), MRB_ARGS_REQ(1)), MRB_MT_ENTRY(int_lcm, MRB_SYM(lcm), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl integer_ext_rom_mt = MRB_MT_ROM_TAB(integer_ext_rom_entries); void @@ -500,7 +499,7 @@ mrb_mruby_numeric_ext_gem_init(mrb_state* mrb) struct RClass *ic = mrb->integer_class; mrb_define_alias_id(mrb, ic, MRB_SYM(modulo), MRB_OPSYM(mod)); - mrb_mt_init_rom(ic, &integer_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, ic, integer_ext_rom_entries); mrb_define_class_method_id(mrb, ic, MRB_SYM(sqrt), int_sqrt, MRB_ARGS_REQ(1)); #ifndef MRB_NO_FLOAT diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c index 96219990a..ba74c9174 100644 --- a/mrbgems/mruby-object-ext/src/object.c +++ b/mrbgems/mruby-object-ext/src/object.c @@ -105,23 +105,21 @@ static const mrb_mt_entry nil_ext_rom_entries[] = { MRB_MT_ENTRY(nil_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), #endif }; -static mrb_mt_tbl nil_ext_rom_mt = MRB_MT_ROM_TAB(nil_ext_rom_entries); static const mrb_mt_entry bob_ext_rom_entries[] = { MRB_MT_ENTRY(obj_instance_exec, MRB_SYM(instance_exec), MRB_ARGS_ANY()|MRB_ARGS_BLOCK()), }; -static mrb_mt_tbl bob_ext_rom_mt = MRB_MT_ROM_TAB(bob_ext_rom_entries); void mrb_mruby_object_ext_gem_init(mrb_state* mrb) { struct RClass * n = mrb->nil_class; - mrb_mt_init_rom(n, &nil_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, n, nil_ext_rom_entries); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(itself), mrb_obj_itself, MRB_ARGS_NONE()); - mrb_mt_init_rom(mrb_class_get_id(mrb, MRB_SYM(BasicObject)), &bob_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), bob_ext_rom_entries); } void diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index 68720aee0..f9be0ef29 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -251,14 +251,13 @@ static const mrb_mt_entry proc_ext_rom_entries[] = { MRB_MT_ENTRY(proc_source_location, MRB_SYM(source_location), MRB_ARGS_NONE()), MRB_MT_ENTRY(proc_inspect, MRB_SYM(to_s), MRB_ARGS_NONE()), }; -static mrb_mt_tbl proc_ext_rom_mt = MRB_MT_ROM_TAB(proc_ext_rom_entries); void mrb_mruby_proc_ext_gem_init(mrb_state* mrb) { struct RClass *p = mrb->proc_class; - mrb_mt_init_rom(p, &proc_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, p, proc_ext_rom_entries); mrb_define_private_method_id(mrb, mrb->kernel_module, MRB_SYM(proc), kernel_proc, MRB_ARGS_BLOCK()); } diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index c6c2cb495..db9483a55 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -574,7 +574,6 @@ static const mrb_mt_entry random_rom_entries[] = { MRB_MT_ENTRY(random_m_srand, MRB_SYM(srand), MRB_ARGS_OPT(1)), MRB_MT_ENTRY(random_m_bytes, MRB_SYM(bytes), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl random_rom_mt = MRB_MT_ROM_TAB(random_rom_entries); void mrb_mruby_random_gem_init(mrb_state *mrb) { @@ -591,7 +590,7 @@ void mrb_mruby_random_gem_init(mrb_state *mrb) mrb_define_private_method_id(mrb, mrb->kernel_module, MRB_SYM(rand), random_f_rand, MRB_ARGS_OPT(1)); mrb_define_private_method_id(mrb, mrb->kernel_module, MRB_SYM(srand), random_f_srand, MRB_ARGS_OPT(1)); - mrb_mt_init_rom(random, &random_rom_mt); + MRB_MT_INIT_ROM(mrb, random, random_rom_entries); mrb_define_method_id(mrb, array, MRB_SYM(shuffle), mrb_ary_shuffle, MRB_ARGS_OPT(1)); mrb_define_method_id(mrb, array, MRB_SYM_B(shuffle), mrb_ary_shuffle_bang, MRB_ARGS_OPT(1)); mrb_define_method_id(mrb, array, MRB_SYM(sample), mrb_ary_sample, MRB_ARGS_OPT(2)); diff --git a/mrbgems/mruby-range-ext/src/range.c b/mrbgems/mruby-range-ext/src/range.c index c65470a9c..1c0acc1c2 100644 --- a/mrbgems/mruby-range-ext/src/range.c +++ b/mrbgems/mruby-range-ext/src/range.c @@ -221,14 +221,13 @@ static const mrb_mt_entry range_ext_rom_entries[] = { MRB_MT_ENTRY(range_size, MRB_SYM(size), MRB_ARGS_NONE()), MRB_MT_ENTRY(range_empty_p, MRB_SYM_Q(__empty_range), MRB_ARGS_REQ(3)), }; -static mrb_mt_tbl range_ext_rom_mt = MRB_MT_ROM_TAB(range_ext_rom_entries); void mrb_mruby_range_ext_gem_init(mrb_state* mrb) { struct RClass *s = mrb->range_class; - mrb_mt_init_rom(s, &range_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, s, range_ext_rom_entries); } void diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c index be2920af6..951d6bfe3 100644 --- a/mrbgems/mruby-rational/src/rational.c +++ b/mrbgems/mruby-rational/src/rational.c @@ -1247,7 +1247,6 @@ static const mrb_mt_entry rational_rom_entries[] = { MRB_MT_ENTRY(mrb_rational_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), #endif }; -static mrb_mt_tbl rational_rom_mt = MRB_MT_ROM_TAB(rational_rom_entries); void mrb_mruby_rational_gem_init(mrb_state *mrb) { @@ -1255,7 +1254,7 @@ 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_id(mrb, rat, MRB_SYM(new)); - mrb_mt_init_rom(rat, &rational_rom_mt); + MRB_MT_INIT_ROM(mrb, rat, rational_rom_entries); mrb_define_method_id(mrb, mrb->integer_class, MRB_SYM(to_r), int_to_r, MRB_ARGS_NONE()); mrb_define_method_id(mrb, mrb->nil_class, MRB_SYM(to_r), nil_to_r, MRB_ARGS_NONE()); mrb_define_private_method_id(mrb, mrb->kernel_module, MRB_SYM(Rational), rational_m, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); diff --git a/mrbgems/mruby-set/src/set.c b/mrbgems/mruby-set/src/set.c index 4da1591a6..21fc84d8e 100644 --- a/mrbgems/mruby-set/src/set.c +++ b/mrbgems/mruby-set/src/set.c @@ -1509,7 +1509,6 @@ static const mrb_mt_entry set_rom_entries[] = { MRB_MT_ENTRY(set_flatten, MRB_SYM(flatten), MRB_ARGS_NONE()), MRB_MT_ENTRY(set_flatten_bang, MRB_SYM_B(flatten), MRB_ARGS_NONE()), }; -static mrb_mt_tbl set_rom_mt = MRB_MT_ROM_TAB(set_rom_entries); void mrb_mruby_set_gem_init(mrb_state *mrb) @@ -1525,7 +1524,7 @@ mrb_mruby_set_gem_init(mrb_state *mrb) mrb_define_private_method(mrb, set, "initialize_copy", set_init_copy, MRB_ARGS_REQ(1)); - mrb_mt_init_rom(set, &set_rom_mt); + MRB_MT_INIT_ROM(mrb, set, set_rom_entries); mrb_define_alias(mrb, set, "eql?", "=="); } diff --git a/mrbgems/mruby-socket/src/socket.c b/mrbgems/mruby-socket/src/socket.c index 270a35ecf..efbba6ed8 100644 --- a/mrbgems/mruby-socket/src/socket.c +++ b/mrbgems/mruby-socket/src/socket.c @@ -1275,7 +1275,6 @@ static const mrb_mt_entry addrinfo_rom_entries[] = { MRB_MT_ENTRY(mrb_addrinfo_getnameinfo, MRB_SYM(getnameinfo), MRB_ARGS_OPT(1)), MRB_MT_ENTRY(mrb_addrinfo_unix_path, MRB_SYM(unix_path), MRB_ARGS_NONE()), }; -static mrb_mt_tbl addrinfo_rom_mt = MRB_MT_ROM_TAB(addrinfo_rom_entries); static const mrb_mt_entry basicsocket_rom_entries[] = { MRB_MT_ENTRY(mrb_basicsocket_recvfrom, MRB_SYM(_recvfrom), MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)), @@ -1298,12 +1297,10 @@ static const mrb_mt_entry basicsocket_rom_entries[] = { MRB_MT_ENTRY(mrb_win32_basicsocket_syswrite, MRB_SYM(write), MRB_ARGS_REQ(1)), #endif }; -static mrb_mt_tbl basicsocket_rom_mt = MRB_MT_ROM_TAB(basicsocket_rom_entries); static const mrb_mt_entry ipsocket_rom_entries[] = { MRB_MT_ENTRY(mrb_ipsocket_recvfrom, MRB_SYM(recvfrom), MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)), }; -static mrb_mt_tbl ipsocket_rom_mt = MRB_MT_ROM_TAB(ipsocket_rom_entries); static const mrb_mt_entry socket_option_rom_entries[] = { MRB_MT_ENTRY(socket_option_init, MRB_SYM(initialize), MRB_ARGS_REQ(4)), @@ -1317,7 +1314,6 @@ static const mrb_mt_entry socket_option_rom_entries[] = { MRB_MT_ENTRY(socket_option_notimp, MRB_SYM(linger), MRB_ARGS_REQ(0)), MRB_MT_ENTRY(socket_option_notimp, MRB_SYM(unpack), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl socket_option_rom_mt = MRB_MT_ROM_TAB(socket_option_rom_entries); void mrb_mruby_socket_gem_init(mrb_state* mrb) @@ -1354,10 +1350,10 @@ mrb_mruby_socket_gem_init(mrb_state* mrb) mrb_define_class_method_id(mrb, option, MRB_SYM(bool), socket_option_s_bool, MRB_ARGS_REQ(4)); mrb_define_class_method_id(mrb, option, MRB_SYM(int), socket_option_s_int, MRB_ARGS_REQ(4)); - mrb_mt_init_rom(ainfo, &addrinfo_rom_mt); - mrb_mt_init_rom(bsock, &basicsocket_rom_mt); - mrb_mt_init_rom(ipsock, &ipsocket_rom_mt); - mrb_mt_init_rom(option, &socket_option_rom_mt); + MRB_MT_INIT_ROM(mrb, ainfo, addrinfo_rom_entries); + MRB_MT_INIT_ROM(mrb, bsock, basicsocket_rom_entries); + MRB_MT_INIT_ROM(mrb, ipsock, ipsocket_rom_entries); + MRB_MT_INIT_ROM(mrb, option, socket_option_rom_entries); struct RClass *constants = mrb_define_module_under_id(mrb, sock, MRB_SYM(Constants)); diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index 5e6a3d57b..451882c30 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -2274,14 +2274,13 @@ static const mrb_mt_entry string_ext_rom_entries[] = { MRB_MT_ENTRY(str_rjust_core, MRB_SYM(rjust), MRB_ARGS_ARG(1,1)), MRB_MT_ENTRY(str_center_core, MRB_SYM(center), MRB_ARGS_ARG(1,1)), }; -static mrb_mt_tbl string_ext_rom_mt = MRB_MT_ROM_TAB(string_ext_rom_entries); void mrb_mruby_string_ext_gem_init(mrb_state* mrb) { struct RClass *s = mrb->string_class; - mrb_mt_init_rom(s, &string_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, s, string_ext_rom_entries); mrb_define_method_id(mrb, mrb->integer_class, MRB_SYM(chr), int_chr, MRB_ARGS_NONE()|MRB_ARGS_OPT(1)); } diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 457e3a22e..3ba721ac5 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -793,7 +793,6 @@ static const mrb_mt_entry struct_rom_entries[] = { MRB_MT_ENTRY(mrb_struct_to_h, MRB_SYM(to_h), MRB_ARGS_NONE()), MRB_MT_ENTRY(mrb_struct_values_at, MRB_SYM(values_at), MRB_ARGS_ANY()), }; -static mrb_mt_tbl struct_rom_mt = MRB_MT_ROM_TAB(struct_rom_entries); void mrb_mruby_struct_gem_init(mrb_state* mrb) @@ -804,7 +803,7 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_class_method_id(mrb, st, MRB_SYM(new), mrb_struct_s_def, MRB_ARGS_ANY()); /* 15.2.18.3.1 */ - mrb_mt_init_rom(st, &struct_rom_mt); + MRB_MT_INIT_ROM(mrb, st, struct_rom_entries); } void diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index 4a97d84f6..5825d0c62 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -62,7 +62,6 @@ static const mrb_mt_entry symbol_ext_rom_entries[] = { MRB_MT_ENTRY(mrb_sym_length, MRB_SYM(length), MRB_ARGS_NONE()), MRB_MT_ENTRY(mrb_sym_length, MRB_SYM(size), MRB_ARGS_NONE()), }; -static mrb_mt_tbl symbol_ext_rom_mt = MRB_MT_ROM_TAB(symbol_ext_rom_entries); void mrb_mruby_symbol_ext_gem_init(mrb_state* mrb) @@ -71,7 +70,7 @@ mrb_mruby_symbol_ext_gem_init(mrb_state* mrb) #ifdef MRB_USE_ALL_SYMBOLS mrb_define_class_method_id(mrb, s, MRB_SYM(all_symbols), mrb_sym_all_symbols, MRB_ARGS_NONE()); #endif - mrb_mt_init_rom(s, &symbol_ext_rom_mt); + MRB_MT_INIT_ROM(mrb, s, symbol_ext_rom_entries); } void diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index fb7b570f6..458f91d23 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -1715,7 +1715,6 @@ static const mrb_mt_entry time_rom_entries[] = { MRB_MT_ENTRY(time_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), /* 15.2.19.7.24 */ #endif }; -static mrb_mt_tbl time_rom_mt = MRB_MT_ROM_TAB(time_rom_entries); void mrb_mruby_time_gem_init(mrb_state* mrb) @@ -1731,7 +1730,7 @@ mrb_mruby_time_gem_init(mrb_state* mrb) mrb_define_class_method_id(mrb, tc, MRB_SYM(now), time_now, MRB_ARGS_NONE()); /* 15.2.19.6.5 */ mrb_define_class_method_id(mrb, tc, MRB_SYM(utc), time_gm, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.6 */ - mrb_mt_init_rom(tc, &time_rom_mt); + MRB_MT_INIT_ROM(mrb, tc, time_rom_entries); } void diff --git a/src/array.c b/src/array.c index f4f7d274e..27a5b0097 100644 --- a/src/array.c +++ b/src/array.c @@ -2287,7 +2287,6 @@ static const mrb_mt_entry array_rom_entries[] = { MRB_MT_ENTRY(mrb_ary_sort_bang, MRB_SYM_B(sort), MRB_ARGS_NONE()), MRB_MT_ENTRY(mrb_ary_svalue, MRB_SYM(__svalue), MRB_ARGS_NONE()), }; -static mrb_mt_tbl array_rom_mt = MRB_MT_ROM_TAB(array_rom_entries); void mrb_init_array(mrb_state *mrb) @@ -2299,5 +2298,5 @@ mrb_init_array(mrb_state *mrb) mrb_define_class_method_id(mrb, a, MRB_OPSYM(aref), mrb_ary_s_create, MRB_ARGS_ANY()); /* 15.2.12.4.1 */ - mrb_mt_init_rom(a, &array_rom_mt); + MRB_MT_INIT_ROM(mrb, a, array_rom_entries); } diff --git a/src/class.c b/src/class.c index 99dba79ba..04eeb562d 100644 --- a/src/class.c +++ b/src/class.c @@ -159,7 +159,10 @@ mt_copy(mrb_state *mrb, mrb_mt_tbl *t) return t2; } -/* Frees memory of the method table (skips readonly/ROM layers) */ +/* Frees memory of the method table (mutable layers only). + Stops at the first readonly (ROM) layer; ROM wrappers are + shared (by iclasses, dup, etc.) and freed via mrb->rom_mt + at state close. */ static void mt_free(mrb_state *mrb, mrb_mt_tbl *t) { @@ -171,11 +174,27 @@ mt_free(mrb_state *mrb, mrb_mt_tbl *t) } } -/* Pushes a ROM table layer onto the class's method table chain. - The readonly flag is already set by MRB_MT_ROM_TAB(). */ +/* Allocates a per-state ROM wrapper for the const entries array + and pushes it onto the class's method table chain. + The wrapper is also registered in mrb->rom_mt for cleanup + at mrb_close, since ROM layers are shared and must not be + freed by mt_free during normal GC. */ void -mrb_mt_init_rom(struct RClass *c, mrb_mt_tbl *rom) +mrb_mt_init_rom(mrb_state *mrb, struct RClass *c, + const mrb_mt_entry *entries, int size) { + mrb_mt_tbl *rom = (mrb_mt_tbl*)mrb_malloc(mrb, sizeof(mrb_mt_tbl)); + rom->size = size; + rom->alloc = size | MRB_MT_READONLY_BIT; + rom->ptr = (mrb_mt_entry*)entries; + + /* register for cleanup at mrb_close */ + struct mrb_mt_rom_list *node = + (struct mrb_mt_rom_list*)mrb_malloc(mrb, sizeof(struct mrb_mt_rom_list)); + node->tbl = rom; + node->next = mrb->rom_mt; + mrb->rom_mt = node; + /* push ROM layer */ mrb_mt_tbl *t = c->mt; if (!t || mt_readonly_p(t)) { @@ -275,7 +294,8 @@ mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c) return total; } -/* Frees class method table for garbage collection */ +/* Frees mutable layers of the class method table for GC. + ROM layers are left intact (freed via mrb->rom_mt at close). */ void mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) { @@ -4270,7 +4290,6 @@ static const mrb_mt_entry bob_rom_entries[] = { MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(singleton_method_removed), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), MRB_MT_ENTRY(mrb_do_nothing, MRB_SYM(singleton_method_undefined), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), }; -static mrb_mt_tbl bob_rom_mt = MRB_MT_ROM_TAB(bob_rom_entries); static const mrb_mt_entry cls_rom_entries[] = { MRB_MT_ENTRY(mrb_instance_alloc, MRB_SYM(allocate), MRB_ARGS_NONE()), @@ -4278,7 +4297,6 @@ static const mrb_mt_entry cls_rom_entries[] = { MRB_MT_ENTRY(mrb_class_initialize, MRB_SYM(initialize), MRB_ARGS_OPT(1) | MRB_MT_PRIVATE), /* 15.2.3.3.1 */ MRB_MT_ENTRY(mrb_class_superclass, MRB_SYM(superclass), MRB_ARGS_NONE()), /* 15.2.3.3.4 */ }; -static mrb_mt_tbl cls_rom_mt = MRB_MT_ROM_TAB(cls_rom_entries); static const mrb_mt_entry mod_rom_entries[] = { MRB_MT_ENTRY(mrb_mod_eqq, MRB_OPSYM(eqq), MRB_ARGS_REQ(1)), /* 15.2.2.4.7 */ @@ -4316,7 +4334,6 @@ static const mrb_mt_entry mod_rom_entries[] = { MRB_MT_ENTRY(mrb_mod_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()), MRB_MT_ENTRY(mrb_mod_undef, MRB_SYM(undef_method), MRB_ARGS_ANY()), /* 15.2.2.4.41 */ }; -static mrb_mt_tbl mod_rom_mt = MRB_MT_ROM_TAB(mod_rom_entries); void mrb_init_class(mrb_state *mrb) @@ -4351,18 +4368,18 @@ mrb_init_class(mrb_state *mrb) mrb_class_name_class(mrb, NULL, mod, MRB_SYM(Module)); /* 15.2.2 */ mrb_class_name_class(mrb, NULL, cls, MRB_SYM(Class)); /* 15.2.3 */ - mrb_mt_init_rom(bob, &bob_rom_mt); + MRB_MT_INIT_ROM(mrb, bob, bob_rom_entries); mrb_method_t m; MRB_METHOD_FROM_PROC(m, &neq_proc); mrb_define_method_raw(mrb, bob, MRB_OPSYM(neq), m); mrb_define_class_method_id(mrb, cls, MRB_SYM(new), mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); - mrb_mt_init_rom(cls, &cls_rom_mt); + MRB_MT_INIT_ROM(mrb, cls, cls_rom_entries); init_class_new(mrb, cls); - mrb_mt_init_rom(mod, &mod_rom_mt); + MRB_MT_INIT_ROM(mrb, mod, mod_rom_entries); mrb_define_alias_id(mrb, mod, MRB_SYM(attr), MRB_SYM(attr_reader)); /* 15.2.2.4.11 */ mrb_undef_method_id(mrb, cls, MRB_SYM(module_function)); diff --git a/src/error.c b/src/error.c index b62d4c3a0..2115f3f5b 100644 --- a/src/error.c +++ b/src/error.c @@ -901,7 +901,6 @@ static const mrb_mt_entry exception_rom_entries[] = { MRB_MT_ENTRY(mrb_exc_backtrace, MRB_SYM(backtrace), MRB_ARGS_NONE()), MRB_MT_ENTRY(exc_set_backtrace, MRB_SYM(set_backtrace), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl exception_rom_mt = MRB_MT_ROM_TAB(exception_rom_entries); void mrb_init_exception(mrb_state *mrb) @@ -909,7 +908,7 @@ mrb_init_exception(mrb_state *mrb) struct RClass *exception = mrb->eException_class = mrb_define_class_id(mrb, MRB_SYM(Exception), mrb->object_class); /* 15.2.22 */ MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION); mrb_define_class_method_id(mrb, exception, MRB_SYM(exception), mrb_instance_new, MRB_ARGS_OPT(1)); - mrb_mt_init_rom(exception, &exception_rom_mt); + MRB_MT_INIT_ROM(mrb, exception, exception_rom_entries); mrb->eStandardError_class = mrb_define_class_id(mrb, MRB_SYM(StandardError), mrb->eException_class); /* 15.2.23 */ mrb_define_class_id(mrb, MRB_SYM(ArgumentError), E_STANDARD_ERROR); /* 15.2.24 */ diff --git a/src/hash.c b/src/hash.c index b6a58c352..084d98a6c 100644 --- a/src/hash.c +++ b/src/hash.c @@ -2341,7 +2341,6 @@ static const mrb_mt_entry hash_rom_entries[] = { MRB_MT_ENTRY(mrb_hash_pat_values, MRB_SYM(__pat_values), MRB_ARGS_REQ(1)), /* for pattern matching keys */ MRB_MT_ENTRY(mrb_hash_except_keys, MRB_SYM(__except), MRB_ARGS_REQ(1)), /* for pattern matching **rest */ }; -static mrb_mt_tbl hash_rom_mt = MRB_MT_ROM_TAB(hash_rom_entries); void mrb_init_hash(mrb_state *mrb) @@ -2351,6 +2350,6 @@ mrb_init_hash(mrb_state *mrb) mrb->hash_class = h = mrb_define_class_id(mrb, MRB_SYM(Hash), mrb->object_class); /* 15.2.13 */ MRB_SET_INSTANCE_TT(h, MRB_TT_HASH); - mrb_mt_init_rom(h, &hash_rom_mt); + MRB_MT_INIT_ROM(mrb, h, hash_rom_entries); } #undef lesser diff --git a/src/kernel.c b/src/kernel.c index bfc1713d9..e7cd65834 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -699,7 +699,6 @@ static const mrb_mt_entry kernel_rom_entries[] = { MRB_MT_ENTRY(mrb_print_m, MRB_SYM(print), MRB_ARGS_ANY() | MRB_MT_PRIVATE), /* 15.3.1.3.35 */ #endif }; -static mrb_mt_tbl kernel_rom_mt = MRB_MT_ROM_TAB(kernel_rom_entries); void mrb_init_kernel(mrb_state *mrb) @@ -713,7 +712,7 @@ mrb_init_kernel(mrb_state *mrb) #endif mrb_define_class_method_id(mrb, krn, MRB_SYM(raise), mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ - mrb_mt_init_rom(krn, &kernel_rom_mt); + MRB_MT_INIT_ROM(mrb, krn, kernel_rom_entries); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); } diff --git a/src/numeric.c b/src/numeric.c index f27b4a64e..5233a28b7 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -2307,7 +2307,6 @@ static const mrb_mt_entry numeric_rom_entries[] = { MRB_MT_ENTRY(num_fdiv, MRB_SYM(fdiv), MRB_ARGS_REQ(1)), #endif }; -static mrb_mt_tbl numeric_rom_mt = MRB_MT_ROM_TAB(numeric_rom_entries); static const mrb_mt_entry integer_rom_entries[] = { MRB_MT_ENTRY(int_pow, MRB_OPSYM(pow), MRB_ARGS_REQ(1)), @@ -2346,7 +2345,6 @@ static const mrb_mt_entry integer_rom_entries[] = { MRB_MT_ENTRY(int_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), /* 15.2.8.3.23 */ #endif }; -static mrb_mt_tbl integer_rom_mt = MRB_MT_ROM_TAB(integer_rom_entries); #ifndef MRB_NO_FLOAT static const mrb_mt_entry float_rom_entries[] = { @@ -2380,7 +2378,6 @@ static const mrb_mt_entry float_rom_entries[] = { MRB_MT_ENTRY(flo_abs, MRB_SYM(abs), MRB_ARGS_NONE()), /* 15.2.7.4.3 */ MRB_MT_ENTRY(flo_hash, MRB_SYM(hash), MRB_ARGS_NONE()), }; -static mrb_mt_tbl float_rom_mt = MRB_MT_ROM_TAB(float_rom_entries); #endif /* !MRB_NO_FLOAT */ void @@ -2393,14 +2390,14 @@ mrb_init_numeric(mrb_state *mrb) /* Numeric Class */ numeric = mrb_define_class_id(mrb, MRB_SYM(Numeric), mrb->object_class); /* 15.2.7 */ - mrb_mt_init_rom(numeric, &numeric_rom_mt); + MRB_MT_INIT_ROM(mrb, numeric, numeric_rom_entries); /* Integer Class */ mrb->integer_class = integer = mrb_define_class_id(mrb, MRB_SYM(Integer), numeric); /* 15.2.8 */ MRB_SET_INSTANCE_TT(integer, MRB_TT_INTEGER); MRB_UNDEF_ALLOCATOR(integer); mrb_undef_class_method_id(mrb, integer, MRB_SYM(new)); - mrb_mt_init_rom(integer, &integer_rom_mt); + MRB_MT_INIT_ROM(mrb, integer, integer_rom_entries); /* Fixnum Class for compatibility */ mrb_define_const_id(mrb, mrb->object_class, MRB_SYM(Fixnum), mrb_obj_value(integer)); @@ -2411,7 +2408,7 @@ mrb_init_numeric(mrb_state *mrb) MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); MRB_UNDEF_ALLOCATOR(fl); mrb_undef_class_method(mrb, fl, "new"); - mrb_mt_init_rom(fl, &float_rom_mt); + MRB_MT_INIT_ROM(mrb, fl, float_rom_entries); #ifdef INFINITY mrb_define_const_id(mrb, fl, MRB_SYM(INFINITY), mrb_float_value(mrb, INFINITY)); diff --git a/src/object.c b/src/object.c index 1b1a18a77..6d2845103 100644 --- a/src/object.c +++ b/src/object.c @@ -330,7 +330,6 @@ static const mrb_mt_entry nil_rom_entries[] = { MRB_MT_ENTRY(nil_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()), /* 15.2.4.3.5 */ MRB_MT_ENTRY(nil_inspect, MRB_SYM(inspect), MRB_ARGS_NONE()), }; -static mrb_mt_tbl nil_rom_mt = MRB_MT_ROM_TAB(nil_rom_entries); static const mrb_mt_entry true_rom_entries[] = { MRB_MT_ENTRY(true_and, MRB_OPSYM(and), MRB_ARGS_REQ(1)), /* 15.2.5.3.1 */ @@ -339,7 +338,6 @@ static const mrb_mt_entry true_rom_entries[] = { MRB_MT_ENTRY(true_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()), /* 15.2.5.3.4 */ MRB_MT_ENTRY(true_to_s, MRB_SYM(inspect), MRB_ARGS_NONE()), }; -static mrb_mt_tbl true_rom_mt = MRB_MT_ROM_TAB(true_rom_entries); static const mrb_mt_entry false_rom_entries[] = { MRB_MT_ENTRY(false_and, MRB_OPSYM(and), MRB_ARGS_REQ(1)), /* 15.2.4.3.1 */ @@ -348,7 +346,6 @@ static const mrb_mt_entry false_rom_entries[] = { MRB_MT_ENTRY(false_to_s, MRB_SYM(to_s), MRB_ARGS_NONE()), /* 15.2.6.3.4 */ MRB_MT_ENTRY(false_to_s, MRB_SYM(inspect), MRB_ARGS_NONE()), }; -static mrb_mt_tbl false_rom_mt = MRB_MT_ROM_TAB(false_rom_entries); void mrb_init_object(mrb_state *mrb) @@ -360,17 +357,17 @@ mrb_init_object(mrb_state *mrb) mrb->nil_class = n = mrb_define_class_id(mrb, MRB_SYM(NilClass), mrb->object_class); MRB_SET_INSTANCE_TT(n, MRB_TT_FALSE); mrb_undef_class_method_id(mrb, n, MRB_SYM(new)); - mrb_mt_init_rom(n, &nil_rom_mt); + MRB_MT_INIT_ROM(mrb, n, nil_rom_entries); mrb->true_class = t = mrb_define_class_id(mrb, MRB_SYM(TrueClass), mrb->object_class); MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE); mrb_undef_class_method_id(mrb, t, MRB_SYM(new)); - mrb_mt_init_rom(t, &true_rom_mt); + MRB_MT_INIT_ROM(mrb, t, true_rom_entries); mrb->false_class = f = mrb_define_class_id(mrb, MRB_SYM(FalseClass), mrb->object_class); MRB_SET_INSTANCE_TT(f, MRB_TT_FALSE); mrb_undef_class_method_id(mrb, f, MRB_SYM(new)); - mrb_mt_init_rom(f, &false_rom_mt); + MRB_MT_INIT_ROM(mrb, f, false_rom_entries); } static const char* diff --git a/src/proc.c b/src/proc.c index 41028d7dc..93cf46c5b 100644 --- a/src/proc.c +++ b/src/proc.c @@ -552,7 +552,6 @@ static const mrb_mt_entry proc_rom_entries[] = { MRB_MT_ENTRY(proc_eql, MRB_SYM_Q(eql), MRB_ARGS_REQ(1)), MRB_MT_ENTRY(proc_hash, MRB_SYM(hash), MRB_ARGS_NONE()), /* 15.2.17.4.2 */ }; -static mrb_mt_tbl proc_rom_mt = MRB_MT_ROM_TAB(proc_rom_entries); void mrb_init_proc(mrb_state *mrb) @@ -563,7 +562,7 @@ mrb_init_proc(mrb_state *mrb) MRB_SET_INSTANCE_TT(pc, MRB_TT_PROC); MRB_UNDEF_ALLOCATOR(pc); mrb_define_class_method_id(mrb, pc, MRB_SYM(new), mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); - mrb_mt_init_rom(pc, &proc_rom_mt); + MRB_MT_INIT_ROM(mrb, pc, proc_rom_entries); MRB_METHOD_FROM_PROC(m, &call_proc); mrb_define_method_raw(mrb, pc, MRB_SYM(call), m); /* 15.2.17.4.3 */ diff --git a/src/range.c b/src/range.c index c95b322d7..bd501ca8d 100644 --- a/src/range.c +++ b/src/range.c @@ -583,7 +583,6 @@ static const mrb_mt_entry range_rom_entries[] = { MRB_MT_ENTRY(range_initialize_copy, MRB_SYM(initialize_copy), MRB_ARGS_REQ(1) | MRB_MT_PRIVATE), /* 15.2.14.4.15(x) */ MRB_MT_ENTRY(range_num_to_a, MRB_SYM(__num_to_a), MRB_ARGS_NONE()), }; -static mrb_mt_tbl range_rom_mt = MRB_MT_ROM_TAB(range_rom_entries); void mrb_init_range(mrb_state *mrb) @@ -594,5 +593,5 @@ mrb_init_range(mrb_state *mrb) mrb->range_class = r; MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE); - mrb_mt_init_rom(r, &range_rom_mt); + MRB_MT_INIT_ROM(mrb, r, range_rom_entries); } diff --git a/src/state.c b/src/state.c index ee536901a..bfb729d51 100644 --- a/src/state.c +++ b/src/state.c @@ -187,6 +187,18 @@ mrb_close(mrb_state *mrb) mrb_gc_destroy(mrb, &mrb->gc); mrb_free_context(mrb, mrb->root_c); mrb_free_symtbl(mrb); + + /* free heap-allocated ROM method table wrappers */ + { + struct mrb_mt_rom_list *node = mrb->rom_mt; + while (node) { + struct mrb_mt_rom_list *next = node->next; + mrb_free(mrb, node->tbl); + mrb_free(mrb, node); + node = next; + } + } + mrb_free(mrb, mrb); } diff --git a/src/string.c b/src/string.c index 4c5081e11..def95e535 100644 --- a/src/string.c +++ b/src/string.c @@ -3559,7 +3559,6 @@ static const mrb_mt_entry string_rom_entries[] = { MRB_MT_ENTRY(mrb_str_to_f, MRB_SYM(to_f), MRB_ARGS_NONE()), /* 15.2.10.5.38 */ #endif }; -static mrb_mt_tbl string_rom_mt = MRB_MT_ROM_TAB(string_rom_entries); void mrb_init_string(mrb_state *mrb) @@ -3572,7 +3571,7 @@ mrb_init_string(mrb_state *mrb) mrb->string_class = s = mrb_define_class_id(mrb, MRB_SYM(String), mrb->object_class); /* 15.2.10 */ MRB_SET_INSTANCE_TT(s, MRB_TT_STRING); - mrb_mt_init_rom(s, &string_rom_mt); + MRB_MT_INIT_ROM(mrb, s, string_rom_entries); mrb_define_method_id(mrb, mrb->kernel_module, MRB_SYM(__ENCODING__), mrb_encoding, MRB_ARGS_NONE()); } diff --git a/src/symbol.c b/src/symbol.c index 41c3d70af..01c7cb6ec 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -1009,7 +1009,6 @@ static const mrb_mt_entry symbol_rom_entries[] = { MRB_MT_ENTRY(sym_cmp, MRB_OPSYM(cmp), MRB_ARGS_REQ(1)), MRB_MT_ENTRY(mrb_obj_equal_m, MRB_OPSYM(eq), MRB_ARGS_REQ(1)), }; -static mrb_mt_tbl symbol_rom_mt = MRB_MT_ROM_TAB(symbol_rom_entries); void mrb_init_symbol(mrb_state *mrb) @@ -1020,5 +1019,5 @@ mrb_init_symbol(mrb_state *mrb) MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); mrb_undef_class_method_id(mrb, sym, MRB_SYM(new)); - mrb_mt_init_rom(sym, &symbol_rom_mt); + MRB_MT_INIT_ROM(mrb, sym, symbol_rom_entries); }