summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Rakefile142
-rw-r--r--include/mruby/irep.h9
-rw-r--r--include/mruby/presym.h2
-rw-r--r--lib/mruby/build.rb8
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c98
-rw-r--r--src/codedump.c26
-rw-r--r--src/dump.c47
-rw-r--r--src/gc.c6
-rw-r--r--src/load.c2
-rw-r--r--src/symbol.c2
-rw-r--r--src/vm.c11
-rw-r--r--tasks/presym.rake139
12 files changed, 234 insertions, 258 deletions
diff --git a/Rakefile b/Rakefile
index 8be192155..8ac1f7f8f 100644
--- a/Rakefile
+++ b/Rakefile
@@ -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);
diff --git a/src/gc.c b/src/gc.c
index 04724ab1e..fb3a7bd16 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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
diff --git a/src/vm.c b/src/vm.c
index 85835149a..b56e960a2 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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