Fix increment/decrement not wrapping small ints in simplified case, see #26

This commit is contained in:
dcodeIO 2018-02-15 09:22:46 +01:00
parent d31e484b15
commit f729444320
6 changed files with 2197 additions and 516 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3343,32 +3343,42 @@ export class Compiler extends DiagnosticEmitter {
throw new Error("unary postfix operator expected");
}
var setValue: ExpressionRef;
var tempLocal: Local | null = null;
// simplify if dropped anyway
if (contextualType == Type.void)
return this.compileAssignmentWithValue(expression.operand,
this.module.createBinary(op,
getValue,
nativeOne
), false
if (contextualType == Type.void) {
setValue = this.module.createBinary(op,
getValue,
nativeOne
);
// use a temp local for the intermediate value and prepare a setter
var tempLocal = this.currentFunction.getTempLocal(this.currentType);
var setValue = this.module.createBinary(op,
this.module.createGetLocal(tempLocal.index, nativeType),
nativeOne
);
// otherwise use a temp local for the intermediate value
} else {
tempLocal = this.currentFunction.getTempLocal(this.currentType);
setValue = this.module.createBinary(op,
this.module.createGetLocal(tempLocal.index, nativeType),
nativeOne
);
}
if (possiblyOverflows) {
assert(this.currentType.is(TypeFlags.SMALL | TypeFlags.INTEGER));
setValue = makeSmallIntegerWrap(setValue, this.currentType, this.module);
}
setValue = this.compileAssignmentWithValue(expression.operand, setValue, false); // sets currentType = void
this.currentType = tempLocal.type;
this.currentFunction.freeTempLocal(tempLocal);
if (contextualType == Type.void) {
assert(!tempLocal);
return setValue;
}
this.currentType = assert(tempLocal).type;
this.currentFunction.freeTempLocal(<Local>tempLocal);
return this.module.createBlock(null, [
this.module.createSetLocal(tempLocal.index, getValue),
this.module.createSetLocal((<Local>tempLocal).index, getValue),
setValue,
this.module.createGetLocal(tempLocal.index, nativeType)
this.module.createGetLocal((<Local>tempLocal).index, nativeType)
], nativeType);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +1,130 @@
// see also: https://github.com/AssemblyScript/assemblyscript/issues/26
// becomes simplified: val++
// uses a temp. local: ctx = val++
var badByte: u8 = 0xFF;
badByte += 1;
assert(badByte == 0);
// i8
{
let val: i8 = 127;
let ctx: i8;
var anotherBadByte: u8 = 0xFF;
var badIncrementer: u8 = 1;
anotherBadByte += badIncrementer;
assert(anotherBadByte == 0);
val++;
assert(val == -128);
function local(): void {
var badByte: u8 = 0xFF;
badByte += 1;
assert(badByte == 0);
val--;
assert(val == 127);
var anotherBadByte: u8 = 0xFF;
var badIncrementer: u8 = 1;
anotherBadByte += badIncrementer;
assert(anotherBadByte == 0);
ctx = val++;
assert(val == -128);
ctx = val--;
assert(val == 127);
++val;
assert(val == -128);
--val;
assert(val == 127);
ctx = ++val;
assert(val == -128);
ctx = --val;
assert(val == 127);
assert(val + 1 == -128);
}
local();
// i16
{
let val: i16 = 32767;
let ctx: i16;
function loadU8FF(): u8 {
store<u8>(0, 0xff);
return load<u8>(0);
val++;
assert(val == -32768);
val--;
assert(val == 32767);
ctx = val++;
assert(val == -32768);
ctx = val--;
assert(val == 32767);
++val;
assert(val == -32768);
--val;
assert(val == 32767);
ctx = ++val;
assert(val == -32768);
ctx = --val;
assert(val == 32767);
assert(val + 1 == -32768);
}
var valueU8: u8 = loadU8FF();
valueU8 += 1;
assert(valueU8 == 0);
// u8
{
let val: u8 = 0;
let ctx: u8;
function storeU8FFadd1(val: u8): void {
store<u8>(0, val);
assert(load<u8>(0) == 0);
val--;
assert(val == 0xff);
val++;
assert(val == 0);
ctx = val--;
assert(val == 0xff);
ctx = val++;
assert(val == 0);
--val;
assert(val == 0xff);
++val;
assert(val == 0);
ctx = --val;
assert(val == 0xff);
ctx = ++val;
assert(val == 0);
assert(val - 1 == 0xff);
}
valueU8 = 0xFF;
storeU8FFadd1(valueU8 + 1);
// u16
{
let val: u16 = 0;
let ctx: u16;
store<u8>(0, valueU8 + 1);
assert(load<u8>(0) == 0);
val--;
assert(val == 0xffff);
store<u8>(0, ++valueU8);
assert(load<u8>(0) == 0);
assert(valueU8 == 0);
val++;
assert(val == 0);
ctx = val--;
assert(val == 0xffff);
ctx = val++;
assert(val == 0);
--val;
assert(val == 0xffff);
++val;
assert(val == 0);
ctx = --val;
assert(val == 0xffff);
ctx = ++val;
assert(val == 0);
assert(val - 1 == 0xffff);
}

File diff suppressed because it is too large Load Diff