diff options
| -rw-r--r-- | Rakefile | 142 | ||||
| -rw-r--r-- | include/mruby/irep.h | 9 | ||||
| -rw-r--r-- | include/mruby/presym.h | 2 | ||||
| -rw-r--r-- | lib/mruby/build.rb | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 98 | ||||
| -rw-r--r-- | src/codedump.c | 26 | ||||
| -rw-r--r-- | src/dump.c | 47 | ||||
| -rw-r--r-- | src/gc.c | 6 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/symbol.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 11 | ||||
| -rw-r--r-- | tasks/presym.rake | 139 |
12 files changed, 234 insertions, 258 deletions
@@ -25,9 +25,9 @@ end # load custom rules load "#{MRUBY_ROOT}/tasks/core.rake" load "#{MRUBY_ROOT}/tasks/mrblib.rake" + load "#{MRUBY_ROOT}/tasks/mrbgems.rake" load "#{MRUBY_ROOT}/tasks/libmruby.rake" -load "#{MRUBY_ROOT}/tasks/presym.rake" load "#{MRUBY_ROOT}/tasks/benchmark.rake" @@ -55,6 +55,9 @@ else depfiles = [] end +cfiles = Dir.glob("#{MRUBY_ROOT}/src/*.c") +rbfiles = Dir.glob("#{MRUBY_ROOT}/mrblib/**/*.rb") +psfiles = [] MRuby.each_target do |target| gems.each do |gem| current_dir = gem.dir.relative_path_from(Dir.pwd) @@ -89,13 +92,142 @@ MRuby.each_target do |target| depfiles += [ exec ] end end + + cfiles += Dir.glob(gem.dir+"/{src,core,tools/*}/*.c") + if gem.cdump? + rbfiles += Dir.glob(gem.dir+"/mrblib/**/*.rb") + psfiles += Dir.glob(gem.dir+"/**/presym") + end end end -desc "preallocated symbols" -task :gensym do - MRuby.each_target{|build| Rake::Task[build.presym_file].invoke} +mkdir_p "#{MRUBY_ROOT}/build" +symbols = [] +psfiles.each do |file| + symbols += File.readlines(file).grep_v(/^# /) end +symbols.each{|x| x.chomp!} +presym_file="#{MRUBY_ROOT}/build/presym" +presym_inc="#{presym_file}.inc" +op_table = { + "!" => "not", + "!=" => "neq", + "!~" => "nmatch", + "%" => "mod", + "&" => "and", + "&&" => "andand", + "*" => "mul", + "**" => "pow", + "+" => "add", + "+@" => "plus", + "-" => "sub", + "-@" => "minus", + "/" => "div", + "<" => "lt", + "<=" => "le", + "<<" => "lshift", + "<=>" => "cmp", + "==" => "eq", + "===" => "eqq", + "=~" => "match", + ">" => "gt", + ">=" => "ge", + ">>" => "rshift", + "[]" => "aref", + "[]=" => "aset", + "^" => "xor", + "`" => "tick", + "|" => "or", + "||" => "oror", + "~" => "neg", +} +macro_to_symbol = { +# Macro Symbol +# [prefix, suffix] => [prefix, suffix] + ["CV" , "" ] => ["@@" , "" ], + ["IV" , "" ] => ["@" , "" ], + ["" , "_B" ] => ["" , "!" ], + ["" , "_Q" ] => ["" , "?" ], + ["" , "_E" ] => ["" , "=" ], + ["" , "" ] => ["" , "" ], +} + +file presym_file => cfiles+rbfiles+psfiles+[__FILE__] do + prefix_re = Regexp.union(*macro_to_symbol.keys.map(&:first).uniq) + suffix_re = Regexp.union(*macro_to_symbol.keys.map(&:last).uniq) + macro_re = /MRB_(#{prefix_re})SYM(#{suffix_re})\((\w+)\)/o + csymbols = cfiles.map do |f| + src = File.read(f) + src.gsub!(/\/\/.+(\n|$)/, "\n") + [src.scan(/intern_lit\([^\n"]*"([^\n "]*)"/), + src.scan(/mrb_define_method\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_class_method\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_class\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_module\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_module_function\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_const\([^\n"]*"([^\n"]*)"/), + src.scan(/mrb_define_global_const\([^\n"]*"([^\n"]*)"/), + src.scan(macro_re).map{|prefix, suffix, name| + macro_to_symbol[[prefix, suffix]] * name + }] + end + csymbols += File.readlines("#{MRUBY_ROOT}/include/mruby.h").grep(/define E_/).join.scan(/MRB_SYM\((\w+)\)/) + + rbsymbols = rbfiles.map do |f| + src = File.read(f) + src.force_encoding(Encoding::BINARY) + [src.scan(/\bclass +([A-Z]\w*)/), + src.scan(/\bmodule +([A-Z]\w*)/), + src.scan(/\bdef +(\w+[!?=]?)/), + src.scan(/\balias +(\w+[!?]?)/), + src.scan(/\b([A-Z]\w*) *=[^=]/), + src.scan(/(\$[a-zA-Z_]\w*)/), + src.scan(/(\$[$!?0-9]\w*)/), + src.scan(/(@@?[a-zA-Z_]\w*)/), + src.scan(/[^.]\.([a-zA-Z_]\w*[!?]?)/), + src.scan(/\.([a-zA-Z_]\w* *=)/).map{|x|x.map{|s|s.gsub(' ', '')}}, + src.scan(/\b([a-zA-Z_]\w*):/), + src.scan(/:([a-zA-Z_]\w*[!?=]?)/), + src.scan(/[\(\[\{ ]:"([^"]+)"/).map{|x|x.map{|s|s.gsub('\#', '#')}}, + src.scan(/[ \(\[\{]:'([^']+)'/) + ] + end + symbols = (symbols+csymbols+rbsymbols+op_table.keys).flatten.compact.uniq.grep_v(/#/).map{|x| x.gsub("\n", '\n')}.sort_by!{|x| [x.bytesize, x]} + presyms = File.readlines(presym_file) rescue [] + presyms.each{|x| x.chomp!} + if presyms != symbols + _pp "GEN", presym_file.relative_path + File.write(presym_file, symbols.join("\n")) + Rake::Task[presym_inc].invoke + end +end + +task presym_inc do + presyms = File.readlines(presym_file) + presyms.each{|x| x.chomp!} + symbol_to_macro = macro_to_symbol.invert + prefix_re = Regexp.union(*symbol_to_macro.keys.map(&:first).uniq) + suffix_re = Regexp.union(*symbol_to_macro.keys.map(&:last).uniq) + sym_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o + _pp "GEN", presym_inc.relative_path + File.open(presym_inc, "w") do |f| + f.puts "/* MRB_PRESYM_NAMED(lit, num, type, name) */" + f.puts "/* MRB_PRESYM_UNNAMED(lit, num) */" + presyms.each.with_index(1) do |sym, num| + if sym_re =~ sym && (affixes = symbol_to_macro[[$1, $3]]) + f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, #{affixes * 'SYM'}, #{$2})| + elsif name = op_table[sym] + f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, OPSYM, #{name})| + elsif + f.puts %|MRB_PRESYM_UNNAMED("#{sym}", #{num})| + end + end + f.print "#define MRB_PRESYM_MAX #{presyms.size}" + end +end + +desc "preallocated symbols" +task :gensym => presym_file depfiles += MRuby.targets.map { |n, t| t.libraries @@ -154,5 +286,7 @@ task :deep_clean => ["clean", "clean_doc"] do MRuby.each_target do |t| rm_rf t.gem_clone_dir end + rm_f presym_file + rm_f presym_inc puts "Cleaned up mrbgems build folder" end diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 04ab54ee2..12d81d0d3 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -47,9 +47,9 @@ enum mrb_catch_type { struct mrb_irep_catch_handler { uint8_t type; /* enum mrb_catch_type */ - uint8_t begin[2]; /* The starting address to match the hander. Includes this. */ - uint8_t end[2]; /* The endpoint address that matches the hander. Not Includes this. */ - uint8_t target[2]; /* The address to jump to if a match is made. */ + uint8_t begin[4]; /* The starting address to match the hander. Includes this. */ + uint8_t end[4]; /* The endpoint address that matches the hander. Not Includes this. */ + uint8_t target[4]; /* The address to jump to if a match is made. */ }; /* Program data array struct */ @@ -139,6 +139,9 @@ mrb_irep_catch_handler_table(const struct mrb_irep *irep) } } +#define mrb_irep_catch_handler_pack(n, v) uint32_to_bin(n, v) +#define mrb_irep_catch_handler_unpack(v) bin_to_uint32(v) + MRB_END_DECL #endif /* MRUBY_IREP_H */ diff --git a/include/mruby/presym.h b/include/mruby/presym.h index 876e4f4fb..fd08a24da 100644 --- a/include/mruby/presym.h +++ b/include/mruby/presym.h @@ -16,7 +16,7 @@ #define MRB_PRESYM_UNNAMED(lit, num) enum mruby_presym { -#include <mruby/presym.inc> +#include <../build/presym.inc> }; #undef MRB_PRESYM_NAMED diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index 1e3590b28..a9e84effe 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -373,14 +373,6 @@ EOS def libraries [libmruby_static] end - - def presym_file - "#{build_dir}/presym" - end - - def presym_inc - "#{build_dir}/include/mruby/presym.inc" - end end # Build class CrossBuild < Build diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 2e39e8930..d2365f903 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -116,8 +116,15 @@ codegen_error(codegen_scope *s, const char *message) while (s->prev) { codegen_scope *tmp = s->prev; mrb_free(s->mrb, s->iseq); + for (int i=0; i<s->irep->plen; i++) { + mrb_pool_value *pv = &s->pool[i]; + if ((pv->tt & 0x3) == IREP_TT_STR) { + mrb_free(s->mrb, (void*)pv->u.str); + } + } mrb_free(s->mrb, s->pool); mrb_free(s->mrb, s->syms); + mrb_free(s->mrb, s->catch_table); if (s->reps) { /* copied from mrb_irep_free() in state.c */ for (i=0; i<s->irep->rlen; i++) { @@ -361,10 +368,13 @@ no_peephole(codegen_scope *s) return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc; } +#define JMPLINK_START UINT32_MAX + static void gen_jmpdst(codegen_scope *s, uint32_t pc) { - if (pc == 0) { + + if (pc == JMPLINK_START) { gen_S(s, 0); } else { @@ -372,7 +382,7 @@ gen_jmpdst(codegen_scope *s, uint32_t pc) int32_t off = pc - pos2; if (off > INT16_MAX || INT16_MIN > off) { - codegen_error(s, "too big jmp offset"); + codegen_error(s, "too big jump offset"); } gen_S(s, (uint16_t)off); } @@ -390,6 +400,8 @@ genjmp(codegen_scope *s, mrb_code i, uint32_t pc) return pos; } +#define genjmp_0(s,i) genjmp(s,i,JMPLINK_START) + static uint32_t genjmp2(codegen_scope *s, mrb_code i, uint16_t a, uint32_t pc, int val) { @@ -418,6 +430,8 @@ genjmp2(codegen_scope *s, mrb_code i, uint16_t a, uint32_t pc, int val) return pos; } +#define genjmp2_0(s,i,a,val) genjmp2(s,i,a,JMPLINK_START,val) + static void gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) { @@ -519,10 +533,13 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) static uint32_t dispatch(codegen_scope *s, uint32_t pos0) { - int32_t pos1 = pos0 + 2; + int32_t pos1; int32_t offset; int16_t newpos; + if (pos0 == JMPLINK_START) return 0; + + pos1 = pos0 + 2; offset = s->pc - pos1; if (offset > INT16_MAX) { codegen_error(s, "too big jmp offset"); @@ -537,7 +554,7 @@ dispatch(codegen_scope *s, uint32_t pos0) static void dispatch_linked(codegen_scope *s, uint32_t pos) { - if (pos==0) return; + if (pos==JMPLINK_START) return; for (;;) { pos = dispatch(s, pos); if (pos==0) break; @@ -865,10 +882,10 @@ lambda_body(codegen_scope *s, node *tree, int blk) pos = new_label(s); for (i=0; i<oa; i++) { new_label(s); - genjmp(s, OP_JMP, 0); + genjmp_0(s, OP_JMP); } if (oa > 0) { - genjmp(s, OP_JMP, 0); + genjmp_0(s, OP_JMP); } opt = tree->car->cdr->car; i = 0; @@ -915,7 +932,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) if (def_arg) { int idx; genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); - jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0); + jmpif_key_p = genjmp2_0(s, OP_JMPIF, lv_idx(s, kwd_sym), NOVAL); codegen(s, def_arg, VAL); pop(); idx = lv_idx(s, kwd_sym); @@ -926,7 +943,7 @@ lambda_body(codegen_scope *s, node *tree, int blk) int lv = search_upvar(s, kwd_sym, &idx); genop_3(s, OP_GETUPVAR, cursp(), idx, lv); } - jmp_def_set = genjmp(s, OP_JMP, 0); + jmp_def_set = genjmp_0(s, OP_JMP); dispatch(s, jmpif_key_p); } genop_2(s, OP_KARG, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); @@ -1107,7 +1124,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) if (safe) { int recv = cursp()-1; gen_move(s, cursp(), recv, 1); - skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val); + skip = genjmp2_0(s, OP_JMPNIL, cursp(), val); } tree = tree->cdr->cdr->car; if (tree) { @@ -1505,11 +1522,11 @@ codegen(codegen_scope *s, node *tree, int val) pop(); lp->type = LOOP_RESCUE; end = s->pc; - noexc = genjmp(s, OP_JMP, 0); + noexc = genjmp_0(s, OP_JMP); catch_handler_set(s, catch_entry, MRB_CATCH_RESCUE, begin, end, s->pc); tree = tree->cdr; - exend = 0; - pos1 = 0; + exend = JMPLINK_START; + pos1 = JMPLINK_START; if (tree->car) { node *n2 = tree->car; int exc = cursp(); @@ -1520,8 +1537,8 @@ codegen(codegen_scope *s, node *tree, int val) node *n3 = n2->car; node *n4 = n3->car; - if (pos1) dispatch(s, pos1); - pos2 = 0; + dispatch(s, pos1); + pos2 = JMPLINK_START; do { if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) { codegen(s, n4->car, VAL); @@ -1547,7 +1564,7 @@ codegen(codegen_scope *s, node *tree, int val) n4 = n4->cdr; } } while (n4); - pos1 = genjmp(s, OP_JMP, 0); + pos1 = genjmp_0(s, OP_JMP); dispatch_linked(s, pos2); pop(); @@ -1563,7 +1580,7 @@ codegen(codegen_scope *s, node *tree, int val) n2 = n2->cdr; push(); } - if (pos1) { + if (pos1 != JMPLINK_START) { dispatch(s, pos1); genop_1(s, OP_RAISEIF, exc); } @@ -1663,17 +1680,17 @@ codegen(codegen_scope *s, node *tree, int val) pop(); if (val || tree->cdr->car) { if (nil_p) { - pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); - pos1 = genjmp(s, OP_JMP, 0); + pos2 = genjmp2_0(s, OP_JMPNIL, cursp(), val); + pos1 = genjmp_0(s, OP_JMP); dispatch(s, pos2); } else { - pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val); + pos1 = genjmp2_0(s, OP_JMPNOT, cursp(), val); } codegen(s, tree->cdr->car, val); if (val) pop(); if (elsepart || val) { - pos2 = genjmp(s, OP_JMP, 0); + pos2 = genjmp_0(s, OP_JMP); dispatch(s, pos1); codegen(s, elsepart, val); dispatch(s, pos2); @@ -1685,10 +1702,10 @@ codegen(codegen_scope *s, node *tree, int val) else { /* empty then-part */ if (elsepart) { if (nil_p) { - pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); + pos1 = genjmp2_0(s, OP_JMPNIL, cursp(), val); } else { - pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val); + pos1 = genjmp2_0(s, OP_JMPIF, cursp(), val); } codegen(s, elsepart, val); dispatch(s, pos1); @@ -1707,7 +1724,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree->car, VAL); pop(); - pos = genjmp2(s, OP_JMPNOT, cursp(), 0, val); + pos = genjmp2_0(s, OP_JMPNOT, cursp(), val); codegen(s, tree->cdr, val); dispatch(s, pos); } @@ -1719,7 +1736,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree->car, VAL); pop(); - pos = genjmp2(s, OP_JMPIF, cursp(), 0, val); + pos = genjmp2_0(s, OP_JMPIF, cursp(), val); codegen(s, tree->cdr, val); dispatch(s, pos); } @@ -1730,7 +1747,7 @@ codegen(codegen_scope *s, node *tree, int val) struct loopinfo *lp = loop_push(s, LOOP_NORMAL); lp->pc0 = new_label(s); - lp->pc1 = genjmp(s, OP_JMP, 0); + lp->pc1 = genjmp_0(s, OP_JMP); lp->pc2 = new_label(s); codegen(s, tree->cdr, NOVAL); dispatch(s, lp->pc1); @@ -1747,7 +1764,7 @@ codegen(codegen_scope *s, node *tree, int val) struct loopinfo *lp = loop_push(s, LOOP_NORMAL); lp->pc0 = new_label(s); - lp->pc1 = genjmp(s, OP_JMP, 0); + lp->pc1 = genjmp_0(s, OP_JMP); lp->pc2 = new_label(s); codegen(s, tree->cdr, NOVAL); dispatch(s, lp->pc1); @@ -1770,7 +1787,7 @@ codegen(codegen_scope *s, node *tree, int val) uint32_t pos1, pos2, pos3, tmp; node *n; - pos3 = 0; + pos3 = JMPLINK_START; if (tree->car) { head = cursp(); codegen(s, tree->car, VAL); @@ -1778,7 +1795,7 @@ codegen(codegen_scope *s, node *tree, int val) tree = tree->cdr; while (tree) { n = tree->car->car; - pos1 = pos2 = 0; + pos1 = pos2 = JMPLINK_START; while (n) { codegen(s, n->car, VAL); if (head) { @@ -1799,20 +1816,20 @@ codegen(codegen_scope *s, node *tree, int val) n = n->cdr; } if (tree->car->car) { - pos1 = genjmp(s, OP_JMP, 0); + pos1 = genjmp_0(s, OP_JMP); dispatch_linked(s, pos2); } codegen(s, tree->car->cdr, val); if (val) pop(); tmp = genjmp(s, OP_JMP, pos3); pos3 = tmp; - if (pos1) dispatch(s, pos1); + dispatch(s, pos1); tree = tree->cdr; } if (val) { uint32_t pos = cursp(); genop_1(s, OP_LOADNIL, cursp()); - if (pos3) dispatch_linked(s, pos3); + if (pos3 != JMPLINK_START) dispatch_linked(s, pos3); if (head) pop(); if (cursp() != pos) { gen_move(s, cursp(), pos, 0); @@ -1820,7 +1837,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); } else { - if (pos3) { + if (pos3 != JMPLINK_START) { dispatch_linked(s, pos3); } if (head) { @@ -2074,7 +2091,7 @@ codegen(codegen_scope *s, node *tree, int val) exc = cursp(); codegen(s, tree->car, VAL); end = s->pc; - noexc = genjmp(s, OP_JMP, 0); + noexc = genjmp_0(s, OP_JMP); lp->type = LOOP_RESCUE; catch_handler_set(s, catch_entry, MRB_CATCH_RESCUE, begin, end, s->pc); genop_1(s, OP_EXCEPT, exc); @@ -2127,10 +2144,10 @@ codegen(codegen_scope *s, node *tree, int val) if (vsp >= 0) { gen_move(s, vsp, cursp(), 1); } - pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); + pos = genjmp2_0(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), val); } else { - pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); + pos = genjmp2_0(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), val); } codegen(s, tree->cdr->cdr->car, VAL); pop(); @@ -3141,7 +3158,7 @@ loop_push(codegen_scope *s, enum looptype t) struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo)); p->type = t; - p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0; + p->pc0 = p->pc1 = p->pc2 = p->pc3 = JMPLINK_START; p->prev = s->loop; p->acc = cursp(); s->loop = p; @@ -3223,15 +3240,12 @@ catch_handler_set(codegen_scope *s, int ent, enum mrb_catch_type type, uint32_t struct mrb_irep_catch_handler *e; mrb_assert(ent >= 0 && ent < s->irep->clen); - mrb_assert(begin < MAXARG_S); - mrb_assert(end < MAXARG_S); - mrb_assert(target < MAXARG_S); e = &s->catch_table[ent]; uint8_to_bin(type, &e->type); - uint16_to_bin(begin, e->begin); - uint16_to_bin(end, e->end); - uint16_to_bin(target, e->target); + mrb_irep_catch_handler_pack(begin, e->begin); + mrb_irep_catch_handler_pack(end, e->end); + mrb_irep_catch_handler_pack(target, e->target); } static struct RProc* diff --git a/src/codedump.c b/src/codedump.c index 94d4f24c0..576ff6ceb 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -86,9 +86,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep) const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep); for (; i > 0; i --, e ++) { - int begin = bin_to_uint16(e->begin); - int end = bin_to_uint16(e->end); - int target = bin_to_uint16(e->target); + uint32_t begin = mrb_irep_catch_handler_unpack(e->begin); + uint32_t end = mrb_irep_catch_handler_unpack(e->end); + uint32_t target = mrb_irep_catch_handler_unpack(e->target); char buf[20]; const char *type; @@ -105,7 +105,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep) type = buf; break; } - printf("catch type: %-8s begin: %04d end: %04d target: %04d\n", type, begin, end, target); + printf("catch type: %-8s begin: %04" PRIu32 " end: %04" PRIu32 " target: %04" PRIu32 "\n", type, begin, end, target); } } @@ -387,37 +387,37 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_ALIAS\t:%s\t%s\n", mrb_sym_dump(mrb, irep->syms[a]), mrb_sym_dump(mrb, irep->syms[b])); break; CASE(OP_ADD, B); - printf("OP_ADD\tR%d\t\n", a); + printf("OP_ADD\tR%d\tR%d\n", a, a+1); break; CASE(OP_ADDI, BB); printf("OP_ADDI\tR%d\t%d\n", a, b); break; CASE(OP_SUB, B); - printf("OP_SUB\tR%d\t\n", a); + printf("OP_SUB\tR%d\tR%d\n", a, a+1); break; CASE(OP_SUBI, BB); printf("OP_SUBI\tR%d\t%d\n", a, b); break; CASE(OP_MUL, B); - printf("OP_MUL\tR%d\t\n", a); + printf("OP_MUL\tR%d\tR%d\n", a, a+1); break; CASE(OP_DIV, B); - printf("OP_DIV\tR%d\t\n", a); + printf("OP_DIV\tR%d\tR%d\n", a, a+1); break; CASE(OP_LT, B); - printf("OP_LT\t\tR%d\t\n", a); + printf("OP_LT\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_LE, B); - printf("OP_LE\t\tR%d\t\n", a); + printf("OP_LE\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_GT, B); - printf("OP_GT\t\tR%d\t\n", a); + printf("OP_GT\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_GE, B); - printf("OP_GE\t\tR%d\t\n", a); + printf("OP_GE\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_EQ, B); - printf("OP_EQ\t\tR%d\t\n", a); + printf("OP_EQ\t\tR%d\tR%d\n", a, a+1); break; CASE(OP_ARRAY, BB); printf("OP_ARRAY\tR%d\t%d\t", a, b); diff --git a/src/dump.c b/src/dump.c index a79df597b..85074d5a2 100644 --- a/src/dump.c +++ b/src/dump.c @@ -48,14 +48,15 @@ write_irep_header(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) return cur - buf; } - static size_t get_iseq_block_size(mrb_state *mrb, const mrb_irep *irep) { size_t size = 0; + size += sizeof(uint16_t); /* clen */ size += sizeof(uint16_t); /* ilen */ size += irep->ilen * sizeof(mrb_code); /* iseq(n) */ + size += irep->clen * sizeof(struct mrb_irep_catch_handler); return size; } @@ -64,10 +65,13 @@ static ptrdiff_t write_iseq_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf, uint8_t flags) { uint8_t *cur = buf; + size_t seqlen = irep->ilen * sizeof(mrb_code) + + irep->clen * sizeof(struct mrb_irep_catch_handler); + cur += uint16_to_bin(irep->clen, cur); /* number of catch handlers */ cur += uint16_to_bin(irep->ilen, cur); /* number of opcode */ - memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); - cur += irep->ilen * sizeof(mrb_code); + memcpy(cur, irep->iseq, seqlen); + cur += seqlen; return cur - buf; } @@ -136,8 +140,9 @@ get_pool_block_size(mrb_state *mrb, const mrb_irep *irep) default: /* packed IREP_TT_STRING */ { - mrb_int len = irep->pool[pool_no].tt >> 1; /* unpack length */ + mrb_int len = irep->pool[pool_no].tt >> 2; /* unpack length */ mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); + size += sizeof(uint16_t); size += (size_t)len+1; } break; @@ -262,39 +267,12 @@ write_syms_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) } static size_t -get_catch_table_block_size(mrb_state *mrb, const mrb_irep *irep) -{ - size_t size = 0; - - size += sizeof(uint16_t); /* number of catch handler */ - size += (sizeof(struct mrb_irep_catch_handler)) * irep->clen; - - return size; -} - -static ptrdiff_t -write_catch_table_block(mrb_state *mrb, const mrb_irep *irep, uint8_t *buf) -{ - uint8_t *cur = buf; - const struct mrb_irep_catch_handler *e = mrb_irep_catch_handler_table(irep); - mrb_static_assert1(sizeof(*e) == 7); - - if (e == NULL) return 0; - /* irep->clen has already been written before iseq block */ - memcpy(cur, (const void *)e, sizeof(*e) * irep->clen); - cur += sizeof(*e) * irep->clen; - - return cur - buf; -} - -static size_t get_irep_record_size_1(mrb_state *mrb, const mrb_irep *irep) { size_t size = 0; size += get_irep_header_size(mrb); size += get_iseq_block_size(mrb, irep); - size += get_catch_table_block_size(mrb, irep); size += get_pool_block_size(mrb, irep); size += get_syms_block_size(mrb, irep); return size; @@ -324,13 +302,7 @@ write_irep_record(mrb_state *mrb, const mrb_irep *irep, uint8_t *bin, size_t *ir } bin += write_irep_header(mrb, irep, bin); - /* - * The catch handler table is after iseq block, but the number of - * elements is placed before iseq block. - */ - bin += uint16_to_bin(irep->clen, bin); bin += write_iseq_block(mrb, irep, bin, flags); - bin += write_catch_table_block(mrb, irep, bin); bin += write_pool_block(mrb, irep, bin); bin += write_syms_block(mrb, irep, bin); @@ -392,6 +364,7 @@ write_section_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t *bin, size_t *l if (result != MRB_DUMP_OK) { return result; } + mrb_assert(rsize == get_irep_record_size(mrb, irep)); *len_p = cur - bin + rsize; write_section_irep_header(mrb, *len_p, bin); @@ -467,7 +467,7 @@ mrb_gc_protect(mrb_state *mrb, mrb_value obj) gc_protect(mrb, &mrb->gc, mrb_basic_ptr(obj)); } -#define GC_ROOT_NAME "_gc_root_" +#define GC_ROOT_SYM MRB_SYM(_gc_root_) /* mrb_gc_register() keeps the object from GC. @@ -484,7 +484,7 @@ mrb_gc_register(mrb_state *mrb, mrb_value obj) mrb_value table; if (mrb_immediate_p(obj)) return; - root = mrb_intern_lit(mrb, GC_ROOT_NAME); + root = GC_ROOT_SYM; table = mrb_gv_get(mrb, root); if (mrb_nil_p(table) || !mrb_array_p(table)) { table = mrb_ary_new(mrb); @@ -503,7 +503,7 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj) mrb_int i; if (mrb_immediate_p(obj)) return; - root = mrb_intern_lit(mrb, GC_ROOT_NAME); + root = GC_ROOT_SYM; table = mrb_gv_get(mrb, root); if (mrb_nil_p(table)) return; if (!mrb_array_p(table)) { diff --git a/src/load.c b/src/load.c index 23e11d331..48496ba48 100644 --- a/src/load.c +++ b/src/load.c @@ -107,7 +107,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag if (irep->ilen > 0) { size_t data_len = sizeof(mrb_code) * irep->ilen + sizeof(struct mrb_irep_catch_handler) * irep->clen; - mrb_static_assert1(sizeof(struct mrb_irep_catch_handler) == 7); + mrb_static_assert1(sizeof(struct mrb_irep_catch_handler) == 13); if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) { return NULL; } diff --git a/src/symbol.c b/src/symbol.c index 18ef44e77..c78f41f63 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -20,7 +20,7 @@ static const struct { const char *name; uint16_t len; } presym_table[] = { -#include <mruby/presym.inc> +#include <../build/presym.inc> }; static mrb_sym @@ -813,7 +813,7 @@ catch_handler_find(mrb_state *mrb, mrb_callinfo *ci, const mrb_code *pc, uint32_ e = mrb_irep_catch_handler_table(irep) + cnt - 1; for (; cnt > 0; cnt --, e --) { if (((UINT32_C(1) << e->type) & filter) && - catch_cover_p(xpc, bin_to_uint16(e->begin), bin_to_uint16(e->end))) { + catch_cover_p(xpc, mrb_irep_catch_handler_unpack(e->begin), mrb_irep_catch_handler_unpack(e->end))) { return e; } } @@ -1069,7 +1069,6 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_LOADL16, BS) { goto op_loadl; } @@ -1300,19 +1299,19 @@ RETRY_TRY_BLOCK: } CASE(OP_JMPUW, S) { + a = (pc - irep->iseq) + (int16_t)a; CHECKPOINT_RESTORE(RBREAK_TAG_JUMP) { struct RBreak *brk = (struct RBreak*)mrb->exc; mrb_value target = mrb_break_value_get(brk); mrb_assert(mrb_integer_p(target)); a = (uint32_t)mrb_integer(target); mrb_assert(a >= 0 && a < irep->ilen); - a = a - (pc - irep->iseq); } CHECKPOINT_MAIN(RBREAK_TAG_JUMP) { ch = catch_handler_find(mrb, mrb->c->ci, pc, MRB_CATCH_FILTER_ENSURE); if (ch) { /* avoiding a jump from a catch handler into the same handler */ - if (a < bin_to_uint16(ch->begin) || a >= bin_to_uint16(ch->end)) { + if (a < mrb_irep_catch_handler_unpack(ch->begin) || a >= mrb_irep_catch_handler_unpack(ch->end)) { THROW_TAGGED_BREAK(mrb, RBREAK_TAG_JUMP, proc, mrb_fixnum_value(a)); } } @@ -1320,7 +1319,7 @@ RETRY_TRY_BLOCK: CHECKPOINT_END(RBREAK_TAG_JUMP); mrb->exc = NULL; /* clear break object */ - pc += (int16_t)a; + pc = irep->iseq + a; JUMP; } @@ -2009,7 +2008,7 @@ RETRY_TRY_BLOCK: mrb->c->stack = ci[1].stackent; } mrb_stack_extend(mrb, irep->nregs); - pc = irep->iseq + bin_to_uint16(ch->target); + pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } else { mrb_int acc; diff --git a/tasks/presym.rake b/tasks/presym.rake deleted file mode 100644 index 1d6ef490e..000000000 --- a/tasks/presym.rake +++ /dev/null @@ -1,139 +0,0 @@ -op_table = { - "!" => "not", - "!=" => "neq", - "!~" => "nmatch", - "%" => "mod", - "&" => "and", - "&&" => "andand", - "*" => "mul", - "**" => "pow", - "+" => "add", - "+@" => "plus", - "-" => "sub", - "-@" => "minus", - "/" => "div", - "<" => "lt", - "<=" => "le", - "<<" => "lshift", - "<=>" => "cmp", - "==" => "eq", - "===" => "eqq", - "=~" => "match", - ">" => "gt", - ">=" => "ge", - ">>" => "rshift", - "[]" => "aref", - "[]=" => "aset", - "^" => "xor", - "`" => "tick", - "|" => "or", - "||" => "oror", - "~" => "neg", -} -macro_to_symbol = { -# Macro Symbol -# [prefix, suffix] => [prefix, suffix] - ["CV" , "" ] => ["@@" , "" ], - ["IV" , "" ] => ["@" , "" ], - ["" , "_B" ] => ["" , "!" ], - ["" , "_Q" ] => ["" , "?" ], - ["" , "_E" ] => ["" , "=" ], - ["" , "" ] => ["" , "" ], -} - -core_cfiles = Dir.glob("#{MRUBY_ROOT}/src/*.c") -core_rbfiles = Dir.glob("#{MRUBY_ROOT}/mrblib/*.rb") -MRuby.each_target do |build| - cfiles = core_cfiles.dup - rbfiles = core_rbfiles.dup - psfiles = [] - presym_file = build.presym_file - presym_inc = build.presym_inc - - build.compilers.each {|c| c.include_paths << "#{build.build_dir}/include"} - build.gems.each do |gem| - cfiles.concat(Dir.glob(gem.dir+"/{src,core,tools/*}/*.c")) - if gem.cdump? - rbfiles.concat(gem.rbfiles) - psfiles.concat(Dir.glob(gem.dir+"/**/presym")) - end - gem.compilers.each {|c| c.include_paths << "#{build.build_dir}/include"} - end - - file presym_file => [*cfiles, *rbfiles, *psfiles, __FILE__] do - prefix_re = Regexp.union(*macro_to_symbol.keys.map(&:first).uniq) - suffix_re = Regexp.union(*macro_to_symbol.keys.map(&:last).uniq) - macro_re = /MRB_(#{prefix_re})SYM(#{suffix_re})\((\w+)\)/o - csymbols = cfiles.map do |f| - src = File.read(f) - src.gsub!(/\/\/.+(\n|$)/, "\n") - [src.scan(/intern_lit\([^\n"]*"([^\n "]*)"/), - src.scan(/mrb_define_method\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_class_method\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_class\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_module\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_module_function\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_const\([^\n"]*"([^\n"]*)"/), - src.scan(/mrb_define_global_const\([^\n"]*"([^\n"]*)"/), - src.scan(macro_re).map{|prefix, suffix, name| - macro_to_symbol[[prefix, suffix]] * name - }] - end - csymbols += File.readlines("#{MRUBY_ROOT}/include/mruby.h").grep(/define E_/).join.scan(/MRB_SYM\((\w+)\)/) - - rbsymbols = rbfiles.map do |f| - src = File.read(f) - src.force_encoding(Encoding::BINARY) - [src.scan(/\bclass +([A-Z]\w*)/), - src.scan(/\bmodule +([A-Z]\w*)/), - src.scan(/\bdef +(\w+[!?=]?)/), - src.scan(/\balias +(\w+[!?]?)/), - src.scan(/\b([A-Z]\w*) *=[^=]/), - src.scan(/(\$[a-zA-Z_]\w*)/), - src.scan(/(\$[$!?0-9]\w*)/), - src.scan(/(@@?[a-zA-Z_]\w*)/), - src.scan(/[^.]\.([a-zA-Z_]\w*[!?]?)/), - src.scan(/\.([a-zA-Z_]\w* *=)/).map{|x|x.map{|s|s.gsub(' ', '')}}, - src.scan(/\b([a-zA-Z_]\w*):/), - src.scan(/:([a-zA-Z_]\w*[!?=]?)/), - src.scan(/[\(\[\{ ]:"([^"]+)"/).map{|x|x.map{|s|s.gsub('\#', '#')}}, - src.scan(/[ \(\[\{]:'([^']+)'/) - ] - end - symbols = [csymbols, rbsymbols, op_table.keys, psfiles.map{|file| symbols.concat(File.readlines(file).grep_v(/^# /))}] - symbols = symbols.flatten.compact.uniq.grep_v(/#/).map{|x| x.gsub("\n", '\n')}.sort_by!{|x| [x.bytesize, x]} - presyms = File.readlines(presym_file) rescue [] - presyms.each{|x| x.chomp!} - if presyms != symbols - _pp "GEN", presym_file.relative_path - mkdir_p(File.dirname(presym_file)) - File.write(presym_file, symbols.join("\n")) - Rake::Task["gensym:#{presym_inc}"].invoke - end - end - - task "gensym:#{presym_inc}" do - presyms = File.readlines(presym_file) - presyms.each{|x| x.chomp!} - symbol_to_macro = macro_to_symbol.invert - prefix_re = Regexp.union(*symbol_to_macro.keys.map(&:first).uniq) - suffix_re = Regexp.union(*symbol_to_macro.keys.map(&:last).uniq) - macro_re = /\A(#{prefix_re})?([\w&&\D]\w*)(#{suffix_re})?\z/o - mkdir_p(File.dirname(presym_inc)) - _pp "GEN", presym_inc.relative_path - File.open(presym_inc, "w") do |f| - f.puts "/* MRB_PRESYM_NAMED(lit, num, type, name) */" - f.puts "/* MRB_PRESYM_UNNAMED(lit, num) */" - presyms.each.with_index(1) do |sym, num| - if macro_re =~ sym && (affixes = symbol_to_macro[[$1, $3]]) - f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, #{affixes * 'SYM'}, #{$2})| - elsif name = op_table[sym] - f.puts %|MRB_PRESYM_NAMED("#{sym}", #{num}, OPSYM, #{name})| - elsif - f.puts %|MRB_PRESYM_UNNAMED("#{sym}", #{num})| - end - end - f.print "#define MRB_PRESYM_MAX #{presyms.size}" - end - end -end |
