mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
zero copy C literal strings in symbol table
This commit is contained in:
+2
-2
@@ -230,6 +230,8 @@ mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, int, mrb_value*);
|
||||
mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, int, mrb_value*, mrb_value);
|
||||
mrb_sym mrb_intern_cstr(mrb_state*,const char*);
|
||||
mrb_sym mrb_intern(mrb_state*,const char*,size_t);
|
||||
mrb_sym mrb_intern_literal(mrb_state*,const char*,size_t);
|
||||
#define mrb_intern_lit(mrb, lit) mrb_intern_literal(mrb, (lit), sizeof(lit) - 1)
|
||||
mrb_sym mrb_intern_str(mrb_state*,mrb_value);
|
||||
mrb_value mrb_check_intern_cstr(mrb_state*,const char*);
|
||||
mrb_value mrb_check_intern(mrb_state*,const char*,size_t);
|
||||
@@ -239,8 +241,6 @@ const char *mrb_sym2name_len(mrb_state*,mrb_sym,size_t*);
|
||||
mrb_value mrb_sym2str(mrb_state*,mrb_sym);
|
||||
mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
|
||||
|
||||
#define mrb_intern_lit(mrb, lit) mrb_intern(mrb, (lit), sizeof(lit) - 1)
|
||||
|
||||
void *mrb_malloc(mrb_state*, size_t); /* raise RuntimeError if no mem */
|
||||
void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */
|
||||
void *mrb_realloc(mrb_state*, void*, size_t); /* ditto */
|
||||
|
||||
+39
-8
@@ -13,7 +13,8 @@
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
typedef struct symbol_name {
|
||||
size_t len;
|
||||
mrb_bool lit;
|
||||
uint16_t len;
|
||||
const char *name;
|
||||
} symbol_name;
|
||||
|
||||
@@ -34,8 +35,8 @@ sym_hash_func(mrb_state *mrb, const symbol_name s)
|
||||
KHASH_DECLARE(n2s, symbol_name, mrb_sym, 1)
|
||||
KHASH_DEFINE (n2s, symbol_name, mrb_sym, 1, sym_hash_func, sym_hash_equal)
|
||||
/* ------------------------------------------------------ */
|
||||
mrb_sym
|
||||
mrb_intern(mrb_state *mrb, const char *name, size_t len)
|
||||
static mrb_sym
|
||||
sym_intern(mrb_state *mrb, const char *name, size_t len, int lit)
|
||||
{
|
||||
khash_t(n2s) *h = mrb->name2sym;
|
||||
symbol_name sname;
|
||||
@@ -43,6 +44,10 @@ mrb_intern(mrb_state *mrb, const char *name, size_t len)
|
||||
mrb_sym sym;
|
||||
char *p;
|
||||
|
||||
if (len > UINT16_MAX) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
|
||||
}
|
||||
sname.lit = lit;
|
||||
sname.len = len;
|
||||
sname.name = name;
|
||||
k = kh_get(n2s, mrb, h, sname);
|
||||
@@ -50,16 +55,33 @@ mrb_intern(mrb_state *mrb, const char *name, size_t len)
|
||||
return kh_value(h, k);
|
||||
|
||||
sym = ++mrb->symidx;
|
||||
p = (char *)mrb_malloc(mrb, len+1);
|
||||
memcpy(p, name, len);
|
||||
p[len] = 0;
|
||||
sname.name = (const char*)p;
|
||||
if (lit) {
|
||||
sname.name = name;
|
||||
}
|
||||
else {
|
||||
p = (char *)mrb_malloc(mrb, len+1);
|
||||
memcpy(p, name, len);
|
||||
p[len] = 0;
|
||||
sname.name = (const char*)p;
|
||||
}
|
||||
k = kh_put(n2s, mrb, h, sname);
|
||||
kh_value(h, k) = sym;
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
mrb_sym
|
||||
mrb_intern(mrb_state *mrb, const char *name, size_t len)
|
||||
{
|
||||
return sym_intern(mrb, name, len, 0);
|
||||
}
|
||||
|
||||
mrb_sym
|
||||
mrb_intern_literal(mrb_state *mrb, const char *name, size_t len)
|
||||
{
|
||||
return sym_intern(mrb, name, len, 1);
|
||||
}
|
||||
|
||||
mrb_sym
|
||||
mrb_intern_cstr(mrb_state *mrb, const char *name)
|
||||
{
|
||||
@@ -79,6 +101,9 @@ mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
|
||||
symbol_name sname;
|
||||
khiter_t k;
|
||||
|
||||
if (len > UINT16_MAX) {
|
||||
mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
|
||||
}
|
||||
sname.len = len;
|
||||
sname.name = name;
|
||||
|
||||
@@ -129,7 +154,13 @@ mrb_free_symtbl(mrb_state *mrb)
|
||||
khiter_t k;
|
||||
|
||||
for (k = kh_begin(h); k != kh_end(h); k++)
|
||||
if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_key(h, k).name);
|
||||
if (kh_exist(h, k)) {
|
||||
symbol_name s = kh_key(h, k);
|
||||
|
||||
if (!s.lit) {
|
||||
mrb_free(mrb, (char*)s.name);
|
||||
}
|
||||
}
|
||||
kh_destroy(n2s, mrb, mrb->name2sym);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user