mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-22 07:20:05 +00:00
addUpvalue() now checks for UInt overflows
This commit is contained in:
parent
7e9b61e018
commit
0b415ad49d
27
src/cparse.c
27
src/cparse.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user