diff options
| -rw-r--r-- | include/mrbconf.h | 1 | ||||
| -rw-r--r-- | include/mruby.h | 3 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-config/mrbgem.rake | 31 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-symbol-ext/src/symbol.c | 12 | ||||
| -rw-r--r-- | mrbgems/mruby-symbol-ext/test/symbol.rb | 11 | ||||
| -rw-r--r-- | src/hash.c | 1 | ||||
| -rw-r--r-- | src/state.c | 1 | ||||
| -rw-r--r-- | src/symbol.c | 99 | ||||
| -rw-r--r-- | src/vm.c | 3 |
10 files changed, 137 insertions, 33 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index b1aec8334..08e69d3aa 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -120,6 +120,7 @@ /* -DMRB_ENABLE_XXXX to enable following features */ //#define MRB_ENABLE_DEBUG_HOOK /* hooks for debugger */ +//#define MRB_ENABLE_ALL_SYMBOLS /* Symbols.all_symbols */ /* end of configuration */ diff --git a/include/mruby.h b/include/mruby.h index 2f2d98677..e9fd08102 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -242,6 +242,9 @@ typedef struct mrb_state { struct symbol_name *symtbl; /* symbol table */ mrb_sym symhash[256]; size_t symcapa; +#ifndef MRB_ENABLE_SYMBOLL_ALL + char symbuf[8]; /* buffer for small symbol names */ +#endif #ifdef MRB_ENABLE_DEBUG_HOOK void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs); diff --git a/mrbgems/mruby-bin-config/mrbgem.rake b/mrbgems/mruby-bin-config/mrbgem.rake index b9ba0e42c..f293c1b9b 100644 --- a/mrbgems/mruby-bin-config/mrbgem.rake +++ b/mrbgems/mruby-bin-config/mrbgem.rake @@ -1,17 +1,22 @@ -MRuby.each_target do - next if kind_of? MRuby::CrossBuild +unless MRuby::Build.current.kind_of?(MRuby::CrossBuild) + MRuby::Gem::Specification.new('mruby-bin-config') do |spec| + name = 'mruby-config' + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = "#{name} command" - mruby_config = 'mruby-config' + (ENV['OS'] == 'Windows_NT' ? '.bat' : '') - mruby_config_path = "#{build_dir}/bin/#{mruby_config}" - @bins << mruby_config + mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '') + mruby_config_path = "#{build.build_dir}/bin/#{mruby_config}" + make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak" + build.bins << mruby_config - make_cfg = "#{build_dir}/lib/libmruby.flags.mak" - file mruby_config_path => [libmruby_static, make_cfg] do |t| - FileUtils.copy "#{File.dirname(__FILE__)}/#{mruby_config}", t.name - config = Hash[open(make_cfg).read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}] - IO.write(t.name, File.open(t.name) {|f| - f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LIBS|MRUBY_LDFLAGS_BEFORE_LIBS|MRUBY_LDFLAGS|MRUBY_LIBMRUBY_PATH)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"} - }) - FileUtils.chmod(0755, t.name) + file mruby_config_path => [build.libmruby_static, make_cfg] do |t| + config = Hash[File.readlines(make_cfg).map(&:chomp).map {|l| + l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')} + }] + tmplt = File.read("#{__dir__}/#{mruby_config}") + File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config)) + FileUtils.chmod(0755, t.name) + end end end diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 48bf06461..bfc08cd94 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2357,13 +2357,9 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_BACK_REF: if (val) { - char buf[3]; - int sym; + char buf[] = {'$', nchar(tree)}; + int sym = new_sym(s, mrb_intern(s->mrb, buf, sizeof(buf))); - buf[0] = '$'; - buf[1] = nchar(tree); - buf[2] = 0; - sym = new_sym(s, mrb_intern_cstr(s->mrb, buf)); genop_2(s, OP_GETGV, cursp(), sym); push(); } diff --git a/mrbgems/mruby-symbol-ext/src/symbol.c b/mrbgems/mruby-symbol-ext/src/symbol.c index 215226502..ccb2971dc 100644 --- a/mrbgems/mruby-symbol-ext/src/symbol.c +++ b/mrbgems/mruby-symbol-ext/src/symbol.c @@ -3,11 +3,6 @@ #include <mruby/array.h> #include <mruby/string.h> -typedef struct symbol_name { - size_t len; - const char *name; -} symbol_name; - /* * call-seq: * Symbol.all_symbols => array @@ -23,6 +18,7 @@ typedef struct symbol_name { * :Tms, :getwd, :$=, :ThreadGroup, * :wait2, :$>] */ +#ifdef MRB_ENABLE_ALL_SYMBOLS static mrb_value mrb_sym_all_symbols(mrb_state *mrb, mrb_value self) { @@ -30,11 +26,13 @@ mrb_sym_all_symbols(mrb_state *mrb, mrb_value self) mrb_value ary = mrb_ary_new_capa(mrb, mrb->symidx); for (i=1, lim=mrb->symidx+1; i<lim; i++) { - mrb_ary_push(mrb, ary, mrb_symbol_value(i)); + mrb_sym sym = i<<1; + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); } return ary; } +#endif /* * call-seq: @@ -60,7 +58,9 @@ void mrb_mruby_symbol_ext_gem_init(mrb_state* mrb) { struct RClass *s = mrb->symbol_class; +#ifdef MRB_ENABLE_ALL_SYMBOLS mrb_define_class_method(mrb, s, "all_symbols", mrb_sym_all_symbols, MRB_ARGS_NONE()); +#endif mrb_define_method(mrb, s, "length", mrb_sym_length, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "size", mrb_sym_length, MRB_ARGS_NONE()); } diff --git a/mrbgems/mruby-symbol-ext/test/symbol.rb b/mrbgems/mruby-symbol-ext/test/symbol.rb index 2c7a62b0c..61ecad247 100644 --- a/mrbgems/mruby-symbol-ext/test/symbol.rb +++ b/mrbgems/mruby-symbol-ext/test/symbol.rb @@ -1,10 +1,13 @@ +# coding: utf-8 ## # Symbol(Ext) Test -assert('Symbol.all_symbols') do - foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort - symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort - assert_equal foo, symbols +if Symbol.respond_to?(:all_symbols) + assert('Symbol.all_symbols') do + foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort + symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort + assert_equal foo, symbols + end end %w[size length].each do |n| diff --git a/src/hash.c b/src/hash.c index 6b92344c3..fd963c3de 100644 --- a/src/hash.c +++ b/src/hash.c @@ -536,6 +536,7 @@ ht_copy(mrb_state *mrb, htable *t) seg = t->rootseg; t2 = ht_new(mrb); + if (t->size == 0) return t2; while (seg) { for (i=0; i<seg->size; i++) { diff --git a/src/state.c b/src/state.c index e678b37f3..c3ce1dc33 100644 --- a/src/state.c +++ b/src/state.c @@ -26,6 +26,7 @@ mrb_open_core(mrb_allocf f, void *ud) static const struct mrb_context mrb_context_zero = { 0 }; mrb_state *mrb; + if (f == NULL) f = mrb_default_allocf; mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); if (mrb == NULL) return NULL; diff --git a/src/symbol.c b/src/symbol.c index 4242f3d8e..9cc566245 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -28,6 +28,81 @@ sym_validate_len(mrb_state *mrb, size_t len) } } +#ifndef MRB_ENABLE_ALL_SYMBOLS +static char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + +static mrb_sym +sym_inline_pack(const char *name, uint16_t len) +{ + char c; + char *p; + int i; + mrb_sym sym = 0; + int lower = 1; + + if (len > 6) return 0; /* too long */ + for (i=0; i<len; i++) { + uint32_t bits; + + c = name[i]; + if (c == 0) return 0; /* NUL in name */ + p = strchr(pack_table, (int)c); + if (p == 0) return 0; /* non alnum char */ + bits = (uint32_t)(p - pack_table)+1; + if (bits > 27) lower = 0; + sym |= bits<<(i*6+2); + } + if (lower) { + sym = 0; + for (i=0; i<len; i++) { + uint32_t bits; + + c = name[i]; + p = strchr(pack_table, (int)c); + bits = (uint32_t)(p - pack_table)+1; + sym |= bits<<(i*5+2); + } + return sym | 3; + } + if (len == 6) return 0; + return sym | 1; +} + +static const char* +sym_inline_unpack(mrb_sym sym, char *buf) +{ + int i; + + if (sym == 0) return NULL; + if ((sym&1) == 0) return NULL; /* need to be inline sym */ + if (sym&2) { /* all lower case (5bits/char) */ + for (i=0; i<6; i++) { + uint32_t bits; + char c; + + bits = sym>>(i*5+2) & 31; + if (bits == 0) break; + c = pack_table[bits-1]; + buf[i] = c; + } + buf[i] = '\0'; + return buf; + } + + for (i=0; i<5; i++) { + uint32_t bits; + char c; + + bits = sym>>(i*6+2) & 63; + if (bits == 0) break; + c = pack_table[bits-1]; + buf[i] = c; + } + buf[i] = '\0'; + return buf; +} +#endif + uint8_t symhash(const char *key, size_t len) { @@ -50,19 +125,25 @@ find_symbol(mrb_state *mrb, const char *name, uint16_t len, uint8_t hash) mrb_sym i; symbol_name *sname; +#ifndef MRB_ENABLE_ALL_SYMBOLS + /* inline symbol */ + i = sym_inline_pack(name, len); + if (i > 0) return i; +#endif + i = mrb->symhash[hash]; if (i == 0) return 0; do { sname = &mrb->symtbl[i]; if (sname->len == len && memcmp(sname->name, name, len) == 0) { - return i; + return i<<1; } if (sname->prev == 0xff) { i -= 0xff; sname = &mrb->symtbl[i]; while (mrb->symtbl < sname) { if (sname->len == len && memcmp(sname->name, name, len) == 0) { - return (mrb_sym)(sname - mrb->symtbl); + return (mrb_sym)(sname - mrb->symtbl)<<1; } sname--; } @@ -117,7 +198,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) } mrb->symhash[hash] = sym; - return sym; + return sym<<1; } MRB_API mrb_sym @@ -170,6 +251,15 @@ mrb_check_intern_str(mrb_state *mrb, mrb_value str) MRB_API const char* mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp) { +#ifndef MRB_ENABLE_ALL_SYMBOLS + if (sym & 1) { /* inline packed symbol */ + sym_inline_unpack(sym, mrb->symbuf); + if (lenp) *lenp = strlen(mrb->symbuf); + return mrb->symbuf; + } +#endif + + sym >>= 1; if (sym == 0 || mrb->symidx < sym) { if (lenp) *lenp = 0; return NULL; @@ -446,6 +536,9 @@ mrb_sym2str(mrb_state *mrb, mrb_sym sym) const char *name = mrb_sym2name_len(mrb, sym, &len); if (!name) return mrb_undef_value(); /* can't happen */ + if (sym&1) { /* inline symbol */ + return mrb_str_new(mrb, name, len); + } return mrb_str_new_static(mrb, name, len); } @@ -1810,7 +1810,8 @@ RETRY_TRY_BLOCK: kdict = argv[argc-1]; mrb_hash_check_kdict(mrb, kdict); } - else if (r || argc <= m1+m2+o) { + else if (r || argc <= m1+m2+o + || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) { kdict = mrb_hash_new(mrb); kargs = 0; } |
