shithub: libmujs

Download patch

ref: 34b9fda6f8778c7dbfae55c2480f09ffb6f0d952
parent: ff6f94236518e06e6274fe50c2a660ed45ec776d
author: Tor Andersson <tor@ccxvii.net>
date: Fri Jan 24 19:58:14 EST 2014

Create special initializer opcodes for brevity.

Pop the key and value, don't pop the object.

--- a/jscompile.c
+++ b/jscompile.c
@@ -115,7 +115,7 @@
 	else if (num == 1)
 		emit(J, F, OP_NUMBER_1);
 	else if (num == (short)num) {
-		emit(J, F, OP_NUMBER_X);
+		emit(J, F, OP_NUMBER_N);
 		emitraw(J, F, (short)num);
 	} else {
 		emit(J, F, OP_NUMBER);
@@ -178,12 +178,9 @@
 	int i = 0;
 	while (list) {
 		if (list->a->type != EXP_UNDEF) {
-			emit(J, F, OP_DUP);
-			emit(J, F, OP_NUMBER_X);
-			emitraw(J, F, i++);
 			cexp(J, F, list->a);
-			emit(J, F, OP_SETPROP);
-			emit(J, F, OP_POP);
+			emit(J, F, OP_INITPROP_N);
+			emitraw(J, F, i++);
 		} else {
 			++i;
 		}
@@ -197,16 +194,19 @@
 		js_Ast *kv = list->a;
 		if (kv->type == EXP_PROP_VAL) {
 			js_Ast *prop = kv->a;
-			emit(J, F, OP_DUP);
 			if (prop->type == AST_IDENTIFIER || prop->type == AST_STRING) {
 				cexp(J, F, kv->b);
-				emitstring(J, F, OP_SETPROPS, prop->string);
-				emit(J, F, OP_POP);
+				emitstring(J, F, OP_INITPROP_S, prop->string);
 			} else if (prop->type == AST_NUMBER) {
-				emitnumber(J, F, prop->number);
-				cexp(J, F, kv->b);
-				emit(J, F, OP_SETPROP);
-				emit(J, F, OP_POP);
+				if (prop->number == (short)prop->number) {
+					cexp(J, F, kv->b);
+					emit(J, F, OP_INITPROP_N);
+					emitraw(J, F, (short)prop->number);
+				} else {
+					emitnumber(J, F, prop->number);
+					cexp(J, F, kv->b);
+					emit(J, F, OP_INITPROP);
+				}
 			} else {
 				jsC_error(J, list, "illegal property name in object initializer");
 			}
@@ -245,7 +245,7 @@
 	case EXP_MEMBER:
 		cexp(J, F, lhs->a);
 		cexp(J, F, rhs);
-		emitstring(J, F, OP_SETPROPS, lhs->b->string);
+		emitstring(J, F, OP_SETPROP_S, lhs->b->string);
 		break;
 	default:
 		jsC_error(J, lhs, "invalid l-value in assignment");
@@ -280,7 +280,7 @@
 	case EXP_MEMBER:
 		cexp(J, F, lhs->a);
 		emit(J, F, OP_ROT2);
-		emitstring(J, F, OP_SETPROPS, lhs->b->string);
+		emitstring(J, F, OP_SETPROP_S, lhs->b->string);
 		emit(J, F, OP_POP);
 		break;
 	default:
@@ -306,7 +306,7 @@
 	case EXP_MEMBER:
 		cexp(J, F, lhs->a);
 		emit(J, F, OP_DUP);
-		emitstring(J, F, OP_GETPROPS, lhs->b->string);
+		emitstring(J, F, OP_GETPROP_S, lhs->b->string);
 		if (dup) emit(J, F, OP_DUP1ROT3);
 		break;
 	default:
@@ -324,7 +324,7 @@
 	case EXP_INDEX:
 		break;
 	case EXP_MEMBER:
-		emitstring(J, F, OP_SETPROPS, lhs->b->string);
+		emitstring(J, F, OP_SETPROP_S, lhs->b->string);
 		break;
 	default:
 		jsC_error(J, lhs, "invalid l-value in assignment");
@@ -353,7 +353,7 @@
 		break;
 	case EXP_MEMBER:
 		cexp(J, F, exp->a);
-		emitstring(J, F, OP_DELPROPS, exp->b->string);
+		emitstring(J, F, OP_DELPROP_S, exp->b->string);
 		break;
 	default:
 		jsC_error(J, exp, "invalid l-value in delete expression");
@@ -375,7 +375,7 @@
 	case EXP_MEMBER:
 		cexp(J, F, fun->a);
 		emit(J, F, OP_DUP);
-		emitstring(J, F, OP_GETPROPS, fun->b->string);
+		emitstring(J, F, OP_GETPROP_S, fun->b->string);
 		emit(J, F, OP_ROT2);
 		break;
 	default:
@@ -428,7 +428,7 @@
 
 	case EXP_MEMBER:
 		cexp(J, F, exp->a);
-		emitstring(J, F, OP_GETPROPS, exp->b->string);
+		emitstring(J, F, OP_GETPROP_S, exp->b->string);
 		break;
 
 	case EXP_CALL:
--- a/jscompile.h
+++ b/jscompile.h
@@ -18,7 +18,7 @@
 
 	OP_NUMBER_0,	/* -- 0 */
 	OP_NUMBER_1,	/* -- 1 */
-	OP_NUMBER_X,	/* -K- K */
+	OP_NUMBER_N,	/* -K- K */
 
 	OP_NUMBER,	/* -N- <number> */
 	OP_STRING,	/* -S- <string> */
@@ -43,12 +43,16 @@
 
 	OP_IN,		/* <name> <obj> -- <exists?> */
 
+	OP_INITPROP,	/* <obj> <key> <val> -- <obj> */
+	OP_INITPROP_N,	/* <obj> <val> -- <obj> */
+	OP_INITPROP_S,	/* <obj> <val> -- <obj> */
+
 	OP_GETPROP,	/* <obj> <name> -- <value> */
-	OP_GETPROPS,	/* <obj> -S- <value> */
+	OP_GETPROP_S,	/* <obj> -S- <value> */
 	OP_SETPROP,	/* <obj> <name> <value> -- <value> */
-	OP_SETPROPS,	/* <obj> <value> -S- <value> */
+	OP_SETPROP_S,	/* <obj> <value> -S- <value> */
 	OP_DELPROP,	/* <obj> <name> -- <success> */
-	OP_DELPROPS,	/* <obj> -S- <success> */
+	OP_DELPROP_S,	/* <obj> -S- <success> */
 
 	OP_ITERATOR,	/* <obj> -- <iobj> */
 	OP_NEXTITER,	/* <iobj> -- <iobj> <name> true || false */
--- a/jsdump.c
+++ b/jsdump.c
@@ -648,15 +648,17 @@
 		case OP_GETVAR:
 		case OP_SETVAR:
 		case OP_DELVAR:
-		case OP_GETPROPS:
-		case OP_SETPROPS:
-		case OP_DELPROPS:
+		case OP_GETPROP_S:
+		case OP_SETPROP_S:
+		case OP_DELPROP_S:
+		case OP_INITPROP_S:
 		case OP_CATCH:
 			pc(' ');
 			ps(F->strtab[*p++]);
 			break;
 
-		case OP_NUMBER_X:
+		case OP_NUMBER_N:
+		case OP_INITPROP_N:
 		case OP_CALL:
 		case OP_NEW:
 		case OP_JUMP:
--- a/jsrun.c
+++ b/jsrun.c
@@ -688,7 +688,7 @@
 
 		case OP_NUMBER_0: js_pushnumber(J, 0); break;
 		case OP_NUMBER_1: js_pushnumber(J, 1); break;
-		case OP_NUMBER_X: js_pushnumber(J, *pc++); break;
+		case OP_NUMBER_N: js_pushnumber(J, *pc++); break;
 		case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break;
 		case OP_STRING: js_pushliteral(J, ST[*pc++]); break;
 
@@ -733,6 +733,28 @@
 			js_pushboolean(J, b);
 			break;
 
+		case OP_INITPROP:
+			str = js_tostring(J, -2);
+			obj = js_toobject(J, -3);
+			jsR_setproperty(J, obj, str, -1);
+			js_pop(J, 2);
+			break;
+
+		case OP_INITPROP_S:
+			str = ST[*pc++];
+			obj = js_toobject(J, -2);
+			jsR_setproperty(J, obj, str, -1);
+			js_pop(J, 1);
+			break;
+
+		case OP_INITPROP_N:
+			js_pushnumber(J, *pc++);
+			str = js_tostring(J, -2);
+			obj = js_toobject(J, -3);
+			jsR_setproperty(J, obj, str, -1);
+			js_pop(J, 2);
+			break;
+
 		case OP_GETPROP:
 			str = js_tostring(J, -1);
 			obj = js_toobject(J, -2);
@@ -740,7 +762,7 @@
 			js_rot3pop2(J);
 			break;
 
-		case OP_GETPROPS:
+		case OP_GETPROP_S:
 			str = ST[*pc++];
 			obj = js_toobject(J, -1);
 			jsR_getproperty(J, obj, str);
@@ -748,13 +770,13 @@
 			break;
 
 		case OP_SETPROP:
-			obj = js_toobject(J, -3);
 			str = js_tostring(J, -2);
+			obj = js_toobject(J, -3);
 			jsR_setproperty(J, obj, str, -1);
 			js_rot3pop2(J);
 			break;
 
-		case OP_SETPROPS:
+		case OP_SETPROP_S:
 			str = ST[*pc++];
 			obj = js_toobject(J, -2);
 			jsR_setproperty(J, obj, str, -1);
@@ -762,13 +784,13 @@
 			break;
 
 		case OP_DELPROP:
-			obj = js_toobject(J, -2);
 			str = js_tostring(J, -1);
+			obj = js_toobject(J, -2);
 			jsR_delproperty(J, obj, str);
 			js_pop(J, 2);
 			break;
 
-		case OP_DELPROPS:
+		case OP_DELPROP_S:
 			str = ST[*pc++];
 			obj = js_toobject(J, -1);
 			jsR_delproperty(J, obj, str);