Math scaffolding

This commit is contained in:
dcodeIO 2018-03-24 17:18:15 +01:00
parent 19a616dd96
commit 721d77012b
15 changed files with 1637 additions and 25 deletions

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1795,7 +1795,7 @@ export function compileCall(
}
return ret;
}
case "offsetof": { // offsetof<T!>(fieldName?)
case "offsetof": { // offsetof<T!>(fieldName?: string) -> usize
compiler.currentType = compiler.options.usizeType;
if (operands.length > 1) {
if (!(typeArguments && typeArguments.length == 1)) {

View File

@ -1745,6 +1745,7 @@ export class Compiler extends DiagnosticEmitter {
);
continue;
}
let isInlined = false;
if (declaration.is(CommonFlags.CONST)) {
if (init) {
init = this.precomputeExpressionRef(init);
@ -1787,10 +1788,10 @@ export class Compiler extends DiagnosticEmitter {
DiagnosticCode.Duplicate_identifier_0,
declaration.name.range, name
);
return 0;
return this.module.createUnreachable();
}
scopedLocals.set(name, local);
return 0;
isInlined = true;
} else {
this.warning(
DiagnosticCode.Compiling_constant_with_non_constant_initializer_as_mutable,
@ -1804,13 +1805,15 @@ export class Compiler extends DiagnosticEmitter {
);
}
}
if (declaration.is(CommonFlags.LET)) { // here: not top-level
currentFunction.flow.addScopedLocal(name, type, declaration.name); // reports
} else {
currentFunction.addLocal(type, name); // reports
}
if (init) {
initializers.push(this.compileAssignmentWithValue(declaration.name, init));
if (!isInlined) {
if (declaration.isAny(CommonFlags.LET | CommonFlags.CONST)) { // here: not top-level
currentFunction.flow.addScopedLocal(name, type, declaration.name); // reports
} else {
currentFunction.addLocal(type, name); // reports
}
if (init) {
initializers.push(this.compileAssignmentWithValue(declaration.name, init));
}
}
}
return initializers.length // we can unwrap these here because the

View File

@ -75,7 +75,9 @@ import {
VariableStatement,
VariableDeclaration,
VoidStatement,
WhileStatement
WhileStatement,
mangleInternalPath
} from "./ast";
const builtinsFile = LIBRARY_PREFIX + "builtins.ts";
@ -108,11 +110,12 @@ export class Parser extends DiagnosticEmitter {
// check if already parsed
var normalizedPath = normalizePath(path);
var internalPath = mangleInternalPath(normalizedPath);
var sources = program.sources;
for (let i = 0, k = sources.length; i < k; ++i) {
if (sources[i].normalizedPath == normalizedPath) return;
if (sources[i].internalPath == internalPath) return;
}
this.seenlog.add(normalizedPath);
this.seenlog.add(internalPath);
// create the source element
var source = new Source(
@ -1803,9 +1806,10 @@ export class Parser extends DiagnosticEmitter {
}
}
let ret = Node.createExportStatement(members, path, flags, tn.range(startPos, tn.pos));
if (ret.normalizedPath && !this.seenlog.has(<string>ret.normalizedPath)) {
this.backlog.push(<string>ret.normalizedPath);
this.seenlog.add(<string>ret.normalizedPath);
let internalPath = ret.internalPath;
if (internalPath != null && !this.seenlog.has(internalPath)) {
this.backlog.push(internalPath);
this.seenlog.add(internalPath);
}
tn.skip(Token.SEMICOLON);
return ret;
@ -1914,9 +1918,10 @@ export class Parser extends DiagnosticEmitter {
} else {
ret = Node.createImportStatement(members, path, tn.range(startPos, tn.pos));
}
if (!this.seenlog.has(ret.normalizedPath)) {
this.backlog.push(ret.normalizedPath);
this.seenlog.add(ret.normalizedPath);
let internalPath = ret.internalPath;
if (!this.seenlog.has(internalPath)) {
this.backlog.push(internalPath);
this.seenlog.add(internalPath);
}
tn.skip(Token.SEMICOLON);
return ret;

93
std/assembly.d.ts vendored
View File

@ -345,6 +345,99 @@ declare class Set<T> {
clear(): void;
}
declare namespace JSMath {
export const E: f64;
export const LN2: f64;
export const LN10: f64;
export const LOG2E: f64;
export const LOG10E: f64;
export const PI: f64;
export const SQRT1_2: f64;
export const SQRT2: f64;
export function abs(x: f64): f64;
export function acos(x: f64): f64;
export function acosh(x: f64): f64;
export function asin(x: f64): f64;
export function asinh(x: f64): f64;
export function atan(x: f64): f64;
export function atan2(y: f64, x: f64): f64;
export function atanh(x: f64): f64;
export function cbrt(x: f64): f64;
export function ceil(x: f64): f64;
export function clz32(x: f64): i32;
export function cos(x: f64): f64;
export function cosh(x: f64): f64;
export function exp(x: f64): f64;
export function expm1(x: f64): f64;
export function floor(x: f64): f64;
export function fround(x: f64): f32;
export function hypot(value1: f64, value2: f64): f64; // TODO: see std/math
export function imul(a: f64, b: f64): i32;
export function log(x: f64): f64;
export function log10(x: f64): f64;
export function log1p(x: f64): f64;
export function log2(x: f64): f64;
export function max(value1: f64, value2: f64): f64; // TODO: see std/math
export function min(value1: f64, value2: f64): f64; // TODO: see std/math
export function pow(base: f64, exponent: f64): f64;
export function random(): f64;
export function round(x: f64): f64;
export function sign(x: f64): f64;
export function sin(x: f64): f64;
export function sinh(x: f64): f64;
export function sqrt(x: f64): f64;
export function tan(x: f64): f64;
export function tanh(x: f64): f64;
export function trunc(x: f64): f64;
}
declare namespace Math {
export const E: f64;
export const LN2: f64;
export const LN10: f64;
export const LOG2E: f64;
export const LOG10E: f64;
export const PI: f64;
export const SQRT1_2: f64;
export const SQRT2: f64;
export function abs(x: f64): f64;
export function ceil(x: f64): f64;
export function clz32(x: f64): i32;
export function floor(x: f64): f64;
export function fround(x: f64): f32;
export function imul(a: f64, b: f64): i32;
export function log(x: f64): f64;
export function max(value1: f64, value2: f64): f64; // TODO: see std/math
export function min(value1: f64, value2: f64): f64; // TODO: see std/math
export function round(x: f64): f64;
export function sign(x: f64): f64;
export function sqrt(x: f64): f64;
export function trunc(x: f64): f64;
}
declare namespace Mathf {
export const E: f32;
export const LN2: f32;
export const LN10: f32;
export const LOG2E: f32;
export const LOG10E: f32;
export const PI: f32;
export const SQRT1_2: f32;
export const SQRT2: f32;
export function abs(x: f32): f32;
export function ceil(x: f32): f32;
export function clz32(x: f32): i32;
export function floor(x: f32): f32;
export function imul(a: f32, b: f32): i32;
export function log(x: f32): f32;
export function max(value1: f32, value2: f32): f32; // TODO: see std/math
export function min(value1: f32, value2: f32): f32; // TODO: see std/math
export function round(x: f32): f32;
export function sign(x: f32): f32;
export function sqrt(x: f32): f32;
export function trunc(x: f32): f32;
}
// Internal decorators
/** Annotates an element as a program global. */

View File

@ -38,7 +38,7 @@ export declare function floor<T>(value: T): T;
export declare function copysign<T>(left: T, right: T): T;
export declare function nearest<T>(left: T, right: T): T;
export declare function nearest<T>(value: T): T;
export declare function reinterpret<T>(value: void): T;

307
std/assembly/math.ts Normal file
View File

@ -0,0 +1,307 @@
export declare namespace JSMath {
export const E: f64;
export const LN2: f64;
export const LN10: f64;
export const LOG2E: f64;
export const LOG10E: f64;
export const PI: f64;
export const SQRT1_2: f64;
export const SQRT2: f64;
export function abs(x: f64): f64;
export function acos(x: f64): f64;
export function acosh(x: f64): f64;
export function asin(x: f64): f64;
export function asinh(x: f64): f64;
export function atan(x: f64): f64;
export function atan2(y: f64, x: f64): f64;
export function atanh(x: f64): f64;
export function cbrt(x: f64): f64;
export function ceil(x: f64): f64;
export function clz32(x: f64): i32;
export function cos(x: f64): f64;
export function cosh(x: f64): f64;
export function exp(x: f64): f64;
export function expm1(x: f64): f64;
export function floor(x: f64): f64;
export function fround(x: f64): f32;
export function hypot(value1: f64, value2: f64): f64; // hypot(...values: f64[]): f64;
export function imul(a: f64, b: f64): i32;
export function log(x: f64): f64;
export function log10(x: f64): f64;
export function log1p(x: f64): f64;
export function log2(x: f64): f64;
export function max(value1: f64, value2: f64): f64; // max(...values: f64[]): f64;
export function min(value1: f64, value2: f64): f64; // min(...values: f64[]): f64;
export function pow(base: f64, exponent: f64): f64;
export function random(): f64;
export function round(x: f64): f64;
export function sign(x: f64): f64;
export function sin(x: f64): f64;
export function sinh(x: f64): f64;
export function sqrt(x: f64): f64;
export function tan(x: f64): f64;
export function tanh(x: f64): f64;
export function trunc(x: f64): f64;
}
import {
abs as builtin_abs,
ceil as builtin_ceil,
clz as builtin_clz,
floor as builtin_floor,
max as builtin_max,
min as builtin_min,
nearest as builtin_nearest,
sqrt as builtin_sqrt,
trunc as builtin_trunc
} from "./builtins";
export namespace Math {
export const E = 2.7182818284590452354;
export const LN2 = 0.69314718055994530942;
export const LN10 = 2.30258509299404568402;
export const LOG2E = 1.4426950408889634074;
export const LOG10E = 0.43429448190325182765;
export const PI = 3.14159265358979323846;
export const SQRT1_2 = 0.70710678118654752440;
export const SQRT2 = 1.41421356237309504880;
export function abs(x: f64): f64 {
return builtin_abs(x);
}
export function ceil(x: f64): f64 {
return builtin_ceil(x);
}
export function clz32(x: f64): i32 {
return builtin_clz(<i32>x);
}
export function floor(x: f64): f64 {
return builtin_floor(x);
}
export function fround(x: f64): f32 {
return <f32>x;
}
export function imul(x: f64, y: f64): i32 {
return <i32>x * <i32>y;
}
export function log(x: f64): f64 {
// based on musl's implementation of log:
// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
// Developed at SunPro, a Sun Microsystems, Inc. business.
// Permission to use, copy, modify, and distribute this
// software is freely granted, provided that this notice
// is preserved.
const
ln2_hi = 6.93147180369123816490e-01, // 3fe62e42 fee00000
ln2_lo = 1.90821492927058770002e-10, // 3dea39ef 35793c76
Lg1 = 6.666666666666735130e-01, // 3FE55555 55555593
Lg2 = 3.999999999940941908e-01, // 3FD99999 9997FA04
Lg3 = 2.857142874366239149e-01, // 3FD24924 94229359
Lg4 = 2.222219843214978396e-01, // 3FCC71C5 1D8E78AF
Lg5 = 1.818357216161805012e-01, // 3FC74664 96CB03DE
Lg6 = 1.531383769920937332e-01, // 3FC39A09 D078C69F
Lg7 = 1.479819860511658591e-01; // 3FC2F112 DF3E5244
var u = reinterpret<u64>(x);
var hfsq: f64, f: f64, s: f64, z: f64, R: f64, w: f64, t1: f64, t2: f64, dk: f64;
var hx = <u32>(u >> 32);
var k = 0;
if (hx < 0x00100000 || <bool>(hx>>31)) {
if (u<<1 == 0) {
return -1/(x*x); // log(+-0)=-inf
}
if (hx>>31) {
return (x-x)/0.0; // log(-#) = NaN
}
// subnormal number, scale x up
k -= 54;
x *= 1.8014398509481984e16; // 0x1p54
u = reinterpret<u64>(x);
hx = <u32>(u>>32);
} else if (hx >= 0x7ff00000) {
return x;
} else if (hx == 0x3ff00000 && u<<32 == 0) {
return 0;
}
// reduce x into [sqrt(2)/2, sqrt(2)]
hx += 0x3ff00000 - 0x3fe6a09e;
k += (<i32>hx>>20) - 0x3ff;
hx = (hx&0x000fffff) + 0x3fe6a09e;
u = <u64>hx<<32 | (u&0xffffffff);
x = reinterpret<f64>(u);
f = x - 1.0;
hfsq = 0.5*f*f;
s = f/(2.0+f);
z = s*s;
w = z*z;
t1 = w*(Lg2+w*(Lg4+w*Lg6));
t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
R = t2 + t1;
dk = k;
return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
}
// export function log2(x: f64): f64 {
// return log(x) / LN2;
// }
// export function log10(x: f64): f64 {
// return log(x) / LN10;
// }
export function max(value1: f64, value2: f64): f64 {
return builtin_max(value1, value2);
}
export function min(value1: f64, value2: f64): f64 {
return builtin_min(value1, value2);
}
export function round(x: f64): f64 {
return builtin_nearest(x);
}
export function sign(x: f64): f64 {
return x > 0 ? 1 : x < 0 ? -1 : x;
}
export function sqrt(x: f64): f64 {
return builtin_sqrt(x);
}
export function trunc(x: f64): f64 {
return builtin_trunc(x);
}
}
export namespace Mathf {
export const E = <f32>Math.E;
export const LN2 = <f32>Math.LN2;
export const LN10 = <f32>Math.LN10;
export const LOG2E = <f32>Math.LOG2E;
export const LOG10E = <f32>Math.LOG10E;
export const PI = <f32>Math.PI;
export const SQRT1_2 = <f32>Math.SQRT1_2;
export const SQRT2 = <f32>Math.SQRT2;
export function abs(x: f32): f32 {
return builtin_abs(x);
}
export function ceil(x: f32): f32 {
return builtin_ceil(x);
}
export function clz32(x: f32): i32 {
return builtin_clz(<i32>x);
}
export function floor(x: f32): f32 {
return builtin_floor(x);
}
export function imul(x: f32, y: f32): i32 {
return <i32>x * <i32>y;
}
export function log(x: f32): f32 {
// based on musl's implementaion of logf:
// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
// Developed at SunPro, a Sun Microsystems, Inc. business.
// Permission to use, copy, modify, and distribute this
// software is freely granted, provided that this notice
// is preserved.
const
ln2_hi: f32 = 6.9313812256e-01, // 0x3f317180
ln2_lo: f32 = 9.0580006145e-06, // 0x3717f7d1
Lg1: f32 = 0.66666662693, // 0xaaaaaa.0p-24
Lg2: f32 = 0.40000972152, // 0xccce13.0p-25
Lg3: f32 = 0.28498786688, // 0x91e9ee.0p-25
Lg4: f32 = 0.24279078841; // 0xf89e26.0p-26
var u = reinterpret<u32>(x);
var hfsq: f32, f: f32, s: f32, z: f32, R: f32, w: f32, t1: f32, t2: f32, dk: f32;
var ix = u;
var k = 0;
if (ix < 0x00800000 || <bool>(ix>>31)) { // x < 2**-126
if (ix<<1 == 0) {
return -1/(x*x); // log(+-0)=-inf
}
if (ix>>31) {
return (x-x)/<f32>0; // log(-#) = NaN
}
// subnormal number, scale up x
k -= 25;
x *= 3.3554432; // 0x1p25f;
u = reinterpret<u32>(x);
ix = u;
} else if (ix >= 0x7f800000) {
return x;
} else if (ix == 0x3f800000) {
return 0;
}
// reduce x into [sqrt(2)/2, sqrt(2)]
ix += 0x3f800000 - 0x3f3504f3;
k += <u32>(<i32>ix>>23) - 0x7f;
ix = (ix&0x007fffff) + 0x3f3504f3;
x = reinterpret<f32>(ix);
f = x - 1.0;
s = f/(2.0 + f);
z = s*s;
w = z*z;
t1= w*(Lg2+w*Lg4);
t2= z*(Lg1+w*Lg3);
R = t2 + t1;
hfsq = 0.5*f*f;
dk = <f32>k;
return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
}
// export function log2(x: f32): f32 {
// return log(x) / LN2;
// }
// export function log10(x: f32): f32 {
// return log(x) / LN10;
// }
export function max(value1: f32, value2: f32): f32 {
return builtin_max(value1, value2);
}
export function min(value1: f32, value2: f32): f32 {
return builtin_min(value1, value2);
}
export function round(x: f32): f32 {
return builtin_nearest(x);
}
export function sign(x: f32): f32 {
return x > 0 ? 1 : x < 0 ? -1 : x;
}
export function sqrt(x: f32): f32 {
return builtin_sqrt(x);
}
export function trunc(x: f32): f32 {
return builtin_trunc(x);
}
}

46
std/portable.d.ts vendored
View File

@ -310,6 +310,52 @@ interface Iterable<T> {
interface Iterator<T> {}
declare namespace Math {
export const E: f64;
export const LN2: f64;
export const LN10: f64;
export const LOG2E: f64;
export const LOG10E: f64;
export const PI: f64;
export const SQRT1_2: f64;
export const SQRT2: f64;
export function abs(x: f64): f64;
export function acos(x: f64): f64;
export function acosh(x: f64): f64;
export function asin(x: f64): f64;
export function asinh(x: f64): f64;
export function atan(x: f64): f64;
export function atan2(y: f64, x: f64): f64;
export function atanh(x: f64): f64;
export function cbrt(x: f64): f64;
export function ceil(x: f64): f64;
export function clz32(x: f64): i32;
export function cos(x: f64): f64;
export function cosh(x: f64): f64;
export function exp(x: f64): f64;
export function expm1(x: f64): f64;
export function floor(x: f64): f64;
export function fround(x: f64): f32;
export function hypot(value1: f64, value2: f64): f64; // TODO: see std/math
export function imul(a: f64, b: f64): i32;
export function log(x: f64): f64;
export function log10(x: f64): f64;
export function log1p(x: f64): f64;
export function log2(x: f64): f64;
export function max(value1: f64, value2: f64): f64; // TODO: see std/math
export function min(value1: f64, value2: f64): f64; // TODO: see std/math
export function pow(base: f64, exponent: f64): f64;
export function random(): f64;
export function round(x: f64): f64;
export function sign(x: f64): f64;
export function sin(x: f64): f64;
export function sinh(x: f64): f64;
export function sqrt(x: f64): f64;
export function tan(x: f64): f64;
export function tanh(x: f64): f64;
export function trunc(x: f64): f64;
}
declare namespace console {
/** @deprecated */
function log(message: string): void;

View File

@ -120,7 +120,8 @@ tests.forEach(filename => {
my: {
externalFunction: function() { },
externalConstant: 2
}
},
JSMath: Math
});
console.log("- " + chalk.green("instantiate OK"));
} catch (e) {

View File

@ -0,0 +1,524 @@
(module
(type $FF (func (param f64) (result f64)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $ff (func (param f32) (result f32)))
(type $Ff (func (param f64) (result f32)))
(type $v (func))
(import "JSMath" "log" (func $(lib)/math/JSMath.log (param f64) (result f64)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(import "JSMath" "fround" (func $(lib)/math/JSMath.fround (param f64) (result f32)))
(memory $0 1)
(data (i32.const 4) "\0b\00\00\00s\00t\00d\00/\00m\00a\00t\00h\00.\00t\00s")
(export "memory" (memory $0))
(start $start)
(func "$(lib)/math/Math.log" (; 3 ;) (type $FF) (param $0 f64) (result f64)
(local $1 i32)
(local $2 i32)
(local $3 i64)
(local $4 f64)
(local $5 i32)
(local $6 f64)
(local $7 f64)
(local $8 f64)
(if
(i32.and
(if (result i32)
(tee_local $5
(i32.lt_u
(tee_local $1
(i32.wrap/i64
(i64.shr_u
(tee_local $3
(i64.reinterpret/f64
(get_local $0)
)
)
(i64.const 32)
)
)
)
(i32.const 1048576)
)
)
(get_local $5)
(i32.shr_u
(get_local $1)
(i32.const 31)
)
)
(i32.const 1)
)
(block
(if
(i64.eq
(i64.shl
(get_local $3)
(i64.const 1)
)
(i64.const 0)
)
(return
(f64.div
(f64.const -1)
(f64.mul
(get_local $0)
(get_local $0)
)
)
)
)
(if
(i32.shr_u
(get_local $1)
(i32.const 31)
)
(return
(f64.div
(f64.sub
(get_local $0)
(get_local $0)
)
(f64.const 0)
)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 54)
)
)
(set_local $1
(i32.wrap/i64
(i64.shr_u
(tee_local $3
(i64.reinterpret/f64
(f64.mul
(get_local $0)
(f64.const 18014398509481984)
)
)
)
(i64.const 32)
)
)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.const 2146435072)
)
(return
(get_local $0)
)
(if
(i32.and
(if (result i32)
(tee_local $5
(i32.eq
(get_local $1)
(i32.const 1072693248)
)
)
(i64.eq
(i64.shl
(get_local $3)
(i64.const 32)
)
(i64.const 0)
)
(get_local $5)
)
(i32.const 1)
)
(return
(f64.const 0)
)
)
)
)
(set_local $2
(i32.add
(get_local $2)
(i32.sub
(i32.shr_s
(tee_local $1
(i32.add
(get_local $1)
(i32.const 614242)
)
)
(i32.const 20)
)
(i32.const 1023)
)
)
)
(set_local $6
(f64.mul
(f64.mul
(f64.const 0.5)
(tee_local $4
(f64.sub
(f64.reinterpret/i64
(i64.or
(i64.shl
(i64.extend_u/i32
(i32.add
(i32.and
(get_local $1)
(i32.const 1048575)
)
(i32.const 1072079006)
)
)
(i64.const 32)
)
(i64.and
(get_local $3)
(i64.const 4294967295)
)
)
)
(f64.const 1)
)
)
)
(get_local $4)
)
)
(set_local $0
(f64.mul
(tee_local $8
(f64.mul
(tee_local $7
(f64.div
(get_local $4)
(f64.add
(f64.const 2)
(get_local $4)
)
)
)
(get_local $7)
)
)
(get_local $8)
)
)
(f64.add
(f64.add
(f64.sub
(f64.add
(f64.mul
(get_local $7)
(f64.add
(get_local $6)
(f64.add
(f64.mul
(get_local $8)
(f64.add
(f64.const 0.6666666666666735)
(f64.mul
(get_local $0)
(f64.add
(f64.const 0.2857142874366239)
(f64.mul
(get_local $0)
(f64.add
(f64.const 0.1818357216161805)
(f64.mul
(get_local $0)
(f64.const 0.14798198605116586)
)
)
)
)
)
)
)
(f64.mul
(get_local $0)
(f64.add
(f64.const 0.3999999999940942)
(f64.mul
(get_local $0)
(f64.add
(f64.const 0.22222198432149784)
(f64.mul
(get_local $0)
(f64.const 0.15313837699209373)
)
)
)
)
)
)
)
)
(f64.mul
(tee_local $0
(f64.convert_s/i32
(get_local $2)
)
)
(f64.const 1.9082149292705877e-10)
)
)
(get_local $6)
)
(get_local $4)
)
(f64.mul
(get_local $0)
(f64.const 0.6931471803691238)
)
)
)
(func "$(lib)/math/Mathf.log" (; 4 ;) (type $ff) (param $0 f32) (result f32)
(local $1 i32)
(local $2 i32)
(local $3 f32)
(local $4 f32)
(local $5 f32)
(local $6 i32)
(if
(i32.and
(if (result i32)
(tee_local $6
(i32.lt_u
(tee_local $1
(i32.reinterpret/f32
(get_local $0)
)
)
(i32.const 8388608)
)
)
(get_local $6)
(i32.shr_u
(get_local $1)
(i32.const 31)
)
)
(i32.const 1)
)
(block
(if
(i32.eqz
(i32.shl
(get_local $1)
(i32.const 1)
)
)
(return
(f32.div
(f32.const -1)
(f32.mul
(get_local $0)
(get_local $0)
)
)
)
)
(if
(i32.shr_u
(get_local $1)
(i32.const 31)
)
(return
(f32.div
(f32.sub
(get_local $0)
(get_local $0)
)
(f32.const 0)
)
)
)
(set_local $2
(i32.sub
(get_local $2)
(i32.const 25)
)
)
(set_local $1
(i32.reinterpret/f32
(f32.mul
(get_local $0)
(f32.const 3.355443239212036)
)
)
)
)
(if
(i32.ge_u
(get_local $1)
(i32.const 2139095040)
)
(return
(get_local $0)
)
(if
(i32.eq
(get_local $1)
(i32.const 1065353216)
)
(return
(f32.const 0)
)
)
)
)
(set_local $2
(i32.add
(get_local $2)
(i32.sub
(i32.shr_s
(tee_local $1
(i32.add
(get_local $1)
(i32.const 4913933)
)
)
(i32.const 23)
)
(i32.const 127)
)
)
)
(set_local $3
(f32.mul
(tee_local $5
(f32.mul
(tee_local $4
(f32.div
(tee_local $0
(f32.sub
(f32.reinterpret/i32
(i32.add
(i32.and
(get_local $1)
(i32.const 8388607)
)
(i32.const 1060439283)
)
)
(f32.const 1)
)
)
(f32.add
(f32.const 2)
(get_local $0)
)
)
)
(get_local $4)
)
)
(get_local $5)
)
)
(f32.add
(f32.add
(f32.sub
(f32.add
(f32.mul
(get_local $4)
(f32.add
(tee_local $4
(f32.mul
(f32.mul
(f32.const 0.5)
(get_local $0)
)
(get_local $0)
)
)
(f32.add
(f32.mul
(get_local $5)
(f32.add
(f32.const 0.6666666269302368)
(f32.mul
(get_local $3)
(f32.const 0.2849878668785095)
)
)
)
(f32.mul
(get_local $3)
(f32.add
(f32.const 0.40000972151756287)
(f32.mul
(get_local $3)
(f32.const 0.24279078841209412)
)
)
)
)
)
)
(f32.mul
(tee_local $3
(f32.convert_s/i32
(get_local $2)
)
)
(f32.const 9.05800061445916e-06)
)
)
(get_local $4)
)
(get_local $0)
)
(f32.mul
(get_local $3)
(f32.const 0.6931381225585938)
)
)
)
(func $start (; 5 ;) (type $v)
(if
(f64.ne
(call "$(lib)/math/Math.log"
(f64.const 123)
)
(call "$(lib)/math/JSMath.log"
(f64.const 123)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 2)
(i32.const 0)
)
(unreachable)
)
)
(if
(f32.ne
(call "$(lib)/math/Mathf.log"
(f32.const 123)
)
(call "$(lib)/math/JSMath.fround"
(call "$(lib)/math/JSMath.log"
(f64.const 123)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 3)
(i32.const 0)
)
(unreachable)
)
)
)
)

View File

@ -0,0 +1,3 @@
// TODO
assert(Math.log(123) == JSMath.log(123));
assert(Mathf.log(123) == JSMath.fround(JSMath.log(123)));

View File

@ -0,0 +1,630 @@
(module
(type $FF (func (param f64) (result f64)))
(type $F (func (result f64)))
(type $iiiiv (func (param i32 i32 i32 i32)))
(type $ff (func (param f32) (result f32)))
(type $f (func (result f32)))
(type $Ff (func (param f64) (result f32)))
(type $v (func))
(import "JSMath" "log" (func $(lib)/math/JSMath.log (param f64) (result f64)))
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
(import "JSMath" "fround" (func $(lib)/math/JSMath.fround (param f64) (result f32)))
(global $HEAP_BASE i32 (i32.const 32))
(memory $0 1)
(data (i32.const 4) "\0b\00\00\00s\00t\00d\00/\00m\00a\00t\00h\00.\00t\00s\00")
(export "memory" (memory $0))
(start $start)
(func "$(lib)/math/Math.log" (; 3 ;) (type $FF) (param $0 f64) (result f64)
(local $1 i64)
(local $2 f64)
(local $3 f64)
(local $4 f64)
(local $5 f64)
(local $6 f64)
(local $7 f64)
(local $8 f64)
(local $9 f64)
(local $10 f64)
(local $11 i32)
(local $12 i32)
(local $13 i32)
(nop)
(set_local $1
(i64.reinterpret/f64
(get_local $0)
)
)
(nop)
(set_local $11
(i32.wrap/i64
(i64.shr_u
(get_local $1)
(i64.const 32)
)
)
)
(set_local $12
(i32.const 0)
)
(if
(i32.and
(if (result i32)
(tee_local $13
(i32.lt_u
(get_local $11)
(i32.const 1048576)
)
)
(get_local $13)
(i32.and
(i32.shr_u
(get_local $11)
(i32.const 31)
)
(i32.const 1)
)
)
(i32.const 1)
)
(block
(if
(i64.eq
(i64.shl
(get_local $1)
(i64.const 1)
)
(i64.const 0)
)
(return
(f64.div
(f64.const -1)
(f64.mul
(get_local $0)
(get_local $0)
)
)
)
)
(if
(i32.shr_u
(get_local $11)
(i32.const 31)
)
(return
(f64.div
(f64.sub
(get_local $0)
(get_local $0)
)
(f64.const 0)
)
)
)
(set_local $12
(i32.sub
(get_local $12)
(i32.const 54)
)
)
(set_local $0
(f64.mul
(get_local $0)
(f64.const 18014398509481984)
)
)
(set_local $1
(i64.reinterpret/f64
(get_local $0)
)
)
(set_local $11
(i32.wrap/i64
(i64.shr_u
(get_local $1)
(i64.const 32)
)
)
)
)
(if
(i32.ge_u
(get_local $11)
(i32.const 2146435072)
)
(return
(get_local $0)
)
(if
(i32.and
(if (result i32)
(tee_local $13
(i32.eq
(get_local $11)
(i32.const 1072693248)
)
)
(i64.eq
(i64.shl
(get_local $1)
(i64.const 32)
)
(i64.const 0)
)
(get_local $13)
)
(i32.const 1)
)
(return
(f64.const 0)
)
)
)
)
(set_local $11
(i32.add
(get_local $11)
(i32.sub
(i32.const 1072693248)
(i32.const 1072079006)
)
)
)
(set_local $12
(i32.add
(get_local $12)
(i32.sub
(i32.shr_s
(get_local $11)
(i32.const 20)
)
(i32.const 1023)
)
)
)
(set_local $11
(i32.add
(i32.and
(get_local $11)
(i32.const 1048575)
)
(i32.const 1072079006)
)
)
(set_local $1
(i64.or
(i64.shl
(i64.extend_u/i32
(get_local $11)
)
(i64.const 32)
)
(i64.and
(get_local $1)
(i64.const 4294967295)
)
)
)
(set_local $0
(f64.reinterpret/i64
(get_local $1)
)
)
(set_local $3
(f64.sub
(get_local $0)
(f64.const 1)
)
)
(set_local $2
(f64.mul
(f64.mul
(f64.const 0.5)
(get_local $3)
)
(get_local $3)
)
)
(set_local $4
(f64.div
(get_local $3)
(f64.add
(f64.const 2)
(get_local $3)
)
)
)
(set_local $5
(f64.mul
(get_local $4)
(get_local $4)
)
)
(set_local $7
(f64.mul
(get_local $5)
(get_local $5)
)
)
(set_local $8
(f64.mul
(get_local $7)
(f64.add
(f64.const 0.3999999999940942)
(f64.mul
(get_local $7)
(f64.add
(f64.const 0.22222198432149784)
(f64.mul
(get_local $7)
(f64.const 0.15313837699209373)
)
)
)
)
)
)
(set_local $9
(f64.mul
(get_local $5)
(f64.add
(f64.const 0.6666666666666735)
(f64.mul
(get_local $7)
(f64.add
(f64.const 0.2857142874366239)
(f64.mul
(get_local $7)
(f64.add
(f64.const 0.1818357216161805)
(f64.mul
(get_local $7)
(f64.const 0.14798198605116586)
)
)
)
)
)
)
)
)
(set_local $6
(f64.add
(get_local $9)
(get_local $8)
)
)
(set_local $10
(f64.convert_s/i32
(get_local $12)
)
)
(return
(f64.add
(f64.add
(f64.sub
(f64.add
(f64.mul
(get_local $4)
(f64.add
(get_local $2)
(get_local $6)
)
)
(f64.mul
(get_local $10)
(f64.const 1.9082149292705877e-10)
)
)
(get_local $2)
)
(get_local $3)
)
(f64.mul
(get_local $10)
(f64.const 0.6931471803691238)
)
)
)
)
(func "$(lib)/math/Mathf.log" (; 4 ;) (type $ff) (param $0 f32) (result f32)
(local $1 i32)
(local $2 f32)
(local $3 f32)
(local $4 f32)
(local $5 f32)
(local $6 f32)
(local $7 f32)
(local $8 f32)
(local $9 f32)
(local $10 f32)
(local $11 i32)
(local $12 i32)
(local $13 i32)
(nop)
(set_local $1
(i32.reinterpret/f32
(get_local $0)
)
)
(nop)
(set_local $11
(get_local $1)
)
(set_local $12
(i32.const 0)
)
(if
(i32.and
(if (result i32)
(tee_local $13
(i32.lt_u
(get_local $11)
(i32.const 8388608)
)
)
(get_local $13)
(i32.and
(i32.shr_u
(get_local $11)
(i32.const 31)
)
(i32.const 1)
)
)
(i32.const 1)
)
(block
(if
(i32.eq
(i32.shl
(get_local $11)
(i32.const 1)
)
(i32.const 0)
)
(return
(f32.div
(f32.const -1)
(f32.mul
(get_local $0)
(get_local $0)
)
)
)
)
(if
(i32.shr_u
(get_local $11)
(i32.const 31)
)
(return
(f32.div
(f32.sub
(get_local $0)
(get_local $0)
)
(f32.const 0)
)
)
)
(set_local $12
(i32.sub
(get_local $12)
(i32.const 25)
)
)
(set_local $0
(f32.mul
(get_local $0)
(f32.const 3.355443239212036)
)
)
(set_local $1
(i32.reinterpret/f32
(get_local $0)
)
)
(set_local $11
(get_local $1)
)
)
(if
(i32.ge_u
(get_local $11)
(i32.const 2139095040)
)
(return
(get_local $0)
)
(if
(i32.eq
(get_local $11)
(i32.const 1065353216)
)
(return
(f32.const 0)
)
)
)
)
(set_local $11
(i32.add
(get_local $11)
(i32.sub
(i32.const 1065353216)
(i32.const 1060439283)
)
)
)
(set_local $12
(i32.add
(get_local $12)
(i32.sub
(i32.shr_s
(get_local $11)
(i32.const 23)
)
(i32.const 127)
)
)
)
(set_local $11
(i32.add
(i32.and
(get_local $11)
(i32.const 8388607)
)
(i32.const 1060439283)
)
)
(set_local $0
(f32.reinterpret/i32
(get_local $11)
)
)
(set_local $3
(f32.sub
(get_local $0)
(f32.const 1)
)
)
(set_local $4
(f32.div
(get_local $3)
(f32.add
(f32.const 2)
(get_local $3)
)
)
)
(set_local $5
(f32.mul
(get_local $4)
(get_local $4)
)
)
(set_local $7
(f32.mul
(get_local $5)
(get_local $5)
)
)
(set_local $8
(f32.mul
(get_local $7)
(f32.add
(f32.const 0.40000972151756287)
(f32.mul
(get_local $7)
(f32.const 0.24279078841209412)
)
)
)
)
(set_local $9
(f32.mul
(get_local $5)
(f32.add
(f32.const 0.6666666269302368)
(f32.mul
(get_local $7)
(f32.const 0.2849878668785095)
)
)
)
)
(set_local $6
(f32.add
(get_local $9)
(get_local $8)
)
)
(set_local $2
(f32.mul
(f32.mul
(f32.const 0.5)
(get_local $3)
)
(get_local $3)
)
)
(set_local $10
(f32.convert_s/i32
(get_local $12)
)
)
(return
(f32.add
(f32.add
(f32.sub
(f32.add
(f32.mul
(get_local $4)
(f32.add
(get_local $2)
(get_local $6)
)
)
(f32.mul
(get_local $10)
(f32.const 9.05800061445916e-06)
)
)
(get_local $2)
)
(get_local $3)
)
(f32.mul
(get_local $10)
(f32.const 0.6931381225585938)
)
)
)
)
(func $start (; 5 ;) (type $v)
(if
(i32.eqz
(f64.eq
(call "$(lib)/math/Math.log"
(f64.const 123)
)
(call "$(lib)/math/JSMath.log"
(f64.const 123)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 2)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(f32.eq
(call "$(lib)/math/Mathf.log"
(f32.const 123)
)
(call "$(lib)/math/JSMath.fround"
(call "$(lib)/math/JSMath.log"
(f64.const 123)
)
)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 3)
(i32.const 0)
)
(unreachable)
)
)
)
)