mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Update dist files; Also parse name and source mapping sections in lib/parse
This commit is contained in:
parent
c45a35b1c1
commit
acfef646ef
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
#  parse
|
||||
|
||||
A WebAssembly binary parser in WebAssembly.
|
||||
A WebAssembly binary parser in WebAssembly. Super small, super fast, with TypeScript support.
|
||||
|
||||
API
|
||||
---
|
||||
@ -53,6 +53,18 @@ API
|
||||
* **onExport**?(index: `number`, kind: `ExternalKind`, kindIndex: `number`, nameOff: `number`, nameLen: `number`): `void`<br />
|
||||
Called with each export if the export section is evaluated.
|
||||
|
||||
* **onSourceMappingURL**?(offset: `number`, length: `number`): `void`<br />
|
||||
Called with the source map URL if the 'sourceMappingURL' section is evaluated.
|
||||
|
||||
* **onModuleName**?(offset: `number`, length: `number`): `void`<br />
|
||||
Called with the module name if present and the 'name' section is evaluated.
|
||||
|
||||
* **onFunctionName**?(index: `number`, offset: `number`, length: `number`): `void`<br />
|
||||
Called with each function name if present and the 'name' section is evaluated.
|
||||
|
||||
* **onLocalName**?(funcIndex: `number`, index: `number`, offset: `number`, length: `number`): `void`<br />
|
||||
Called with each local name if present and the 'name' section is evaluated.
|
||||
|
||||
* **Type**<br />
|
||||
A value or element type, depending on context.
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
Type,
|
||||
SectionId,
|
||||
ExternalKind,
|
||||
NameType,
|
||||
MAX_PAGES,
|
||||
MAX_TABLES,
|
||||
Opcode
|
||||
@ -90,14 +91,22 @@ declare function onFunction(index: u32, typeIndex: u32): void;
|
||||
declare function onGlobal(index: u32, type: u32, mutability: u32): void;
|
||||
declare function onExport(index: u32, kind: u32, kindIndex: u32, nameOffset: u32, nameLength: u32): void;
|
||||
declare function onStart(index: u32): void;
|
||||
declare function onSourceMappingURL(offset: u32, length: u32): void;
|
||||
declare function onModuleName(offset: u32, length: u32): void;
|
||||
declare function onFunctionName(index: u32, offset: u32, length: u32): void;
|
||||
declare function onLocalName(funcIndex: u32, index: u32, offset: u32, length: u32): void;
|
||||
|
||||
/** Starts parsing the module that has been placed in memory. */
|
||||
function parse(): void {
|
||||
export function parse(begin: usize, end: usize): void {
|
||||
off = begin;
|
||||
var magic = readUint<u32>();
|
||||
if (magic != 0x6D736100) unreachable();
|
||||
var version = readUint<u32>();
|
||||
if (version != 1) unreachable();
|
||||
var end: usize = current_memory() << 16;
|
||||
var fun_space_index: u32 = 0;
|
||||
var glo_space_index: u32 = 0;
|
||||
var mem_space_index: u32 = 0;
|
||||
var tbl_space_index: u32 = 0;
|
||||
while (off < end) {
|
||||
let section_off = off;
|
||||
let id = readVaruint(7);
|
||||
@ -105,13 +114,11 @@ function parse(): void {
|
||||
let name_off = 0;
|
||||
let name_len = 0;
|
||||
if (!id) {
|
||||
let before = off;
|
||||
name_len = readVaruint(32);
|
||||
if (!name_len) {
|
||||
off = section_off;
|
||||
break;
|
||||
}
|
||||
name_off = off;
|
||||
off += name_len;
|
||||
payload_len -= off - before;
|
||||
} else if (id > <u32>SectionId.Data) unreachable();
|
||||
let payload_off = off;
|
||||
if (onSection(
|
||||
@ -126,16 +133,27 @@ function parse(): void {
|
||||
let count = readVaruint(32);
|
||||
for (let index: u32 = 0; index < count; ++index) {
|
||||
let form = readVarint(7) & 0x7f;
|
||||
onType(index, form);
|
||||
onType(
|
||||
index,
|
||||
form
|
||||
);
|
||||
let paramCount = readVaruint(32);
|
||||
for (let paramIndex: u32 = 0; paramIndex < paramCount; ++paramIndex) {
|
||||
let paramType = readVarint(7) & 0x7f;
|
||||
onTypeParam(index, paramIndex, paramType);
|
||||
onTypeParam(
|
||||
index,
|
||||
paramIndex,
|
||||
paramType
|
||||
);
|
||||
}
|
||||
let returnCount = readVaruint(1); // MVP
|
||||
for (let returnIndex: u32 = 0; returnIndex < returnCount; ++returnIndex) {
|
||||
let returnType = readVarint(7) & 0x7f;
|
||||
onTypeReturn(index, returnIndex, returnType);
|
||||
onTypeReturn(
|
||||
index,
|
||||
returnIndex,
|
||||
returnType
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -145,10 +163,10 @@ function parse(): void {
|
||||
for (let index: u32 = 0; index < count; ++index) {
|
||||
let module_len = readVaruint(32);
|
||||
let module_off = off;
|
||||
off += module_off;
|
||||
off += module_len;
|
||||
let field_len = readVaruint(32);
|
||||
let field_off = off;
|
||||
off += field_off;
|
||||
off += field_len;
|
||||
let kind = readUint<u8>();
|
||||
onImport(
|
||||
index,
|
||||
@ -161,7 +179,10 @@ function parse(): void {
|
||||
switch (kind) {
|
||||
case ExternalKind.Function: {
|
||||
let type = readVaruint(32);
|
||||
onFunctionImport(index, type);
|
||||
onFunctionImport(
|
||||
fun_space_index++,
|
||||
type
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ExternalKind.Table: {
|
||||
@ -169,20 +190,35 @@ function parse(): void {
|
||||
let flags = readVaruint(1);
|
||||
let initial = readVaruint(32);
|
||||
let maximum: u32 = flags & 1 ? readVaruint(32) : MAX_TABLES;
|
||||
onTableImport(index, type, initial, maximum, flags);
|
||||
onTableImport(
|
||||
tbl_space_index++,
|
||||
type,
|
||||
initial,
|
||||
maximum,
|
||||
flags
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ExternalKind.Memory: {
|
||||
let flags = readVaruint(1);
|
||||
let initial = readVaruint(32);
|
||||
let maximum: u32 = flags & 1 ? readVaruint(32) : MAX_PAGES;
|
||||
onMemoryImport(index, initial, maximum, flags);
|
||||
onMemoryImport(
|
||||
mem_space_index++,
|
||||
initial,
|
||||
maximum,
|
||||
flags
|
||||
);
|
||||
break;
|
||||
}
|
||||
case ExternalKind.Global: {
|
||||
let type = readVarint(7) & 0x7f;
|
||||
let mutability = readVaruint(1);
|
||||
onGlobalImport(index, type, mutability);
|
||||
onGlobalImport(
|
||||
glo_space_index++,
|
||||
type,
|
||||
mutability
|
||||
);
|
||||
break;
|
||||
}
|
||||
default: unreachable();
|
||||
@ -192,9 +228,12 @@ function parse(): void {
|
||||
}
|
||||
case SectionId.Function: {
|
||||
let count = readVaruint(32);
|
||||
for (let index: u32 = 0; index < count; ++index) {
|
||||
for (let i: u32 = 0; i < count; ++i) {
|
||||
let typeIndex = readVaruint(32);
|
||||
onFunction(index, typeIndex);
|
||||
onFunction(
|
||||
fun_space_index++,
|
||||
typeIndex
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -204,13 +243,18 @@ function parse(): void {
|
||||
let flags = readVaruint(1);
|
||||
let initial = readVaruint(32);
|
||||
let maximum: u32 = flags ? readVaruint(32) : MAX_PAGES;
|
||||
onMemory(index, initial, maximum, flags);
|
||||
onMemory(
|
||||
mem_space_index++,
|
||||
initial,
|
||||
maximum,
|
||||
flags
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SectionId.Global: {
|
||||
let count = readVaruint(32);
|
||||
for (let index: u32 = 0; index < count; ++index) {
|
||||
for (let i: u32 = 0; i < count; ++i) {
|
||||
let type = readVarint(7) & 0x7f;
|
||||
let mutability = readVaruint(1);
|
||||
let op = readUint<u8>();
|
||||
@ -239,7 +283,11 @@ function parse(): void {
|
||||
}
|
||||
op = readUint<u8>();
|
||||
if (op != Opcode.end) unreachable();
|
||||
onGlobal(index, type, mutability);
|
||||
onGlobal(
|
||||
glo_space_index++,
|
||||
type,
|
||||
mutability
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -268,8 +316,80 @@ function parse(): void {
|
||||
);
|
||||
break;
|
||||
}
|
||||
case SectionId.Custom:
|
||||
case SectionId.Code: { // TODO
|
||||
case SectionId.Custom: {
|
||||
if (
|
||||
name_len == 4 &&
|
||||
load<u32>(name_off) == 0x656D616E // "name"
|
||||
) {
|
||||
let name_type = readVaruint(7);
|
||||
let name_payload_len = readVaruint(32);
|
||||
let name_payload_off = off;
|
||||
switch (name_type) {
|
||||
case NameType.Module: {
|
||||
let module_name_len = readVaruint(32);
|
||||
let module_name_off = off;
|
||||
onModuleName(
|
||||
module_name_off,
|
||||
module_name_len
|
||||
);
|
||||
break;
|
||||
}
|
||||
case NameType.Function: {
|
||||
let count = readVaruint(32);
|
||||
for (let i: u32 = 0; i < count; ++i) {
|
||||
let fn_index = readVaruint(32);
|
||||
let fn_name_len = readVaruint(32);
|
||||
let fn_name_off = off;
|
||||
off += fn_name_len;
|
||||
onFunctionName(
|
||||
fn_index,
|
||||
fn_name_off,
|
||||
fn_name_len
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NameType.Local: {
|
||||
let count = readVaruint(32);
|
||||
for (let i: u32 = 0; i < count; ++i) {
|
||||
let fn_index = readVaruint(32);
|
||||
let lc_count = readVaruint(32);
|
||||
for (let j: u32 = 0; j < lc_count; ++j) {
|
||||
let lc_index = readVaruint(32);
|
||||
let lc_name_len = readVaruint(32);
|
||||
let lc_name_off = off;
|
||||
off += lc_name_len;
|
||||
onLocalName(
|
||||
fn_index,
|
||||
lc_index,
|
||||
lc_name_off,
|
||||
lc_name_len
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: unreachable();
|
||||
}
|
||||
off = name_payload_off + name_payload_len; // ignore errors
|
||||
break;
|
||||
} else if (
|
||||
name_len == 16 &&
|
||||
load<u64>(name_off ) == 0x614D656372756F73 && // "sourceMa"
|
||||
load<u64>(name_off + 8) == 0x4C5255676E697070 // "ppingURL"
|
||||
) {
|
||||
let url_len = readVaruint(32);
|
||||
let url_off = off;
|
||||
off += url_len;
|
||||
onSourceMappingURL(
|
||||
url_off,
|
||||
url_len
|
||||
);
|
||||
}
|
||||
off = payload_off + payload_len; // ignore errors
|
||||
break;
|
||||
}
|
||||
case SectionId.Code: { // skip
|
||||
off += payload_len;
|
||||
break;
|
||||
}
|
||||
@ -279,7 +399,5 @@ function parse(): void {
|
||||
off += payload_len;
|
||||
}
|
||||
}
|
||||
if (off != end) unreachable();
|
||||
}
|
||||
|
||||
// Start parsing immediately
|
||||
parse();
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
"build:as": "asc assembly/index.ts -O3 -b build/index.wasm --noMemory --importMemory --sourceMap --noDebug --validate",
|
||||
"build:as": "asc assembly/index.ts -O3 -b build/index.wasm --noMemory --importMemory --noDebug --sourceMap --validate",
|
||||
"build": "npm run build:as && webpack --mode production --display-modules",
|
||||
"test": "ts-node tests/"
|
||||
},
|
||||
|
@ -35,6 +35,13 @@ export enum ExternalKind {
|
||||
Global = 3
|
||||
}
|
||||
|
||||
/** Name section types. */
|
||||
export enum NameType {
|
||||
Module = 0,
|
||||
Function = 1,
|
||||
Local = 2
|
||||
}
|
||||
|
||||
/** Maximum number of pages. */
|
||||
export const MAX_PAGES = 0xffff;
|
||||
|
||||
|
@ -36,7 +36,15 @@ export interface ParseOptions {
|
||||
/** Called with the start function index if the start section is evaluated. */
|
||||
onStart?(index: number): void;
|
||||
/** Called with each export if the export section is evaluated. */
|
||||
onExport?(index: number, kind: ExternalKind, kindIndex: number, nameOff: number, nameLen: number);
|
||||
onExport?(index: number, kind: ExternalKind, kindIndex: number, nameOff: number, nameLen: number): void;
|
||||
/** Called with the source map URL if the 'sourceMappingURL' section is evaluated. */
|
||||
onSourceMappingURL?(offset: number, length: number): void;
|
||||
/** Called with the module name if present and the 'name' section is evaluated. */
|
||||
onModuleName?(offset: number, length: number): void;
|
||||
/** Called with each function name if present and the 'name' section is evaluated. */
|
||||
onFunctionName?(index: number, offset: number, length: number): void;
|
||||
/** Called with each local name if present and the 'name' section is evaluated. */
|
||||
onLocalName?(funcIndex: number, index: number, offset: number, length: number): void;
|
||||
}
|
||||
|
||||
/** Parses the contents of a WebAssembly binary according to the specified options. */
|
||||
@ -47,9 +55,9 @@ export function parse(binary: Uint8Array, options?: ParseOptions): void {
|
||||
if (!compiled) compiled = new WebAssembly.Module(base64_decode(WASM_DATA));
|
||||
|
||||
// use the binary as the parser's memory
|
||||
var bytes = binary.length + 5; // leave space for u8 + u32 zero terminator
|
||||
var pages = ((bytes + 0xffff) & ~0xffff) >> 16;
|
||||
var memory = new WebAssembly.Memory({ initial: pages });
|
||||
var nBytes = binary.length;
|
||||
var nPages = ((nBytes + 0xffff) & ~0xffff) >> 16;
|
||||
var memory = new WebAssembly.Memory({ initial: nPages });
|
||||
var buffer = new Uint8Array(memory.buffer);
|
||||
buffer.set(binary);
|
||||
|
||||
@ -58,13 +66,8 @@ export function parse(binary: Uint8Array, options?: ParseOptions): void {
|
||||
|
||||
// instantiate the parser and return its exports
|
||||
function nop(): void {}
|
||||
var imports = {
|
||||
env: {
|
||||
memory: memory
|
||||
}
|
||||
};
|
||||
[
|
||||
"onSection",
|
||||
var imports = { env: { memory } };
|
||||
[ "onSection",
|
||||
"onType",
|
||||
"onTypeParam",
|
||||
"onTypeReturn",
|
||||
@ -77,10 +80,14 @@ export function parse(binary: Uint8Array, options?: ParseOptions): void {
|
||||
"onFunction",
|
||||
"onGlobal",
|
||||
"onExport",
|
||||
"onStart"
|
||||
"onStart",
|
||||
"onSourceMappingURL",
|
||||
"onModuleName",
|
||||
"onFunctionName",
|
||||
"onLocalName"
|
||||
].forEach((name: string): void => imports.env[name] = options[name] || nop);
|
||||
var instance = new WebAssembly.Instance(compiled, imports);
|
||||
return instance.exports;
|
||||
instance.exports.parse(0, nBytes);
|
||||
}
|
||||
|
||||
export declare namespace parse {
|
||||
|
@ -6,58 +6,56 @@ import {
|
||||
parse
|
||||
} from "..";
|
||||
|
||||
const testBinary = fs.readFileSync(__dirname + "/libm.wasm");
|
||||
|
||||
function onSection(id: SectionId, offset: number, length: number, nameOffset: number, nameLength: number): boolean {
|
||||
var name = id == 0 ? parse.readString(nameOffset, nameLength) : SectionId[id];
|
||||
var name = id == 0 ? "'" + parse.readString(nameOffset, nameLength) + "'" : SectionId[id];
|
||||
console.log(name + " section at " + offset + ".." + (offset + length));
|
||||
return true;
|
||||
}
|
||||
|
||||
function onType(index: number, form: Type): void {
|
||||
console.log("- FunctionType[" + index + "] is " + Type[form]);
|
||||
console.log("- FunctionType[" + index + "]: " + Type[form]);
|
||||
}
|
||||
|
||||
function onTypeParam(index: number, paramIndex: number, paramType: Type): void {
|
||||
console.log(" > param[" + paramIndex + "] = " + Type[paramType]);
|
||||
console.log(" > param[" + paramIndex + "] -> " + Type[paramType]);
|
||||
}
|
||||
|
||||
function onTypeReturn(index: number, returnIndex: number, returnType: Type): void {
|
||||
console.log(" > return[" + returnIndex + "] = " + Type[returnType]);
|
||||
console.log(" > return[" + returnIndex + "] -> " + Type[returnType]);
|
||||
}
|
||||
|
||||
function onImport(index: number, kind: ExternalKind, moduleOff: number, moduleLen: number, fieldOff: number, fieldLen: number): void {
|
||||
var moduleName = parse.readString(moduleOff, moduleLen);
|
||||
var fieldName = parse.readString(fieldOff, fieldLen);
|
||||
console.log("- Import[" + index + "] is '" + moduleName + "." + fieldName + "'");
|
||||
console.log("- Import[" + index + "]: '" + moduleName + "." + fieldName + "'");
|
||||
}
|
||||
|
||||
function onFunctionImport(index: number, type: number): void {
|
||||
console.log(" > FunctionType[" + type + "]");
|
||||
function onFunctionImport(funIndex: number, type: number): void {
|
||||
console.log(" - Function[" + funIndex + "] -> FunctionType[" + type + "]");
|
||||
}
|
||||
|
||||
function onTableImport(index: number, type: Type, initial: number, maximum: number, flags: number): void {
|
||||
console.log(" > " + Type[type] + ", initial=" + initial + ", maximum=" + maximum);
|
||||
function onTableImport(tblIndex: number, type: Type, initial: number, maximum: number, flags: number): void {
|
||||
console.log(" - Table[" + tblIndex + "] -> " + Type[type] + ": initial=" + initial + ", maximum=" + maximum);
|
||||
}
|
||||
|
||||
function onMemoryImport(index: number, initial: number, maximum: number, flags: number): void {
|
||||
console.log(" > initial=" + initial + ", maximum=" + maximum);
|
||||
function onMemoryImport(memIndex: number, initial: number, maximum: number, flags: number): void {
|
||||
console.log(" - Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum);
|
||||
}
|
||||
|
||||
function onGlobalImport(index: number, type: Type, mutability: number): void {
|
||||
console.log(" > " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
|
||||
function onGlobalImport(gloIndex: number, type: Type, mutability: number): void {
|
||||
console.log(" - Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
|
||||
}
|
||||
|
||||
function onMemory(index: number, initial: number, maximum: number, flags: number): void {
|
||||
console.log("- Memory[" + index + "]: initial=" + initial + ", maximum=" + maximum);
|
||||
function onMemory(memIndex: number, initial: number, maximum: number, flags: number): void {
|
||||
console.log("- Memory[" + memIndex + "]: initial=" + initial + ", maximum=" + maximum);
|
||||
}
|
||||
|
||||
function onFunction(index: number, typeIndex: number): void {
|
||||
console.log("- Function[" + index + "]: FunctionType[" + typeIndex + "]");
|
||||
function onFunction(funIndex: number, typeIndex: number): void {
|
||||
console.log("- Function[" + funIndex + "] -> FunctionType[" + typeIndex + "]");
|
||||
}
|
||||
|
||||
function onGlobal(index: number, type: Type, mutability: number): void {
|
||||
console.log("- Global[" + index + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
|
||||
function onGlobal(gloIndex: number, type: Type, mutability: number): void {
|
||||
console.log("- Global[" + gloIndex + "]: " + (mutability & 1 ? "mutable " : "const ") + Type[type]);
|
||||
}
|
||||
|
||||
function onStart(index: number): void {
|
||||
@ -66,22 +64,53 @@ function onStart(index: number): void {
|
||||
|
||||
function onExport(index: number, kind: ExternalKind, kindIndex: number, fieldOffset: number, fieldLength: number): void {
|
||||
var field = parse.readString(fieldOffset, fieldLength);
|
||||
console.log("- Export[" + index + "]: '" + field + "' -> " + ExternalKind[kind] + "[" + kindIndex + "]");
|
||||
console.log("- Export[" + index + "], '" + field + "' -> " + ExternalKind[kind] + "[" + kindIndex + "]");
|
||||
}
|
||||
|
||||
const result = parse(testBinary, {
|
||||
onSection,
|
||||
onType,
|
||||
onTypeParam,
|
||||
onTypeReturn,
|
||||
onImport,
|
||||
onFunctionImport,
|
||||
onTableImport,
|
||||
onMemoryImport,
|
||||
onGlobalImport,
|
||||
onMemory,
|
||||
onFunction,
|
||||
onGlobal,
|
||||
onStart,
|
||||
onExport
|
||||
function onSourceMappingURL(offset: number, length: number): void {
|
||||
var url = parse.readString(offset, length);
|
||||
console.log("- sourceMap: " + url);
|
||||
}
|
||||
|
||||
function onModuleName(offset: number, length: number): void {
|
||||
var name = parse.readString(offset, length);
|
||||
console.log("- moduleName: " + name);
|
||||
}
|
||||
|
||||
function onFunctionName(index: number, offset: number, length: number): void {
|
||||
var name = parse.readString(offset, length);
|
||||
console.log(" - Function[" + index + "] name: " + name);
|
||||
}
|
||||
|
||||
function onLocalName(funcIndex: number, index: number, offset: number, length: number): void {
|
||||
var name = parse.readString(offset, length);
|
||||
console.log(" - Function[" + funcIndex + "].local[" + index + "] name: " + name);
|
||||
}
|
||||
|
||||
[ "../build/index.wasm",
|
||||
"libm.wasm"
|
||||
].forEach((filename: string): void => {
|
||||
const binary: Uint8Array = fs.readFileSync(__dirname + "/" + filename);
|
||||
console.log("Testing '" + filename + "' ...");
|
||||
parse(binary, {
|
||||
onSection,
|
||||
onType,
|
||||
onTypeParam,
|
||||
onTypeReturn,
|
||||
onImport,
|
||||
onFunctionImport,
|
||||
onTableImport,
|
||||
onMemoryImport,
|
||||
onGlobalImport,
|
||||
onMemory,
|
||||
onFunction,
|
||||
onGlobal,
|
||||
onStart,
|
||||
onExport,
|
||||
onSourceMappingURL,
|
||||
onModuleName,
|
||||
onFunctionName,
|
||||
onLocalName
|
||||
});
|
||||
console.log();
|
||||
});
|
||||
|
@ -2047,7 +2047,9 @@ export namespace NativeMathf {
|
||||
}
|
||||
|
||||
export function random(): f32 {
|
||||
return <f32>NativeMath.random();
|
||||
var f: f32; // FIXME: demoting from f64 to f32 might yield 1.0f
|
||||
do f = <f32>NativeMath.random(); while (f == 1.0);
|
||||
return f;
|
||||
}
|
||||
|
||||
export function round(x: f32): f32 { // see: musl/src/math/roundf.c
|
||||
|
@ -12221,9 +12221,20 @@
|
||||
)
|
||||
)
|
||||
(func $~lib/math/NativeMathf.random (; 143 ;) (type $f) (result f32)
|
||||
(f32.demote/f64
|
||||
(call $~lib/math/NativeMath.random)
|
||||
(local $0 f32)
|
||||
(loop $continue|0
|
||||
(br_if $continue|0
|
||||
(f32.eq
|
||||
(tee_local $0
|
||||
(f32.demote/f64
|
||||
(call $~lib/math/NativeMath.random)
|
||||
)
|
||||
)
|
||||
(f32.const 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(get_local $0)
|
||||
)
|
||||
(func $~lib/math/NativeMath.round (; 144 ;) (type $FF) (param $0 f64) (result f64)
|
||||
(local $1 f64)
|
||||
|
@ -14455,11 +14455,26 @@
|
||||
)
|
||||
)
|
||||
(func $~lib/math/NativeMathf.random (; 143 ;) (type $f) (result f32)
|
||||
(return
|
||||
(f32.demote/f64
|
||||
(call $~lib/math/NativeMath.random)
|
||||
(local $0 f32)
|
||||
(nop)
|
||||
(block $break|0
|
||||
(loop $continue|0
|
||||
(set_local $0
|
||||
(f32.demote/f64
|
||||
(call $~lib/math/NativeMath.random)
|
||||
)
|
||||
)
|
||||
(br_if $continue|0
|
||||
(f32.eq
|
||||
(get_local $0)
|
||||
(f32.const 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(return
|
||||
(get_local $0)
|
||||
)
|
||||
)
|
||||
(func $~lib/math/NativeMath.round (; 144 ;) (type $FF) (param $0 f64) (result f64)
|
||||
(local $1 i64)
|
||||
|
Loading…
x
Reference in New Issue
Block a user