diff --git a/jscompile.c b/jscompile.c index 0b82ee4..ef15196 100644 --- a/jscompile.c +++ b/jscompile.c @@ -744,6 +744,48 @@ static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catch cstm(J, F, finallystm); } +/* Switch */ + +static void cswitch(JF, js_Ast *ref, js_Ast *head) +{ + js_Ast *node, *clause, *def = NULL; + int end; + + cexp(J, F, ref); + + /* emit an if-else chain of tests for the case clause expressions */ + for (node = head; node; node = node->b) { + clause = node->a; + if (clause->type == STM_DEFAULT) { + if (def) + jsC_error(J, clause, "more than one default label in switch"); + def = clause; + } else { + emit(J, F, OP_DUP); + cexp(J, F, clause->a); + emit(J, F, OP_STRICTEQ); + clause->casejump = jump(J, F, OP_JTRUE); + } + } + if (def) + def->casejump = jump(J, F, OP_JUMP); + else + end = jump(J, F, OP_JUMP); + + /* emit the casue clause bodies */ + for (node = head; node; node = node->b) { + clause = node->a; + label(J, F, clause->casejump); + if (clause->type == STM_DEFAULT) + cstmlist(J, F, clause->a); + else + cstmlist(J, F, clause->b); + } + + if (!def) + label(J, F, end); +} + /* Statements */ static void cstm(JF, js_Ast *stm) @@ -843,6 +885,11 @@ static void cstm(JF, js_Ast *stm) labeljumps(J, F, stm->jumps, here(J,F), loop); break; + case STM_SWITCH: + cswitch(J, F, stm->a, stm->b); + labeljumps(J, F, stm->jumps, here(J,F), 0); + break; + case STM_LABEL: cstm(J, F, stm->b); /* skip consecutive labels */ @@ -905,8 +952,6 @@ static void cstm(JF, js_Ast *stm) emit(J, F, OP_ENDWITH); break; - // switch - case STM_TRY: if (stm->b && stm->c) { if (stm->d) diff --git a/jsparse.c b/jsparse.c index 98b35bf..33dad4b 100644 --- a/jsparse.c +++ b/jsparse.c @@ -67,6 +67,7 @@ static js_Ast *jsP_newnode(js_State *J, int type, js_Ast *a, js_Ast *b, js_Ast * node->number = 0; node->string = NULL; node->jumps = NULL; + node->casejump = 0; node->parent = NULL; if (a) a->parent = node; diff --git a/jsparse.h b/jsparse.h index 10a9457..efe641e 100644 --- a/jsparse.h +++ b/jsparse.h @@ -131,6 +131,7 @@ struct js_Ast double number; const char *string; js_JumpList *jumps; /* list of break/continue jumps to patch */ + int casejump; /* for switch case clauses */ js_Ast *gcnext; /* next in alloc list */ };