clarify contextual flags a bit, rename to constraints

This commit is contained in:
dcode 2019-06-12 12:13:49 +02:00
parent e30fe7e3cb
commit 6a0277bf02
2 changed files with 261 additions and 261 deletions

View File

@ -5,7 +5,7 @@
import {
Compiler,
ContextualFlags,
Constraints,
RuntimeFeatures,
flatten
} from "./compiler";
@ -782,8 +782,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.i32, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.i32, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -873,8 +873,8 @@ export function compileCall(
checkArgsRequired(operands, 2, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.i32, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.i32, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -883,7 +883,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
let expr: ExpressionRef;
switch (type.kind) {
case TypeKind.I8:
@ -934,8 +934,8 @@ export function compileCall(
checkArgsRequired(operands, 2, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.i32, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.i32, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -944,7 +944,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
let expr: ExpressionRef;
switch (type.kind) {
case TypeKind.I8:
@ -995,8 +995,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.f64, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1120,8 +1120,8 @@ export function compileCall(
checkArgsRequired(operands, 2, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.f64, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1130,7 +1130,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT | ContextualFlags.WRAP);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP);
let op: BinaryOp;
switch (type.kind) {
case TypeKind.I8:
@ -1190,8 +1190,8 @@ export function compileCall(
checkArgsRequired(operands, 2, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.f64, Constraints.MUST_WRAP);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1200,7 +1200,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT | ContextualFlags.WRAP);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP);
let op: BinaryOp;
switch (type.kind) {
case TypeKind.I8:
@ -1261,8 +1261,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.NONE);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, Constraints.NONE);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1312,8 +1312,8 @@ export function compileCall(
checkArgsRequired(operands, 2, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.NONE);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, Constraints.NONE);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1322,7 +1322,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
let op: BinaryOp;
switch (type.kind) {
// TODO: does an integer version make sense?
@ -1344,8 +1344,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.NONE);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, Constraints.NONE);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1407,13 +1407,13 @@ export function compileCall(
switch (type.kind) {
case TypeKind.I32:
case TypeKind.U32: {
let arg0 = compiler.compileExpression(operands[0], Type.f32, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.f32, Constraints.CONV_IMPLICIT);
expr = module.unary(UnaryOp.ReinterpretF32, arg0);
break;
}
case TypeKind.I64:
case TypeKind.U64: {
let arg0 = compiler.compileExpression(operands[0], Type.f64, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.f64, Constraints.CONV_IMPLICIT);
expr = module.unary(UnaryOp.ReinterpretF64, arg0);
break;
}
@ -1423,7 +1423,7 @@ export function compileCall(
compiler.options.isWasm64
? Type.f64
: Type.f32,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
expr = module.unary(
compiler.options.isWasm64
@ -1434,12 +1434,12 @@ export function compileCall(
break;
}
case TypeKind.F32: {
let arg0 = compiler.compileExpression(operands[0], Type.i32, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.i32, Constraints.CONV_IMPLICIT);
expr = module.unary(UnaryOp.ReinterpretI32, arg0);
break;
}
case TypeKind.F64: {
let arg0 = compiler.compileExpression(operands[0], Type.i64, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.i64, Constraints.CONV_IMPLICIT);
expr = module.unary(UnaryOp.ReinterpretI64, arg0);
break;
}
@ -1461,8 +1461,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.NONE);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, Constraints.NONE);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.currentType = type;
@ -1499,8 +1499,8 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, ContextualFlags.NONE);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.f64, Constraints.NONE);
let type = compiler.currentType;
if (type.is(TypeFlags.REFERENCE)) {
compiler.error(
@ -1562,7 +1562,7 @@ export function compileCall(
) ? contextualType : type;
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let numOperands = operands.length;
let immOffset = numOperands >= 2 ? evaluateImmediateOffset(operands[1], compiler) : 0; // reports
@ -1616,19 +1616,19 @@ export function compileCall(
let type = typeArguments![0];
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = isAsm
? compiler.compileExpression(operands[1],
contextualType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
: compiler.compileExpression(
operands[1],
type,
type.is(TypeFlags.INTEGER)
? ContextualFlags.NONE // no need to convert to small int (but now might result in a float)
: ContextualFlags.IMPLICIT
? Constraints.NONE // no need to convert to small int (but now might result in a float)
: Constraints.CONV_IMPLICIT
);
let inType = compiler.currentType;
if (
@ -1705,7 +1705,7 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let immOffset = operands.length == 2 ? evaluateImmediateOffset(operands[1], compiler) : 0; // reports
if (immOffset < 0) {
@ -1737,20 +1737,20 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = isAsm
? compiler.compileExpression(
operands[1],
contextualType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
: compiler.compileExpression(
operands[1],
type,
type.is(TypeFlags.INTEGER)
? ContextualFlags.NONE // no need to convert to small int (but now might result in a float)
: ContextualFlags.IMPLICIT
? Constraints.NONE // no need to convert to small int (but now might result in a float)
: Constraints.CONV_IMPLICIT
);
let inType = compiler.currentType;
if (
@ -1796,19 +1796,19 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = isAsm
? compiler.compileExpression(operands[1],
contextualType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
: compiler.compileExpression(
operands[1],
type,
type.is(TypeFlags.INTEGER)
? ContextualFlags.NONE // no need to convert to small int (but now might result in a float)
: ContextualFlags.IMPLICIT
? Constraints.NONE // no need to convert to small int (but now might result in a float)
: Constraints.CONV_IMPLICIT
);
let inType = compiler.currentType;
if (
@ -1861,24 +1861,24 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = isAsm
? compiler.compileExpression(operands[1],
contextualType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
: compiler.compileExpression(
operands[1],
type,
type.is(TypeFlags.INTEGER)
? ContextualFlags.NONE // no need to convert to small int (but now might result in a float)
: ContextualFlags.IMPLICIT
? Constraints.NONE // no need to convert to small int (but now might result in a float)
: Constraints.CONV_IMPLICIT
);
let inType = compiler.currentType;
let arg2 = compiler.compileExpression(operands[2],
inType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
if (
type.is(TypeFlags.INTEGER) &&
@ -1926,14 +1926,14 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = compiler.compileExpression(operands[1], type,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg2 = compiler.compileExpression(operands[2],
Type.i64,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
compiler.currentType = Type.i32;
return module.atomic_wait(arg0, arg1, arg2, type.toNativeType());
@ -1947,11 +1947,11 @@ export function compileCall(
) return module.unreachable();
let arg0 = compiler.compileExpression(operands[0],
compiler.options.usizeType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let arg1 = compiler.compileExpression(operands[1],
Type.i32,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
compiler.currentType = Type.i32;
return module.atomic_notify(arg0, arg1);
@ -1965,7 +1965,7 @@ export function compileCall(
checkArgsRequired(operands, 3, reportNode, compiler)
) return module.unreachable();
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT)
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT)
: compiler.compileExpression(operands[0], Type.auto);
let type = compiler.currentType;
if (!type.isAny(TypeFlags.VALUE | TypeFlags.REFERENCE)) {
@ -1975,7 +1975,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg1 = compiler.compileExpression(operands[1], type, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], type, Constraints.CONV_IMPLICIT);
let arg2 = compiler.makeIsTrueish(
compiler.compileExpression(operands[2], Type.bool),
compiler.currentType // ^
@ -2011,7 +2011,7 @@ export function compileCall(
checkArgsRequired(operands, 1, reportNode, compiler)
) return module.unreachable();
return module.host(HostOp.MemoryGrow, null, [
compiler.compileExpression(operands[0], Type.i32, ContextualFlags.IMPLICIT)
compiler.compileExpression(operands[0], Type.i32, Constraints.CONV_IMPLICIT)
]);
}
case BuiltinSymbols.memory_copy: { // memory.copy(dest: usize, src: usize: n: usize) -> void
@ -2027,9 +2027,9 @@ export function compileCall(
return compiler.compileCallDirect(instance, operands, reportNode);
}
let usizeType = compiler.options.usizeType;
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], usizeType, ContextualFlags.IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], usizeType, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], usizeType, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], usizeType, Constraints.CONV_IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], usizeType, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.void;
return module.memory_copy(arg0, arg1, arg2);
}
@ -2046,9 +2046,9 @@ export function compileCall(
return compiler.compileCallDirect(instance, operands, reportNode);
}
let usizeType = compiler.options.usizeType;
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.u8, ContextualFlags.IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], usizeType, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], usizeType, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.u8, Constraints.CONV_IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], usizeType, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.void;
return module.memory_fill(arg0, arg1, arg2);
}
@ -2085,8 +2085,8 @@ export function compileCall(
return module.unreachable();
}
let arg0 = typeArguments
? compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT | ContextualFlags.WRAP)
: compiler.compileExpression(operands[0], Type.bool, ContextualFlags.WRAP);
? compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP)
: compiler.compileExpression(operands[0], Type.bool, Constraints.MUST_WRAP);
let type = compiler.currentType;
compiler.currentType = type.nonNullableType;
@ -2333,7 +2333,7 @@ export function compileCall(
return module.unreachable();
}
compiler.currentType = classInstance.type;
return compiler.compileInstantiate(classInstance, operands, ContextualFlags.NONE, reportNode);
return compiler.compileInstantiate(classInstance, operands, Constraints.NONE, reportNode);
}
// === User-defined diagnostics ===============================================================
@ -2373,7 +2373,7 @@ export function compileCall(
compiler.currentType = Type.i8;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.i8, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.i8, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.i16: {
if (
@ -2383,7 +2383,7 @@ export function compileCall(
compiler.currentType = Type.i16;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.i16, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.i16, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.i32: {
if (
@ -2393,7 +2393,7 @@ export function compileCall(
compiler.currentType = Type.i32;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.i32, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.i32, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.i64: {
if (
@ -2403,7 +2403,7 @@ export function compileCall(
compiler.currentType = Type.i64;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.i64, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.i64, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.isize: {
let isizeType = compiler.options.isizeType;
@ -2414,7 +2414,7 @@ export function compileCall(
compiler.currentType = isizeType;
return module.unreachable();
}
return compiler.compileExpression(operands[0], isizeType, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], isizeType, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.u8: {
if (
@ -2424,7 +2424,7 @@ export function compileCall(
compiler.currentType = Type.u8;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.u8, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.u8, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.u16: {
if (
@ -2434,7 +2434,7 @@ export function compileCall(
compiler.currentType = Type.u16;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.u16, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.u16, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.u32: {
if (
@ -2444,7 +2444,7 @@ export function compileCall(
compiler.currentType = Type.u32;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.u32, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.u32, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.u64: {
if (
@ -2454,7 +2454,7 @@ export function compileCall(
compiler.currentType = Type.u64;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.u64, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.u64, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.usize: {
let usizeType = compiler.options.usizeType;
@ -2465,7 +2465,7 @@ export function compileCall(
compiler.currentType = usizeType;
return module.unreachable();
}
return compiler.compileExpression(operands[0], usizeType, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], usizeType, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.bool: {
if (
@ -2475,7 +2475,7 @@ export function compileCall(
compiler.currentType = Type.bool;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.bool, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.bool, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.f32: {
if (
@ -2485,7 +2485,7 @@ export function compileCall(
compiler.currentType = Type.f32;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.f32, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.f32, Constraints.CONV_EXPLICIT);
}
case BuiltinSymbols.f64: {
if (
@ -2495,7 +2495,7 @@ export function compileCall(
compiler.currentType = Type.f64;
return module.unreachable();
}
return compiler.compileExpression(operands[0], Type.f64, ContextualFlags.EXPLICIT);
return compiler.compileExpression(operands[0], Type.f64, Constraints.CONV_EXPLICIT);
}
// === SIMD ===================================================================================
@ -2514,7 +2514,7 @@ export function compileCall(
for (let i = 0; i < 16; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.i8, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.i8, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2543,7 +2543,7 @@ export function compileCall(
for (let i = 0; i < 8; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.i16, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.i16, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2572,7 +2572,7 @@ export function compileCall(
for (let i = 0; i < 4; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.i32, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.i32, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2601,7 +2601,7 @@ export function compileCall(
for (let i = 0; i < 2; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.i64, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.i64, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2632,7 +2632,7 @@ export function compileCall(
for (let i = 0; i < 4; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.f32, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.f32, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2661,7 +2661,7 @@ export function compileCall(
for (let i = 0; i < 2; ++i) {
let value = operands[i];
if (value) {
let expr = compiler.precomputeExpression(value, Type.f64, ContextualFlags.IMPLICIT);
let expr = compiler.precomputeExpression(value, Type.f64, Constraints.CONV_IMPLICIT);
if (getExpressionId(expr) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2723,7 +2723,7 @@ export function compileCall(
return module.unreachable();
}
}
let arg0 = compiler.compileExpression(operands[0], type, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], type, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.v128;
return module.unary(op, arg0);
}
@ -2770,8 +2770,8 @@ export function compileCall(
return module.unreachable();
}
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.precomputeExpression(operands[1], Type.u8, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.precomputeExpression(operands[1], Type.u8, Constraints.CONV_IMPLICIT);
compiler.currentType = type;
if (getExpressionId(arg1) != ExpressionId.Const) {
compiler.error(
@ -2838,8 +2838,8 @@ export function compileCall(
return module.unreachable();
}
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.precomputeExpression(operands[1], Type.u8, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.precomputeExpression(operands[1], Type.u8, Constraints.CONV_IMPLICIT);
if (getExpressionId(arg1) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -2858,7 +2858,7 @@ export function compileCall(
);
return module.unreachable();
}
let arg2 = compiler.compileExpression(operands[2], type, ContextualFlags.IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], type, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.v128;
return module.simd_replace(op, arg0, idx, arg2);
}
@ -2910,13 +2910,13 @@ export function compileCall(
return module.unreachable();
}
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
let mask = new Uint8Array(16);
let maxIdx = (laneCount << 1) - 1;
for (let i = 0; i < laneCount; ++i) {
let operand = operands[2 + i];
let argN = compiler.precomputeExpression(operand, Type.u8, ContextualFlags.IMPLICIT);
let argN = compiler.precomputeExpression(operand, Type.u8, Constraints.CONV_IMPLICIT);
if (getExpressionId(argN) != ExpressionId.Const) {
compiler.error(
DiagnosticCode.Expression_must_be_a_compile_time_constant,
@ -3242,8 +3242,8 @@ export function compileCall(
compiler.currentType = Type.v128;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.v128;
return module.binary(op, arg0, arg1);
}
@ -3334,7 +3334,7 @@ export function compileCall(
compiler.currentType = Type.v128;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.v128;
return module.unary(op, arg0);
}
@ -3413,8 +3413,8 @@ export function compileCall(
compiler.currentType = Type.v128;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.i32, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.i32, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.v128;
return module.simd_shift(op, arg0, arg1);
}
@ -3436,8 +3436,8 @@ export function compileCall(
case BuiltinSymbols.v128_or: { op = BinaryOp.OrVec128; break; }
case BuiltinSymbols.v128_xor: { op = BinaryOp.XorVec128; break; }
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
return module.binary(op, arg0, arg1);
}
case BuiltinSymbols.v128_not: { // any_bitwise_unary(a: v128) -> v128
@ -3449,7 +3449,7 @@ export function compileCall(
compiler.currentType = Type.v128;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
return module.unary(UnaryOp.NotVec128, arg0);
}
case BuiltinSymbols.v128_bitselect: { // bitselect(v1: v128, v2: v128, c: v128) -> v128
@ -3461,9 +3461,9 @@ export function compileCall(
compiler.currentType = Type.v128;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, ContextualFlags.IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
let arg2 = compiler.compileExpression(operands[2], Type.v128, Constraints.CONV_IMPLICIT);
return module.simd_bitselect(arg0, arg1, arg2);
}
case BuiltinSymbols.v128_any_true: // any_test<T!>(a: v128) -> bool
@ -3536,7 +3536,7 @@ export function compileCall(
compiler.currentType = Type.bool;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.v128, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
compiler.currentType = Type.bool;
return module.unary(op, arg0);
}
@ -3565,7 +3565,7 @@ export function compileCall(
compiler.currentType = Type.void;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.u32, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], Type.u32, Constraints.CONV_IMPLICIT);
compiler.runtimeFeatures |= RuntimeFeatures.visitGlobals;
compiler.currentType = Type.void;
return module.call(BuiltinSymbols.visit_globals, [ arg0 ], NativeType.None);
@ -3578,8 +3578,8 @@ export function compileCall(
compiler.currentType = Type.void;
return module.unreachable();
}
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, ContextualFlags.IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.u32, ContextualFlags.IMPLICIT);
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.u32, Constraints.CONV_IMPLICIT);
compiler.runtimeFeatures |= RuntimeFeatures.visitMembers;
compiler.currentType = Type.void;
return module.call(BuiltinSymbols.visit_members, [ arg0, arg1 ], NativeType.None);
@ -3950,7 +3950,7 @@ export function compileAbort(
// assertion succeeds respectively is only being computed if the program actually crashes.
// Hence, let's make it so that the autorelease is skipped at the end of the current block,
// essentially ignoring the message GC-wise. Doesn't matter anyway on a crash.
messageArg = compiler.compileExpression(message, stringInstance.type, ContextualFlags.IMPLICIT | ContextualFlags.SKIP_AUTORELEASE);
messageArg = compiler.compileExpression(message, stringInstance.type, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN);
} else {
messageArg = stringInstance.type.toNativeZero(module);
}
@ -4241,7 +4241,7 @@ function evaluateConstantType(
);
return null;
}
compiler.compileExpression(operands[0], typeArguments[0], ContextualFlags.IMPLICIT);
compiler.compileExpression(operands[0], typeArguments[0], Constraints.CONV_IMPLICIT);
} else {
compiler.compileExpression(operands[0], Type.auto);
}
@ -4265,7 +4265,7 @@ function evaluateImmediateOffset(expression: Expression, compiler: Compiler): i3
var expr: ExpressionRef;
var value: i32;
if (compiler.options.isWasm64) {
expr = compiler.precomputeExpression(expression, Type.usize64, ContextualFlags.IMPLICIT);
expr = compiler.precomputeExpression(expression, Type.usize64, Constraints.CONV_IMPLICIT);
if (
getExpressionId(expr) != ExpressionId.Const ||
getExpressionType(expr) != NativeType.I64 ||
@ -4279,7 +4279,7 @@ function evaluateImmediateOffset(expression: Expression, compiler: Compiler): i3
value = -1;
}
} else {
expr = compiler.precomputeExpression(expression, Type.usize32, ContextualFlags.IMPLICIT);
expr = compiler.precomputeExpression(expression, Type.usize32, Constraints.CONV_IMPLICIT);
if (
getExpressionId(expr) != ExpressionId.Const ||
getExpressionType(expr) != NativeType.I32 ||

View File

@ -233,23 +233,23 @@ export class Options {
}
}
/** Requests or indicates compilation conditions of statements and expressions. */
export const enum ContextualFlags {
/** Various constraints in expression compilation. */
export const enum Constraints {
NONE = 0,
/** Implicit conversion required. */
IMPLICIT = 1 << 0,
/** Explicit conversion required. */
EXPLICIT = 1 << 1,
/** Small integer wrap required. */
WRAP = 1 << 2,
/** Must implicitly convert to the target type. */
CONV_IMPLICIT = 1 << 0,
/** Must explicitly convert to the target type. */
CONV_EXPLICIT = 1 << 1,
/** Must wrap small integer values to match the target type. */
MUST_WRAP = 1 << 2,
/** Value is known to be immediately dropped. */
/** Indicates that the value will be dropped immediately. */
WILL_DROP = 1 << 3,
/** Value is known to be immediately assigned to a retaining target. */
SKIP_AUTORELEASE = 1 << 4,
/** Data can be compiled statically. */
STATIC_CAPABLE = 1 << 5
/** Indicates that the value will be retained immediately. */
WILL_RETAIN = 1 << 4,
/** Indicates that static data is preferred. */
PREFER_STATIC = 1 << 5
}
/** Runtime features to be activated by the compiler. */
@ -813,7 +813,7 @@ export class Compiler extends DiagnosticEmitter {
this.currentFlow = global.file.startFunction.flow;
}
initExpr = this.compileExpression(initializerNode, Type.auto, // reports
ContextualFlags.WRAP | ContextualFlags.SKIP_AUTORELEASE
Constraints.MUST_WRAP | Constraints.WILL_RETAIN
);
if (this.skippedAutoreleases.has(initExpr)) initAutoreleaseSkipped = true;
this.currentFlow = previousFlow;
@ -886,7 +886,7 @@ export class Compiler extends DiagnosticEmitter {
this.currentFlow = global.file.startFunction.flow;
}
initExpr = this.compileExpression(initializerNode, type,
ContextualFlags.IMPLICIT | ContextualFlags.WRAP | ContextualFlags.SKIP_AUTORELEASE | ContextualFlags.STATIC_CAPABLE
Constraints.CONV_IMPLICIT | Constraints.MUST_WRAP | Constraints.WILL_RETAIN | Constraints.PREFER_STATIC
);
if (this.skippedAutoreleases.has(initExpr)) initAutoreleaseSkipped = true;
this.currentFlow = previousFlow;
@ -995,7 +995,7 @@ export class Compiler extends DiagnosticEmitter {
let initExpr: ExpressionRef;
if (valueNode) {
initExpr = this.compileExpression(valueNode, Type.i32,
ContextualFlags.IMPLICIT // autorelease is not applicable in i32 context
Constraints.CONV_IMPLICIT // autorelease is not applicable in i32 context
);
if (getExpressionId(initExpr) != ExpressionId.Const) {
initExpr = module.precomputeExpression(initExpr);
@ -1138,7 +1138,7 @@ export class Compiler extends DiagnosticEmitter {
assert(!instance.isAny(CommonFlags.CONSTRUCTOR | CommonFlags.GET | CommonFlags.SET | CommonFlags.MAIN));
let expr = this.compileExpression((<ExpressionStatement>bodyNode).expression, returnType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
if (!stmts) stmts = [ expr ];
else stmts.push(expr);
@ -1965,7 +1965,7 @@ export class Compiler extends DiagnosticEmitter {
compileExpressionStatement(
statement: ExpressionStatement
): ExpressionRef {
return this.compileExpression(statement.expression, Type.void, ContextualFlags.IMPLICIT);
return this.compileExpression(statement.expression, Type.void, Constraints.CONV_IMPLICIT);
}
compileForStatement(
@ -2017,7 +2017,7 @@ export class Compiler extends DiagnosticEmitter {
// Compile incrementor
var incrementor = statement.incrementor;
var incrExpr: ExpressionRef = 0;
if (incrementor) incrExpr = this.compileExpression(incrementor, Type.void, ContextualFlags.IMPLICIT | ContextualFlags.WILL_DROP);
if (incrementor) incrExpr = this.compileExpression(incrementor, Type.void, Constraints.CONV_IMPLICIT | Constraints.WILL_DROP);
// Compile body (break: drop out, continue: fall through to incrementor, + loop)
var breakLabel = innerFlow.breakLabel = "break|" + label; innerFlow.breakLabel = breakLabel;
@ -2193,9 +2193,9 @@ export class Compiler extends DiagnosticEmitter {
this.currentType = Type.void;
return module.unreachable();
}
let contextualFlags = ContextualFlags.IMPLICIT;
if (flow.actualFunction.is(CommonFlags.MODULE_EXPORT)) contextualFlags |= ContextualFlags.WRAP;
expr = this.compileExpression(valueExpression, returnType, contextualFlags | ContextualFlags.SKIP_AUTORELEASE);
let constraints = Constraints.CONV_IMPLICIT;
if (flow.actualFunction.is(CommonFlags.MODULE_EXPORT)) constraints |= Constraints.MUST_WRAP;
expr = this.compileExpression(valueExpression, returnType, constraints | Constraints.WILL_RETAIN);
// when returning a local, and it is already retained, skip the final set
// of retaining it as the return value and releasing it as a variable
@ -2269,7 +2269,7 @@ export class Compiler extends DiagnosticEmitter {
var numCases = cases.length;
if (!numCases) {
return this.compileExpression(statement.condition, Type.void,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
}
@ -2286,7 +2286,7 @@ export class Compiler extends DiagnosticEmitter {
breaks[0] = module.local_set( // initializer
tempLocalIndex,
this.compileExpression(statement.condition, Type.u32,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
);
@ -2301,7 +2301,7 @@ export class Compiler extends DiagnosticEmitter {
module.binary(BinaryOp.EqI32,
module.local_get(tempLocalIndex, NativeType.I32),
this.compileExpression(label, Type.u32,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
)
);
@ -2437,7 +2437,7 @@ export class Compiler extends DiagnosticEmitter {
if (!type) continue;
if (declaration.initializer) {
initExpr = this.compileExpression(declaration.initializer, type, // reports
ContextualFlags.IMPLICIT | ContextualFlags.SKIP_AUTORELEASE
Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN
);
initAutoreleaseSkipped = this.skippedAutoreleases.has(initExpr);
}
@ -2445,7 +2445,7 @@ export class Compiler extends DiagnosticEmitter {
// Otherwise infer type from initializer
} else if (declaration.initializer) {
initExpr = this.compileExpression(declaration.initializer, Type.auto,
ContextualFlags.SKIP_AUTORELEASE
Constraints.WILL_RETAIN
); // reports
initAutoreleaseSkipped = this.skippedAutoreleases.has(initExpr);
if (this.currentType == Type.void) {
@ -2607,7 +2607,7 @@ export class Compiler extends DiagnosticEmitter {
statement: VoidStatement
): ExpressionRef {
return this.compileExpression(statement.expression, Type.void,
ContextualFlags.EXPLICIT | ContextualFlags.WILL_DROP
Constraints.CONV_EXPLICIT | Constraints.WILL_DROP
);
}
@ -2695,12 +2695,12 @@ export class Compiler extends DiagnosticEmitter {
compileInlineConstant(
element: VariableLikeElement,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
assert(element.is(CommonFlags.INLINED));
var type = element.type;
switch (
!(contextualFlags & (ContextualFlags.IMPLICIT | ContextualFlags.EXPLICIT)) &&
!(constraints & (Constraints.CONV_IMPLICIT | Constraints.CONV_EXPLICIT)) &&
type.is(TypeFlags.INTEGER) &&
contextualType.is(TypeFlags.INTEGER) &&
type.size < contextualType.size
@ -2775,34 +2775,34 @@ export class Compiler extends DiagnosticEmitter {
compileExpression(
expression: Expression,
contextualType: Type,
contextualFlags: ContextualFlags = ContextualFlags.NONE
constraints: Constraints = Constraints.NONE
): ExpressionRef {
this.currentType = contextualType;
var expr: ExpressionRef;
if (contextualType == Type.void) contextualFlags |= ContextualFlags.WILL_DROP;
if (contextualType == Type.void) constraints |= Constraints.WILL_DROP;
switch (expression.kind) {
case NodeKind.ASSERTION: {
expr = this.compileAssertionExpression(<AssertionExpression>expression, contextualType, contextualFlags);
expr = this.compileAssertionExpression(<AssertionExpression>expression, contextualType, constraints);
break;
}
case NodeKind.BINARY: {
expr = this.compileBinaryExpression(<BinaryExpression>expression, contextualType, contextualFlags);
expr = this.compileBinaryExpression(<BinaryExpression>expression, contextualType, constraints);
break;
}
case NodeKind.CALL: {
expr = this.compileCallExpression(<CallExpression>expression, contextualType, contextualFlags);
expr = this.compileCallExpression(<CallExpression>expression, contextualType, constraints);
break;
}
case NodeKind.COMMA: {
expr = this.compileCommaExpression(<CommaExpression>expression, contextualType, contextualFlags);
expr = this.compileCommaExpression(<CommaExpression>expression, contextualType, constraints);
break;
}
case NodeKind.ELEMENTACCESS: {
expr = this.compileElementAccessExpression(<ElementAccessExpression>expression, contextualType, contextualFlags);
expr = this.compileElementAccessExpression(<ElementAccessExpression>expression, contextualType, constraints);
break;
}
case NodeKind.FUNCTION: {
expr = this.compileFunctionExpression(<FunctionExpression>expression, contextualType.signatureReference, contextualFlags);
expr = this.compileFunctionExpression(<FunctionExpression>expression, contextualType.signatureReference, constraints);
break;
}
case NodeKind.IDENTIFIER:
@ -2811,39 +2811,39 @@ export class Compiler extends DiagnosticEmitter {
case NodeKind.THIS:
case NodeKind.SUPER:
case NodeKind.TRUE: {
expr = this.compileIdentifierExpression(<IdentifierExpression>expression, contextualType, contextualFlags);
expr = this.compileIdentifierExpression(<IdentifierExpression>expression, contextualType, constraints);
break;
}
case NodeKind.INSTANCEOF: {
expr = this.compileInstanceOfExpression(<InstanceOfExpression>expression, contextualType, contextualFlags);
expr = this.compileInstanceOfExpression(<InstanceOfExpression>expression, contextualType, constraints);
break;
}
case NodeKind.LITERAL: {
expr = this.compileLiteralExpression(<LiteralExpression>expression, contextualType, contextualFlags);
expr = this.compileLiteralExpression(<LiteralExpression>expression, contextualType, constraints);
break;
}
case NodeKind.NEW: {
expr = this.compileNewExpression(<NewExpression>expression, contextualType, contextualFlags);
expr = this.compileNewExpression(<NewExpression>expression, contextualType, constraints);
break;
}
case NodeKind.PARENTHESIZED: {
expr = this.compileExpression((<ParenthesizedExpression>expression).expression, contextualType, contextualFlags);
expr = this.compileExpression((<ParenthesizedExpression>expression).expression, contextualType, constraints);
break;
}
case NodeKind.PROPERTYACCESS: {
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType, contextualFlags);
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType, constraints);
break;
}
case NodeKind.TERNARY: {
expr = this.compileTernaryExpression(<TernaryExpression>expression, contextualType, contextualFlags);
expr = this.compileTernaryExpression(<TernaryExpression>expression, contextualType, constraints);
break;
}
case NodeKind.UNARYPOSTFIX: {
expr = this.compileUnaryPostfixExpression(<UnaryPostfixExpression>expression, contextualType, contextualFlags);
expr = this.compileUnaryPostfixExpression(<UnaryPostfixExpression>expression, contextualType, constraints);
break;
}
case NodeKind.UNARYPREFIX: {
expr = this.compileUnaryPrefixExpression(<UnaryPrefixExpression>expression, contextualType, contextualFlags);
expr = this.compileUnaryPrefixExpression(<UnaryPrefixExpression>expression, contextualType, constraints);
break;
}
default: {
@ -2856,13 +2856,13 @@ export class Compiler extends DiagnosticEmitter {
}
// ensure conversion and wrapping in case the respective function doesn't on its own
var currentType = this.currentType;
var wrap = (contextualFlags & ContextualFlags.WRAP) != 0;
var wrap = (constraints & Constraints.MUST_WRAP) != 0;
if (currentType != contextualType) {
if (contextualFlags & ContextualFlags.EXPLICIT) {
if (constraints & Constraints.CONV_EXPLICIT) {
expr = this.convertExpression(expr, currentType, contextualType, true, wrap, expression);
wrap = false;
this.currentType = contextualType;
} else if (contextualFlags & ContextualFlags.IMPLICIT) {
} else if (constraints & Constraints.CONV_IMPLICIT) {
expr = this.convertExpression(expr, currentType, contextualType, false, wrap, expression);
wrap = false;
this.currentType = contextualType;
@ -2879,10 +2879,10 @@ export class Compiler extends DiagnosticEmitter {
precomputeExpression(
expression: Expression,
contextualType: Type,
contextualFlags: ContextualFlags = ContextualFlags.NONE
constraints: Constraints = Constraints.NONE
): ExpressionRef {
return this.module.precomputeExpression(
this.compileExpression(expression, contextualType, contextualFlags)
this.compileExpression(expression, contextualType, constraints)
);
}
@ -3082,9 +3082,9 @@ export class Compiler extends DiagnosticEmitter {
compileAssertionExpression(
expression: AssertionExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var inheritedFlags = contextualFlags & ~(ContextualFlags.IMPLICIT | ContextualFlags.EXPLICIT);
var inheritedConstraints = constraints & ~(Constraints.CONV_IMPLICIT | Constraints.CONV_EXPLICIT);
switch (expression.assertionKind) {
case AssertionKind.PREFIX:
case AssertionKind.AS: {
@ -3095,11 +3095,11 @@ export class Compiler extends DiagnosticEmitter {
flow.contextualTypeArguments
);
if (!toType) return this.module.unreachable();
return this.compileExpression(expression.expression, toType, inheritedFlags | ContextualFlags.EXPLICIT);
return this.compileExpression(expression.expression, toType, inheritedConstraints | Constraints.CONV_EXPLICIT);
}
case AssertionKind.NONNULL: {
assert(!expression.toType);
let expr = this.compileExpression(expression.expression, contextualType.exceptVoid, inheritedFlags);
let expr = this.compileExpression(expression.expression, contextualType.exceptVoid, inheritedConstraints);
let type = this.currentType;
if (this.currentFlow.isNonnull(expr, type)) {
this.info(
@ -3134,7 +3134,7 @@ export class Compiler extends DiagnosticEmitter {
compileBinaryExpression(
expression: BinaryExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var left = expression.left;
@ -3759,7 +3759,7 @@ export class Compiler extends DiagnosticEmitter {
}
if (compound) {
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
} else {
rightExpr = this.compileExpression(right, leftType);
rightType = this.currentType;
@ -3848,7 +3848,7 @@ export class Compiler extends DiagnosticEmitter {
}
if (compound) {
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -3939,7 +3939,7 @@ export class Compiler extends DiagnosticEmitter {
if (compound) {
leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType);
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
} else {
rightExpr = this.compileExpression(right, leftType);
rightType = this.currentType;
@ -4031,7 +4031,7 @@ export class Compiler extends DiagnosticEmitter {
// Mathf.pow if lhs is f32 (result is f32)
if (this.currentType.kind == TypeKind.F32) {
rightExpr = this.compileExpression(right, Type.f32, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, Type.f32, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
if (!(instance = this.f32PowInstance)) {
let namespace = this.program.lookupGlobal(CommonSymbols.Mathf);
@ -4065,7 +4065,7 @@ export class Compiler extends DiagnosticEmitter {
left
);
leftType = this.currentType;
rightExpr = this.compileExpression(right, Type.f64, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, Type.f64, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
if (!(instance = this.f64PowInstance)) {
let namespace = this.program.lookupGlobal(CommonSymbols.Math);
@ -4121,7 +4121,7 @@ export class Compiler extends DiagnosticEmitter {
if (compound) {
leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType);
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -4230,7 +4230,7 @@ export class Compiler extends DiagnosticEmitter {
if (compound) {
leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType);
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -4394,7 +4394,7 @@ export class Compiler extends DiagnosticEmitter {
return this.module.unreachable();
}
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
switch (this.currentType.kind) {
case TypeKind.I8:
@ -4461,7 +4461,7 @@ export class Compiler extends DiagnosticEmitter {
}
leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType); // must clear garbage bits
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
switch (this.currentType.kind) {
case TypeKind.I8:
@ -4549,7 +4549,7 @@ export class Compiler extends DiagnosticEmitter {
}
leftExpr = this.ensureSmallIntegerWrap(leftExpr, leftType); // must clear garbage bits
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
switch (this.currentType.kind) {
case TypeKind.U8:
@ -4618,7 +4618,7 @@ export class Compiler extends DiagnosticEmitter {
}
if (compound) {
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -4708,7 +4708,7 @@ export class Compiler extends DiagnosticEmitter {
}
if (compound) {
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -4801,7 +4801,7 @@ export class Compiler extends DiagnosticEmitter {
}
if (compound) {
rightExpr = this.compileExpression(right, leftType, ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, Constraints.CONV_IMPLICIT);
rightType = this.currentType;
} else {
rightExpr = this.compileExpression(right, leftType);
@ -4876,14 +4876,14 @@ export class Compiler extends DiagnosticEmitter {
case Token.AMPERSAND_AMPERSAND: { // left && right -> (t = left) ? right : t
let flow = this.currentFlow;
let inheritedFlags = contextualFlags & (ContextualFlags.SKIP_AUTORELEASE | ContextualFlags.WRAP);
leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedFlags);
let inheritedConstraints = constraints & (Constraints.WILL_RETAIN | Constraints.MUST_WRAP);
leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedConstraints);
leftType = this.currentType;
let rightFlow = flow.fork();
this.currentFlow = rightFlow;
rightFlow.inheritNonnullIfTrue(leftExpr);
rightExpr = this.compileExpression(right, leftType, inheritedFlags | ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, inheritedConstraints | Constraints.CONV_IMPLICIT);
rightType = leftType;
// simplify if only interested in true or false
@ -4915,7 +4915,7 @@ export class Compiler extends DiagnosticEmitter {
rightExpr = this.makeRetain(rightExpr);
rightAutoreleaseSkipped = true;
}
} else if (!(contextualFlags & ContextualFlags.SKIP_AUTORELEASE)) { // otherwise keep right alive a little longer
} else if (!(constraints & Constraints.WILL_RETAIN)) { // otherwise keep right alive a little longer
rightExpr = this.moveAutorelease(rightExpr, rightFlow, flow);
}
@ -4974,14 +4974,14 @@ export class Compiler extends DiagnosticEmitter {
}
case Token.BAR_BAR: { // left || right -> ((t = left) ? t : right)
let flow = this.currentFlow;
let inheritedFlags = contextualFlags & (ContextualFlags.SKIP_AUTORELEASE | ContextualFlags.WRAP);
leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedFlags);
let inheritedConstraints = constraints & (Constraints.WILL_RETAIN | Constraints.MUST_WRAP);
leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedConstraints);
leftType = this.currentType;
let rightFlow = flow.fork();
this.currentFlow = rightFlow;
rightFlow.inheritNonnullIfFalse(leftExpr);
rightExpr = this.compileExpression(right, leftType, inheritedFlags | ContextualFlags.IMPLICIT);
rightExpr = this.compileExpression(right, leftType, inheritedConstraints | Constraints.CONV_IMPLICIT);
rightType = leftType;
// simplify if only interested in true or false
@ -5013,7 +5013,7 @@ export class Compiler extends DiagnosticEmitter {
rightExpr = this.makeRetain(rightExpr);
rightAutoreleaseSkipped = true;
}
} else if (!(contextualFlags & ContextualFlags.SKIP_AUTORELEASE)) { // otherwise keep right alive a little longer
} else if (!(constraints & Constraints.WILL_RETAIN)) { // otherwise keep right alive a little longer
rightExpr = this.moveAutorelease(rightExpr, rightFlow, flow);
}
@ -5124,7 +5124,7 @@ export class Compiler extends DiagnosticEmitter {
// it can actually resolve every kind of expression without ever having to recompile.
rightType = operatorInstance.signature.parameterTypes[1];
}
var rightExpr = this.compileExpression(right, rightType, ContextualFlags.IMPLICIT);
var rightExpr = this.compileExpression(right, rightType, Constraints.CONV_IMPLICIT);
return this.makeCallDirect(operatorInstance, [ leftExpr, rightExpr ], reportNode);
}
@ -5232,7 +5232,7 @@ export class Compiler extends DiagnosticEmitter {
assert(targetType != Type.void);
return this.makeAssignment(
target,
this.compileExpression(valueExpression, targetType, ContextualFlags.IMPLICIT | ContextualFlags.SKIP_AUTORELEASE),
this.compileExpression(valueExpression, targetType, Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN),
expression,
thisExpression,
elementExpression,
@ -5388,7 +5388,7 @@ export class Compiler extends DiagnosticEmitter {
}
let targetType = (<Class>target).type;
let thisExpr = this.compileExpression(assert(thisExpression), this.options.usizeType);
let elementExpr = this.compileExpression(indexExpression, Type.i32, ContextualFlags.IMPLICIT);
let elementExpr = this.compileExpression(indexExpression, Type.i32, Constraints.CONV_IMPLICIT);
if (tee) {
let tempLocalTarget = flow.getTempLocal(targetType);
let tempLocalElement = flow.getAndFreeTempLocal(this.currentType);
@ -5700,8 +5700,8 @@ export class Compiler extends DiagnosticEmitter {
expression: CallExpression,
/** Contextual type indicating the return type the caller expects, if any. */
contextualType: Type,
/** Contextual flags indicating contextual conditions. */
contextualFlags: ContextualFlags
/** Constraints indicating contextual conditions. */
constraints: Constraints
): ExpressionRef {
var module = this.module;
@ -5740,7 +5740,7 @@ export class Compiler extends DiagnosticEmitter {
this.makeAllocation(<Class>classInstance)
)
),
ContextualFlags.SKIP_AUTORELEASE
Constraints.WILL_RETAIN
);
assert(this.skippedAutoreleases.has(theCall)); // guaranteed
let stmts: ExpressionRef[] = [
@ -5858,7 +5858,7 @@ export class Compiler extends DiagnosticEmitter {
flow.contextualTypeArguments
);
if (!concreteType) return module.unreachable();
argumentExprs[i] = this.compileExpression(argumentExpression, concreteType, ContextualFlags.IMPLICIT);
argumentExprs[i] = this.compileExpression(argumentExpression, concreteType, Constraints.CONV_IMPLICIT);
}
}
let resolvedTypeArguments = new Array<Type>(numTypeParameters);
@ -5894,7 +5894,7 @@ export class Compiler extends DiagnosticEmitter {
expression.arguments,
expression,
thisExpr,
contextualFlags
constraints
);
}
@ -5950,7 +5950,7 @@ export class Compiler extends DiagnosticEmitter {
}
case ElementKind.FUNCTION_TARGET: {
signature = (<FunctionTarget>target).signature;
indexArg = this.compileExpression(expression.expression, (<FunctionTarget>target).type, ContextualFlags.IMPLICIT);
indexArg = this.compileExpression(expression.expression, (<FunctionTarget>target).type, Constraints.CONV_IMPLICIT);
break;
}
@ -6113,7 +6113,7 @@ export class Compiler extends DiagnosticEmitter {
argumentExpressions: Expression[],
reportNode: Node,
thisArg: ExpressionRef = 0,
contextualFlags: ContextualFlags = ContextualFlags.NONE
constraints: Constraints = Constraints.NONE
): ExpressionRef {
var numArguments = argumentExpressions.length;
var signature = instance.signature;
@ -6143,13 +6143,13 @@ export class Compiler extends DiagnosticEmitter {
let args = new Array<ExpressionRef>(numArguments);
for (let i = 0; i < numArguments; ++i) {
args[i] = this.compileExpression(argumentExpressions[i], parameterTypes[i],
ContextualFlags.IMPLICIT | ContextualFlags.SKIP_AUTORELEASE
Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN
);
}
// make the inlined call (is aware of autoreleases)
let expr = this.makeCallInline(instance, args, thisArg, (contextualFlags & ContextualFlags.WILL_DROP) != 0);
let expr = this.makeCallInline(instance, args, thisArg, (constraints & Constraints.WILL_DROP) != 0);
if (this.currentType.isManaged) {
if (!(contextualFlags & ContextualFlags.SKIP_AUTORELEASE)) {
if (!(constraints & Constraints.WILL_RETAIN)) {
expr = this.makeAutorelease(expr, this.currentFlow);
} else {
this.skippedAutoreleases.add(expr);
@ -6171,15 +6171,15 @@ export class Compiler extends DiagnosticEmitter {
var parameterTypes = signature.parameterTypes;
for (let i = 0; i < numArguments; ++i, ++index) {
operands[index] = this.compileExpression(argumentExpressions[i], parameterTypes[i],
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
}
assert(index == numArgumentsInclThis);
if (signature.returnType.isManaged) {
if (contextualFlags & ContextualFlags.WILL_DROP) {
if (constraints & Constraints.WILL_DROP) {
// Skip autorelease and simply release
return this.makeCallDirect(instance, operands, reportNode, true);
} else if (contextualFlags & ContextualFlags.SKIP_AUTORELEASE) {
} else if (constraints & Constraints.WILL_RETAIN) {
// Skip autorelease and remember
let expr = this.makeCallDirect(instance, operands, reportNode, false, true);
this.skippedAutoreleases.add(expr);
@ -6189,7 +6189,7 @@ export class Compiler extends DiagnosticEmitter {
}
}
return this.makeCallDirect(instance, operands, reportNode,
(contextualFlags & ContextualFlags.WILL_DROP) != 0
(constraints & Constraints.WILL_DROP) != 0
);
}
@ -6256,7 +6256,7 @@ export class Compiler extends DiagnosticEmitter {
let initExpr = this.compileExpression(
assert(instance.prototype.signatureNode.parameters[i].initializer),
initType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
let argumentLocal = flow.addScopedLocal(signature.getParameterName(i), initType);
if (!flow.canOverflow(initExpr, initType)) flow.setLocalFlag(argumentLocal.index, LocalFlags.WRAPPED);
@ -6398,7 +6398,7 @@ export class Compiler extends DiagnosticEmitter {
this.compileExpression(
initializer,
type,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
);
} else {
@ -6715,7 +6715,7 @@ export class Compiler extends DiagnosticEmitter {
operands.push(this.compileExpression(
<Expression>parameterNodes[i].initializer,
parameterTypes[i],
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
));
continue;
}
@ -6726,7 +6726,7 @@ export class Compiler extends DiagnosticEmitter {
if (this.compileGlobal(global)) {
if (global.is(CommonFlags.INLINED)) {
operands.push(
this.compileInlineConstant(global, parameterTypes[i], ContextualFlags.IMPLICIT)
this.compileInlineConstant(global, parameterTypes[i], Constraints.CONV_IMPLICIT)
);
} else {
operands.push(
@ -6817,7 +6817,7 @@ export class Compiler extends DiagnosticEmitter {
var parameterTypes = signature.parameterTypes;
for (let i = 0; i < numArguments; ++i, ++index) {
operands[index] = this.compileExpression(argumentExpressions[i], parameterTypes[i],
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
}
assert(index == numArgumentsInclThis);
@ -6881,24 +6881,24 @@ export class Compiler extends DiagnosticEmitter {
compileCommaExpression(
expression: CommaExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var expressions = expression.expressions;
var numExpressions = expressions.length;
var exprs = new Array<ExpressionRef>(numExpressions--);
for (let i = 0; i < numExpressions; ++i) {
exprs[i] = this.compileExpression(expressions[i], Type.void, // drop all except last
ContextualFlags.IMPLICIT | ContextualFlags.WILL_DROP
Constraints.CONV_IMPLICIT | Constraints.WILL_DROP
);
}
exprs[numExpressions] = this.compileExpression(expressions[numExpressions], contextualType, contextualFlags);
exprs[numExpressions] = this.compileExpression(expressions[numExpressions], contextualType, constraints);
return this.module.block(null, exprs, this.currentType.toNativeType());
}
compileElementAccessExpression(
expression: ElementAccessExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var target = this.resolver.resolveElementAccessExpression(
expression,
@ -6917,11 +6917,11 @@ export class Compiler extends DiagnosticEmitter {
return this.module.unreachable();
}
let thisArg = this.compileExpression(expression.expression, (<Class>target).type,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
);
return this.compileCallDirect(indexedGet, [
expression.elementExpression
], expression, thisArg, contextualFlags & (ContextualFlags.WILL_DROP | ContextualFlags.SKIP_AUTORELEASE));
], expression, thisArg, constraints);
}
}
this.error(
@ -6934,7 +6934,7 @@ export class Compiler extends DiagnosticEmitter {
compileFunctionExpression(
expression: FunctionExpression,
contextualSignature: Signature | null,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var declaration = expression.declaration.clone(); // generic contexts can have multiple
assert(!declaration.typeParameters); // function expression cannot be generic
@ -7088,7 +7088,7 @@ export class Compiler extends DiagnosticEmitter {
compileIdentifierExpression(
expression: IdentifierExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var flow = this.currentFlow;
@ -7215,7 +7215,7 @@ export class Compiler extends DiagnosticEmitter {
let type = (<Local>target).type;
assert(type != Type.void);
if ((<Local>target).is(CommonFlags.INLINED)) {
return this.compileInlineConstant(<Local>target, contextualType, contextualFlags);
return this.compileInlineConstant(<Local>target, contextualType, constraints);
}
let localIndex = (<Local>target).index;
assert(localIndex >= 0);
@ -7232,7 +7232,7 @@ export class Compiler extends DiagnosticEmitter {
let type = (<Global>target).type;
assert(type != Type.void);
if ((<Global>target).is(CommonFlags.INLINED)) {
return this.compileInlineConstant(<Global>target, contextualType, contextualFlags);
return this.compileInlineConstant(<Global>target, contextualType, constraints);
}
this.currentType = type;
return this.module.global_get((<Global>target).internalName, type.toNativeType());
@ -7275,7 +7275,7 @@ export class Compiler extends DiagnosticEmitter {
compileInstanceOfExpression(
expression: InstanceOfExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
// NOTE that this differs from TypeScript in that the rhs is a type, not an expression. at the
@ -7291,7 +7291,7 @@ export class Compiler extends DiagnosticEmitter {
// instanceof <basic> - must be exact
if (!expectedType.is(TypeFlags.REFERENCE)) {
return module.block(null, [
this.convertExpression(expr, actualType, Type.void, (contextualFlags & ContextualFlags.EXPLICIT) != 0, false, expression.expression),
module.drop(expr),
module.i32(actualType == expectedType ? 1 : 0)
], NativeType.I32);
}
@ -7299,7 +7299,7 @@ export class Compiler extends DiagnosticEmitter {
// <basic> instanceof <reference> - always false
if (!actualType.is(TypeFlags.REFERENCE)) {
return module.block(null, [
this.convertExpression(expr, actualType, Type.void, (contextualFlags & ContextualFlags.EXPLICIT) != 0,false, expression.expression),
module.drop(expr),
module.i32(0)
], NativeType.I32);
}
@ -7356,7 +7356,7 @@ export class Compiler extends DiagnosticEmitter {
// downcast - check statically
if (actualType.isAssignableTo(expectedType)) {
return module.block(null, [
this.convertExpression(expr, actualType, Type.void, (contextualFlags & ContextualFlags.EXPLICIT) != 0, false, expression.expression),
this.convertExpression(expr, actualType, Type.void, false, false, expression.expression),
module.i32(1)
], NativeType.I32);
@ -7395,7 +7395,7 @@ export class Compiler extends DiagnosticEmitter {
// false
return module.block(null, [
this.convertExpression(expr, actualType, Type.void, (contextualFlags & ContextualFlags.EXPLICIT) != 0, false, expression.expression),
module.drop(expr),
module.i32(0)
], NativeType.I32);
}
@ -7403,7 +7403,7 @@ export class Compiler extends DiagnosticEmitter {
compileLiteralExpression(
expression: LiteralExpression,
contextualType: Type,
contextualFlags: ContextualFlags,
constraints: Constraints,
implicitlyNegate: bool = false
): ExpressionRef {
var module = this.module;
@ -7416,8 +7416,7 @@ export class Compiler extends DiagnosticEmitter {
return this.compileArrayLiteral(
assert(classType.typeArguments)[0],
(<ArrayLiteralExpression>expression).elementExpressions,
false, // TODO: isConst?
contextualFlags,
constraints,
expression
);
}
@ -7484,8 +7483,7 @@ export class Compiler extends DiagnosticEmitter {
compileArrayLiteral(
elementType: Type,
expressions: (Expression | null)[],
isConst: bool,
contextualFlags: ContextualFlags,
constraints: Constraints,
reportNode: Node
): ExpressionRef {
var module = this.module;
@ -7510,7 +7508,7 @@ export class Compiler extends DiagnosticEmitter {
let expr = expression
? module.precomputeExpression(
this.compileExpression(<Expression>expression, elementType,
ContextualFlags.IMPLICIT
Constraints.CONV_IMPLICIT
)
)
: elementType.toNativeZero(module);
@ -7533,7 +7531,7 @@ export class Compiler extends DiagnosticEmitter {
// make both the buffer and array header static if assigned to a global. this can't be done
// if inside of a function because each invocation must create a new array reference then.
if (contextualFlags & ContextualFlags.STATIC_CAPABLE) {
if (constraints & Constraints.PREFER_STATIC) {
let arraySegment = this.ensureStaticArrayHeader(elementType, bufferSegment);
let arrayAddress = i64_add(arraySegment.offset, i64_new(runtimeHeaderSize));
this.currentType = arrayType;
@ -7693,7 +7691,7 @@ export class Compiler extends DiagnosticEmitter {
exprs[i + 1] = this.module.store( // TODO: handle setters as well
type.byteSize,
this.module.local_get(tempLocal.index, this.options.nativeSizeType),
this.compileExpression(values[i], (<Field>member).type, ContextualFlags.IMPLICIT),
this.compileExpression(values[i], (<Field>member).type, Constraints.CONV_IMPLICIT),
type.toNativeType(),
(<Field>member).memoryOffset
);
@ -7719,7 +7717,7 @@ export class Compiler extends DiagnosticEmitter {
compileNewExpression(
expression: NewExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var flow = this.currentFlow;
@ -7761,8 +7759,8 @@ export class Compiler extends DiagnosticEmitter {
);
}
if (!classInstance) return module.unreachable();
if (contextualType == Type.void) contextualFlags |= ContextualFlags.WILL_DROP;
return this.compileInstantiate(classInstance, expression.arguments, contextualFlags, expression);
if (contextualType == Type.void) constraints |= Constraints.WILL_DROP;
return this.compileInstantiate(classInstance, expression.arguments, constraints, expression);
}
/** Gets the compiled constructor of the specified class or generates one if none is present. */
@ -7879,7 +7877,7 @@ export class Compiler extends DiagnosticEmitter {
/** Constructor arguments. */
argumentExpressions: Expression[],
/** Contextual flags. */
contextualFlags: ContextualFlags,
constraints: Constraints,
/** Node to report on. */
reportNode: Node
): ExpressionRef {
@ -7889,7 +7887,7 @@ export class Compiler extends DiagnosticEmitter {
argumentExpressions,
reportNode,
this.options.usizeType.toNativeZero(this.module),
contextualFlags
constraints
);
if (getExpressionType(expr) != NativeType.None) { // possibly IMM_DROPPED
this.currentType = classInstance.type; // important because a super ctor could be called
@ -7905,7 +7903,7 @@ export class Compiler extends DiagnosticEmitter {
compilePropertyAccessExpression(
propertyAccess: PropertyAccessExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var flow = this.currentFlow;
@ -7923,7 +7921,7 @@ export class Compiler extends DiagnosticEmitter {
let globalType = (<Global>target).type;
assert(globalType != Type.void);
if ((<Global>target).is(CommonFlags.INLINED)) {
return this.compileInlineConstant(<Global>target, contextualType, contextualFlags);
return this.compileInlineConstant(<Global>target, contextualType, constraints);
}
this.currentType = globalType;
return module.global_get((<Global>target).internalName, globalType.toNativeType());
@ -7985,7 +7983,7 @@ export class Compiler extends DiagnosticEmitter {
compileTernaryExpression(
expression: TernaryExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var ifThen = expression.ifThen;
var ifElse = expression.ifElse;
@ -8008,15 +8006,17 @@ export class Compiler extends DiagnosticEmitter {
: this.compileExpression(ifElse, contextualType);
}
var inheritedConstraints = constraints & Constraints.WILL_RETAIN;
var ifThenFlow = outerFlow.fork();
this.currentFlow = ifThenFlow;
var ifThenExpr = this.compileExpression(ifThen, contextualType, contextualFlags & ContextualFlags.SKIP_AUTORELEASE);
var ifThenExpr = this.compileExpression(ifThen, contextualType, inheritedConstraints);
var ifThenType = this.currentType;
var IfThenAutoreleaseSkipped = this.skippedAutoreleases.has(ifThenExpr);
var ifElseFlow = outerFlow.fork();
this.currentFlow = ifElseFlow;
var ifElseExpr = this.compileExpression(ifElse, contextualType, contextualFlags & ContextualFlags.SKIP_AUTORELEASE);
var ifElseExpr = this.compileExpression(ifElse, contextualType, inheritedConstraints);
var ifElseType = this.currentType;
var ifElseAutoreleaseSkipped = this.skippedAutoreleases.has(ifElseExpr);
@ -8052,7 +8052,7 @@ export class Compiler extends DiagnosticEmitter {
ifElseAutoreleaseSkipped = true;
}
} else if (!IfThenAutoreleaseSkipped && commonType.isManaged) { // keep alive a little longer
// if (!(contextualFlags & ContextualFlags.SKIP_AUTORELEASE)) {
// if (!(constraints & Constraints.WILL_RETAIN)) {
ifThenExpr = this.moveAutorelease(ifThenExpr, ifThenFlow, outerFlow);
ifElseExpr = this.moveAutorelease(ifElseExpr, ifElseFlow, outerFlow);
// }
@ -8076,7 +8076,7 @@ export class Compiler extends DiagnosticEmitter {
compileUnaryPostfixExpression(
expression: UnaryPostfixExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var flow = this.currentFlow;
@ -8085,7 +8085,7 @@ export class Compiler extends DiagnosticEmitter {
var getValue = this.compileExpression( // reports
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// shortcut if compiling the getter already failed
@ -8306,7 +8306,7 @@ export class Compiler extends DiagnosticEmitter {
compileUnaryPrefixExpression(
expression: UnaryPrefixExpression,
contextualType: Type,
contextualFlags: ContextualFlags
constraints: Constraints
): ExpressionRef {
var module = this.module;
var compound = false;
@ -8317,7 +8317,7 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileExpression(
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8346,7 +8346,7 @@ export class Compiler extends DiagnosticEmitter {
(<LiteralExpression>expression.operand).literalKind == LiteralKind.FLOAT
)) {
// implicitly negate integer and float literals. also enables proper checking of literal ranges.
expr = this.compileLiteralExpression(<LiteralExpression>expression.operand, contextualType, ContextualFlags.NONE, true);
expr = this.compileLiteralExpression(<LiteralExpression>expression.operand, contextualType, Constraints.NONE, true);
// compileExpression normally does this:
if (this.options.sourceMap) this.addDebugLocation(expr, expression.range);
break;
@ -8355,7 +8355,7 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileExpression(
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8422,7 +8422,7 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileExpression(
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8489,7 +8489,7 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileExpression(
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8555,7 +8555,7 @@ export class Compiler extends DiagnosticEmitter {
expr = this.compileExpression(
expression.operand,
contextualType.exceptVoid,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8583,7 +8583,7 @@ export class Compiler extends DiagnosticEmitter {
: contextualType.is(TypeFlags.FLOAT)
? Type.i64
: contextualType,
ContextualFlags.NONE
Constraints.NONE
);
// check operator overload
@ -8873,7 +8873,7 @@ export class Compiler extends DiagnosticEmitter {
let initializerNode = field.prototype.initializerNode;
if (initializerNode) { // use initializer
let initExpr = this.compileExpression(initializerNode, fieldType, // reports
ContextualFlags.IMPLICIT | ContextualFlags.SKIP_AUTORELEASE
Constraints.CONV_IMPLICIT | Constraints.WILL_RETAIN
);
if (fieldType.isManaged && !this.skippedAutoreleases.has(initExpr)) {
initExpr = this.makeRetain(initExpr);