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",