shithub: libmujs

Download patch

ref: 4c326a51a42436f9277cc86bf83d2e6dc4d3711e
parent: 60253cedab034cda3765a882fe2525a215c4d390
author: Tor Andersson <[email protected]>
date: Wed Jan 22 18:31:55 EST 2014

Compile switch statements.

--- a/jscompile.c
+++ b/jscompile.c
@@ -744,6 +744,48 @@
 	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 @@
 		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 */
@@ -904,8 +951,6 @@
 		cstm(J, F, stm->b);
 		emit(J, F, OP_ENDWITH);
 		break;
-
-	// switch
 
 	case STM_TRY:
 		if (stm->b && stm->c) {
--- a/jsparse.c
+++ b/jsparse.c
@@ -67,6 +67,7 @@
 	node->number = 0;
 	node->string = NULL;
 	node->jumps = NULL;
+	node->casejump = 0;
 
 	node->parent = NULL;
 	if (a) a->parent = node;
--- a/jsparse.h
+++ b/jsparse.h
@@ -131,6 +131,7 @@
 	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 */
 };