summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-compiler
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-12-15 17:44:57 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-12-15 17:57:45 +0900
commit05129ab9b3934ebc26a11f28d7d995793ea8baa5 (patch)
treecb8d9da98ad7bebded3f47c4135686e8656edc5a /mrbgems/mruby-compiler
parent7ecb96a00af720ee30d002861fefc0f9ce515441 (diff)
downloadmruby-05129ab9b3934ebc26a11f28d7d995793ea8baa5.tar.gz
mruby-05129ab9b3934ebc26a11f28d7d995793ea8baa5.zip
Check if destinations are too distant; fix #3900 fix #3901
Diffstat (limited to 'mrbgems/mruby-compiler')
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index 460368f88..c4227ca8e 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -392,6 +392,14 @@ scope_error(codegen_scope *s)
exit(EXIT_FAILURE);
}
+static void
+distcheck(codegen_scope *s, int diff)
+{
+ if (diff > MAXARG_sBx || diff < -MAXARG_sBx) {
+ codegen_error(s, "too distant jump address");
+ }
+}
+
static inline void
dispatch(codegen_scope *s, int pc)
{
@@ -413,9 +421,7 @@ dispatch(codegen_scope *s, int pc)
scope_error(s);
break;
}
- if (diff > MAXARG_sBx) {
- codegen_error(s, "too distant jump address");
- }
+ distcheck(s, diff);
s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
}
@@ -1364,6 +1370,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));
}
+ distcheck(s, pos2);
tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
if (n4) {
@@ -1381,6 +1388,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n3->cdr->cdr->car, val);
if (val) pop();
}
+ distcheck(s, exend);
tmp = genop(s, MKOP_sBx(OP_JMP, exend));
exend = tmp;
n2 = n2->cdr;
@@ -1526,6 +1534,7 @@ codegen(codegen_scope *s, node *tree, int val)
dispatch(s, lp->pc1);
codegen(s, tree->car, VAL);
pop();
+ distcheck(s, lp->pc2 - s->pc);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
loop_pop(s, val);
@@ -1542,6 +1551,7 @@ codegen(codegen_scope *s, node *tree, int val)
dispatch(s, lp->pc1);
codegen(s, tree->car, VAL);
pop();
+ distcheck(s, lp->pc2 - s->pc);
genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
loop_pop(s, val);
@@ -1584,6 +1594,7 @@ codegen(codegen_scope *s, node *tree, int val)
else {
pop();
}
+ distcheck(s, pos2);
tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
n = n->cdr;
@@ -1594,6 +1605,7 @@ codegen(codegen_scope *s, node *tree, int val)
}
codegen(s, tree->car->cdr, val);
if (val) pop();
+ distcheck(s, pos3);
tmp = genop(s, MKOP_sBx(OP_JMP, pos3));
pos3 = tmp;
if (pos1) dispatch(s, pos1);
@@ -2091,6 +2103,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
}
codegen(s, tree, NOVAL);
+ distcheck(s, s->loop->pc1 - s->pc);
genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));
}
else {
@@ -2114,6 +2127,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (s->ensure_level > s->loop->ensure_level) {
genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
}
+ distcheck(s, s->loop->pc2 - s->pc);
genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));
}
if (val) push();
@@ -2146,6 +2160,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (s->ensure_level > lp->ensure_level) {
genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);
}
+ distcheck(s, s->loop->pc1 - s->pc);
genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
}
}
@@ -3005,6 +3020,7 @@ loop_break(codegen_scope *s, node *tree)
if (tree) {
genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
}
+ distcheck(s, s->loop->pc3);
tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3));
loop->pc3 = tmp;
}