summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-03-19 18:42:53 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-03-19 18:42:53 +0900
commit4cf38eb9032ab70544f940941703a0c09529539f (patch)
treee7e8343d7eaf22483985283eeeefefe15e09a323
parentd01118d2617ea6a0c6f32789cee072eb3dbf42ee (diff)
downloadmruby-4cf38eb9032ab70544f940941703a0c09529539f.tar.gz
mruby-4cf38eb9032ab70544f940941703a0c09529539f.zip
Fixed OP_RESCUE code generation bug; fix #3519
916b8e let code executed with mrb->exc set, and may cause a crash like #3519. Instead modified OP_RESCUE again. To retrieve the exception object, we use `OP_RESCUE R(A), 0, 0` (old behavior). To compare the exception object and the class, we use `OP_RESCUE R(A), R(B), 1`. The reason we use OP_RESCUE for two instruction switched by operand C is to save the instruction space. As a result, the following code: ```ruby begin raise "a" rescue TypeError p 1 rescue RuntimeError p 2 end ``` will be compiled as: ``` irep 0x55cd1f565cb0 nregs=4 nlocals=1 pools=1 syms=4 reps=0 file: - 2 000 OP_ONERR 005 2 001 OP_LOADSELF R1 2 002 OP_STRING R2 L(0) ; "a" 2 003 OP_SEND R1 :raise 1 2 004 OP_JMP 023 2 005 OP_RESCUE R1 3 006 OP_GETCONST R2 :TypeError 3 007 OP_RESCUE R1 R2 cont 3 008 OP_JMPIF R2 010 3 009 OP_JMP 014 4 010 OP_LOADSELF R1 4 011 OP_LOADI R2 1 4 012 OP_SEND R1 :p 1 4 013 OP_JMP 024 5 014 OP_GETCONST R2 :RuntimeError 5 015 OP_RESCUE R1 R2 cont 5 016 OP_JMPIF R2 018 5 017 OP_JMP 022 6 018 OP_LOADSELF R1 6 019 OP_LOADI R2 2 6 020 OP_SEND R1 :p 1 6 021 OP_JMP 024 6 022 OP_RAISE R1 6 023 OP_POPERR 1 6 024 OP_STOP ```
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c7
1 files changed, 2 insertions, 5 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index dbf9dcd39..1ca86761c 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -1293,8 +1293,8 @@ codegen(codegen_scope *s, node *tree, int val)
if (tree->car) {
node *n2 = tree->car;
int exc = cursp();
- int cnt = 0;
+ genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
push();
while (n2) {
node *n3 = n2->car;
@@ -1304,9 +1304,6 @@ codegen(codegen_scope *s, node *tree, int val)
pos2 = 0;
do {
if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) {
- if (cnt == 0) {
- genop(s, MKOP_ABC(OP_RESCUE, exc, 0, cnt)); cnt = 1;
- }
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
push();
codegen(s, n4->car, VAL);
@@ -1322,7 +1319,7 @@ codegen(codegen_scope *s, node *tree, int val)
push();
}
pop();
- genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), cnt)); cnt = 1;
+ genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));
}
tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;