shithub: libmujs

Download patch

ref: bb6a85a31c46f82577bacc1cc21d3c3b9df02b82
parent: 32f3e71169acdf4955b859f68c128b2c6c3635f5
author: Tor Andersson <tor.andersson@artifex.com>
date: Thu Jan 5 10:32:17 EST 2023

Issue #171: Compile sparse array initializers correctly.

Don't initialize the holes with "undefined".
Elided array entries should be skipped altogether.

--- a/astnames.h
+++ b/astnames.h
@@ -5,7 +5,7 @@
 "exp_number",
 "exp_string",
 "exp_regexp",
-"exp_undef",
+"exp_elision",
 "exp_null",
 "exp_true",
 "exp_false",
--- a/jscompile.c
+++ b/jscompile.c
@@ -284,8 +284,12 @@
 {
 	while (list) {
 		emitline(J, F, list->a);
-		cexp(J, F, list->a);
-		emit(J, F, OP_INITARRAY);
+		if (list->a->type == EXP_ELISION) {
+			emit(J, F, OP_SKIPARRAY);
+		} else {
+			cexp(J, F, list->a);
+			emit(J, F, OP_INITARRAY);
+		}
 		list = list->b;
 	}
 }
@@ -580,9 +584,7 @@
 		emitline(J, F, exp);
 		emitnumber(J, F, exp->number);
 		break;
-	case EXP_UNDEF:
-		emitline(J, F, exp);
-		emit(J, F, OP_UNDEF);
+	case EXP_ELISION:
 		break;
 	case EXP_NULL:
 		emitline(J, F, exp);
--- a/jsi.h
+++ b/jsi.h
@@ -578,7 +578,7 @@
 	EXP_REGEXP,
 
 	/* literals */
-	EXP_UNDEF, /* for array elisions */
+	EXP_ELISION, /* for array elisions */
 	EXP_NULL,
 	EXP_TRUE,
 	EXP_FALSE,
@@ -743,6 +743,7 @@
 
 	OP_IN,		/* <name> <obj> -- <exists?> */
 
+	OP_SKIPARRAY,	/* <obj> -- <obj> */
 	OP_INITARRAY,	/* <obj> <val> -- <obj> */
 	OP_INITPROP,	/* <obj> <key> <val> -- <obj> */
 	OP_INITGETTER,	/* <obj> <key> <closure> -- <obj> */
--- a/jsparse.c
+++ b/jsparse.c
@@ -187,7 +187,7 @@
 {
 	int line = J->lexline;
 	if (J->lookahead == ',')
-		return EXP0(UNDEF);
+		return EXP0(ELISION);
 	return assignment(J, 0);
 }
 
--- a/jsrun.c
+++ b/jsrun.c
@@ -1690,6 +1690,9 @@
 			js_pushboolean(J, b);
 			break;
 
+		case OP_SKIPARRAY:
+			js_setlength(J, -1, js_getlength(J, -1) + 1);
+			break;
 		case OP_INITARRAY:
 			js_setindex(J, -2, js_getlength(J, -2));
 			break;
--- a/opnames.h
+++ b/opnames.h
@@ -25,6 +25,7 @@
 "setvar",
 "delvar",
 "in",
+"skiparray",
 "initarray",
 "initprop",
 "initgetter",
--- a/pp.c
+++ b/pp.c
@@ -209,7 +209,7 @@
 	case EXP_NUMBER:
 	case EXP_STRING:
 	case EXP_REGEXP:
-	case EXP_UNDEF:
+	case EXP_ELISION:
 	case EXP_NULL:
 	case EXP_TRUE:
 	case EXP_FALSE:
@@ -415,7 +415,7 @@
 	case EXP_STRING: pstr(exp->string); break;
 	case EXP_REGEXP: pregexp(exp->string, exp->number); break;
 
-	case EXP_UNDEF: break;
+	case EXP_ELISION: ps("elision"); break;
 	case EXP_NULL: ps("null"); break;
 	case EXP_TRUE: ps("true"); break;
 	case EXP_FALSE: ps("false"); break;