1
0
mirror of https://github.com/fluencelabs/assemblyscript synced 2025-06-19 01:41:30 +00:00

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

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

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

File diff suppressed because it is too large Load Diff

@ -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; // i8
badByte += 1; {
assert(badByte == 0); let val: i8 = 127;
let ctx: i8;
var anotherBadByte: u8 = 0xFF; val++;
var badIncrementer: u8 = 1; assert(val == -128);
anotherBadByte += badIncrementer;
assert(anotherBadByte == 0);
function local(): void { val--;
var badByte: u8 = 0xFF; assert(val == 127);
badByte += 1;
assert(badByte == 0);
var anotherBadByte: u8 = 0xFF; ctx = val++;
var badIncrementer: u8 = 1; assert(val == -128);
anotherBadByte += badIncrementer;
assert(anotherBadByte == 0); 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 { val++;
store<u8>(0, 0xff); assert(val == -32768);
return load<u8>(0);
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(); // u8
valueU8 += 1; {
assert(valueU8 == 0); let val: u8 = 0;
let ctx: u8;
function storeU8FFadd1(val: u8): void { val--;
store<u8>(0, val); assert(val == 0xff);
assert(load<u8>(0) == 0);
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; // u16
storeU8FFadd1(valueU8 + 1); {
let val: u16 = 0;
let ctx: u16;
store<u8>(0, valueU8 + 1); val--;
assert(load<u8>(0) == 0); assert(val == 0xffff);
store<u8>(0, ++valueU8); val++;
assert(load<u8>(0) == 0); assert(val == 0);
assert(valueU8 == 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