summaryrefslogtreecommitdiff
path: root/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'symbol.c')
-rw-r--r--symbol.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/symbol.c b/symbol.c
index ae6003ef15..a408ee052e 100644
--- a/symbol.c
+++ b/symbol.c
@@ -19,6 +19,9 @@
#ifndef SYMBOL_DEBUG
# define SYMBOL_DEBUG 0
#endif
+#ifndef CHECK_ID_SERIAL
+# define CHECK_ID_SERIAL SYMBOL_DEBUG
+#endif
#define SYMBOL_PINNED_P(sym) (RSYMBOL(sym)->id&~ID_SCOPE_MASK)
@@ -375,20 +378,41 @@ set_id_entry(rb_id_serial_t num, VALUE str, VALUE sym)
}
static VALUE
-get_id_entry(rb_id_serial_t num, const enum id_entry_type t)
+get_id_serial_entry(rb_id_serial_t num, ID id, const enum id_entry_type t)
{
if (num && num <= global_symbols.last_id) {
size_t idx = num / ID_ENTRY_UNIT;
VALUE ids = global_symbols.ids;
VALUE ary;
if (idx < (size_t)RARRAY_LEN(ids) && !NIL_P(ary = rb_ary_entry(ids, (long)idx))) {
- VALUE result = rb_ary_entry(ary, (long)(num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE + t);
- if (!NIL_P(result)) return result;
+ long pos = (long)(num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE;
+ VALUE result = rb_ary_entry(ary, pos + t);
+ if (NIL_P(result)) return 0;
+#if CHECK_ID_SERIAL
+ if (id) {
+ VALUE sym = result;
+ if (t != ID_ENTRY_SYM)
+ sym = rb_ary_entry(ary, pos + ID_ENTRY_SYM);
+ if (STATIC_SYM_P(sym)) {
+ if (STATIC_SYM2ID(sym) != id) return 0;
+ }
+ else {
+ if (RSYMBOL(sym)->id != id) return 0;
+ }
+ }
+#endif
+ return result;
}
}
return 0;
}
+static VALUE
+get_id_entry(ID id, const enum id_entry_type t)
+{
+ return get_id_serial_entry(rb_id_to_serial(id), id, t);
+}
+
static inline ID
#ifdef __GNUC__
__attribute__((unused))
@@ -396,7 +420,7 @@ __attribute__((unused))
rb_id_serial_to_id(rb_id_serial_t num)
{
if (is_notop_id((ID)num)) {
- VALUE sym = get_id_entry(num, ID_ENTRY_SYM);
+ VALUE sym = get_id_serial_entry(num, 0, ID_ENTRY_SYM);
return SYM2ID(sym);
}
else {
@@ -584,7 +608,7 @@ lookup_str_sym(const VALUE str)
static VALUE
lookup_id_str(ID id)
{
- return get_id_entry(rb_id_to_serial(id), ID_ENTRY_STR);
+ return get_id_entry(id, ID_ENTRY_STR);
}
ID
@@ -719,7 +743,8 @@ rb_str_intern(VALUE str)
enc = ascii;
}
else {
- str = rb_str_new_frozen(str);
+ str = rb_str_dup(str);
+ OBJ_FREEZE(str);
}
str = rb_fstring(str);
type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
@@ -763,7 +788,7 @@ VALUE
rb_id2sym(ID x)
{
if (!DYNAMIC_ID_P(x)) return STATIC_ID2SYM(x);
- return get_id_entry(rb_id_to_serial(x), ID_ENTRY_SYM);
+ return get_id_entry(x, ID_ENTRY_SYM);
}