14#include "internal/error.h"
15#include "internal/gc.h"
18#include "internal/symbol.h"
27# define USE_SYMBOL_GC 1
30# define SYMBOL_DEBUG 0
32#ifndef CHECK_ID_SERIAL
33# define CHECK_ID_SERIAL SYMBOL_DEBUG
36#define SYMBOL_PINNED_P(sym) (RSYMBOL(sym)->id&~ID_SCOPE_MASK)
38#define STATIC_SYM2ID(sym) RSHIFT((unsigned long)(sym), RUBY_SPECIAL_SHIFT)
41static ID register_static_symid_str(
ID,
VALUE);
42#define REGISTER_SYMID(id, name) register_static_symid((id), (name), strlen(name), enc)
45#define is_identchar(p,e,enc) (ISALNUM((unsigned char)*(p)) || (*(p)) == '_' || !ISASCII(*(p)))
47#define op_tbl_count numberof(op_tbl)
49#define op_tbl_len(i) (!op_tbl[i].name[1] ? 1 : !op_tbl[i].name[2] ? 2 : 3)
57 for (i =
'!'; i <=
'~'; ++i) {
60 register_static_symid(i, &c, 1, enc);
68static const int ID_ENTRY_UNIT = 512;
109#define GLOBAL_SYMBOLS_ENTER(symbols) rb_symbols_t *symbols = &ruby_global_symbols; RB_VM_LOCK_ENTER()
110#define GLOBAL_SYMBOLS_LEAVE() RB_VM_LOCK_LEAVE()
136 if ((
str = lookup_id_str(
id)) != 0) {
149 if (!(
str = lookup_id_str(
id))) {
165 sym = lookup_str_sym(
str);
171is_special_global_name(
const char *m,
const char *e,
rb_encoding *enc)
175 if (m >= e)
return 0;
176 if (is_global_name_punct(*m)) {
179 else if (*m ==
'-') {
180 if (++m >= e)
return 0;
191 }
while (m < e &&
ISDIGIT(*m));
193 return m == e ? mb + 1 : 0;
212 const char *end =
name + nlen;
214 if (nlen < 1)
return FALSE;
221 static int ctype_titlecase = 0;
224 if (!ctype_titlecase) {
225 static const UChar cname[] =
"titlecaseletter";
226 static const UChar *
const end = cname +
sizeof(cname) - 1;
244#define IDSET_ATTRSET_FOR_SYNTAX ((1U<<ID_LOCAL)|(1U<<ID_CONST))
245#define IDSET_ATTRSET_FOR_INTERN (~(~0U<<(1<<ID_SCOPE_SHIFT)) & ~(1U<<ID_ATTRSET))
253#define t struct enc_synmane_type_leading_chars_tag
258 const char *m =
name;
259 const char *e = m +
len;
267 else if (
len <= 0 ) {
275 if (is_special_global_name(++m, e, enc)) {
307 default:
return (
t) {
invalid, 0, 1, };
328 case '|':
case '^':
case '&':
case '/':
case '%':
case '~':
case '`':
345 if (allowed_attrset & (1U <<
ID_JUNK)) {
354 if (rb_sym_constant_char_p(
name,
len, enc)) {
368 enc_synmane_type_leading_chars(
name,
len, enc, allowed_attrset);
369 const char *m =
name +
f.nread;
380 if (
len > 1 && *(e-1) ==
'=') {
393 if (m + 1 < e || *m !=
'=')
break;
396 if (!(allowed_attrset & (1U <<
type)))
return -1;
403 return m == e ?
type : -1;
413rb_str_symname_type(
VALUE name,
unsigned int allowed_attrset)
426 size_t idx =
num / ID_ENTRY_UNIT;
445 if (
num && num <= symbols->last_id) {
446 size_t idx =
num / ID_ENTRY_UNIT;
482 return get_id_serial_entry(rb_id_to_serial(
id),
id,
t);
541 return register_static_symid_str(
id,
str);
557 register_sym(symbols,
str,
sym);
587must_be_dynamic_symbol(
VALUE x)
597 rb_bug(
"wrong argument: inappropriate Symbol (%p)", (
void *)x);
622 RSYMBOL(dsym)->hashval = RSHIFT((
long)hashval, 1);
623 register_sym(symbols,
str, dsym);
639 unregister_sym(symbols, fstr,
sym);
684 sym = dsymbol_check(symbols,
sym);
700 sym = lookup_str_sym_with_lock(symbols,
str);
720 sym = lookup_str_sym(
str);
723 return intern_str(
str, 1);
732 if (next_serial == 0) {
749 id = next_id_base_with_lock(symbols);
763 if (sym_check_asciionly(
str)) {
767 if ((
nid = next_id_base()) == (
ID)-1) {
774 return register_static_symid_str(
id,
str);
799 return intern_str(
str, 0);
812 unregister_sym(symbols,
str,
sym);
851 sym = lookup_str_sym_with_lock(symbols,
str);
860 if (enc != ascii && sym_check_asciionly(
str)) {
875 id = intern_str(
str, 0);
894 sym = dsymbol_check(symbols,
sym);
899 ID num = next_id_base_with_lock(symbols);
904 set_id_entry(symbols, rb_id_to_serial(
num), fstr,
sym);
940 return lookup_id_str(
id);
1096 sym_check_asciionly(
name);
1098 return lookup_str_id(
name);
1127 name = dsymbol_check(symbols,
name);
1145 sym_check_asciionly(
name);
1147 if ((
sym = lookup_str_sym(
name)) != 0) {
1160 sym_check_asciionly(
name);
1162 return lookup_str_id(
name);
1172 sym_check_asciionly(
name);
1174 if ((
sym = lookup_str_sym(
name)) != 0) {
1181#undef rb_sym_intern_ascii_cstr
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_ary_entry(VALUE ary, long offset)
#define FUNC_MINIMIZED(x)
#define WARN_UNUSED_RESULT(x)
enum ruby_id_types id_types
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
rb_encoding * rb_ascii8bit_encoding(void)
rb_encoding * rb_enc_get(VALUE obj)
int rb_enc_to_index(rb_encoding *enc)
void rb_enc_set_index(VALUE obj, int idx)
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
rb_encoding * rb_usascii_encoding(void)
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
int rb_objspace_garbage_object_p(VALUE obj)
VALUE rb_newobj_of(VALUE klass, VALUE flags)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
#define rb_intern_str(string)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_bug(const char *fmt,...)
void rb_name_error(ID id, const char *fmt,...)
VALUE rb_ident_hash_new(void)
void rb_name_error_str(VALUE str, const char *fmt,...)
void rb_fatal(const char *fmt,...)
const char * rb_builtin_class_name(VALUE x)
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_convert_type_with_id(VALUE v, int t, const char *nam, ID mid)
VALUE rb_hash_delete_entry(VALUE hash, VALUE key)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
void *PTR64 __attribute__((mode(DI)))
#define rb_enc_isupper(c, enc)
#define ENC_CODERANGE_7BIT
#define rb_enc_isctype(c, t, enc)
int rb_enc_str_coderange(VALUE)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
#define rb_enc_mbc_to_codepoint(p, e, enc)
#define MBCLEN_CHARFOUND_LEN(ret)
#define rb_enc_asciicompat(enc)
#define rb_enc_islower(c, enc)
#define ENC_CODERANGE_BROKEN
#define MBCLEN_CHARFOUND_P(ret)
VALUE rb_str_cat(VALUE, const char *, long)
VALUE rb_check_string_type(VALUE)
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
int rb_str_hash_cmp(VALUE, VALUE)
st_index_t rb_str_hash(VALUE)
Internal header for Hash.
Internal header for Object.
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc)
Internal header for RubyVM.
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
#define rb_sym_intern_ascii_cstr(...)
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
int memcmp(const void *s1, const void *s2, size_t len)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define ONIGENC_IS_UNICODE(enc)
#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, p, end)
#define ONIGENC_CASE_FOLD
#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM
#define RB_OBJ_WRITE(a, slot, b)
WB for new reference from ‘a’ to ‘b’.
#define StringValuePtr(v)
#define st_init_table_with_size
size_t strlen(const char *)
int(* mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar **pp, const OnigUChar *end, OnigUChar *to, const struct OnigEncodingTypeST *enc)
char ary[RSTRING_EMBED_LEN_MAX+1]
enum enc_synmane_type_leading_chars_tag::@168 kind
ID rb_intern2(const char *name, long len)
VALUE rb_sym_intern(const char *ptr, long len, rb_encoding *enc)
#define is_identchar(p, e, enc)
#define SYMBOL_PINNED_P(sym)
int rb_enc_symname_p(const char *name, rb_encoding *enc)
rb_symbols_t ruby_global_symbols
int rb_is_instance_name(VALUE name)
int rb_symname_p(const char *name)
VALUE rb_check_symbol(volatile VALUE *namep)
Returns Symbol for the given name if it is interned already, or nil.
VALUE rb_sym_all_symbols(void)
void rb_gc_free_dsymbol(VALUE sym)
int rb_is_global_id(ID id)
#define GLOBAL_SYMBOLS_LEAVE()
ID rb_intern3(const char *name, long len, rb_encoding *enc)
size_t rb_sym_immortal_count(void)
#define STATIC_SYM2ID(sym)
VALUE rb_sym2str(VALUE sym)
VALUE rb_to_symbol_type(VALUE obj)
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
int rb_is_instance_id(ID id)
int rb_is_class_name(VALUE name)
int rb_is_const_id(ID id)
#define IDSET_ATTRSET_FOR_SYNTAX
ID rb_make_internal_id(void)
ID rb_intern(const char *name)
int rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset)
VALUE rb_check_symbol_cstr(const char *ptr, long len, rb_encoding *enc)
#define GLOBAL_SYMBOLS_ENTER(symbols)
int rb_enc_symname2_p(const char *name, long len, rb_encoding *enc)
int rb_is_attrset_sym(VALUE sym)
int rb_is_const_name(VALUE name)
#define IDSET_ATTRSET_FOR_INTERN
int rb_is_class_id(ID id)
const char * rb_id2name(ID id)
int rb_is_attrset_id(ID id)
int rb_is_local_id(ID id)
int rb_is_const_sym(VALUE sym)
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
VALUE rb_sym_intern_ascii(const char *ptr, long len)
int rb_is_local_name(VALUE name)
VALUE rb_str_intern(VALUE str)
#define STATIC_ID2SYM(id)
#define is_attrset_id(id)
#define is_const_sym(sym)
#define is_instance_id(id)
#define is_attrset_sym(sym)
#define ASSERT_vm_locking()