mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-18 17:31:29 +00:00
Move some numeric builtins to stdlib; Minor refactoring
This commit is contained in:
153
src/builtins.ts
153
src/builtins.ts
@ -54,22 +54,6 @@ export function compileGetConstant(
|
||||
reportNode: Node
|
||||
): ExpressionRef {
|
||||
switch (global.internalName) {
|
||||
case "NaN": { // context-sensitive
|
||||
if (compiler.currentType == Type.f32) {
|
||||
return compiler.module.createF32(NaN);
|
||||
} else {
|
||||
compiler.currentType = Type.f64;
|
||||
return compiler.module.createF64(NaN);
|
||||
}
|
||||
}
|
||||
case "Infinity": { // context-sensitive
|
||||
if (compiler.currentType == Type.f32) {
|
||||
return compiler.module.createF32(Infinity);
|
||||
} else {
|
||||
compiler.currentType = Type.f64;
|
||||
return compiler.module.createF64(Infinity);
|
||||
}
|
||||
}
|
||||
case "HEAP_BASE": { // never inlined for linking purposes
|
||||
compiler.currentType = compiler.options.usizeType;
|
||||
return compiler.module.createGetGlobal("HEAP_BASE", compiler.currentType.toNativeType());
|
||||
@ -154,143 +138,6 @@ export function compileCall(
|
||||
|
||||
// math
|
||||
|
||||
case "isNaN": { // isNaN<T?>(value: T) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (operands.length != 1) {
|
||||
if (typeArguments && typeArguments.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
}
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
if (typeArguments) {
|
||||
if (typeArguments.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]);
|
||||
} else {
|
||||
arg0 = compiler.compileExpression(operands[0], Type.f64, ConversionKind.NONE);
|
||||
}
|
||||
|
||||
switch (compiler.currentType.kind) {
|
||||
case TypeKind.F32: {
|
||||
ret = module.createBinary(
|
||||
BinaryOp.GtU32,
|
||||
module.createBinary(
|
||||
BinaryOp.AndI32,
|
||||
module.createUnary(UnaryOp.ReinterpretF32, arg0),
|
||||
module.createI32(0x7FFFFFFF)
|
||||
),
|
||||
module.createI32(0x7F800000)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case TypeKind.F64: {
|
||||
ret = module.createBinary(
|
||||
BinaryOp.GtU64,
|
||||
module.createBinary(
|
||||
BinaryOp.AndI64,
|
||||
module.createUnary(UnaryOp.ReinterpretF64, arg0),
|
||||
module.createI64(0xFFFFFFFF, 0x7FFFFFFF)
|
||||
),
|
||||
module.createI64(0, 0x7FF00000)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case TypeKind.VOID: {
|
||||
compiler.error(
|
||||
DiagnosticCode.Operation_not_supported,
|
||||
reportNode.range
|
||||
);
|
||||
ret = module.createUnreachable();
|
||||
break;
|
||||
}
|
||||
default: { // every other type is never NaN
|
||||
ret = module.createI32(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
compiler.currentType = Type.bool;
|
||||
return ret;
|
||||
}
|
||||
case "isFinite": { // isFinite<T?>(value: T) -> bool
|
||||
compiler.currentType = Type.bool;
|
||||
if (operands.length != 1) {
|
||||
if (typeArguments && typeArguments.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
}
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||
reportNode.range, "1", operands.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
if (typeArguments) {
|
||||
if (typeArguments.length != 1) {
|
||||
compiler.error(
|
||||
DiagnosticCode.Expected_0_type_arguments_but_got_1,
|
||||
reportNode.range, "1", typeArguments.length.toString(10)
|
||||
);
|
||||
return module.createUnreachable();
|
||||
}
|
||||
arg0 = compiler.compileExpression(operands[0], typeArguments[0]);
|
||||
} else {
|
||||
arg0 = compiler.compileExpression(operands[0], Type.f64, ConversionKind.NONE);
|
||||
}
|
||||
switch (compiler.currentType.kind) {
|
||||
case TypeKind.F32: {
|
||||
ret = module.createBinary(
|
||||
BinaryOp.LtU32,
|
||||
module.createBinary(
|
||||
BinaryOp.AndI32,
|
||||
module.createUnary(UnaryOp.ReinterpretF32, arg0),
|
||||
module.createI32(0x7FFFFFFF)
|
||||
),
|
||||
module.createI32(0x7F800000)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case TypeKind.F64: {
|
||||
ret = module.createBinary(
|
||||
BinaryOp.LtU64,
|
||||
module.createBinary(
|
||||
BinaryOp.AndI64,
|
||||
module.createUnary(UnaryOp.ReinterpretF64, arg0),
|
||||
module.createI64(0xFFFFFFFF, 0x7FFFFFFF)
|
||||
),
|
||||
module.createI64(0, 0x7FF00000)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case TypeKind.VOID: {
|
||||
compiler.error(
|
||||
DiagnosticCode.Operation_not_supported,
|
||||
reportNode.range
|
||||
);
|
||||
ret = module.createUnreachable();
|
||||
break;
|
||||
}
|
||||
default: { // every other type is always finite
|
||||
ret = module.createI32(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
compiler.currentType = Type.bool;
|
||||
return ret;
|
||||
}
|
||||
case "clz": { // clz<T?>(value: T) -> T
|
||||
if (operands.length != 1) {
|
||||
if (typeArguments) {
|
||||
|
Reference in New Issue
Block a user