зеркало из https://github.com/github/ruby.git
symbol.c: immortal IDs
* symbol.c (global_symbols): make IDs immortal always, instead of treating dynamic symbols as IDs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47913 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
5617e31771
Коммит
3e69b074c5
6
.gdbinit
6
.gdbinit
|
@ -378,9 +378,9 @@ define rp_id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
printf "(%ld): ", $id
|
printf "(%ld): ", $id
|
||||||
rb_numtable_entry global_symbols.id_str $id
|
if global_symbols.ids.size > ($id >> RUBY_ID_SCOPE_SHIFT)
|
||||||
if $rb_numtable_rec
|
set $str = global_symbols.ids.ptr[$id >> RUBY_ID_SCOPE_SHIFT]->str
|
||||||
rp_string $rb_numtable_rec
|
rp_string $str
|
||||||
else
|
else
|
||||||
echo undef\n
|
echo undef\n
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
Tue Oct 14 16:22:59 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue Oct 14 16:23:04 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* symbol.c (global_symbols): make IDs immortal always, instead
|
||||||
|
of treating dynamic symbols as IDs.
|
||||||
|
|
||||||
* iseq.c, marshal.c, string.c: use rb_str_intern instead of
|
* iseq.c, marshal.c, string.c: use rb_str_intern instead of
|
||||||
rb_str_dynamic_intern.
|
rb_str_dynamic_intern.
|
||||||
|
|
493
symbol.c
493
symbol.c
|
@ -18,10 +18,9 @@
|
||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "probes.h"
|
#include "probes.h"
|
||||||
|
|
||||||
#define SYMBOL_PINNED FL_USER1
|
#define SYMBOL_PINNED_P(sym) (RSYMBOL(sym)->id&~ID_SCOPE_MASK)
|
||||||
#define SYMBOL_PINNED_P(sym) FL_TEST((sym), SYMBOL_PINNED)
|
|
||||||
|
|
||||||
#define ID_DYNAMIC_SYM_P(id) (!(id&ID_STATIC_SYM)&&id>tLAST_OP_ID)
|
#define DYNAMIC_ID_P(id) (!(id&ID_STATIC_SYM)&&id>tLAST_OP_ID)
|
||||||
#define STATIC_SYM2ID(sym) RSHIFT((unsigned long)(sym), RUBY_SPECIAL_SHIFT)
|
#define STATIC_SYM2ID(sym) RSHIFT((unsigned long)(sym), RUBY_SPECIAL_SHIFT)
|
||||||
#define STATIC_ID2SYM(id) (((VALUE)(id)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG)
|
#define STATIC_ID2SYM(id) (((VALUE)(id)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG)
|
||||||
|
|
||||||
|
@ -77,10 +76,36 @@ static const struct {
|
||||||
STATIC_ASSERT(op_tbl_name_size, sizeof(op_tbl[0].name) == 3);
|
STATIC_ASSERT(op_tbl_name_size, sizeof(op_tbl[0].name) == 3);
|
||||||
#define op_tbl_len(i) (!op_tbl[i].name[1] ? 1 : !op_tbl[i].name[2] ? 2 : 3)
|
#define op_tbl_len(i) (!op_tbl[i].name[1] ? 1 : !op_tbl[i].name[2] ? 2 : 3)
|
||||||
|
|
||||||
|
static void
|
||||||
|
Init_op_tbl(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
rb_encoding *const enc = rb_usascii_encoding();
|
||||||
|
|
||||||
|
for (i = '!'; i <= '~'; ++i) {
|
||||||
|
if (!ISALNUM(i) && i != '_') {
|
||||||
|
char c = (char)i;
|
||||||
|
register_static_symid(i, &c, 1, enc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < op_tbl_count; ++i) {
|
||||||
|
register_static_symid(op_tbl[i].token, op_tbl[i].name, op_tbl_len(i), enc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {ID_ENTRY_UNIT = 2048};
|
||||||
|
|
||||||
|
struct id_entry {
|
||||||
|
VALUE str, sym;
|
||||||
|
};
|
||||||
|
|
||||||
static struct symbols {
|
static struct symbols {
|
||||||
ID last_id;
|
ID last_id;
|
||||||
st_table *str_id;
|
st_table *str_sym;
|
||||||
st_table *id_str;
|
struct {
|
||||||
|
size_t size;
|
||||||
|
struct id_entry *ptr;
|
||||||
|
} ids;
|
||||||
VALUE dsymbol_fstr_hash;
|
VALUE dsymbol_fstr_hash;
|
||||||
} global_symbols = {tNEXT_ID-1};
|
} global_symbols = {tNEXT_ID-1};
|
||||||
|
|
||||||
|
@ -97,24 +122,31 @@ Init_sym(void)
|
||||||
rb_gc_register_mark_object(dsym_fstrs);
|
rb_gc_register_mark_object(dsym_fstrs);
|
||||||
rb_obj_hide(dsym_fstrs);
|
rb_obj_hide(dsym_fstrs);
|
||||||
|
|
||||||
global_symbols.str_id = st_init_table_with_size(&symhash, 1000);
|
global_symbols.str_sym = st_init_table_with_size(&symhash, 1000);
|
||||||
global_symbols.id_str = st_init_numtable_with_size(1000);
|
global_symbols.ids.size = ID_ENTRY_UNIT;
|
||||||
|
global_symbols.ids.ptr = ALLOC_N(struct id_entry, global_symbols.ids.size);
|
||||||
|
|
||||||
|
Init_op_tbl();
|
||||||
Init_id();
|
Init_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding *const enc, const ID type));
|
WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding *const enc, const ID type));
|
||||||
WARN_UNUSED_RESULT(static VALUE dsymbol_check(const VALUE sym));
|
WARN_UNUSED_RESULT(static VALUE dsymbol_check(const VALUE sym));
|
||||||
WARN_UNUSED_RESULT(static ID dsymbol_pindown(VALUE sym));
|
|
||||||
WARN_UNUSED_RESULT(static ID lookup_str_id(VALUE str));
|
WARN_UNUSED_RESULT(static ID lookup_str_id(VALUE str));
|
||||||
WARN_UNUSED_RESULT(static VALUE lookup_str_sym(const VALUE str));
|
WARN_UNUSED_RESULT(static VALUE lookup_str_sym(const VALUE str));
|
||||||
WARN_UNUSED_RESULT(static VALUE lookup_id_str(ID id));
|
WARN_UNUSED_RESULT(static VALUE lookup_id_str(ID id));
|
||||||
WARN_UNUSED_RESULT(static ID attrsetname_to_attr(VALUE name));
|
WARN_UNUSED_RESULT(static ID attrsetname_to_attr(VALUE name));
|
||||||
WARN_UNUSED_RESULT(static ID attrsetname_to_attr_id(VALUE name));
|
WARN_UNUSED_RESULT(static ID attrsetname_to_attr_id(VALUE name));
|
||||||
|
WARN_UNUSED_RESULT(static ID intern_str(VALUE str, int mutable));
|
||||||
|
|
||||||
|
#define id_to_serial(id) (is_notop_id(id) ? id >> ID_SCOPE_SHIFT : id)
|
||||||
|
|
||||||
ID
|
ID
|
||||||
rb_id_attrset(ID id)
|
rb_id_attrset(ID id)
|
||||||
{
|
{
|
||||||
|
VALUE str, sym;
|
||||||
|
int scope;
|
||||||
|
|
||||||
if (!is_notop_id(id)) {
|
if (!is_notop_id(id)) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case tAREF: case tASET:
|
case tAREF: case tASET:
|
||||||
|
@ -124,7 +156,7 @@ rb_id_attrset(ID id)
|
||||||
rb_id2str(id));
|
rb_id2str(id));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int scope = id_type(id);
|
scope = id_type(id);
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
case ID_LOCAL: case ID_INSTANCE: case ID_GLOBAL:
|
case ID_LOCAL: case ID_INSTANCE: case ID_GLOBAL:
|
||||||
case ID_CONST: case ID_CLASS: case ID_JUNK:
|
case ID_CONST: case ID_CLASS: case ID_JUNK:
|
||||||
|
@ -133,7 +165,6 @@ rb_id_attrset(ID id)
|
||||||
return id;
|
return id;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
VALUE str;
|
|
||||||
if ((str = lookup_id_str(id)) != 0) {
|
if ((str = lookup_id_str(id)) != 0) {
|
||||||
rb_name_error(id, "cannot make unknown type ID %d:%"PRIsVALUE" attrset",
|
rb_name_error(id, "cannot make unknown type ID %d:%"PRIsVALUE" attrset",
|
||||||
scope, str);
|
scope, str);
|
||||||
|
@ -145,18 +176,26 @@ rb_id_attrset(ID id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (id&ID_STATIC_SYM) {
|
|
||||||
id &= ~ID_SCOPE_MASK;
|
|
||||||
id |= ID_ATTRSET;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VALUE str;
|
|
||||||
|
|
||||||
/* make new dynamic symbol */
|
/* make new symbol and ID */
|
||||||
str = rb_str_dup(RSYMBOL((VALUE)id)->fstr);
|
if (!(str = lookup_id_str(id))) {
|
||||||
rb_str_cat(str, "=", 1);
|
static const char id_types[][8] = {
|
||||||
id = SYM2ID(rb_str_intern(str));
|
"local",
|
||||||
|
"instance",
|
||||||
|
"invalid",
|
||||||
|
"global",
|
||||||
|
"attrset",
|
||||||
|
"const",
|
||||||
|
"class",
|
||||||
|
"junk",
|
||||||
|
};
|
||||||
|
rb_name_error(id, "cannot make anonymous %.*s ID %"PRIxVALUE" attrset",
|
||||||
|
(int)sizeof(id_types[0]), id_types[scope], (VALUE)id);
|
||||||
}
|
}
|
||||||
|
str = rb_str_dup(str);
|
||||||
|
rb_str_cat(str, "=", 1);
|
||||||
|
sym = lookup_str_sym(str);
|
||||||
|
id = sym ? rb_sym2id(sym) : intern_str(str, 1);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,35 +369,41 @@ rb_str_symname_type(VALUE name, unsigned int allowed_attrset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
register_symid_direct(VALUE str, ID id)
|
set_id_entry(ID num, VALUE str, VALUE sym)
|
||||||
{
|
{
|
||||||
st_add_direct(global_symbols.str_id, (st_data_t)str, (st_data_t)id);
|
struct id_entry *entry;
|
||||||
st_add_direct(global_symbols.id_str, (st_data_t)id, (st_data_t)str);
|
if (num >= global_symbols.ids.size) {
|
||||||
|
size_t new_size = (num / ID_ENTRY_UNIT + 1) * ID_ENTRY_UNIT;
|
||||||
|
REALLOC_N(global_symbols.ids.ptr, struct id_entry, new_size);
|
||||||
|
global_symbols.ids.size = new_size;
|
||||||
|
}
|
||||||
|
entry = &global_symbols.ids.ptr[num];
|
||||||
|
entry->str = str;
|
||||||
|
entry->sym = sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct id_entry *
|
||||||
unregister_sym_str(VALUE str)
|
get_id_entry(ID num)
|
||||||
{
|
{
|
||||||
st_data_t str_data = (st_data_t)str;
|
if (num && num <= global_symbols.last_id) {
|
||||||
return st_delete(global_symbols.str_id, &str_data, NULL);
|
return &global_symbols.ids.ptr[num];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
unregister_sym_id(VALUE sym)
|
register_sym(VALUE str, VALUE sym)
|
||||||
{
|
{
|
||||||
st_data_t sym_data = (st_data_t)sym;
|
st_add_direct(global_symbols.str_sym, (st_data_t)str, (st_data_t)sym);
|
||||||
return st_delete(global_symbols.id_str, &sym_data, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unregister_sym(VALUE str, VALUE sym)
|
unregister_sym(VALUE str, VALUE sym)
|
||||||
{
|
{
|
||||||
if (!unregister_sym_str(str)) {
|
st_data_t str_data = (st_data_t)str;
|
||||||
|
if (!st_delete(global_symbols.str_sym, &str_data, NULL)) {
|
||||||
rb_bug("%p can't remove str from str_id (%s)", (void *)sym, RSTRING_PTR(str));
|
rb_bug("%p can't remove str from str_id (%s)", (void *)sym, RSTRING_PTR(str));
|
||||||
}
|
}
|
||||||
if (!unregister_sym_id(sym)) {
|
|
||||||
rb_bug("%p can't remove sym from id_str (%s)", (void *)sym, RSTRING_PTR(str));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID
|
static ID
|
||||||
|
@ -371,6 +416,9 @@ register_static_symid(ID id, const char *name, long len, rb_encoding *enc)
|
||||||
static ID
|
static ID
|
||||||
register_static_symid_str(ID id, VALUE str)
|
register_static_symid_str(ID id, VALUE str)
|
||||||
{
|
{
|
||||||
|
ID num = id_to_serial(id);
|
||||||
|
VALUE sym = STATIC_ID2SYM(id);
|
||||||
|
|
||||||
OBJ_FREEZE(str);
|
OBJ_FREEZE(str);
|
||||||
str = rb_fstring(str);
|
str = rb_fstring(str);
|
||||||
|
|
||||||
|
@ -378,7 +426,8 @@ register_static_symid_str(ID id, VALUE str)
|
||||||
RUBY_DTRACE_SYMBOL_CREATE(RSTRING_PTR(str), rb_sourcefile(), rb_sourceline());
|
RUBY_DTRACE_SYMBOL_CREATE(RSTRING_PTR(str), rb_sourcefile(), rb_sourceline());
|
||||||
}
|
}
|
||||||
|
|
||||||
register_symid_direct(str, id);
|
register_sym(str, sym);
|
||||||
|
set_id_entry(num, str, sym);
|
||||||
rb_gc_register_mark_object(str);
|
rb_gc_register_mark_object(str);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
@ -397,12 +446,12 @@ sym_check_asciionly(VALUE str)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
* _str_ itself will be registered at the global symbol table. _str_
|
* _str_ itself will be registered at the global symbol table. _str_
|
||||||
* can be modified before the registration, since the encoding will be
|
* can be modified before the registration, since the encoding will be
|
||||||
* set to ASCII-8BIT if it is a special global name.
|
* set to ASCII-8BIT if it is a special global name.
|
||||||
*/
|
*/
|
||||||
static ID intern_str(VALUE str);
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
must_be_dynamic_symbol(VALUE x)
|
must_be_dynamic_symbol(VALUE x)
|
||||||
|
@ -423,6 +472,7 @@ must_be_dynamic_symbol(VALUE x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type)
|
dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type)
|
||||||
|
@ -432,9 +482,9 @@ dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const
|
||||||
rb_enc_associate(dsym, enc);
|
rb_enc_associate(dsym, enc);
|
||||||
OBJ_FREEZE(dsym);
|
OBJ_FREEZE(dsym);
|
||||||
RB_OBJ_WRITE(dsym, &RSYMBOL(dsym)->fstr, str);
|
RB_OBJ_WRITE(dsym, &RSYMBOL(dsym)->fstr, str);
|
||||||
RSYMBOL(dsym)->type = type;
|
RSYMBOL(dsym)->id = type;
|
||||||
|
|
||||||
register_symid_direct(str, (ID)dsym);
|
register_sym(str, dsym);
|
||||||
rb_hash_aset(global_symbols.dsymbol_fstr_hash, str, Qtrue);
|
rb_hash_aset(global_symbols.dsymbol_fstr_hash, str, Qtrue);
|
||||||
|
|
||||||
if (RUBY_DTRACE_SYMBOL_CREATE_ENABLED()) {
|
if (RUBY_DTRACE_SYMBOL_CREATE_ENABLED()) {
|
||||||
|
@ -449,7 +499,7 @@ dsymbol_check(const VALUE sym)
|
||||||
{
|
{
|
||||||
if (UNLIKELY(rb_objspace_garbage_object_p(sym))) {
|
if (UNLIKELY(rb_objspace_garbage_object_p(sym))) {
|
||||||
const VALUE fstr = RSYMBOL(sym)->fstr;
|
const VALUE fstr = RSYMBOL(sym)->fstr;
|
||||||
const ID type = RSYMBOL(sym)->type;
|
const ID type = RSYMBOL(sym)->id & ID_SCOPE_MASK;
|
||||||
RSYMBOL(sym)->fstr = 0;
|
RSYMBOL(sym)->fstr = 0;
|
||||||
|
|
||||||
unregister_sym(fstr, sym);
|
unregister_sym(fstr, sym);
|
||||||
|
@ -460,34 +510,23 @@ dsymbol_check(const VALUE sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID
|
|
||||||
dsymbol_pindown(VALUE sym)
|
|
||||||
{
|
|
||||||
must_be_dynamic_symbol(sym);
|
|
||||||
|
|
||||||
if (UNLIKELY(SYMBOL_PINNED_P(sym) == 0)) {
|
|
||||||
VALUE fstr = RSYMBOL(sym)->fstr;
|
|
||||||
sym = dsymbol_check(sym);
|
|
||||||
FL_SET(sym, SYMBOL_PINNED);
|
|
||||||
|
|
||||||
/* make it permanent object */
|
|
||||||
rb_gc_register_mark_object(sym);
|
|
||||||
rb_gc_register_mark_object(fstr);
|
|
||||||
rb_hash_delete(global_symbols.dsymbol_fstr_hash, fstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ID)sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID
|
static ID
|
||||||
lookup_str_id(VALUE str)
|
lookup_str_id(VALUE str)
|
||||||
{
|
{
|
||||||
st_data_t id_data;
|
st_data_t sym_data;
|
||||||
if (st_lookup(global_symbols.str_id, (st_data_t)str, &id_data)) {
|
if (st_lookup(global_symbols.str_sym, (st_data_t)str, &sym_data)) {
|
||||||
const ID id = (ID)id_data;
|
const VALUE sym = (VALUE)sym_data;
|
||||||
|
|
||||||
if (!ID_DYNAMIC_SYM_P(id) || SYMBOL_PINNED_P(id)) {
|
if (STATIC_SYM_P(sym)) {
|
||||||
return id;
|
return STATIC_SYM2ID(sym);
|
||||||
|
}
|
||||||
|
else if (DYNAMIC_SYM_P(sym)) {
|
||||||
|
ID id = RSYMBOL(sym)->id;
|
||||||
|
if (id & ~ID_SCOPE_MASK) return id;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_bug("non-symbol object %s:%"PRIxVALUE" for %"PRIsVALUE" in symbol table",
|
||||||
|
rb_builtin_class_name(sym), sym, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (ID)0;
|
return (ID)0;
|
||||||
|
@ -497,15 +536,13 @@ static VALUE
|
||||||
lookup_str_sym(const VALUE str)
|
lookup_str_sym(const VALUE str)
|
||||||
{
|
{
|
||||||
st_data_t sym_data;
|
st_data_t sym_data;
|
||||||
if (st_lookup(global_symbols.str_id, (st_data_t)str, &sym_data)) {
|
if (st_lookup(global_symbols.str_sym, (st_data_t)str, &sym_data)) {
|
||||||
const ID id = (ID)sym_data;
|
VALUE sym = (VALUE)sym_data;
|
||||||
|
|
||||||
if (ID_DYNAMIC_SYM_P(id)) {
|
if (DYNAMIC_SYM_P(sym)) {
|
||||||
return dsymbol_check(id);
|
sym = dsymbol_check(sym);
|
||||||
}
|
|
||||||
else {
|
|
||||||
return STATIC_ID2SYM(id);
|
|
||||||
}
|
}
|
||||||
|
return sym;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return (VALUE)0;
|
return (VALUE)0;
|
||||||
|
@ -515,46 +552,26 @@ lookup_str_sym(const VALUE str)
|
||||||
static VALUE
|
static VALUE
|
||||||
lookup_id_str(ID id)
|
lookup_id_str(ID id)
|
||||||
{
|
{
|
||||||
st_data_t data;
|
const struct id_entry *entry;
|
||||||
if (ID_DYNAMIC_SYM_P(id)) {
|
|
||||||
return RSYMBOL(id)->fstr;
|
if ((entry = get_id_entry(id_to_serial(id))) != 0) {
|
||||||
}
|
return entry->str;
|
||||||
if (st_lookup(global_symbols.id_str, id, &data)) {
|
|
||||||
return (VALUE)data;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID
|
ID
|
||||||
rb_intern_cstr_without_pindown(const char *name, long len, rb_encoding *enc)
|
rb_intern3(const char *name, long len, rb_encoding *enc)
|
||||||
{
|
{
|
||||||
st_data_t id;
|
VALUE sym;
|
||||||
struct RString fake_str;
|
struct RString fake_str;
|
||||||
VALUE str = rb_setup_fake_str(&fake_str, name, len, enc);
|
VALUE str = rb_setup_fake_str(&fake_str, name, len, enc);
|
||||||
OBJ_FREEZE(str);
|
OBJ_FREEZE(str);
|
||||||
|
|
||||||
if (st_lookup(global_symbols.str_id, str, &id)) {
|
sym = lookup_str_sym(str);
|
||||||
if (ID_DYNAMIC_SYM_P((ID)id)) {
|
if (sym) return rb_sym2id(sym);
|
||||||
return (ID)dsymbol_check((VALUE)id);
|
|
||||||
}
|
|
||||||
return (ID)id;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = rb_enc_str_new(name, len, enc); /* make true string */
|
str = rb_enc_str_new(name, len, enc); /* make true string */
|
||||||
return intern_str(str);
|
return intern_str(str, 1);
|
||||||
}
|
|
||||||
|
|
||||||
ID
|
|
||||||
rb_intern3(const char *name, long len, rb_encoding *enc)
|
|
||||||
{
|
|
||||||
ID id;
|
|
||||||
|
|
||||||
id = rb_intern_cstr_without_pindown(name, len, enc);
|
|
||||||
if (ID_DYNAMIC_SYM_P(id)) {
|
|
||||||
id = dsymbol_pindown((VALUE)id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID
|
static ID
|
||||||
|
@ -563,109 +580,24 @@ next_id_base(void)
|
||||||
if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
|
if (global_symbols.last_id >= ~(ID)0 >> (ID_SCOPE_SHIFT+RUBY_SPECIAL_SHIFT)) {
|
||||||
return (ID)-1;
|
return (ID)-1;
|
||||||
}
|
}
|
||||||
++global_symbols.last_id;
|
else {
|
||||||
return global_symbols.last_id << ID_SCOPE_SHIFT;
|
const size_t num = ++global_symbols.last_id;
|
||||||
|
return num << ID_SCOPE_SHIFT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ID
|
static ID
|
||||||
next_id(VALUE str)
|
intern_str(VALUE str, int mutable)
|
||||||
{
|
{
|
||||||
const char *name, *m, *e;
|
|
||||||
long len, last;
|
|
||||||
rb_encoding *enc, *symenc;
|
|
||||||
unsigned char c;
|
|
||||||
ID id;
|
ID id;
|
||||||
ID nid;
|
ID nid;
|
||||||
int mb;
|
|
||||||
|
|
||||||
RSTRING_GETMEM(str, name, len);
|
id = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
|
||||||
m = name;
|
if (id == (ID)-1) id = ID_JUNK;
|
||||||
e = m + len;
|
if (sym_check_asciionly(str)) {
|
||||||
enc = rb_enc_get(str);
|
if (!mutable) str = rb_str_dup(str);
|
||||||
symenc = enc;
|
rb_enc_associate(str, rb_usascii_encoding());
|
||||||
|
|
||||||
if (!len || (rb_cString && !rb_enc_asciicompat(enc))) {
|
|
||||||
junk:
|
|
||||||
id = ID_JUNK;
|
|
||||||
goto new_id;
|
|
||||||
}
|
}
|
||||||
last = len-1;
|
|
||||||
id = 0;
|
|
||||||
switch (*m) {
|
|
||||||
case '$':
|
|
||||||
if (len < 2) goto junk;
|
|
||||||
id |= ID_GLOBAL;
|
|
||||||
if ((mb = is_special_global_name(++m, e, enc)) != 0) {
|
|
||||||
if (!--mb) symenc = rb_usascii_encoding();
|
|
||||||
goto new_id;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '@':
|
|
||||||
if (m[1] == '@') {
|
|
||||||
if (len < 3) goto junk;
|
|
||||||
m++;
|
|
||||||
id |= ID_CLASS;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (len < 2) goto junk;
|
|
||||||
id |= ID_INSTANCE;
|
|
||||||
}
|
|
||||||
m++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c = m[0];
|
|
||||||
if (c != '_' && rb_enc_isascii(c, enc) && rb_enc_ispunct(c, enc)) {
|
|
||||||
/* operators */
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (len == 1) {
|
|
||||||
id = c;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
for (i = 0; i < op_tbl_count; i++) {
|
|
||||||
if (*op_tbl[i].name == *m &&
|
|
||||||
strcmp(op_tbl[i].name, m) == 0) {
|
|
||||||
id = op_tbl[i].token;
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (name[last] == '=') {
|
|
||||||
/* attribute assignment */
|
|
||||||
if (last > 1 && name[last-1] == '=')
|
|
||||||
goto junk;
|
|
||||||
id = rb_intern3(name, last, enc);
|
|
||||||
if (id > tLAST_OP_ID && !is_attrset_id(id)) {
|
|
||||||
enc = rb_enc_get(rb_id2str(id));
|
|
||||||
id = rb_id_attrset(id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
id = ID_ATTRSET;
|
|
||||||
}
|
|
||||||
else if (id == 0) {
|
|
||||||
if (rb_enc_isupper(m[0], enc)) {
|
|
||||||
id = ID_CONST;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
id = ID_LOCAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!rb_enc_isdigit(*m, enc)) {
|
|
||||||
while (m <= name + last && is_identchar(m, e, enc)) {
|
|
||||||
if (ISASCII(*m)) {
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m += rb_enc_mbclen(m, e, enc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id != ID_ATTRSET && m - name < len) id = ID_JUNK;
|
|
||||||
if (sym_check_asciionly(str)) symenc = rb_usascii_encoding();
|
|
||||||
new_id:
|
|
||||||
if (symenc != enc) rb_enc_associate(str, symenc);
|
|
||||||
if ((nid = next_id_base()) == (ID)-1) {
|
if ((nid = next_id_base()) == (ID)-1) {
|
||||||
str = rb_str_ellipsize(str, 20);
|
str = rb_str_ellipsize(str, 20);
|
||||||
rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %"PRIsVALUE")",
|
rb_raise(rb_eRuntimeError, "symbol table overflow (symbol %"PRIsVALUE")",
|
||||||
|
@ -673,14 +605,6 @@ next_id(VALUE str)
|
||||||
}
|
}
|
||||||
id |= nid;
|
id |= nid;
|
||||||
id |= ID_STATIC_SYM;
|
id |= ID_STATIC_SYM;
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ID
|
|
||||||
intern_str(VALUE str)
|
|
||||||
{
|
|
||||||
ID id = next_id(str);
|
|
||||||
if (ID_DYNAMIC_SYM_P(id) && is_attrset_id(id)) return id;
|
|
||||||
return register_static_symid_str(id, str);
|
return register_static_symid_str(id, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +630,7 @@ rb_intern_str(VALUE str)
|
||||||
return SYM2ID(sym);
|
return SYM2ID(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
return intern_str(rb_str_dup(str));
|
return intern_str(str, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -745,13 +669,17 @@ rb_str_intern(VALUE str)
|
||||||
{
|
{
|
||||||
#if USE_SYMBOL_GC
|
#if USE_SYMBOL_GC
|
||||||
rb_encoding *enc, *ascii;
|
rb_encoding *enc, *ascii;
|
||||||
|
int type;
|
||||||
|
#else
|
||||||
|
ID id;
|
||||||
|
#endif
|
||||||
VALUE sym = lookup_str_sym(str);
|
VALUE sym = lookup_str_sym(str);
|
||||||
ID type;
|
|
||||||
|
|
||||||
if (sym) {
|
if (sym) {
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_SYMBOL_GC
|
||||||
enc = rb_enc_get(str);
|
enc = rb_enc_get(str);
|
||||||
ascii = rb_usascii_encoding();
|
ascii = rb_usascii_encoding();
|
||||||
if (enc != ascii) {
|
if (enc != ascii) {
|
||||||
|
@ -762,45 +690,56 @@ rb_str_intern(VALUE str)
|
||||||
enc = ascii;
|
enc = ascii;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
str = rb_fstring(str);
|
||||||
type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
|
type = rb_str_symname_type(str, IDSET_ATTRSET_FOR_INTERN);
|
||||||
if (type == ID_ATTRSET) {
|
if (type < 0) type = ID_JUNK;
|
||||||
ID attr_id = attrsetname_to_attr_id(str);
|
return dsymbol_alloc(rb_cSymbol, str, enc, type);
|
||||||
if (attr_id && !ID_DYNAMIC_SYM_P(attr_id)) {
|
|
||||||
attr_id = rb_id_attrset(attr_id);
|
|
||||||
return ID2SYM(attr_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dsymbol_alloc(rb_cSymbol, rb_fstring(str), enc, type);
|
|
||||||
#else
|
#else
|
||||||
return rb_str_intern(str);
|
id = intern_str(str, 0);
|
||||||
|
return ID2SYM(id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ID
|
ID
|
||||||
rb_sym2id(VALUE sym)
|
rb_sym2id(VALUE sym)
|
||||||
{
|
{
|
||||||
|
ID id;
|
||||||
if (STATIC_SYM_P(sym)) {
|
if (STATIC_SYM_P(sym)) {
|
||||||
return STATIC_SYM2ID(sym);
|
id = STATIC_SYM2ID(sym);
|
||||||
|
}
|
||||||
|
else if (DYNAMIC_SYM_P(sym)) {
|
||||||
|
sym = dsymbol_check(sym);
|
||||||
|
id = RSYMBOL(sym)->id;
|
||||||
|
if (UNLIKELY(!(id & ~ID_SCOPE_MASK))) {
|
||||||
|
VALUE fstr = RSYMBOL(sym)->fstr;
|
||||||
|
ID num = next_id_base();
|
||||||
|
|
||||||
|
RSYMBOL(sym)->id = id |= num;
|
||||||
|
/* make it permanent object */
|
||||||
|
set_id_entry(num >>= ID_SCOPE_SHIFT, fstr, sym);
|
||||||
|
rb_gc_register_mark_object(sym);
|
||||||
|
rb_gc_register_mark_object(fstr);
|
||||||
|
rb_hash_delete(global_symbols.dsymbol_fstr_hash, fstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!SYMBOL_PINNED_P(sym)) {
|
rb_raise(rb_eTypeError, "wrong argument type %s (expected Symbol)",
|
||||||
return dsymbol_pindown(sym);
|
rb_builtin_class_name(sym));
|
||||||
}
|
|
||||||
return (ID)sym;
|
|
||||||
}
|
}
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_id2sym(ID x)
|
rb_id2sym(ID x)
|
||||||
{
|
{
|
||||||
if (!ID_DYNAMIC_SYM_P(x)) {
|
const struct id_entry *entry;
|
||||||
return STATIC_ID2SYM(x);
|
|
||||||
}
|
if (!DYNAMIC_ID_P(x)) return STATIC_ID2SYM(x);
|
||||||
else {
|
|
||||||
return (VALUE)x;
|
if ((entry = get_id_entry(id_to_serial(x))) != 0) {
|
||||||
|
return entry->sym;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -820,49 +759,12 @@ rb_id2str(ID id)
|
||||||
{
|
{
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
if (id < tLAST_OP_ID) {
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (id < INT_MAX && rb_ispunct((int)id)) {
|
|
||||||
char name[1];
|
|
||||||
name[0] = (char)id;
|
|
||||||
return rb_fstring_new(name, 1);
|
|
||||||
}
|
|
||||||
for (i = 0; i < op_tbl_count; i++) {
|
|
||||||
if (op_tbl[i].token == id) {
|
|
||||||
const char *name = op_tbl[i].name;
|
|
||||||
return rb_fstring_new(name, op_tbl_len(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((str = lookup_id_str(id)) != 0) {
|
if ((str = lookup_id_str(id)) != 0) {
|
||||||
if (RBASIC(str)->klass == 0)
|
if (RBASIC(str)->klass == 0)
|
||||||
RBASIC_SET_CLASS_RAW(str, rb_cString);
|
RBASIC_SET_CLASS_RAW(str, rb_cString);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_attrset_id(id)) {
|
|
||||||
ID id_stem = (id & ~ID_SCOPE_MASK) | ID_STATIC_SYM;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_LOCAL))) break;
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_CONST))) break;
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_INSTANCE))) break;
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_GLOBAL))) break;
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_CLASS))) break;
|
|
||||||
if (!!(str = rb_id2str(id_stem | ID_JUNK))) break;
|
|
||||||
return 0;
|
|
||||||
} while (0);
|
|
||||||
str = rb_str_dup(str);
|
|
||||||
rb_str_cat(str, "=", 1);
|
|
||||||
register_static_symid_str(id, str);
|
|
||||||
if ((str = lookup_id_str(id)) != 0) {
|
|
||||||
if (RBASIC(str)->klass == 0)
|
|
||||||
RBASIC_SET_CLASS_RAW(str, rb_cString);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,11 +787,17 @@ static int
|
||||||
symbols_i(st_data_t key, st_data_t value, st_data_t arg)
|
symbols_i(st_data_t key, st_data_t value, st_data_t arg)
|
||||||
{
|
{
|
||||||
VALUE ary = (VALUE)arg;
|
VALUE ary = (VALUE)arg;
|
||||||
VALUE sym = ID2SYM((ID)value);
|
VALUE sym = (VALUE)value;
|
||||||
|
|
||||||
if (DYNAMIC_SYM_P(sym) && !SYMBOL_PINNED_P(sym) && rb_objspace_garbage_object_p(sym)) {
|
if (STATIC_SYM_P(sym)) {
|
||||||
|
rb_ary_push(ary, sym);
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
else if (!DYNAMIC_SYM_P(sym)) {
|
||||||
|
rb_bug("invalid symbol: %s", RSTRING_PTR((VALUE)key));
|
||||||
|
}
|
||||||
|
else if (!SYMBOL_PINNED_P(sym) && rb_objspace_garbage_object_p(sym)) {
|
||||||
RSYMBOL(sym)->fstr = 0;
|
RSYMBOL(sym)->fstr = 0;
|
||||||
unregister_sym_id(sym);
|
|
||||||
return ST_DELETE;
|
return ST_DELETE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -918,8 +826,8 @@ symbols_i(st_data_t key, st_data_t value, st_data_t arg)
|
||||||
VALUE
|
VALUE
|
||||||
rb_sym_all_symbols(void)
|
rb_sym_all_symbols(void)
|
||||||
{
|
{
|
||||||
VALUE ary = rb_ary_new2(global_symbols.str_id->num_entries);
|
VALUE ary = rb_ary_new2(global_symbols.str_sym->num_entries);
|
||||||
st_foreach(global_symbols.str_id, symbols_i, ary);
|
st_foreach(global_symbols.str_sym, symbols_i, ary);
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,7 +887,6 @@ rb_is_junk_id(ID id)
|
||||||
ID
|
ID
|
||||||
rb_check_id(volatile VALUE *namep)
|
rb_check_id(volatile VALUE *namep)
|
||||||
{
|
{
|
||||||
ID id;
|
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
VALUE name = *namep;
|
VALUE name = *namep;
|
||||||
|
|
||||||
|
@ -988,7 +895,7 @@ rb_check_id(volatile VALUE *namep)
|
||||||
}
|
}
|
||||||
else if (DYNAMIC_SYM_P(name)) {
|
else if (DYNAMIC_SYM_P(name)) {
|
||||||
if (SYMBOL_PINNED_P(name)) {
|
if (SYMBOL_PINNED_P(name)) {
|
||||||
return (ID)name;
|
return RSYMBOL(name)->id;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*namep = RSYMBOL(name)->fstr;
|
*namep = RSYMBOL(name)->fstr;
|
||||||
|
@ -1008,16 +915,7 @@ rb_check_id(volatile VALUE *namep)
|
||||||
|
|
||||||
sym_check_asciionly(name);
|
sym_check_asciionly(name);
|
||||||
|
|
||||||
if ((id = lookup_str_id(name)) != 0) {
|
return lookup_str_id(name);
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
ID gid = attrsetname_to_attr(name);
|
|
||||||
if (gid) return rb_id_attrset(gid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ID)0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -1027,7 +925,14 @@ rb_check_symbol(volatile VALUE *namep)
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
VALUE name = *namep;
|
VALUE name = *namep;
|
||||||
|
|
||||||
if (SYMBOL_P(name)) {
|
if (STATIC_SYM_P(name)) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
else if (DYNAMIC_SYM_P(name)) {
|
||||||
|
if (!SYMBOL_PINNED_P(name)) {
|
||||||
|
name = dsymbol_check(name);
|
||||||
|
*namep = name;
|
||||||
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
else if (!RB_TYPE_P(name, T_STRING)) {
|
else if (!RB_TYPE_P(name, T_STRING)) {
|
||||||
|
@ -1047,35 +952,18 @@ rb_check_symbol(volatile VALUE *namep)
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
ID gid = attrsetname_to_attr(name);
|
|
||||||
if (gid) return ID2SYM(rb_id_attrset(gid));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID
|
ID
|
||||||
rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
|
rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
|
||||||
{
|
{
|
||||||
ID id;
|
|
||||||
struct RString fake_str;
|
struct RString fake_str;
|
||||||
const VALUE name = rb_setup_fake_str(&fake_str, ptr, len, enc);
|
const VALUE name = rb_setup_fake_str(&fake_str, ptr, len, enc);
|
||||||
|
|
||||||
sym_check_asciionly(name);
|
sym_check_asciionly(name);
|
||||||
|
|
||||||
if ((id = lookup_str_id(name)) != 0) {
|
return lookup_str_id(name);
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rb_is_attrset_name(name)) {
|
|
||||||
fake_str.as.heap.len = len - 1;
|
|
||||||
if ((id = lookup_str_id(name)) != 0) {
|
|
||||||
return rb_id_attrset(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ID)0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -1091,13 +979,6 @@ rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_is_attrset_name(name)) {
|
|
||||||
fake_str.as.heap.len = len - 1;
|
|
||||||
if ((sym = lookup_str_sym(name)) != 0) {
|
|
||||||
return ID2SYM(rb_id_attrset(SYM2ID(sym)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
symbol.h
34
symbol.h
|
@ -17,7 +17,7 @@
|
||||||
struct RSymbol {
|
struct RSymbol {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
VALUE fstr;
|
VALUE fstr;
|
||||||
ID type;
|
ID id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RSYMBOL(obj) (R_CAST(RSymbol)(obj))
|
#define RSYMBOL(obj) (R_CAST(RSymbol)(obj))
|
||||||
|
@ -28,13 +28,7 @@ id_type(ID id)
|
||||||
if (id<=tLAST_OP_ID) {
|
if (id<=tLAST_OP_ID) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (id&ID_STATIC_SYM) {
|
return (int)(id&ID_SCOPE_MASK);
|
||||||
return (int)((id)&ID_SCOPE_MASK);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VALUE dsym = (VALUE)id;
|
|
||||||
return (int)(RSYMBOL(dsym)->type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define is_notop_id(id) ((id)>tLAST_OP_ID)
|
#define is_notop_id(id) ((id)>tLAST_OP_ID)
|
||||||
|
@ -46,6 +40,30 @@ id_type(ID id)
|
||||||
#define is_class_id(id) (id_type(id)==ID_CLASS)
|
#define is_class_id(id) (id_type(id)==ID_CLASS)
|
||||||
#define is_junk_id(id) (id_type(id)==ID_JUNK)
|
#define is_junk_id(id) (id_type(id)==ID_JUNK)
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
sym_type(VALUE sym)
|
||||||
|
{
|
||||||
|
ID id;
|
||||||
|
if (STATIC_SYM_P(sym)) {
|
||||||
|
id = RSHIFT(sym, RUBY_SPECIAL_SHIFT);
|
||||||
|
if (id<=tLAST_OP_ID) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
id = RSYMBOL(sym)->id;
|
||||||
|
}
|
||||||
|
return (int)(id&ID_SCOPE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define is_local_sym(sym) (sym_type(sym)==SYM_LOCAL)
|
||||||
|
#define is_global_sym(sym) (sym_type(sym)==SYM_GLOBAL)
|
||||||
|
#define is_instance_sym(sym) (sym_type(sym)==SYM_INSTANCE)
|
||||||
|
#define is_attrset_sym(sym) (sym_type(sym)==SYM_ATTRSET)
|
||||||
|
#define is_const_sym(sym) (sym_type(sym)==SYM_CONST)
|
||||||
|
#define is_class_sym(sym) (sym_type(sym)==SYM_CLASS)
|
||||||
|
#define is_junk_sym(sym) (sym_type(sym)==SYM_JUNK)
|
||||||
|
|
||||||
RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
|
RUBY_FUNC_EXPORTED const unsigned int ruby_global_name_punct_bits[(0x7e - 0x20 + 31) / 32];
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
|
Загрузка…
Ссылка в новой задаче