summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-11-23 00:09:41 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-11-23 21:03:19 +0900
commitc14f230b26aa4f8abe9ecf3814cfebbe584d77c9 (patch)
treeb4d605d19bc2db444a24d41251e7d204bf3a0d30
parenteb301d8aecf454681e78cd7ad6d027e67b121857 (diff)
Assign temporary ID to anonymous ID [Bug #18250]
Dumped iseq binary can not have unnamed symbols/IDs, and ID 0 is stored instead. As `struct rb_id_table` disallows ID 0, also for the distinction, re-assign a new temporary ID based on the local variable table index when loading from the binary, as well as the parser.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/5157
-rw-r--r--compile.c1
-rw-r--r--internal/symbol.h1
-rw-r--r--parse.y5
-rw-r--r--symbol.c11
4 files changed, 14 insertions, 4 deletions
diff --git a/compile.c b/compile.c
index d3cb079562..efe90bed10 100644
--- a/compile.c
+++ b/compile.c
@@ -11554,6 +11554,7 @@ ibf_load_outer_variables(const struct ibf_load * load, ibf_offset_t outer_variab
for (size_t i = 0; i < table_size; i++) {
ID key = ibf_load_id(load, (ID)ibf_load_small_value(load, &reading_pos));
VALUE value = ibf_load_small_value(load, &reading_pos);
+ if (!key) key = rb_make_temporary_id(i);
rb_id_table_insert(tbl, key, value);
}
diff --git a/internal/symbol.h b/internal/symbol.h
index 6875d98db3..4f041330f9 100644
--- a/internal/symbol.h
+++ b/internal/symbol.h
@@ -28,6 +28,7 @@ int rb_is_local_name(VALUE name);
PUREFUNC(int rb_is_const_sym(VALUE sym));
PUREFUNC(int rb_is_attrset_sym(VALUE sym));
ID rb_make_internal_id(void);
+ID rb_make_temporary_id(size_t n);
void rb_gc_free_dsymbol(VALUE);
#if __has_builtin(__builtin_constant_p)
diff --git a/parse.y b/parse.y
index d386561f6a..29517daa20 100644
--- a/parse.y
+++ b/parse.y
@@ -13090,10 +13090,7 @@ rb_init_parse(void)
static ID
internal_id(struct parser_params *p)
{
- const ID max_id = RB_ID_SERIAL_MAX & ~0xffff;
- ID id = (ID)vtable_size(p->lvtbl->args) + (ID)vtable_size(p->lvtbl->vars);
- id = max_id - id;
- return ID_STATIC_SYM | ID_INTERNAL | (id << ID_SCOPE_SHIFT);
+ return rb_make_temporary_id(vtable_size(p->lvtbl->args) + vtable_size(p->lvtbl->vars));
}
#endif /* !RIPPER */
diff --git a/symbol.c b/symbol.c
index 79ec4de502..5ce95f5b07 100644
--- a/symbol.c
+++ b/symbol.c
@@ -952,6 +952,17 @@ rb_make_internal_id(void)
return next_id_base() | ID_INTERNAL | ID_STATIC_SYM;
}
+ID
+rb_make_temporary_id(size_t n)
+{
+ const ID max_id = RB_ID_SERIAL_MAX & ~0xffff;
+ const ID id = max_id - (ID)n;
+ if (id <= ruby_global_symbols.last_id) {
+ rb_raise(rb_eRuntimeError, "too big to make temporary ID: %" PRIdSIZE, n);
+ }
+ return (id << ID_SCOPE_SHIFT) | ID_STATIC_SYM | ID_INTERNAL;
+}
+
static int
symbols_i(st_data_t key, st_data_t value, st_data_t arg)
{