Unary postfix fixes

This commit is contained in:
dcodeIO 2017-12-03 01:18:35 +01:00
parent eaf9253b96
commit 032ae379cd
7 changed files with 310 additions and 15 deletions

View File

@ -1330,7 +1330,7 @@ export class Compiler extends DiagnosticEmitter {
compileAssignment(expression: Expression, valueExpression: Expression, contextualType: Type): ExpressionRef {
this.currentType = this.determineExpressionType(expression, contextualType);
return this.compileAssignmentWithValue(expression, this.compileExpression(valueExpression, this.currentType), contextualType != Type.void);
return this.compileAssignmentWithValue(expression, this.compileExpression(valueExpression, this.currentType, ConversionKind.IMPLICIT), contextualType != Type.void);
}
compileAssignmentWithValue(expression: Expression, valueWithCorrectType: ExpressionRef, tee: bool = false): ExpressionRef {
@ -1773,33 +1773,52 @@ export class Compiler extends DiagnosticEmitter {
compileUnaryPostfixExpression(expression: UnaryPostfixExpression, contextualType: Type): ExpressionRef {
const operator: Token = expression.operator;
// make a getter for the expression (also obtains the type)
const getValue: ExpressionRef = this.compileExpression(expression.expression, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT);
// use a temp local for the intermediate value
const tempLocal: Local = this.currentFunction.addLocal(this.currentType);
let op: BinaryOp;
let nativeType: NativeType;
let nativeOne: ExpressionRef;
if (contextualType == Type.f32) {
if (tempLocal.type == Type.f32) {
op = operator == Token.PLUS_PLUS ? BinaryOp.AddF32 : BinaryOp.SubF32;
nativeType = NativeType.F32;
nativeOne = this.module.createF32(1);
} else if (contextualType == Type.f64) {
} else if (tempLocal.type == Type.f64) {
op = operator == Token.PLUS_PLUS ? BinaryOp.AddF64 : BinaryOp.SubF64;
nativeType = NativeType.F64;
nativeOne = this.module.createF64(1);
} else if (contextualType.isLongInteger) {
} else if (tempLocal.type.isLongInteger) {
op = operator == Token.PLUS_PLUS ? BinaryOp.AddI64 : BinaryOp.SubI64;
nativeType = NativeType.I64;
nativeOne = this.module.createI64(1, 0);
} else {
op = operator == Token.PLUS_PLUS ? BinaryOp.AddI32 : BinaryOp.SubI32;
nativeType = NativeType.I32;
nativeOne = this.module.createI32(1);
}
const getValue: ExpressionRef = this.compileExpression(expression.expression, contextualType);
const setValue: ExpressionRef = this.compileAssignmentWithValue(expression.expression, this.module.createBinary(op, getValue, nativeOne), false); // reports
// make a setter that sets the new value (temp value +/- 1)
const setValue: ExpressionRef = this.compileAssignmentWithValue(expression.expression,
this.module.createBinary(op,
this.module.createGetLocal(tempLocal.index, nativeType),
nativeOne
), false
);
// NOTE: can't preemptively tee_local the return value on the stack because binaryen expects
// this to be well-formed. becomes a tee_local when optimizing, though.
this.currentType = tempLocal.type;
return this.module.createBlock(null, [
getValue,
setValue
this.module.createSetLocal(tempLocal.index, getValue), // +++ this.module.createTeeLocal(tempLocal.index, getValue),
setValue,
this.module.createGetLocal(tempLocal.index, nativeType) // ---
], nativeType);
}

View File

@ -0,0 +1,19 @@
var binaryen = require("binaryen");
// "non-final block elements returning a value must be drop()ed"
// "0 == 0: block with value must not have last element that is none, on"
var mod = new binaryen.Module();
var funcType = mod.addFunctionType("i", binaryen.i32, []);
var func = mod.addFunction("test", funcType, [ binaryen.i32 ],
mod.block("", [
mod.teeLocal(0, mod.i32.const(1)),
mod.nop()
], binaryen.i32)
);
mod.addExport("test", func);
console.log(mod.emitText());
if (!mod.validate())
console.log("-> does not validate");

View File

@ -44,3 +44,5 @@ true;
false;
NaN;
Infinity;
<f32>NaN;
<f32>Infinity;

View File

@ -143,6 +143,12 @@
(drop
(f64.const inf)
)
(drop
(f32.const nan:0x400000)
)
(drop
(f32.const inf)
)
)
)
(;

View File

@ -5,7 +5,6 @@
+1.25;
-1.25;
!1.25;
// ~1.25;
let i: i32 = 0;
@ -15,6 +14,8 @@ let i: i32 = 0;
~i;
++i;
--i;
i++;
i--;
i = +1;
i = -1;
@ -26,6 +27,8 @@ i = !i;
i = ~i;
i = ++i;
i = --i;
i = i++;
i = i--;
let I: i64 = 0;
@ -35,6 +38,8 @@ let I: i64 = 0;
~I;
++I;
--I;
I++;
I--;
I = +1;
I = -1;
@ -46,43 +51,47 @@ I = !I;
I = ~I;
I = ++I;
I = --I;
I = I++;
I = I--;
let f: f32 = 0;
+f;
-f;
!f;
// ~f;
++f;
--f;
f++;
f--;
f = +1.25;
f = -1.25;
i = !1.25;
// i = ~1.25;
f = +f;
f = -f;
i = !f;
// i = ~f;
f = ++f;
f = --f;
f = f++;
f = f--;
let F: f64 = 0;
+F;
-F;
!F;
// ~F;
++F;
--F;
F++;
F--;
F = +1.25;
F = -1.25;
I = !1.25;
// I = ~1.25;
F = +F;
F = -F;
I = !F;
// I = ~F;
F = ++F;
F = --F;
F = F++;
F = F--;

View File

@ -9,6 +9,22 @@
(export "memory" (memory $0))
(start $start)
(func $start (; 0 ;) (type $v)
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i32)
(local $4 i64)
(local $5 i64)
(local $6 i64)
(local $7 i64)
(local $8 f32)
(local $9 f32)
(local $10 f32)
(local $11 f32)
(local $12 f64)
(local $13 f64)
(local $14 f64)
(local $15 f64)
(drop
(i32.const 1)
)
@ -75,6 +91,34 @@
(i32.const 1)
)
)
(drop
(block (result i32)
(set_local $0
(get_global $unary/i)
)
(set_global $unary/i
(i32.add
(get_local $0)
(i32.const 1)
)
)
(get_local $0)
)
)
(drop
(block (result i32)
(set_local $1
(get_global $unary/i)
)
(set_global $unary/i
(i32.sub
(get_local $1)
(i32.const 1)
)
)
(get_local $1)
)
)
(set_global $unary/i
(i32.const 1)
)
@ -137,6 +181,34 @@
(get_global $unary/i)
)
)
(set_global $unary/i
(block (result i32)
(set_local $2
(get_global $unary/i)
)
(set_global $unary/i
(i32.add
(get_local $2)
(i32.const 1)
)
)
(get_local $2)
)
)
(set_global $unary/i
(block (result i32)
(set_local $3
(get_global $unary/i)
)
(set_global $unary/i
(i32.sub
(get_local $3)
(i32.const 1)
)
)
(get_local $3)
)
)
(drop
(get_global $unary/I)
)
@ -169,6 +241,34 @@
(i64.const 1)
)
)
(drop
(block (result i64)
(set_local $4
(get_global $unary/I)
)
(set_global $unary/I
(i64.add
(get_local $4)
(i64.const 1)
)
)
(get_local $4)
)
)
(drop
(block (result i64)
(set_local $5
(get_global $unary/I)
)
(set_global $unary/I
(i64.sub
(get_local $5)
(i64.const 1)
)
)
(get_local $5)
)
)
(set_global $unary/I
(i64.const 1)
)
@ -235,6 +335,34 @@
(get_global $unary/I)
)
)
(set_global $unary/I
(block (result i64)
(set_local $6
(get_global $unary/I)
)
(set_global $unary/I
(i64.add
(get_local $6)
(i64.const 1)
)
)
(get_local $6)
)
)
(set_global $unary/I
(block (result i64)
(set_local $7
(get_global $unary/I)
)
(set_global $unary/I
(i64.sub
(get_local $7)
(i64.const 1)
)
)
(get_local $7)
)
)
(drop
(get_global $unary/f)
)
@ -261,6 +389,34 @@
(f32.const 1)
)
)
(drop
(block (result f32)
(set_local $8
(get_global $unary/f)
)
(set_global $unary/f
(f32.add
(get_local $8)
(f32.const 1)
)
)
(get_local $8)
)
)
(drop
(block (result f32)
(set_local $9
(get_global $unary/f)
)
(set_global $unary/f
(f32.sub
(get_local $9)
(f32.const 1)
)
)
(get_local $9)
)
)
(set_global $unary/f
(f32.const 1.25)
)
@ -311,6 +467,34 @@
(get_global $unary/f)
)
)
(set_global $unary/f
(block (result f32)
(set_local $10
(get_global $unary/f)
)
(set_global $unary/f
(f32.add
(get_local $10)
(f32.const 1)
)
)
(get_local $10)
)
)
(set_global $unary/f
(block (result f32)
(set_local $11
(get_global $unary/f)
)
(set_global $unary/f
(f32.sub
(get_local $11)
(f32.const 1)
)
)
(get_local $11)
)
)
(drop
(get_global $unary/F)
)
@ -337,6 +521,34 @@
(f64.const 1)
)
)
(drop
(block (result f64)
(set_local $12
(get_global $unary/F)
)
(set_global $unary/F
(f64.add
(get_local $12)
(f64.const 1)
)
)
(get_local $12)
)
)
(drop
(block (result f64)
(set_local $13
(get_global $unary/F)
)
(set_global $unary/F
(f64.sub
(get_local $13)
(f64.const 1)
)
)
(get_local $13)
)
)
(set_global $unary/F
(f64.const 1.25)
)
@ -391,6 +603,34 @@
(get_global $unary/F)
)
)
(set_global $unary/F
(block (result f64)
(set_local $14
(get_global $unary/F)
)
(set_global $unary/F
(f64.add
(get_local $14)
(f64.const 1)
)
)
(get_local $14)
)
)
(set_global $unary/F
(block (result f64)
(set_local $15
(get_global $unary/F)
)
(set_global $unary/F
(f64.sub
(get_local $15)
(f64.const 1)
)
)
(get_local $15)
)
)
)
)
(;