From fee7c78de775a6f2fb4fc0a24e44b321c7aab6e3 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sun, 29 Mar 2015 13:31:40 +0300 Subject: [PATCH 1/4] Bug testcase for GH-155 (switch default first) --- .../test-bug-switch-default-first.js | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 ecmascript-testcases/test-bug-switch-default-first.js diff --git a/ecmascript-testcases/test-bug-switch-default-first.js b/ecmascript-testcases/test-bug-switch-default-first.js new file mode 100644 index 00000000..5f6ba60d --- /dev/null +++ b/ecmascript-testcases/test-bug-switch-default-first.js @@ -0,0 +1,67 @@ +/* + * Reported by Andreas Oman (andoma) + * + * https://github.com/svaarala/duktape/issues/155 + */ + +/*=== +10 +11 +10 +10 +11 +11 +10 +11 +10 +===*/ + +// In Duktape 1.1.x this incorrectly returns 10 when v == 1. +function test1(v) { + switch(v) { + default: + case 0: + return 10; + case 1: + return 11; + } +} + +// Swapping case 0 and default would fix it; returns 11. +function test2(v) { + switch(v) { + case 0: + return 10; + default: + case 1: + return 11; + } +} + +// Adding a dummy case also fixed it; returns 11. +function test3(v) { + switch(v) { + case 99: + default: + case 0: + return 10; + case 1: + return 11; + } +} + +try { + print(test1(0)); + print(test1(1)); + print(test1(2)); + + print(test2(0)); + print(test2(1)); + print(test2(2)); + + print(test3(0)); + print(test3(1)); + print(test3(2)); +} catch (e) { + print(e.stack || e); +} From b2dd413c9edf1dfaabbb923341ad74f9036b29fd Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Fri, 3 Apr 2015 02:46:55 +0300 Subject: [PATCH 2/4] Another switch-case test --- .../test-dev-switch-odd-even.js | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ecmascript-testcases/test-dev-switch-odd-even.js diff --git a/ecmascript-testcases/test-dev-switch-odd-even.js b/ecmascript-testcases/test-dev-switch-odd-even.js new file mode 100644 index 00000000..2b2840e6 --- /dev/null +++ b/ecmascript-testcases/test-dev-switch-odd-even.js @@ -0,0 +1,72 @@ +/* + * Multiple case clauses map to same action. + */ + +/*=== +-2 out-of-range even-or-out-of-range +-1 out-of-range even-or-out-of-range +0 even even-or-out-of-range +1 odd odd +2 even even-or-out-of-range +3 odd odd +4 even even-or-out-of-range +5 odd odd +6 even even-or-out-of-range +7 odd odd +8 even even-or-out-of-range +9 odd odd +10 out-of-range even-or-out-of-range +11 out-of-range even-or-out-of-range +12 out-of-range even-or-out-of-range +===*/ + +function classify1(v) { + switch (v) { + case 0: + case 2: + case 4: + case 6: + case 8: + return 'even'; + case 1: + case 3: + case 5: + case 7: + case 9: + return 'odd'; + default: + return 'out-of-range'; + } +} + +function classify2(v) { + switch (v) { + default: + case 0: + case 2: + case 4: + case 6: + case 8: + return 'even-or-out-of-range'; + case 1: + case 3: + case 5: + case 7: + case 9: + return 'odd'; + } +} + +function test() { + var i; + + for (i = -2; i <= 12; i++) { + print(i, classify1(i), classify2(i)); + } +} + +try { + test(); +} catch (e) { + print(e.stack || e); +} From 3e836b3984489ddd8eaba53d74855a06b03c29ba Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sun, 29 Mar 2015 13:31:55 +0300 Subject: [PATCH 3/4] Fix switch control flow when default is first --- src/duk_js_compiler.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/duk_js_compiler.c b/src/duk_js_compiler.c index f4917c83..3326b588 100644 --- a/src/duk_js_compiler.c +++ b/src/duk_js_compiler.c @@ -5303,6 +5303,15 @@ DUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *re duk__advance(comp_ctx); duk__advance_expect(comp_ctx, DUK_TOK_COLON); + /* Fix for https://github.com/svaarala/duktape/issues/155: + * If 'default' is first clause (detected by pc_prevcase < 0) + * we need to ensure we stay in the matching chain. + */ + if (pc_prevcase < 0) { + DUK_DD(DUK_DDPRINT("default clause is first, emit prevcase jump")); + pc_prevcase = duk__emit_jump_empty(comp_ctx); + } + /* default clause matches next statement list (if any) */ pc_default = -2; } else { From 68a2acf734955eea5dc48651610eb85e037693b2 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sun, 29 Mar 2015 13:32:07 +0300 Subject: [PATCH 4/4] Releases: switch default first --- RELEASES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.rst b/RELEASES.rst index 7aaf97bd..f31f134b 100644 --- a/RELEASES.rst +++ b/RELEASES.rst @@ -892,6 +892,9 @@ Planned * Fix Duktape.act() lineNumber bug, PC used for lineNumber was off-by-one which sometimes resulted in incorrect linenumbers (GH-143) +* Fix incorrect switch-case matching when default clause is the first clause + in a switch statement (GH-155) + * Add support for TI-Nspire (using Ndless, see GH-113) 2.0.0 (XXXX-XX-XX)