shithub: libmujs

Download patch

ref: 2b209d3f55fb75fc2e6ce50e5fe89b4507cdd67a
parent: 40572172a5acbbd86fe610d41b6d2195d7b81fb2
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 23 12:07:04 EST 2014

Omit needless setjmp guard over catch block in try/catch statement.

Make the catch opcodes only set the scope chain, and add explicit
try/endtry opcodes for the catch block in try/catch/finally statements.

--- a/jscompile.c
+++ b/jscompile.c
@@ -666,8 +666,14 @@
 			}
 			/* came from catch block */
 			if (prev == node->c) {
-				emit(J, F, OP_ENDCATCH);
-				if (node->d) cstm(J, F, node->d); /* finally */
+				/* ... with finally */
+				if (node->d) {
+					emit(J, F, OP_ENDCATCH);
+					emit(J, F, OP_ENDTRY);
+					cstm(J, F, node->d); /* finally */
+				} else {
+					emit(J, F, OP_ENDCATCH);
+				}
 			}
 			break;
 		}
@@ -693,25 +699,19 @@
 
 static void ctrycatch(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm)
 {
-	int L1, L2, L3;
+	int L1, L2;
 	L1 = jump(J, F, OP_TRY);
 	{
 		/* if we get here, we have caught an exception in the try block */
-		L2 = jump(J, F, OP_CATCH);
-		emitraw(J, F, addstring(J, F, catchvar->string));
-		{
-			/* if we get here, we have caught an exception in the catch block */
-			emit(J, F, OP_THROW); /* rethrow exception */
-		}
-		label(J, F, L2);
+		emitstring(J, F, OP_CATCH, catchvar->string);
 		cstm(J, F, catchstm);
 		emit(J, F, OP_ENDCATCH);
-		L3 = jump(J, F, OP_JUMP); /* skip past the try block */
+		L2 = jump(J, F, OP_JUMP); /* skip past the try block */
 	}
 	label(J, F, L1);
 	cstm(J, F, trystm);
 	emit(J, F, OP_ENDTRY);
-	label(J, F, L3);
+	label(J, F, L2);
 }
 
 static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm, js_Ast *finallystm)
@@ -720,8 +720,7 @@
 	L1 = jump(J, F, OP_TRY);
 	{
 		/* if we get here, we have caught an exception in the try block */
-		L2 = jump(J, F, OP_CATCH);
-		emitraw(J, F, addstring(J, F, catchvar->string));
+		L2 = jump(J, F, OP_TRY);
 		{
 			/* if we get here, we have caught an exception in the catch block */
 			cstm(J, F, finallystm); /* inline finally block */
@@ -728,6 +727,7 @@
 			emit(J, F, OP_THROW); /* rethrow exception */
 		}
 		label(J, F, L2);
+		emitstring(J, F, OP_CATCH, catchvar->string);
 		cstm(J, F, catchstm);
 		emit(J, F, OP_ENDCATCH);
 		L3 = jump(J, F, OP_JUMP); /* skip past the try block to the finally block */
--- a/jscompile.h
+++ b/jscompile.h
@@ -89,8 +89,9 @@
 	OP_TRY,		/* -ADDR- /jump/ or -ADDR- <exception> */
 	OP_ENDTRY,
 
-	OP_CATCH,	/* -ADDR,S- /jump/ or -ADDR,S- <exception> */
+	OP_CATCH,	/* push scope chain with exception variable */
 	OP_ENDCATCH,
+
 	OP_WITH,
 	OP_ENDWITH,
 
--- a/jsdump.c
+++ b/jsdump.c
@@ -651,6 +651,7 @@
 		case OP_GETPROPS:
 		case OP_SETPROPS:
 		case OP_DELPROPS:
+		case OP_CATCH:
 			pc(' ');
 			ps(F->strtab[*p++]);
 			break;
@@ -664,11 +665,6 @@
 		case OP_TRY:
 			printf(" %d", *p++);
 			break;
-		case OP_CATCH:
-			printf(" %d", *p++);
-			pc(' ');
-			ps(F->strtab[*p++]);
-			break;
 		}
 
 		nl();
@@ -713,6 +709,7 @@
 		case JS_CNUMBER: printf("[Number %g]", v.u.object->u.number); break;
 		case JS_CSTRING: printf("[String'%s']", v.u.object->u.string); break;
 		case JS_CERROR: printf("[Error %s]", v.u.object->u.string); break;
+		case JS_CITERATOR: printf("[Iterator %p]", v.u.object); break;
 		default: printf("[Object %p]", v.u.object); break;
 		}
 		break;
--- a/jsrun.c
+++ b/jsrun.c
@@ -822,23 +822,16 @@
 			break;
 
 		case OP_CATCH:
-			offset = *pc++;
 			str = ST[*pc++];
-			if (js_trypc(J, pc)) {
-				pc = J->trybuf[J->trylen].pc;
-			} else {
-				obj = jsV_newobject(J, JS_COBJECT, NULL);
-				js_pushobject(J, obj);
-				js_rot2(J);
-				js_setproperty(J, -2, str);
-				J->E = jsR_newenvironment(J, obj, J->E);
-				js_pop(J, 1);
-				pc = pcstart + offset;
-			}
+			obj = jsV_newobject(J, JS_COBJECT, NULL);
+			js_pushobject(J, obj);
+			js_rot2(J);
+			js_setproperty(J, -2, str);
+			J->E = jsR_newenvironment(J, obj, J->E);
+			js_pop(J, 1);
 			break;
 
 		case OP_ENDCATCH:
-			js_endtry(J);
 			J->E = J->E->outer;
 			break;