addUpvalue() now checks for UInt overflows

This commit is contained in:
CPunch 2021-01-01 23:14:47 -06:00
parent 7e9b61e018
commit 0b415ad49d

View File

@ -298,9 +298,14 @@ static void addLocal(CParseState *pstate, CToken name) {
local->isCaptured = false; local->isCaptured = false;
} }
static int addUpvalue(CCompilerState *ccstate, uint8_t indx, bool isLocal) { static int addUpvalue(CParseState *pstate, CCompilerState *ccstate, uint8_t indx, bool isLocal) {
int upvals = ccstate->function->upvals; int upvals = ccstate->function->upvals;
if (upvals > UINT8_MAX) {
error(pstate, "UInt overflow! Too many upvalues in scope!");
return -1;
}
// check and make sure we haven't already captured it // check and make sure we haven't already captured it
for (int i = 0; i < upvals; i++) { for (int i = 0; i < upvals; i++) {
Upvalue *upval = &ccstate->upvalues[i]; Upvalue *upval = &ccstate->upvalues[i];
@ -308,8 +313,6 @@ static int addUpvalue(CCompilerState *ccstate, uint8_t indx, bool isLocal) {
return i; return i;
} }
// TODO: throw error if upvals >= UINT8_MAX
ccstate->upvalues[upvals].index = indx; ccstate->upvalues[upvals].index = indx;
ccstate->upvalues[upvals].isLocal = isLocal; ccstate->upvalues[upvals].isLocal = isLocal;
return ccstate->function->upvals++; return ccstate->function->upvals++;
@ -327,19 +330,19 @@ static int getLocal(CCompilerState *ccstate, CToken *name) {
return -1; return -1;
} }
static int getUpvalue(CCompilerState *ccstate, CToken *name) { static int getUpvalue(CParseState *pstate, CCompilerState *ccstate, CToken *name) {
if (ccstate->enclosing == NULL) // there's no upvalues to lookup! if (ccstate->enclosing == NULL) // there's no upvalues to lookup!
return -1; return -1;
int local = getLocal(ccstate->enclosing, name); int local = getLocal(ccstate->enclosing, name);
if (local != -1) { if (local != -1) {
ccstate->enclosing->locals[local].isCaptured = true; ccstate->enclosing->locals[local].isCaptured = true;
return addUpvalue(ccstate, local, true); return addUpvalue(pstate, ccstate, local, true);
} }
int upval = getUpvalue(ccstate->enclosing, name); int upval = getUpvalue(pstate, ccstate->enclosing, name);
if (upval != -1) if (upval != -1)
return addUpvalue(ccstate, upval, false); return addUpvalue(pstate, ccstate, upval, false);
return -1; // failed! return -1; // failed!
} }
@ -470,7 +473,7 @@ static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool
opGet = OP_GETLOCAL; opGet = OP_GETLOCAL;
opSet = OP_SETLOCAL; opSet = OP_SETLOCAL;
inc = OP_INCLOCAL; inc = OP_INCLOCAL;
} else if ((arg = getUpvalue(pstate->compiler, &name)) != -1) { } else if ((arg = getUpvalue(pstate, pstate->compiler, &name)) != -1) {
opGet = OP_GETUPVAL; opGet = OP_GETUPVAL;
opSet = OP_SETUPVAL; opSet = OP_SETUPVAL;
inc = OP_INCUPVAL; inc = OP_INCUPVAL;
@ -564,7 +567,7 @@ static void call_(CParseState *pstate, bool canAssign) {
valuePopped(pstate, argCount + 1); // all of these values will be popped off the stack when returned (+1 for the function) valuePopped(pstate, argCount + 1); // all of these values will be popped off the stack when returned (+1 for the function)
writeu8(pstate, OP_CALL); writeu8(pstate, OP_CALL);
writeu8(pstate, argCount); writeu8(pstate, argCount);
writeu8(pstate, pstate->compiler->expectedValues); // TODO writeu8(pstate, pstate->compiler->expectedValues);
valuePushed(pstate, pstate->compiler->expectedValues); valuePushed(pstate, pstate->compiler->expectedValues);
} }
@ -619,7 +622,7 @@ static void dot(CParseState *pstate, bool canAssign) {
uint8_t args = parseArguments(pstate); uint8_t args = parseArguments(pstate);
writeu8(pstate, OP_INVOKE); writeu8(pstate, OP_INVOKE);
writeu8(pstate, args); writeu8(pstate, args);
writeu8(pstate, pstate->compiler->expectedValues); // TODO writeu8(pstate, pstate->compiler->expectedValues);
valuePopped(pstate, args+1); // args + function valuePopped(pstate, args+1); // args + function
valuePushed(pstate, pstate->compiler->expectedValues); valuePushed(pstate, pstate->compiler->expectedValues);
} else { } else {
@ -731,7 +734,7 @@ static void increment(CParseState *pstate, int val) {
if (arg != -1) { if (arg != -1) {
// we found it in out local table! // we found it in out local table!
op = OP_INCLOCAL; op = OP_INCLOCAL;
} else if ((arg = getUpvalue(pstate->compiler, &name)) != -1) { } else if ((arg = getUpvalue(pstate, pstate->compiler, &name)) != -1) {
op = OP_INCUPVAL; op = OP_INCUPVAL;
} else { } else {
// local & upvalue wasn't found, assume it's a global! // local & upvalue wasn't found, assume it's a global!
@ -1480,7 +1483,7 @@ CObjFunction* cosmoP_compileString(CState *state, const char *source, const char
endCompiler(&parser); endCompiler(&parser);
freeParseState(&parser); freeParseState(&parser);
// the VM still expects a result on the stack TODO: push the error string to the stack // the VM still expects a result on the stack
cosmoV_pushValue(state, cosmoV_newNil()); cosmoV_pushValue(state, cosmoV_newNil());
cosmoM_unfreezeGC(state); cosmoM_unfreezeGC(state);
return NULL; return NULL;