From c14f230b26aa4f8abe9ecf3814cfebbe584d77c9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 23 Nov 2021 00:09:41 +0900 Subject: [PATCH] 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. --- compile.c | 1 + internal/symbol.h | 1 + parse.y | 5 +---- symbol.c | 11 +++++++++++ 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) {