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 <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-02-20 22:24:31 +09:00
parent 10f36a0cbb
commit 71cb3c2e3a
36 changed files with 142 additions and 146 deletions
+45 -42
View File
@@ -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 `<mruby/internal.h>` (which provides `mrb_mt_entry`,
`mrb_mt_tbl`, `MRB_MT_ENTRY()`, `MRB_MT_ROM_TAB()`, and flag
constants) and define the ROM entries:
Include `<mruby/class.h>` (which provides `mrb_mt_entry`,
`MRB_MT_ENTRY()`, and flag constants) and define the ROM entries:
```c
#include <mruby/internal.h>
#include <mruby/class.h>
#include <mruby/presym.h>
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);
}
```
+2
View File
@@ -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
+13 -9
View File
@@ -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
+1 -2
View File
@@ -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
+2 -4
View File
@@ -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
+1 -2
View File
@@ -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));
}
+1 -2
View File
@@ -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());
}
+1 -2
View File
@@ -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));
+1 -2
View File
@@ -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));
+1 -2
View File
@@ -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
+2 -4
View File
@@ -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 */
}
+2 -4
View File
@@ -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));
+1 -2
View File
@@ -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
+2 -4
View File
@@ -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
+1 -2
View File
@@ -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());
}
+1 -2
View File
@@ -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));
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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));
+1 -2
View File
@@ -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?", "==");
}
+4 -8
View File
@@ -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));
+1 -2
View File
@@ -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));
}
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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);
}
+28 -11
View File
@@ -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));
+1 -2
View File
@@ -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 */
+1 -2
View File
@@ -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
+1 -2
View File
@@ -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);
}
+3 -6
View File
@@ -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));
+3 -6
View File
@@ -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*
+1 -2
View File
@@ -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 */
+1 -2
View File
@@ -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);
}
+12
View File
@@ -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);
}
+1 -2
View File
@@ -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());
}
+1 -2
View File
@@ -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);
}