shithub: libmujs

Download patch

ref: 8a659b28210220f6e29d5ed671e2c22adde9a7c1
parent: a381ba196327a606bfe0849436a8955d0cb729fc
author: Tor Andersson <tor.andersson@artifex.com>
date: Thu Oct 9 11:08:02 EDT 2014

Typedef instruction and check addresses and literals for overflow when emitting code.

--- a/jscompile.c
+++ b/jscompile.c
@@ -53,6 +53,8 @@
 
 static void emitraw(JF, int value)
 {
+	if (value != (js_Instruction)value)
+		js_syntaxerror(J, "integer overflow in instruction coding");
 	if (F->codelen >= F->codecap) {
 		F->codecap = F->codecap ? F->codecap * 2 : 64;
 		F->code = js_realloc(J, F->code, F->codecap * sizeof *F->code);
@@ -141,9 +143,12 @@
 			emit(J, F, OP_NEG);
 	} else if (num == 1) {
 		emit(J, F, OP_NUMBER_1);
-	} else if (num == (short)num) {
-		emit(J, F, OP_NUMBER_N);
-		emitraw(J, F, (short)num);
+	} else if (num == (js_Instruction)num) {
+		emit(J, F, OP_NUMBER_POS);
+		emitraw(J, F, (js_Instruction)num);
+	} else if (num < 0 && -num == (js_Instruction)(-num)) {
+		emit(J, F, OP_NUMBER_NEG);
+		emitraw(J, F, (js_Instruction)(-num));
 	} else {
 		emit(J, F, OP_NUMBER);
 		emitraw(J, F, addnumber(J, F, num));
@@ -186,17 +191,21 @@
 static void emitjumpto(JF, int opcode, int dest)
 {
 	emit(J, F, opcode);
+	if (dest != (js_Instruction)dest)
+		js_syntaxerror(J, "jump address integer overflow");
 	emitraw(J, F, dest);
 }
 
-static void label(JF, int inst)
+static void labelto(JF, int inst, int addr)
 {
-	F->code[inst] = F->codelen;
+	if (addr != (js_Instruction)addr)
+		js_syntaxerror(J, "jump address integer overflow");
+	F->code[inst] = addr;
 }
 
-static void labelto(JF, int inst, int addr)
+static void label(JF, int inst)
 {
-	F->code[inst] = addr;
+	labelto(J, F, inst, F->codelen);
 }
 
 /* Expressions */
@@ -248,10 +257,10 @@
 				cexp(J, F, kv->b);
 				emitstring(J, F, OP_INITPROP_S, prop->string);
 			} else if (prop->type == EXP_NUMBER) {
-				if (prop->number == (short)prop->number) {
+				if (prop->number == (js_Instruction)prop->number) {
 					cexp(J, F, kv->b);
 					emit(J, F, OP_INITPROP_N);
-					emitraw(J, F, (short)prop->number);
+					emitraw(J, F, (js_Instruction)prop->number);
 				} else {
 					emitnumber(J, F, prop->number);
 					cexp(J, F, kv->b);
--- a/jscompile.h
+++ b/jscompile.h
@@ -12,7 +12,8 @@
 
 	OP_NUMBER_0,	/* -- 0 */
 	OP_NUMBER_1,	/* -- 1 */
-	OP_NUMBER_N,	/* -K- K */
+	OP_NUMBER_POS,	/* -K- K */
+	OP_NUMBER_NEG,	/* -K- -K */
 
 	OP_NUMBER,	/* -N- <number> */
 	OP_STRING,	/* -S- <string> */
@@ -124,7 +125,7 @@
 	unsigned int arguments;
 	unsigned int numparams;
 
-	short *code;
+	js_Instruction *code;
 	unsigned int codecap, codelen;
 
 	js_Function **funtab;
--- a/jsdump.c
+++ b/jsdump.c
@@ -711,8 +711,8 @@
 
 void jsC_dumpfunction(js_State *J, js_Function *F)
 {
-	short *p = F->code;
-	short *end = F->code + F->codelen;
+	js_Instruction *p = F->code;
+	js_Instruction *end = F->code + F->codelen;
 	unsigned int i;
 
 	printf("%s(%d)\n", F->name, F->numparams);
@@ -764,7 +764,8 @@
 		case OP_GETLOCAL:
 		case OP_SETLOCAL:
 		case OP_DELLOCAL:
-		case OP_NUMBER_N:
+		case OP_NUMBER_POS:
+		case OP_NUMBER_NEG:
 		case OP_INITPROP_N:
 		case OP_CALL:
 		case OP_NEW:
--- a/jsi.h
+++ b/jsi.h
@@ -53,6 +53,9 @@
 #define JS_TRYLIMIT 64		/* exception stack size */
 #define JS_GCLIMIT 10000	/* run gc cycle every N allocations */
 
+/* instruction size -- change to unsigned int if you get integer overflow syntax errors */
+typedef unsigned short js_Instruction;
+
 /* String interning */
 
 const char *js_intern(js_State *J, const char *s);
@@ -95,10 +98,10 @@
 	js_Environment *E;
 	int envtop;
 	int top, bot;
-	short *pc;
+	js_Instruction *pc;
 };
 
-void js_savetry(js_State *J, short *pc);
+void js_savetry(js_State *J, js_Instruction *pc);
 
 #define js_trypc(J, PC) \
 	(js_savetry(J, PC), setjmp(J->trybuf[J->trylen++].buf))
--- a/jsrun.c
+++ b/jsrun.c
@@ -995,7 +995,7 @@
 
 /* Exceptions */
 
-void js_savetry(js_State *J, short *pc)
+void js_savetry(js_State *J, js_Instruction *pc)
 {
 	if (J->trylen == JS_TRYLIMIT)
 		js_error(J, "try: exception stack overflow");
@@ -1060,8 +1060,8 @@
 	js_Function **FT = F->funtab;
 	double *NT = F->numtab;
 	const char **ST = F->strtab;
-	short *pcstart = F->code;
-	short *pc = F->code;
+	js_Instruction *pcstart = F->code;
+	js_Instruction *pc = F->code;
 	enum js_OpCode opcode;
 	int offset;
 
@@ -1089,7 +1089,8 @@
 
 		case OP_NUMBER_0: js_pushnumber(J, 0); break;
 		case OP_NUMBER_1: js_pushnumber(J, 1); break;
-		case OP_NUMBER_N: js_pushnumber(J, *pc++); break;
+		case OP_NUMBER_POS: js_pushnumber(J, *pc++); break;
+		case OP_NUMBER_NEG: js_pushnumber(J, -(*pc++)); break;
 		case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break;
 		case OP_STRING: js_pushliteral(J, ST[*pc++]); break;
 
--- a/opnames.h
+++ b/opnames.h
@@ -6,7 +6,8 @@
 "rot4",
 "number_0",
 "number_1",
-"number_n",
+"number_pos",
+"number_neg",
 "number",
 "string",
 "closure",