Browse Source

Merge branch 'fix-switch-default-first'

pull/195/head
Sami Vaarala 10 years ago
parent
commit
8423ec9886
  1. 3
      RELEASES.rst
  2. 67
      ecmascript-testcases/test-bug-switch-default-first.js
  3. 72
      ecmascript-testcases/test-dev-switch-odd-even.js
  4. 9
      src/duk_js_compiler.c

3
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)

67
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);
}

72
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);
}

9
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 {

Loading…
Cancel
Save