summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-22 06:41:29 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-01-22 06:41:29 +0000
commitbb19bcf93ed0414ebe7542f20f395388d325c157 (patch)
treed069b2aa069722624bc6bcd40e73a9204b53bee9 /parse.y
parent2d87a5c1500ccf40141216bf44629d324ce9bf53 (diff)
* parse.y (rb_intern3): split to registration check and new
registration. * parse.y (rb_intern_str): make interned string shared with the given string. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y53
1 files changed, 39 insertions, 14 deletions
diff --git a/parse.y b/parse.y
index 0b58166f3c..1ad9d62265 100644
--- a/parse.y
+++ b/parse.y
@@ -40,6 +40,7 @@
#ifndef RIPPER
static ID register_symid(ID, const char *, long, rb_encoding *);
+static ID register_symid_str(ID, VALUE);
#define REGISTER_SYMID(id, name) register_symid((id), (name), strlen(name), enc)
#include "id.c"
#endif
@@ -10391,6 +10392,12 @@ static ID
register_symid(ID id, const char *name, long len, rb_encoding *enc)
{
VALUE str = rb_enc_str_new(name, len, enc);
+ return register_symid_str(id, str);
+}
+
+static ID
+register_symid_str(ID id, VALUE str)
+{
OBJ_FREEZE(str);
st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
st_add_direct(global_symbols.id_str, id, (st_data_t)str);
@@ -10407,16 +10414,12 @@ sym_check_asciionly(VALUE str)
return cr == ENC_CODERANGE_7BIT;
}
+static ID intern_str(VALUE str);
+
ID
rb_intern3(const char *name, long len, rb_encoding *enc)
{
- const char *m = name;
- const char *e = m + len;
- unsigned char c;
VALUE str;
- ID id;
- long last;
- int mb;
st_data_t data;
struct RString fake_str;
fake_str.basic.flags = T_STRING|RSTRING_NOEMBED;
@@ -10433,6 +10436,25 @@ rb_intern3(const char *name, long len, rb_encoding *enc)
if (st_lookup(global_symbols.sym_id, str, &data))
return (ID)data;
+ str = rb_enc_str_new(name, len, enc); /* make true string */
+ return intern_str(str);
+}
+
+static ID
+intern_str(VALUE str)
+{
+ const char *name, *m, *e;
+ long len, last;
+ rb_encoding *enc;
+ unsigned char c;
+ ID id;
+ int mb;
+
+ RSTRING_GETMEM(str, name, len);
+ m = name;
+ e = m + len;
+ enc = rb_enc_get(str);
+
if (rb_cString && !rb_enc_asciicompat(enc)) {
id = ID_JUNK;
goto new_id;
@@ -10518,7 +10540,7 @@ rb_intern3(const char *name, long len, rb_encoding *enc)
}
id |= ++global_symbols.last_id << ID_SCOPE_SHIFT;
id_register:
- return register_symid(id, name, len, enc);
+ return register_symid_str(id, str);
}
ID
@@ -10538,17 +10560,20 @@ ID
rb_intern_str(VALUE str)
{
rb_encoding *enc;
- ID id;
+ st_data_t id;
+ int ascii = sym_check_asciionly(str);
- if (sym_check_asciionly(str)) {
- enc = rb_usascii_encoding();
+ if (st_lookup(global_symbols.sym_id, str, &id))
+ return (ID)id;
+ if (ascii && (enc = rb_usascii_encoding()) != rb_enc_get(str)) {
+ str = rb_str_dup(str);
+ rb_enc_associate(str, enc);
+ OBJ_FREEZE(str);
}
else {
- enc = rb_enc_get(str);
+ str = rb_str_dup_frozen(str);
}
- id = rb_intern3(RSTRING_PTR(str), RSTRING_LEN(str), enc);
- RB_GC_GUARD(str);
- return id;
+ return intern_str(str);
}
VALUE