mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-10 21:41:25 +00:00
move stuff, run both untouched and optimized
This commit is contained in:
130
src/builtins.ts
130
src/builtins.ts
@ -5,7 +5,8 @@
|
||||
|
||||
import {
|
||||
Compiler,
|
||||
ContextualFlags
|
||||
ContextualFlags,
|
||||
RuntimeFeatures
|
||||
} from "./compiler";
|
||||
|
||||
import {
|
||||
@ -141,6 +142,7 @@ export namespace BuiltinSymbols {
|
||||
export const call_direct = "~lib/builtins/call_direct";
|
||||
export const call_indirect = "~lib/builtins/call_indirect";
|
||||
export const instantiate = "~lib/builtins/instantiate";
|
||||
export const idof = "~lib/builtins/idof";
|
||||
|
||||
export const i8 = "~lib/builtins/i8";
|
||||
export const i16 = "~lib/builtins/i16";
|
||||
@ -464,11 +466,10 @@ export namespace BuiltinSymbols {
|
||||
export const v8x16_shuffle = "~lib/builtins/v8x16.shuffle";
|
||||
|
||||
// internals
|
||||
export const HEAP_BASE = "~lib/builtins/HEAP_BASE";
|
||||
export const RTTI_BASE = "~lib/builtins/RTTI_BASE";
|
||||
export const idof = "~lib/builtins/idof";
|
||||
export const visit_globals = "~lib/builtins/__visit_globals";
|
||||
export const visit_members = "~lib/builtins/__visit_members";
|
||||
export const HEAP_BASE = "~lib/heap/HEAP_BASE";
|
||||
export const RTTI_BASE = "~lib/rt/RTTI_BASE";
|
||||
export const visit_globals = "~lib/rt/__visit_globals";
|
||||
export const visit_members = "~lib/rt/__visit_members";
|
||||
|
||||
// std/diagnostics.ts
|
||||
export const ERROR = "~lib/diagnostics/ERROR";
|
||||
@ -3557,7 +3558,7 @@ export function compileCall(
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], Type.u32, ContextualFlags.IMPLICIT);
|
||||
compiler.needsVisitGlobals = true;
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.visitGlobals;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(BuiltinSymbols.visit_globals, [ arg0 ], NativeType.None);
|
||||
}
|
||||
@ -3571,10 +3572,123 @@ export function compileCall(
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, ContextualFlags.IMPLICIT);
|
||||
let arg1 = compiler.compileExpression(operands[1], Type.u32, ContextualFlags.IMPLICIT);
|
||||
compiler.needsVisitMembers = true;
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.visitMembers;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(BuiltinSymbols.visit_members, [ arg0, arg1 ], NativeType.None);
|
||||
}
|
||||
// The following simply intercept the respective runtime calls in order to force
|
||||
// compilation of runtime functionality to the bottom of generated binaries.
|
||||
case compiler.program.visitInstance.internalName: {
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 2, reportNode, compiler) // ref, cookie
|
||||
) {
|
||||
compiler.currentType = Type.void;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, ContextualFlags.IMPLICIT);
|
||||
let arg1 = compiler.compileExpression(operands[1], Type.u32, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.visit;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(compiler.program.visitInstance.internalName, [ arg0, arg1 ], NativeType.None);
|
||||
}
|
||||
case compiler.program.retainInstance.internalName: {
|
||||
let usizeType = compiler.options.usizeType;
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 1, reportNode, compiler) // ref
|
||||
) {
|
||||
compiler.currentType = usizeType;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.retain;
|
||||
compiler.currentType = usizeType;
|
||||
return module.createCall(compiler.program.retainInstance.internalName, [ arg0 ], compiler.options.nativeSizeType);
|
||||
}
|
||||
case compiler.program.retainReleaseInstance.internalName: {
|
||||
let usizeType = compiler.options.usizeType;
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 2, reportNode, compiler) // newRef, oldRef
|
||||
) {
|
||||
compiler.currentType = usizeType;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
|
||||
let arg1 = compiler.compileExpression(operands[1], usizeType, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.retainRelease;
|
||||
compiler.currentType = usizeType;
|
||||
return module.createCall(compiler.program.retainReleaseInstance.internalName, [ arg0, arg1 ], compiler.options.nativeSizeType);
|
||||
}
|
||||
case compiler.program.releaseInstance.internalName: {
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 1, reportNode, compiler) // ref
|
||||
) {
|
||||
compiler.currentType = Type.void;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.release;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(compiler.program.releaseInstance.internalName, [ arg0 ], NativeType.None);
|
||||
}
|
||||
case compiler.program.allocInstance.internalName: {
|
||||
let usizeType = compiler.options.usizeType;
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 2, reportNode, compiler) // size, id
|
||||
) {
|
||||
compiler.currentType = usizeType;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
|
||||
let arg1 = compiler.compileExpression(operands[1], Type.u32, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.alloc;
|
||||
compiler.currentType = usizeType;
|
||||
return module.createCall(compiler.program.allocInstance.internalName, [ arg0, arg1 ], compiler.options.nativeSizeType);
|
||||
}
|
||||
case compiler.program.reallocInstance.internalName: {
|
||||
let usizeType = compiler.options.usizeType;
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 2, reportNode, compiler) // ref, size
|
||||
) {
|
||||
compiler.currentType = usizeType;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], usizeType, ContextualFlags.IMPLICIT);
|
||||
let arg1 = compiler.compileExpression(operands[1], usizeType, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.realloc;
|
||||
compiler.currentType = usizeType;
|
||||
return module.createCall(compiler.program.reallocInstance.internalName, [ arg0, arg1 ], compiler.options.nativeSizeType);
|
||||
}
|
||||
case compiler.program.freeInstance.internalName: {
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 1, reportNode, compiler) // ref
|
||||
) {
|
||||
compiler.currentType = Type.void;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, ContextualFlags.IMPLICIT);
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.free;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(compiler.program.freeInstance.internalName, [ arg0 ], NativeType.None);
|
||||
}
|
||||
case compiler.program.collectInstance.internalName: {
|
||||
if (
|
||||
checkTypeAbsent(typeArguments, reportNode, prototype) |
|
||||
checkArgsRequired(operands, 0, reportNode, compiler)
|
||||
) {
|
||||
compiler.currentType = Type.void;
|
||||
return module.createUnreachable();
|
||||
}
|
||||
compiler.runtimeFeatures |= RuntimeFeatures.collect;
|
||||
compiler.currentType = Type.void;
|
||||
return module.createCall(compiler.program.collectInstance.internalName, null, NativeType.None);
|
||||
}
|
||||
}
|
||||
|
||||
// try to defer inline asm to a concrete built-in
|
||||
|
@ -250,6 +250,35 @@ export const enum ContextualFlags {
|
||||
STATIC_CAPABLE = 1 << 6
|
||||
}
|
||||
|
||||
/** Runtime features to be activated by the compiler. */
|
||||
export const enum RuntimeFeatures {
|
||||
NONE = 0,
|
||||
/** Requires HEAP_BASE and heap setup. */
|
||||
HEAP = 1 << 0,
|
||||
/** Requires RTTI_BASE and RTTI setup. */
|
||||
RTTI = 1 << 1,
|
||||
/** Requires the alloc function. */
|
||||
alloc = 1 << 2,
|
||||
/** Requires the realloc function. */
|
||||
realloc = 1 << 3,
|
||||
/** Requires the free function. */
|
||||
free = 1 << 4,
|
||||
/** Requires the retain function. */
|
||||
retain = 1 << 5,
|
||||
/** Requires the retainRelease functino. */
|
||||
retainRelease = 1 << 6,
|
||||
/** Requires the release function. */
|
||||
release = 1 << 7,
|
||||
/** Requires the collect function. */
|
||||
collect = 1 << 8,
|
||||
/** Requires the visit function. */
|
||||
visit = 1 << 9,
|
||||
/** Requires the built-in globals visitor. */
|
||||
visitGlobals = 1 << 10,
|
||||
/** Requires the built-in members visitor. */
|
||||
visitMembers = 1 << 11
|
||||
}
|
||||
|
||||
/** Compiler interface. */
|
||||
export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
@ -283,22 +312,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
argcVar: GlobalRef = 0;
|
||||
/** Argument count helper setter. */
|
||||
argcSet: FunctionRef = 0;
|
||||
/** Whether HEAP_BASE is required. */
|
||||
needsHeap: bool = false;
|
||||
/** Indicates whether the __visit_globals function must be generated. */
|
||||
needsVisitGlobals: bool = false;
|
||||
/** Indicated whether the __visit_members function must be generated. */
|
||||
needsVisitMembers: bool = false;
|
||||
/** Whether RTTI is required. */
|
||||
needsRTTI: bool = false;
|
||||
/** Whether the alloc function is required. */
|
||||
needsAlloc: bool = false;
|
||||
/** Whether the retain function is required. */
|
||||
needsRetain: bool = false;
|
||||
/** Whether the retainRelease function is required. */
|
||||
needsRetainRelease: bool = false;
|
||||
/** Whether the release function is required. */
|
||||
needsRelease: bool = false;
|
||||
/** Requires runtime features. */
|
||||
runtimeFeatures: RuntimeFeatures = RuntimeFeatures.NONE;
|
||||
/** Expressions known to have skipped an autorelease. Usually function returns. */
|
||||
skippedAutoreleases: Set<ExpressionRef> = new Set();
|
||||
|
||||
@ -347,7 +362,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.currentFlow = startFunctionInstance.flow;
|
||||
this.currentBody = startFunctionBody;
|
||||
|
||||
// add a mutable heap base dummy
|
||||
// add a mutable heap and rtti base dummies
|
||||
if (options.isWasm64) {
|
||||
module.addGlobal(BuiltinSymbols.HEAP_BASE, NativeType.I64, true, module.createI64(0));
|
||||
module.addGlobal(BuiltinSymbols.RTTI_BASE, NativeType.I64, true, module.createI64(0));
|
||||
@ -383,26 +398,28 @@ export class Compiler extends DiagnosticEmitter {
|
||||
if (!explicitStartFunction) module.setStart(funcRef);
|
||||
}
|
||||
|
||||
// compile gc features if utilized. has two uses: first, whenever the compiler
|
||||
// uses these, all it has to do is set a flag to true. second, when inspecting
|
||||
// generated WATs, it's quite useful that these functions come last.
|
||||
if (this.needsAlloc) this.compileFunction(program.allocInstance);
|
||||
if (this.needsRetain) this.compileFunction(program.retainInstance);
|
||||
if (this.needsRetainRelease) this.compileFunction(program.retainReleaseInstance);
|
||||
if (this.needsRelease) this.compileFunction(program.releaseInstance);
|
||||
if (this.needsVisitGlobals) compileVisitGlobals(this);
|
||||
if (this.needsVisitMembers) compileVisitMembers(this); // called by release
|
||||
// compile runtime implementation (after actual code). note that these may modify features and order is important.
|
||||
if (this.runtimeFeatures & RuntimeFeatures.visit) this.compileFunction(program.visitInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.retain) this.compileFunction(program.retainInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.retainRelease) this.compileFunction(program.retainReleaseInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.release) this.compileFunction(program.releaseInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.collect) this.compileFunction(program.collectInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.visitGlobals) compileVisitGlobals(this);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.visitMembers) compileVisitMembers(this); // called by release
|
||||
if (this.runtimeFeatures & RuntimeFeatures.realloc) this.compileFunction(program.reallocInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.alloc) this.compileFunction(program.allocInstance);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.free) this.compileFunction(program.freeInstance);
|
||||
|
||||
// compile runtime type information
|
||||
module.removeGlobal(BuiltinSymbols.RTTI_BASE);
|
||||
if (this.needsRTTI) compileRTTI(this);
|
||||
if (this.runtimeFeatures & RuntimeFeatures.RTTI) compileRTTI(this);
|
||||
|
||||
// update the heap base pointer
|
||||
var memoryOffset = this.memoryOffset;
|
||||
memoryOffset = i64_align(memoryOffset, options.usizeType.byteSize);
|
||||
this.memoryOffset = memoryOffset;
|
||||
module.removeGlobal(BuiltinSymbols.HEAP_BASE);
|
||||
if (this.needsHeap) {
|
||||
if (this.runtimeFeatures & RuntimeFeatures.HEAP) {
|
||||
if (options.isWasm64) {
|
||||
module.addGlobal(
|
||||
BuiltinSymbols.HEAP_BASE,
|
||||
@ -833,8 +850,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
// ambient builtins like 'HEAP_BASE' need to be resolved but are added explicitly
|
||||
if (global.is(CommonFlags.AMBIENT) && global.hasDecorator(DecoratorFlags.BUILTIN)) {
|
||||
if (global.internalName == BuiltinSymbols.HEAP_BASE) this.needsHeap = true;
|
||||
else if (global.internalName == BuiltinSymbols.RTTI_BASE) this.needsRTTI = true;
|
||||
if (global.internalName == BuiltinSymbols.HEAP_BASE) this.runtimeFeatures |= RuntimeFeatures.HEAP;
|
||||
else if (global.internalName == BuiltinSymbols.RTTI_BASE) this.runtimeFeatures |= RuntimeFeatures.RTTI;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2333,6 +2350,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
}
|
||||
|
||||
// Switch back to the parent flow
|
||||
if (!innerFlow.isAny(FlowFlags.ANY_TERMINATING)) this.performAutoreleases(innerFlow, stmts);
|
||||
innerFlow.unset(
|
||||
FlowFlags.BREAKS |
|
||||
FlowFlags.CONDITIONALLY_BREAKS
|
||||
@ -6524,19 +6542,19 @@ export class Compiler extends DiagnosticEmitter {
|
||||
|
||||
/** Makes retain call, retaining the expression's value. */
|
||||
makeRetain(expr: ExpressionRef): ExpressionRef {
|
||||
this.needsRetain = true;
|
||||
this.runtimeFeatures |= RuntimeFeatures.retain;
|
||||
return this.module.createCall(this.program.retainInstance.internalName, [ expr ], this.options.nativeSizeType);
|
||||
}
|
||||
|
||||
/** Makes a retainRelease call, retaining the new expression's value and releasing the old expression's value. */
|
||||
makeRetainRelease(exprNew: ExpressionRef, exprOld: ExpressionRef): ExpressionRef {
|
||||
this.needsRetainRelease = true;
|
||||
this.runtimeFeatures |= RuntimeFeatures.retainRelease;
|
||||
return this.module.createCall(this.program.retainReleaseInstance.internalName, [ exprNew, exprOld ], this.options.nativeSizeType);
|
||||
}
|
||||
|
||||
/** Makes a release call, releasing the expression's value. Changes the current type to void.*/
|
||||
makeRelease(expr: ExpressionRef): ExpressionRef {
|
||||
this.needsRelease = true;
|
||||
this.runtimeFeatures |= RuntimeFeatures.release;
|
||||
return this.module.createCall(this.program.releaseInstance.internalName, [ expr ], NativeType.None);
|
||||
}
|
||||
|
||||
@ -8846,7 +8864,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
var module = this.module;
|
||||
var options = this.options;
|
||||
this.currentType = classInstance.type;
|
||||
this.needsAlloc = true;
|
||||
this.runtimeFeatures |= RuntimeFeatures.alloc;
|
||||
return module.createCall(program.allocInstance.internalName, [
|
||||
options.isWasm64
|
||||
? module.createI64(classInstance.currentMemoryOffset)
|
||||
|
@ -280,8 +280,8 @@ export abstract class DiagnosticEmitter {
|
||||
var message = DiagnosticMessage.create(code, category, arg0, arg1, arg2).withRange(range);
|
||||
if (relatedRange) message.relatedRange = relatedRange;
|
||||
this.diagnostics.push(message);
|
||||
// console.log(formatDiagnosticMessage(message, true, true) + "\n"); // temporary
|
||||
// console.log(<string>new Error("stack").stack);
|
||||
console.log(formatDiagnosticMessage(message, true, true) + "\n"); // temporary
|
||||
console.log(<string>new Error("stack").stack);
|
||||
}
|
||||
|
||||
/** Emits an informatory diagnostic message. */
|
||||
|
@ -1042,13 +1042,13 @@ export class Program extends DiagnosticEmitter {
|
||||
let flag = decoratorKindToFlag(kind);
|
||||
if (flag) {
|
||||
if (flag == DecoratorFlags.BUILTIN) {
|
||||
if (decorator.range.source.isLibrary) {
|
||||
flags |= flag;
|
||||
} else {
|
||||
if (!(acceptedFlags & flag) && !decorator.range.source.isLibrary) {
|
||||
this.error(
|
||||
DiagnosticCode.Decorator_0_is_not_valid_here,
|
||||
decorator.range, decorator.name.range.toString()
|
||||
);
|
||||
} else {
|
||||
flags |= flag;
|
||||
}
|
||||
} else if (!(acceptedFlags & flag)) {
|
||||
this.error(
|
||||
@ -1562,7 +1562,7 @@ export class Program extends DiagnosticEmitter {
|
||||
parent: Element
|
||||
): void {
|
||||
var name = declaration.name.text;
|
||||
var validDecorators = DecoratorFlags.UNSAFE;
|
||||
var validDecorators = DecoratorFlags.UNSAFE | DecoratorFlags.BUILTIN;
|
||||
if (declaration.is(CommonFlags.AMBIENT)) {
|
||||
validDecorators |= DecoratorFlags.EXTERNAL;
|
||||
} else {
|
||||
|
@ -152,6 +152,10 @@ export declare function alignof<T>(): usize; // | u32 / u64
|
||||
@builtin
|
||||
export declare function offsetof<T>(fieldName?: string): usize; // | u32 / u64
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function idof<T>(): u32;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;
|
||||
@ -1708,18 +1712,6 @@ export namespace v8x16 {
|
||||
): v128;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function ERROR(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function WARNING(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function INFO(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@external("env", "abort")
|
||||
declare function abort(
|
||||
@ -1740,23 +1732,3 @@ declare function trace(
|
||||
a3?: f64,
|
||||
a4?: f64
|
||||
): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare const HEAP_BASE: usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare const RTTI_BASE: usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function idof<T>(): u32;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin @unsafe
|
||||
export declare function __visit_globals(cookie: u32): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin @unsafe
|
||||
export declare function __visit_members(ref: usize, cookie: u32): void;
|
||||
|
11
std/assembly/diagnostics.ts
Normal file
11
std/assembly/diagnostics.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function ERROR(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function WARNING(message?: string): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare function INFO(message?: string): void;
|
3
std/assembly/heap.ts
Normal file
3
std/assembly/heap.ts
Normal file
@ -0,0 +1,3 @@
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare const HEAP_BASE: usize;
|
84
std/assembly/rt.ts
Normal file
84
std/assembly/rt.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { idof } from "./builtins";
|
||||
import { RTTIData, RTTIFlags } from "./common/rtti";
|
||||
import { E_INDEXOUTOFRANGE } from "./util/error";
|
||||
import { BLOCK, BLOCK_OVERHEAD } from "./rt/common";
|
||||
import { ArrayBufferView } from "./arraybuffer";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin
|
||||
export declare const RTTI_BASE: usize;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin @unsafe
|
||||
export declare function __visit_globals(cookie: u32): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@builtin @unsafe
|
||||
export declare function __visit_members(ref: usize, cookie: u32): void;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function __typeinfo(id: u32): RTTIFlags {
|
||||
var ptr = RTTI_BASE;
|
||||
if (!id || id > load<u32>(ptr)) throw new Error(E_INDEXOUTOFRANGE);
|
||||
return changetype<RTTIData>(ptr + id * offsetof<RTTIData>()).flags;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function __instanceof(ref: usize, superId: u32): bool { // keyword
|
||||
var id = changetype<BLOCK>(ref - BLOCK_OVERHEAD).rtId;
|
||||
var ptr = RTTI_BASE;
|
||||
if (id && id <= load<u32>(ptr)) {
|
||||
do if (id == superId) return true;
|
||||
while (id = changetype<RTTIData>(ptr + id * offsetof<RTTIData>()).base);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe
|
||||
export function __allocArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize {
|
||||
var array = __alloc(offsetof<i32[]>(), id);
|
||||
var bufferSize = <usize>length << alignLog2;
|
||||
var buffer = __alloc(bufferSize, idof<ArrayBuffer>());
|
||||
store<usize>(array, __retain(buffer), offsetof<ArrayBufferView>("data"));
|
||||
changetype<ArrayBufferView>(array).dataStart = buffer;
|
||||
changetype<ArrayBufferView>(array).dataLength = bufferSize;
|
||||
store<i32>(changetype<usize>(array), length, offsetof<i32[]>("length_"));
|
||||
if (data) memory.copy(buffer, data, bufferSize);
|
||||
return array;
|
||||
}
|
||||
|
||||
// These are provided by the respective implementation, included as another entry file by asc:
|
||||
|
||||
// @builtin @unsafe
|
||||
// export declare function __alloc(size: usize, id: u32): usize;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __realloc(ref: usize, size: usize): usize;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __free(ref: usize): void;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __retain(ref: usize): usize;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __retainRelease(ref: usize, oldRef: usize): usize;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __release(ref: usize): void;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __collect(): void;
|
||||
|
||||
// // @ts-ignore: decorator
|
||||
// @builtin @unsafe
|
||||
// export declare function __visit(ref: usize, cookie: u32): void;
|
@ -17,10 +17,10 @@ Interface
|
||||
Frees a dynamically allocated chunk of memory by its address.
|
||||
|
||||
* **__retain**(ref: `usize`): `usize`<br />
|
||||
Retains a reference to an instance of a reference type. The instance doesn't become collected as long as there's at least one retained reference. Returns the retained reference.
|
||||
Retains a reference to an object. The object doesn't become collected as long as there's at least one retained reference. Returns the retained reference.
|
||||
|
||||
* **__release**(ref: `usize`): `void`<br />
|
||||
Releases a reference to an instance of a reference type. The instance is considered for collection once all references to it have been released.
|
||||
Releases a reference to an object. The object is considered for collection once all references to it have been released.
|
||||
|
||||
* **__collect**(): `void`<br />
|
||||
Forces a full garbage collection cycle. By default this means that reference cycles are resolved and possibly collected.
|
||||
@ -28,7 +28,7 @@ Interface
|
||||
### Internals
|
||||
|
||||
* **__retainRelease**(newRef: `usize`, oldRef: `usize`): `usize`<br />
|
||||
Retains a reference to an instance of a reference type while releasing the reference it replaces. Returns the retained reference.
|
||||
Retains a reference to an object type while releasing the reference it replaces. Returns the retained reference.
|
||||
|
||||
* **__visit**(ref: `usize`, cookie: `u32`): `void`<br />
|
||||
Concrete visitor implementation called during traversal. Cookie can be used to indicate one of multiple operations.
|
||||
@ -36,13 +36,13 @@ Interface
|
||||
### Built-ins
|
||||
|
||||
* **__typeinfo**(id: `u32`): `RTTIFlags`<br />
|
||||
Obtains the runtime type information for objects with the specified runtime id. Runtime type information is a set of flags indicating whether a reference type is managed, an array or similar, and what the relevant alignments when creating an instance are etc.
|
||||
Obtains the runtime type information for objects with the specified runtime id. Runtime type information is a set of flags indicating whether a reference type is managed, an array or similar, and what the relevant alignments when creating an instance externally are etc.
|
||||
|
||||
* **__visit_globals**(cookie: `u32`): `void`<br />
|
||||
Calls `__visit` on each global that is of a reference type. Not used anymore (originally provided to support tracing GCs) but still here for possible future use.
|
||||
|
||||
* **__visit_members**(ref: `usize`, cookie: `u32`): `void`<br />
|
||||
Calls `__visit` on each member of the instance pointed to by `ref` that is of a reference type.
|
||||
Calls `__visit` on each member of the object pointed to by `ref`.
|
||||
|
||||
Full/half
|
||||
---------
|
||||
@ -57,7 +57,7 @@ The [stub](./index-stub.ts) runtime, though fully functional, provides minimal d
|
||||
Integration notes
|
||||
-----------------
|
||||
|
||||
The underlying reference counting implementation works very similar to other implementations. When an object is stored in a local, global or field, its reference becomes retained (reference count is incremented by 1), respectively when it becomes deleted, it is released (reference count is decremented by 1). Once the reference count reaches zero, the object is considered for collection. Now, if an object is inherently acyclic (most objects are), it is free'd right away, while otherwise it is added to a cycle pool and considered for cycle collection on the next `__collect`.
|
||||
The underlying reference counting implementation works very similar to other implementations. When an object is stored in a local, global or field, its reference becomes retained (reference count is incremented by 1), respectively when it becomes deleted, it is released (reference count is decremented by 1). Once the reference count reaches zero, the object is considered for collection and the reference count of all contained objects (fields, array elements etc.) is decremented by 1. Now, if an object is inherently acyclic (most objects are), it is free'd right away, while otherwise it is added to a cycle pool and considered for cycle collection on the next `__collect`.
|
||||
|
||||
Differences to other implementations include:
|
||||
|
||||
@ -68,20 +68,19 @@ Differences to other implementations include:
|
||||
|
||||
Even though the rules are simple, working with the runtime internals within standard library code can be tricky and requires knowledge of where the compiler will insert runtime calls automatically. For instance, when `changetype`ing a pointer to a reference type or vice-versa, the typechange is performed with no side effects. Means: No retains or releases are inserted and the user has to take care of the implications.
|
||||
|
||||
GOOD: In case of doubt, the following pattern is universal:
|
||||
**GOOD:** In case of doubt, the following pattern is universal:
|
||||
|
||||
```ts
|
||||
var ref = changetype<Ref>(__alloc(SIZE, idof<Ref>())); // retains the object in `ref`
|
||||
// here, the __retain is inserted by the assignment to ref, not by changetype or __alloc
|
||||
...
|
||||
return ref; // knows `ref` is already retained and simply returns it
|
||||
```
|
||||
|
||||
BAD: One common pattern one shouldn't use is:
|
||||
**BAD:** A pattern one shouldn't use is:
|
||||
|
||||
```ts
|
||||
someFunc(changetype<Ref>(__alloc(SIZE, idof<Ref>()))); // might free the object before the call returns
|
||||
```
|
||||
|
||||
You know the drill.
|
||||
|
||||
BONUS: Beware of runtime calls in conditional expressions like a ternary IF, logical AND or OR. Each arm can be in either of two states (either in-flight if immediately retained/returned or not if the expression or the target doesn't support it). Don't fight the compiler there.
|
||||
**BONUS:** Beware of runtime calls in conditional expressions like a ternary IF, logical AND or OR. Each arm can be in either of two states (either in-flight if immediately retained/returned or not if the expression or the target doesn't support it). Don't fight the compiler there.
|
||||
|
@ -41,48 +41,3 @@
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@inline export const BLOCK_MAXSIZE: usize = (1 << 30) - BLOCK_OVERHEAD;
|
||||
|
||||
/////////////////////////////////// Type information interface ////////////////////////////////////
|
||||
|
||||
import { RTTI_BASE } from "builtins";
|
||||
import { RTTIData, RTTIFlags } from "common/rtti";
|
||||
import { E_INDEXOUTOFRANGE } from "../util/error";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
export function __typeinfo(id: u32): RTTIFlags {
|
||||
var ptr = RTTI_BASE;
|
||||
if (!id || id > load<u32>(ptr)) throw new Error(E_INDEXOUTOFRANGE);
|
||||
return changetype<RTTIData>(ptr + id * offsetof<RTTIData>()).flags;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
export function __instanceof(ref: usize, superId: u32): bool { // keyword
|
||||
var id = changetype<BLOCK>(ref - BLOCK_OVERHEAD).rtId;
|
||||
var ptr = RTTI_BASE;
|
||||
if (id && id <= load<u32>(ptr)) {
|
||||
do if (id == superId) return true;
|
||||
while (id = changetype<RTTIData>(ptr + id * offsetof<RTTIData>()).base);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////// Helpers /////////////////////////////////////////////
|
||||
|
||||
import { idof } from "builtins";
|
||||
import { ArrayBufferView } from "arraybuffer";
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
export function __allocArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize {
|
||||
var array = __alloc(offsetof<i32[]>(), id);
|
||||
var bufferSize = <usize>length << alignLog2;
|
||||
var buffer = __alloc(bufferSize, idof<ArrayBuffer>());
|
||||
store<usize>(array, __retain(buffer), offsetof<ArrayBufferView>("data"));
|
||||
changetype<ArrayBufferView>(array).dataStart = buffer;
|
||||
changetype<ArrayBufferView>(array).dataLength = bufferSize;
|
||||
store<i32>(changetype<usize>(array), length, offsetof<i32[]>("length_"));
|
||||
if (data) memory.copy(buffer, data, bufferSize);
|
||||
return array;
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
export { __alloc, __realloc, __free } from "rt/tlsf";
|
||||
export { __retain, __release, __collect } from "rt/purerc";
|
||||
export { __instanceof, __typeinfo } from "rt/common";
|
||||
export { __retain, __release, __collect } from "rt/pure";
|
||||
export { __instanceof, __typeinfo } from "rt";
|
||||
|
@ -1,2 +1,2 @@
|
||||
export { __alloc, __realloc, __free, __retain, __release, __collect } from "rt/stub";
|
||||
export { __instanceof, __typeinfo } from "rt/common";
|
||||
export { __instanceof, __typeinfo } from "rt";
|
||||
|
@ -61,7 +61,7 @@ import { RTTIFlags } from "common/rtti";
|
||||
@inline const VISIT_COLLECTWHITE = 5;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global
|
||||
@global @unsafe @builtin
|
||||
function __visit(ref: usize, cookie: i32): void {
|
||||
if (ref < HEAP_BASE) return;
|
||||
var s = changetype<Block>(ref - BLOCK_OVERHEAD);
|
||||
@ -243,20 +243,20 @@ function collectWhite(s: Block): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __retain(ref: usize): usize {
|
||||
if (ref > HEAP_BASE) increment(changetype<Block>(ref - BLOCK_OVERHEAD));
|
||||
return ref;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __release(ref: usize): void {
|
||||
if (ref > HEAP_BASE) decrement(changetype<Block>(ref - BLOCK_OVERHEAD));
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __retainRelease(ref: usize, oldRef: usize): usize {
|
||||
if (ref != oldRef) {
|
||||
let heapBase = HEAP_BASE;
|
@ -9,7 +9,7 @@ var startOffset: usize = (HEAP_BASE + AL_MASK) & ~AL_MASK;
|
||||
var offset: usize = startOffset;
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
@unsafe @global @builtin
|
||||
export function __alloc(size: usize, id: u32): usize {
|
||||
if (size > BLOCK_MAXSIZE) unreachable();
|
||||
var ptr = offset + BLOCK_OVERHEAD;
|
||||
@ -30,7 +30,7 @@ export function __alloc(size: usize, id: u32): usize {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
@unsafe @global @builtin
|
||||
export function __realloc(ref: usize, size: usize): usize {
|
||||
var block = changetype<BLOCK>(ref - BLOCK_OVERHEAD);
|
||||
var oldSize = <usize>block.rtSize;
|
||||
@ -45,7 +45,7 @@ export function __realloc(ref: usize, size: usize): usize {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@unsafe @global
|
||||
@unsafe @global @builtin
|
||||
export function __free(ref: usize): void {
|
||||
}
|
||||
|
||||
@ -56,28 +56,28 @@ export function __free(ref: usize): void {
|
||||
// }
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __retain(ref: usize): usize {
|
||||
return ref;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __release(ref: usize): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __visit(ref: usize, cookie: u32): void {
|
||||
@global @unsafe @builtin
|
||||
export function __visit(ref: usize, cookie: u32): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
function __retainRelease(ref: usize, oldRef: usize): usize {
|
||||
@global @unsafe @builtin
|
||||
export function __retainRelease(ref: usize, oldRef: usize): usize {
|
||||
return ref;
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __collect(): void {
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ export function freeBlock(root: Root, block: Block): void {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __alloc(size: usize, id: u32): usize {
|
||||
var root = ROOT;
|
||||
if (!root) {
|
||||
@ -547,7 +547,7 @@ export function __alloc(size: usize, id: u32): usize {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __realloc(ref: usize, size: usize): usize {
|
||||
if (DEBUG) assert(ROOT); // must be initialized
|
||||
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
|
||||
@ -555,7 +555,7 @@ export function __realloc(ref: usize, size: usize): usize {
|
||||
}
|
||||
|
||||
// @ts-ignore: decorator
|
||||
@global @unsafe
|
||||
@global @unsafe @builtin
|
||||
export function __free(ref: usize): void {
|
||||
if (DEBUG) assert(ROOT); // must be initialized
|
||||
assert(ref != 0 && !(ref & AL_MASK)); // must exist and be aligned
|
||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
*.wasm
|
||||
*.wasm.map
|
||||
temp.*
|
||||
|
@ -152,6 +152,8 @@ tests.forEach(filename => {
|
||||
Array.prototype.push.apply(cmd, asc_flags);
|
||||
if (args.createBinary)
|
||||
cmd.push("--binaryFile", basename + ".untouched.wasm");
|
||||
else
|
||||
cmd.push("--binaryFile", "temp.wasm");
|
||||
asc.main(cmd, {
|
||||
stdout: stdout,
|
||||
stderr: stderr
|
||||
@ -212,7 +214,7 @@ tests.forEach(filename => {
|
||||
"--validate",
|
||||
"--measure",
|
||||
"--binaryFile", // -> stdout
|
||||
// "-O3"
|
||||
"-O3"
|
||||
];
|
||||
if (asc_flags)
|
||||
Array.prototype.push.apply(cmd, asc_flags);
|
||||
@ -229,127 +231,18 @@ tests.forEach(filename => {
|
||||
failedTests.push(basename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Instantiate
|
||||
try {
|
||||
let memory = new WebAssembly.Memory({ initial: 10 });
|
||||
let exports = {};
|
||||
|
||||
function getString(ptr) {
|
||||
const RUNTIME_HEADER_SIZE = 16;
|
||||
if (!ptr) return "null";
|
||||
var U32 = new Uint32Array(exports.memory ? exports.memory.buffer : memory.buffer);
|
||||
var U16 = new Uint16Array(exports.memory ? exports.memory.buffer : memory.buffer);
|
||||
var len16 = U32[(ptr - RUNTIME_HEADER_SIZE + 12) >>> 2] >>> 1;
|
||||
var ptr16 = ptr >>> 1;
|
||||
return String.fromCharCode.apply(String, U16.subarray(ptr16, ptr16 + len16));
|
||||
}
|
||||
|
||||
var binaryBuffer = stdout.toBuffer();
|
||||
if (args.createBinary)
|
||||
fs.writeFileSync(path.join(basedir, basename + ".optimized.wasm"), binaryBuffer);
|
||||
let rtrace = new Map();
|
||||
let rtraceEnabled = false;
|
||||
let rtraceRetains = 0;
|
||||
let rtraceReleases = 0;
|
||||
let rtraceFrees = 0;
|
||||
let rtraceUsesAfterFree = 0;
|
||||
let runTime = asc.measure(() => {
|
||||
exports = new WebAssembly.Instance(new WebAssembly.Module(binaryBuffer), {
|
||||
env: {
|
||||
memory,
|
||||
abort: function(msg, file, line, column) {
|
||||
console.log(colorsUtil.red(" abort: " + getString(msg) + " at " + getString(file) + ":" + line + ":" + column));
|
||||
},
|
||||
trace: function(msg, n) {
|
||||
console.log(" trace: " + getString(msg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
|
||||
},
|
||||
externalFunction: function() { },
|
||||
externalConstant: 1
|
||||
},
|
||||
math: {
|
||||
mod: function(a, b) { return a % b; }
|
||||
},
|
||||
Math,
|
||||
Date,
|
||||
|
||||
// tests/declare
|
||||
declare: {
|
||||
externalFunction: function() { },
|
||||
externalConstant: 1,
|
||||
"my.externalFunction": function() { },
|
||||
"my.externalConstant": 2
|
||||
},
|
||||
|
||||
// tests/external
|
||||
external: {
|
||||
foo: function() {},
|
||||
"foo.bar": function() {},
|
||||
bar: function() {}
|
||||
},
|
||||
foo: {
|
||||
baz: function() {},
|
||||
"var": 3
|
||||
},
|
||||
|
||||
// runtime tracing
|
||||
rtrace: {
|
||||
retain: function(s) {
|
||||
++rtraceRetains;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
rtrace.set(s, ++rc);
|
||||
// console.log(" retain(" + s + ", RC=" + rc + ")");
|
||||
rtraceEnabled = true;
|
||||
},
|
||||
release: function(s) {
|
||||
++rtraceReleases;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
if (--rc <= 0) {
|
||||
rtrace.delete(s);
|
||||
if (rc < 0) {
|
||||
++rtraceUsesAfterFree;
|
||||
console.log(" USEAFTERFREE(" + s + ", RC=" + rc + ")");
|
||||
}
|
||||
} else rtrace.set(s, rc);
|
||||
// console.log(" release(" + s + ", RC=" + rc + ")");
|
||||
rtraceEnabled = true;
|
||||
},
|
||||
free: function(s) {
|
||||
++rtraceFrees;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
// if (rc != 0) console.log(" free(" + s + ", RC=" + rc + ")");
|
||||
rtrace.delete(s);
|
||||
rtraceEnabled = true;
|
||||
}
|
||||
}
|
||||
}).exports;
|
||||
if (exports.main) {
|
||||
console.log(colorsUtil.white(" [main]"));
|
||||
var code = exports.main();
|
||||
console.log(colorsUtil.white(" [exit " + code + "]\n"));
|
||||
}
|
||||
if (rtraceEnabled) {
|
||||
console.log("- " + "rtrace: " + rtraceRetains + " retains, " + rtraceReleases + " releases, " + rtraceFrees + " explicit frees");
|
||||
if (rtrace.size || rtraceUsesAfterFree) {
|
||||
let msg = "memory leak detected: " + rtrace.size + " leaking, " + rtraceUsesAfterFree + " uses after free";
|
||||
console.log(" " + colorsUtil.red("ERROR: ") + msg);
|
||||
failed = true;
|
||||
failedMessages.set(basename, msg);
|
||||
}
|
||||
console.log();
|
||||
}
|
||||
});
|
||||
console.log("- " + colorsUtil.green("instantiate OK") + " (" + asc.formatTime(runTime) + ")");
|
||||
console.log("\n " + Object.keys(exports).map(key => {
|
||||
return "[" + (typeof exports[key]).substring(0, 3) + "] " + key + " = " + exports[key]
|
||||
}).join("\n "));
|
||||
} catch (e) {
|
||||
console.log("- " + colorsUtil.red("instantiate ERROR: ") + e.stack);
|
||||
let untouchedBuffer = fs.readFileSync(path.join(basedir, "temp.wasm"));
|
||||
let optimizedBuffer = stdout.toBuffer();
|
||||
if (!testInstantiate(basename, untouchedBuffer, "untouched")) {
|
||||
failed = true;
|
||||
failedMessages.set(basename, e.message);
|
||||
failedTests.push(basename);
|
||||
} else {
|
||||
console.log();
|
||||
if (!testInstantiate(basename, optimizedBuffer, "optimized")) {
|
||||
failed = true;
|
||||
failedTests.push(basename);
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) failedTests.push(basename);
|
||||
console.log();
|
||||
});
|
||||
if (failed) return 1;
|
||||
@ -377,3 +270,127 @@ if (failedTests.length) {
|
||||
if (!process.exitCode) {
|
||||
console.log("[ " + colorsUtil.white("OK") + " ]");
|
||||
}
|
||||
|
||||
function testInstantiate(basename, binaryBuffer, name) {
|
||||
var failed = false;
|
||||
try {
|
||||
let memory = new WebAssembly.Memory({ initial: 10 });
|
||||
let exports = {};
|
||||
|
||||
function getString(ptr) {
|
||||
const RUNTIME_HEADER_SIZE = 16;
|
||||
if (!ptr) return "null";
|
||||
var U32 = new Uint32Array(exports.memory ? exports.memory.buffer : memory.buffer);
|
||||
var U16 = new Uint16Array(exports.memory ? exports.memory.buffer : memory.buffer);
|
||||
var len16 = U32[(ptr - RUNTIME_HEADER_SIZE + 12) >>> 2] >>> 1;
|
||||
var ptr16 = ptr >>> 1;
|
||||
return String.fromCharCode.apply(String, U16.subarray(ptr16, ptr16 + len16));
|
||||
}
|
||||
|
||||
let rtrace = new Map();
|
||||
let rtraceEnabled = false;
|
||||
let rtraceRetains = 0;
|
||||
let rtraceReleases = 0;
|
||||
let rtraceFrees = 0;
|
||||
let rtraceUsesAfterFree = 0;
|
||||
|
||||
let runTime = asc.measure(() => {
|
||||
exports = new WebAssembly.Instance(new WebAssembly.Module(binaryBuffer), {
|
||||
env: {
|
||||
memory,
|
||||
abort: function(msg, file, line, column) {
|
||||
console.log(colorsUtil.red(" abort: " + getString(msg) + " at " + getString(file) + ":" + line + ":" + column));
|
||||
},
|
||||
trace: function(msg, n) {
|
||||
console.log(" trace: " + getString(msg) + (n ? " " : "") + Array.prototype.slice.call(arguments, 2, 2 + n).join(", "));
|
||||
},
|
||||
externalFunction: function() { },
|
||||
externalConstant: 1
|
||||
},
|
||||
math: {
|
||||
mod: function(a, b) { return a % b; }
|
||||
},
|
||||
Math,
|
||||
Date,
|
||||
|
||||
// tests/declare
|
||||
declare: {
|
||||
externalFunction: function() { },
|
||||
externalConstant: 1,
|
||||
"my.externalFunction": function() { },
|
||||
"my.externalConstant": 2
|
||||
},
|
||||
|
||||
// tests/external
|
||||
external: {
|
||||
foo: function() {},
|
||||
"foo.bar": function() {},
|
||||
bar: function() {}
|
||||
},
|
||||
foo: {
|
||||
baz: function() {},
|
||||
"var": 3
|
||||
},
|
||||
|
||||
// runtime tracing
|
||||
rtrace: {
|
||||
retain: function(s) {
|
||||
++rtraceRetains;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
rtrace.set(s, ++rc);
|
||||
// console.log(" retain(" + s + ", RC=" + rc + ")");
|
||||
rtraceEnabled = true;
|
||||
},
|
||||
release: function(s) {
|
||||
++rtraceReleases;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
if (--rc <= 0) {
|
||||
rtrace.delete(s);
|
||||
if (rc < 0) {
|
||||
++rtraceUsesAfterFree;
|
||||
console.log(" USEAFTERFREE(" + s + ", RC=" + rc + ")");
|
||||
}
|
||||
} else rtrace.set(s, rc);
|
||||
// console.log(" release(" + s + ", RC=" + rc + ")");
|
||||
rtraceEnabled = true;
|
||||
},
|
||||
free: function(s) {
|
||||
++rtraceFrees;
|
||||
let rc = rtrace.get(s) | 0;
|
||||
// if (rc != 0) console.log(" free(" + s + ", RC=" + rc + ")");
|
||||
rtrace.delete(s);
|
||||
rtraceEnabled = true;
|
||||
}
|
||||
}
|
||||
}).exports;
|
||||
if (exports.main) {
|
||||
console.log(colorsUtil.white(" [main]"));
|
||||
var code = exports.main();
|
||||
console.log(colorsUtil.white(" [exit " + code + "]\n"));
|
||||
}
|
||||
});
|
||||
if (rtraceEnabled) {
|
||||
if (rtrace.size || rtraceUsesAfterFree) {
|
||||
let msg = "memory leak detected: " + rtrace.size + " leaking, " + rtraceUsesAfterFree + " uses after free";
|
||||
console.log("- " + colorsUtil.red("rtrace " + name + " ERROR: ") + msg);
|
||||
failed = true;
|
||||
failedMessages.set(basename, msg);
|
||||
}
|
||||
}
|
||||
if (!failed) {
|
||||
console.log("- " + colorsUtil.green("instantiate " + name + " OK") + " (" + asc.formatTime(runTime) + ")");
|
||||
if (rtraceEnabled) {
|
||||
console.log("\n " + rtraceRetains + " retains\n " + rtraceReleases + " releases\n " + rtraceFrees + " explicit frees");
|
||||
}
|
||||
console.log("\n " + Object.keys(exports).map(key => {
|
||||
return "[" + (typeof exports[key]).substring(0, 3) + "] " + key + " = " + exports[key]
|
||||
}).join("\n "));
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("- " + colorsUtil.red("instantiate " + name + " ERROR: ") + e.stack);
|
||||
failed = true;
|
||||
failedMessages.set(basename, e.message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -3,9 +3,7 @@
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\n\00\00\00\01\00\00\00\10\00\00\00\n\00\00\00d\00o\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(data (i32.const 8) "\n\00\00\00\01\00\00\00\10\00\00\00\n\00\00\00d\00o\00.\00t\00s")
|
||||
(global $do/n (mut i32) (i32.const 10))
|
||||
(global $do/m (mut i32) (i32.const 0))
|
||||
(global $do/o (mut i32) (i32.const 0))
|
||||
@ -13,26 +11,19 @@
|
||||
(start $start)
|
||||
(func $start:do (; 1 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
block
|
||||
global.get $do/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/m
|
||||
end
|
||||
global.get $do/n
|
||||
br_if $continue|0
|
||||
end
|
||||
loop $continue|0
|
||||
global.get $do/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/m
|
||||
global.get $do/n
|
||||
br_if $continue|0
|
||||
end
|
||||
global.get $do/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -43,8 +34,7 @@
|
||||
end
|
||||
global.get $do/m
|
||||
i32.const 10
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -55,24 +45,18 @@
|
||||
end
|
||||
i32.const 10
|
||||
global.set $do/n
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
nop
|
||||
block (result i32)
|
||||
global.get $do/n
|
||||
local.tee $0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
local.get $0
|
||||
end
|
||||
br_if $continue|1
|
||||
end
|
||||
loop $continue|1
|
||||
global.get $do/n
|
||||
local.tee $0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
local.get $0
|
||||
br_if $continue|1
|
||||
end
|
||||
global.get $do/n
|
||||
i32.const -1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -85,66 +69,51 @@
|
||||
global.set $do/n
|
||||
i32.const 0
|
||||
global.set $do/m
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
block
|
||||
global.get $do/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/m
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
block
|
||||
global.get $do/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/o
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/o
|
||||
end
|
||||
global.get $do/n
|
||||
br_if $continue|3
|
||||
end
|
||||
end
|
||||
global.get $do/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $do/o
|
||||
i32.const 9
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 25
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
loop $continue|2
|
||||
global.get $do/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/m
|
||||
loop $continue|3
|
||||
global.get $do/n
|
||||
br_if $continue|2
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $do/n
|
||||
global.get $do/o
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $do/o
|
||||
global.get $do/n
|
||||
br_if $continue|3
|
||||
end
|
||||
global.get $do/n
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $do/o
|
||||
i32.const 9
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 25
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $do/n
|
||||
br_if $continue|2
|
||||
end
|
||||
global.get $do/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -155,8 +124,7 @@
|
||||
end
|
||||
global.get $do/m
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -167,8 +135,7 @@
|
||||
end
|
||||
global.get $do/o
|
||||
i32.const 9
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -182,5 +149,6 @@
|
||||
call $start:do
|
||||
)
|
||||
(func $null (; 3 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
@ -1,9 +1,8 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 0)
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(export "memory" (memory $0))
|
||||
(func $null (; 0 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -7,472 +7,135 @@
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\n\00\00\00\01\00\00\00\10\00\00\00\n\00\00\00e\00r\00r\00o\00r\00")
|
||||
(data (i32.const 40) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00r\00e\00t\00a\00i\00n\00-\00r\00e\00l\00e\00a\00s\00e\00.\00t\00s\00")
|
||||
(data (i32.const 8) "\n\00\00\00\01\00\00\00\10\00\00\00\n\00\00\00e\00r\00r\00o\00r")
|
||||
(data (i32.const 40) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00r\00e\00t\00a\00i\00n\00-\00r\00e\00l\00e\00a\00s\00e\00.\00t\00s")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(elem (i32.const 0) $retain-release/receiveRef)
|
||||
(global $retain-release/REF (mut i32) (i32.const 0))
|
||||
(global $retain-release/glo (mut i32) (i32.const 0))
|
||||
(global $retain-release/TARGET (mut i32) (i32.const 0))
|
||||
(global $~lib/argc (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 92))
|
||||
(export "memory" (memory $0))
|
||||
(export "returnRef" (func $retain-release/returnRef))
|
||||
(export "receiveRef" (func $retain-release/receiveRef))
|
||||
(export "receiveRefDrop" (func $retain-release/receiveRefDrop))
|
||||
(export "receiveRefRetain" (func $retain-release/receiveRefRetain))
|
||||
(export "receiveRefDrop" (func $retain-release/receiveRef))
|
||||
(export "receiveRefRetain" (func $retain-release/receiveRef))
|
||||
(export "takeRef" (func $retain-release/takeRef))
|
||||
(export "provideRef" (func $retain-release/provideRef))
|
||||
(export "provideRef" (func $retain-release/receiveRef))
|
||||
(export "takeReturnRef" (func $retain-release/takeReturnRef))
|
||||
(export "provideReceiveRef" (func $retain-release/provideReceiveRef))
|
||||
(export "provideReceiveRef" (func $retain-release/receiveRef))
|
||||
(export "newRef" (func $retain-release/newRef))
|
||||
(export "assignGlobal" (func $retain-release/assignGlobal))
|
||||
(export "assignField" (func $retain-release/assignField))
|
||||
(export "scopeBlock" (func $retain-release/scopeBlock))
|
||||
(export "scopeBlockToUninitialized" (func $retain-release/scopeBlockToUninitialized))
|
||||
(export "scopeBlockToInitialized" (func $retain-release/scopeBlockToInitialized))
|
||||
(export "scopeBlockToConditional" (func $retain-release/scopeBlockToConditional))
|
||||
(export "scopeTopLevelUninitialized" (func $retain-release/scopeTopLevelUninitialized))
|
||||
(export "scopeTopLevelInitialized" (func $retain-release/scopeTopLevelInitialized))
|
||||
(export "scopeTopLevelConditional" (func $retain-release/scopeTopLevelConditional))
|
||||
(export "scopeIf" (func $retain-release/scopeIf))
|
||||
(export "scopeIfElse" (func $retain-release/scopeIfElse))
|
||||
(export "scopeWhile" (func $retain-release/scopeWhile))
|
||||
(export "scopeDo" (func $retain-release/scopeDo))
|
||||
(export "scopeFor" (func $retain-release/scopeFor))
|
||||
(export "scopeBreak" (func $retain-release/scopeBreak))
|
||||
(export "scopeContinue" (func $retain-release/scopeContinue))
|
||||
(export "scopeBlock" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToUninitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToInitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeBlockToConditional" (func $retain-release/takeRef))
|
||||
(export "scopeTopLevelUninitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeTopLevelInitialized" (func $retain-release/receiveRef))
|
||||
(export "scopeTopLevelConditional" (func $retain-release/takeRef))
|
||||
(export "scopeIf" (func $retain-release/takeRef))
|
||||
(export "scopeIfElse" (func $retain-release/takeRef))
|
||||
(export "scopeWhile" (func $retain-release/takeRef))
|
||||
(export "scopeDo" (func $retain-release/takeRef))
|
||||
(export "scopeFor" (func $retain-release/takeRef))
|
||||
(export "scopeBreak" (func $retain-release/takeRef))
|
||||
(export "scopeContinue" (func $retain-release/takeRef))
|
||||
(export "scopeThrow" (func $retain-release/scopeThrow))
|
||||
(export "scopeUnreachable" (func $retain-release/scopeUnreachable))
|
||||
(export "callInline" (func $retain-release/callInline))
|
||||
(export "provideRefInline" (func $retain-release/provideRefInline))
|
||||
(export "receiveRefInline" (func $retain-release/receiveRefInline))
|
||||
(export "receiveRefInlineDrop" (func $retain-release/receiveRefInlineDrop))
|
||||
(export "callInline" (func $retain-release/receiveRef))
|
||||
(export "provideRefInline" (func $retain-release/receiveRef))
|
||||
(export "receiveRefInline" (func $retain-release/receiveRef))
|
||||
(export "receiveRefInlineDrop" (func $retain-release/receiveRef))
|
||||
(export "provideRefIndirect" (func $retain-release/provideRefIndirect))
|
||||
(export "receiveRefIndirect" (func $retain-release/receiveRefIndirect))
|
||||
(export "receiveRefIndirectDrop" (func $retain-release/receiveRefIndirectDrop))
|
||||
(export "receiveRefIndirectDrop" (func $retain-release/receiveRefIndirect))
|
||||
(start $start)
|
||||
(func $retain-release/Ref#constructor (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 17
|
||||
call $~lib/rt/stub/__alloc
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
end
|
||||
(func $retain-release/Ref#constructor (; 1 ;) (type $FUNCSIG$i) (result i32)
|
||||
i32.const 0
|
||||
i32.const 17
|
||||
call $~lib/rt/stub/__alloc
|
||||
)
|
||||
(func $retain-release/returnRef (; 2 ;) (type $FUNCSIG$i) (result i32)
|
||||
global.get $retain-release/REF
|
||||
)
|
||||
(func $retain-release/receiveRef (; 3 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/takeRef (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $retain-release/takeReturnRef (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/Target#constructor (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 4
|
||||
i32.const 18
|
||||
call $~lib/rt/stub/__alloc
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
i32.const 0
|
||||
i32.store
|
||||
local.get $0
|
||||
)
|
||||
(func $start:retain-release (; 3 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
(func $retain-release/newRef (; 6 ;) (type $FUNCSIG$v)
|
||||
call $retain-release/Ref#constructor
|
||||
global.set $retain-release/REF
|
||||
i32.const 0
|
||||
call $retain-release/Target#constructor
|
||||
global.set $retain-release/TARGET
|
||||
)
|
||||
(func $retain-release/returnRef (; 4 ;) (type $FUNCSIG$i) (result i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
)
|
||||
(func $retain-release/receiveRef (; 5 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
call $retain-release/returnRef
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefDrop (; 6 ;) (type $FUNCSIG$v)
|
||||
call $retain-release/returnRef
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefRetain (; 7 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
call $retain-release/returnRef
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/takeRef (; 8 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__retain
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/provideRef (; 9 ;) (type $FUNCSIG$v)
|
||||
(func $retain-release/assignGlobal (; 7 ;) (type $FUNCSIG$v)
|
||||
global.get $retain-release/REF
|
||||
call $retain-release/takeRef
|
||||
)
|
||||
(func $retain-release/takeReturnRef (; 10 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__retain
|
||||
drop
|
||||
local.get $0
|
||||
)
|
||||
(func $retain-release/provideReceiveRef (; 11 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/REF
|
||||
call $retain-release/takeReturnRef
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/newRef (; 12 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
call $retain-release/Ref#constructor
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/assignGlobal (; 13 ;) (type $FUNCSIG$v)
|
||||
global.get $retain-release/REF
|
||||
global.get $retain-release/glo
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
global.set $retain-release/glo
|
||||
)
|
||||
(func $retain-release/assignField (; 14 ;) (type $FUNCSIG$v)
|
||||
(func $retain-release/assignField (; 8 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/TARGET
|
||||
local.tee $0
|
||||
global.get $retain-release/REF
|
||||
local.get $0
|
||||
i32.load
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
drop
|
||||
local.get $0
|
||||
global.get $retain-release/REF
|
||||
i32.store
|
||||
)
|
||||
(func $retain-release/scopeBlock (; 15 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToUninitialized (; 16 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 0
|
||||
local.set $0
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
local.set $0
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToInitialized (; 17 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
(local $1 i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
local.set $0
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeBlockToConditional (; 18 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
(local $2 i32)
|
||||
i32.const 0
|
||||
local.set $1
|
||||
(func $retain-release/scopeThrow (; 9 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
local.set $1
|
||||
end
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
local.set $1
|
||||
local.get $2
|
||||
call $~lib/rt/stub/__release
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeTopLevelUninitialized (; 19 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
i32.const 0
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeTopLevelInitialized (; 20 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeTopLevelConditional (; 21 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
i32.const 0
|
||||
local.set $1
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__retainRelease
|
||||
local.set $1
|
||||
end
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/scopeIf (; 22 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeIfElse (; 23 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
else
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeWhile (; 24 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeDo (; 25 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
block
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
end
|
||||
local.get $0
|
||||
br_if $continue|0
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeFor (; 26 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
loop $repeat|0
|
||||
local.get $0
|
||||
i32.eqz
|
||||
br_if $break|0
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
br $repeat|0
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 56
|
||||
i32.const 313
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeBreak (; 27 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
br $break|0
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeContinue (; 28 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeThrow (; 29 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
block
|
||||
i32.const 24
|
||||
i32.const 56
|
||||
i32.const 310
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/scopeUnreachable (; 30 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
loop $continue|0
|
||||
local.get $0
|
||||
if
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $1
|
||||
unreachable
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $retain-release/callInline (; 31 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
(func $retain-release/scopeUnreachable (; 10 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/provideRefInline (; 32 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
local.set $0
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefInline (; 33 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
block $retain-release/returnRefInline|inlined.0 (result i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
local.tee $0
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $0
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefInlineDrop (; 34 ;) (type $FUNCSIG$v)
|
||||
block $retain-release/returnRefInline|inlined.1 (result i32)
|
||||
global.get $retain-release/REF
|
||||
call $~lib/rt/stub/__retain
|
||||
end
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/provideRefIndirect (; 35 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(func $retain-release/provideRefIndirect (; 11 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 1
|
||||
global.set $~lib/argc
|
||||
global.get $retain-release/REF
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$vi)
|
||||
)
|
||||
(func $retain-release/receiveRefIndirect (; 36 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(local $1 i32)
|
||||
block (result i32)
|
||||
i32.const 0
|
||||
global.set $~lib/argc
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$i)
|
||||
local.tee $1
|
||||
end
|
||||
i32.eqz
|
||||
drop
|
||||
local.get $1
|
||||
call $~lib/rt/stub/__release
|
||||
)
|
||||
(func $retain-release/receiveRefIndirectDrop (; 37 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
(func $retain-release/receiveRefIndirect (; 12 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
i32.const 0
|
||||
global.set $~lib/argc
|
||||
local.get $0
|
||||
call_indirect (type $FUNCSIG$i)
|
||||
call $~lib/rt/stub/__release
|
||||
drop
|
||||
)
|
||||
(func $start (; 38 ;) (type $FUNCSIG$v)
|
||||
call $start:retain-release
|
||||
(func $start (; 13 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
call $retain-release/Ref#constructor
|
||||
global.set $retain-release/REF
|
||||
i32.const 4
|
||||
i32.const 18
|
||||
call $~lib/rt/stub/__alloc
|
||||
local.tee $0
|
||||
i32.const 0
|
||||
i32.store
|
||||
local.get $0
|
||||
global.set $retain-release/TARGET
|
||||
)
|
||||
(func $~lib/rt/stub/__alloc (; 39 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(func $~lib/rt/stub/__alloc (; 14 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i32)
|
||||
local.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
@ -482,59 +145,45 @@
|
||||
global.get $~lib/rt/stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.get $0
|
||||
i32.const 1
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.const -16
|
||||
i32.and
|
||||
local.set $5
|
||||
local.tee $2
|
||||
current_memory
|
||||
local.set $6
|
||||
local.get $5
|
||||
local.get $6
|
||||
local.tee $4
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $4
|
||||
local.get $2
|
||||
local.get $3
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.const -65536
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $3
|
||||
local.get $6
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.tee $7
|
||||
local.tee $5
|
||||
local.get $4
|
||||
local.get $7
|
||||
local.get $5
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $4
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
local.get $5
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
@ -543,29 +192,17 @@
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
global.set $~lib/rt/stub/offset
|
||||
local.get $2
|
||||
global.set $~lib/rt/stub/offset
|
||||
local.get $3
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $8
|
||||
local.get $8
|
||||
local.tee $2
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $8
|
||||
local.get $2
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/rt/stub/__retain (; 40 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__retainRelease (; 41 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__release (; 42 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $null (; 43 ;) (type $FUNCSIG$v)
|
||||
local.get $3
|
||||
)
|
||||
)
|
||||
|
@ -17,7 +17,7 @@
|
||||
(global $~lib/argc (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 92))
|
||||
(global $~lib/heap/HEAP_BASE i32 (i32.const 92))
|
||||
(export "memory" (memory $0))
|
||||
(export "returnRef" (func $retain-release/returnRef))
|
||||
(export "receiveRef" (func $retain-release/receiveRef))
|
||||
@ -374,7 +374,7 @@
|
||||
block
|
||||
i32.const 24
|
||||
i32.const 56
|
||||
i32.const 310
|
||||
i32.const 313
|
||||
i32.const 4
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,388 +1,25 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "$\00\00\00\01\00\00\00\10\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00")
|
||||
(data (i32.const 64) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00c\00o\00m\00m\00o\00n\00.\00t\00s\00")
|
||||
(data (i32.const 120) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/RTTI_BASE i32 (i32.const 120))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 256))
|
||||
(data (i32.const 8) "$\00\00\00\01\00\00\00\10\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e")
|
||||
(data (i32.const 64) "\14\00\00\00\01\00\00\00\10\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s")
|
||||
(data (i32.const 104) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08")
|
||||
(export "memory" (memory $0))
|
||||
(export "__alloc" (func $~lib/rt/stub/__alloc))
|
||||
(export "__realloc" (func $~lib/rt/stub/__realloc))
|
||||
(export "__free" (func $~lib/rt/stub/__free))
|
||||
(export "__retain" (func $~lib/rt/stub/__retain))
|
||||
(export "__release" (func $~lib/rt/stub/__release))
|
||||
(export "__collect" (func $~lib/rt/stub/__collect))
|
||||
(export "__instanceof" (func $~lib/rt/common/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/common/__typeinfo))
|
||||
(start $start)
|
||||
(func $~lib/rt/stub/__alloc (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i32)
|
||||
local.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/rt/stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $5
|
||||
current_memory
|
||||
local.set $6
|
||||
local.get $5
|
||||
local.get $6
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $2
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $3
|
||||
local.get $6
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.tee $7
|
||||
local.get $4
|
||||
local.get $7
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $4
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
global.set $~lib/rt/stub/offset
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $8
|
||||
local.get $8
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $8
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 2 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.set $5
|
||||
local.get $1
|
||||
local.set $4
|
||||
local.get $2
|
||||
local.set $3
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.eq
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $4
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $3
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $3
|
||||
block (result i32)
|
||||
local.get $5
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $6
|
||||
end
|
||||
block (result i32)
|
||||
local.get $4
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $4
|
||||
local.get $6
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $4
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $3
|
||||
local.get $5
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $4
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $4
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
local.get $3
|
||||
if
|
||||
block (result i32)
|
||||
local.get $5
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $6
|
||||
end
|
||||
block (result i32)
|
||||
local.get $4
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $4
|
||||
local.get $6
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $3
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $4
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $3
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|4
|
||||
loop $continue|4
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $3
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|5
|
||||
loop $continue|5
|
||||
local.get $3
|
||||
if
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/rt/stub/__realloc (; 3 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load offset=12
|
||||
local.set $3
|
||||
local.get $1
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.load offset=8
|
||||
call $~lib/rt/stub/__alloc
|
||||
local.set $4
|
||||
local.get $4
|
||||
local.get $0
|
||||
local.get $3
|
||||
call $~lib/memory/memory.copy
|
||||
local.get $4
|
||||
local.set $0
|
||||
else
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store offset=12
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__free (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/stub/__retain (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__release (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/stub/__collect (; 7 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/common/__instanceof (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(export "__instanceof" (func $~lib/rt/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/__typeinfo))
|
||||
(func $~lib/rt/__instanceof (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
i32.load offset=8
|
||||
local.set $2
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
local.set $3
|
||||
local.get $2
|
||||
local.tee $0
|
||||
if (result i32)
|
||||
local.get $2
|
||||
local.get $3
|
||||
local.get $0
|
||||
i32.const 104
|
||||
i32.load
|
||||
i32.le_u
|
||||
else
|
||||
@ -390,66 +27,51 @@
|
||||
end
|
||||
if
|
||||
loop $continue|0
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.eq
|
||||
if
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
local.get $3
|
||||
local.get $2
|
||||
i32.const 8
|
||||
i32.mul
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 104
|
||||
i32.add
|
||||
i32.load offset=4
|
||||
local.tee $2
|
||||
local.tee $0
|
||||
br_if $continue|0
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/rt/common/__typeinfo (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
local.set $1
|
||||
(func $~lib/rt/__typeinfo (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
i32.eqz
|
||||
if (result i32)
|
||||
i32.const 1
|
||||
else
|
||||
local.get $0
|
||||
local.get $1
|
||||
i32.const 104
|
||||
i32.load
|
||||
i32.gt_u
|
||||
else
|
||||
i32.const 1
|
||||
end
|
||||
if
|
||||
i32.const 24
|
||||
i32.const 80
|
||||
i32.const 55
|
||||
i32.const 23
|
||||
i32.const 34
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
local.get $1
|
||||
local.get $0
|
||||
i32.const 8
|
||||
i32.mul
|
||||
i32.const 3
|
||||
i32.shl
|
||||
i32.const 104
|
||||
i32.add
|
||||
i32.load
|
||||
)
|
||||
(func $start (; 10 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/builtins/HEAP_BASE
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/rt/stub/startOffset
|
||||
global.get $~lib/rt/stub/startOffset
|
||||
global.set $~lib/rt/stub/offset
|
||||
)
|
||||
(func $null (; 11 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 3 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
@ -1,375 +1,20 @@
|
||||
(module
|
||||
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
|
||||
(type $FUNCSIG$viii (func (param i32 i32 i32)))
|
||||
(type $FUNCSIG$vi (func (param i32)))
|
||||
(type $FUNCSIG$ii (func (param i32) (result i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "$\00\00\00\01\00\00\00\10\00\00\00$\00\00\00I\00n\00d\00e\00x\00 \00o\00u\00t\00 \00o\00f\00 \00r\00a\00n\00g\00e\00")
|
||||
(data (i32.const 64) "\"\00\00\00\01\00\00\00\10\00\00\00\"\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00c\00o\00m\00m\00o\00n\00.\00t\00s\00")
|
||||
(data (i32.const 120) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00")
|
||||
(data (i32.const 64) "\14\00\00\00\01\00\00\00\10\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00")
|
||||
(data (i32.const 104) "\10\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
|
||||
(global $~lib/rt/stub/offset (mut i32) (i32.const 0))
|
||||
(global $~lib/builtins/RTTI_BASE i32 (i32.const 120))
|
||||
(global $~lib/builtins/HEAP_BASE i32 (i32.const 256))
|
||||
(global $~lib/rt/RTTI_BASE i32 (i32.const 104))
|
||||
(export "memory" (memory $0))
|
||||
(export "__alloc" (func $~lib/rt/stub/__alloc))
|
||||
(export "__realloc" (func $~lib/rt/stub/__realloc))
|
||||
(export "__free" (func $~lib/rt/stub/__free))
|
||||
(export "__retain" (func $~lib/rt/stub/__retain))
|
||||
(export "__release" (func $~lib/rt/stub/__release))
|
||||
(export "__collect" (func $~lib/rt/stub/__collect))
|
||||
(export "__instanceof" (func $~lib/rt/common/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/common/__typeinfo))
|
||||
(start $start)
|
||||
(func $~lib/rt/stub/__alloc (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
(local $7 i32)
|
||||
(local $8 i32)
|
||||
local.get $0
|
||||
i32.const 1073741808
|
||||
i32.gt_u
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
global.get $~lib/rt/stub/offset
|
||||
i32.const 16
|
||||
i32.add
|
||||
local.set $2
|
||||
local.get $2
|
||||
local.get $0
|
||||
local.tee $3
|
||||
i32.const 1
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.get $4
|
||||
i32.gt_u
|
||||
select
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
local.set $5
|
||||
current_memory
|
||||
local.set $6
|
||||
local.get $5
|
||||
local.get $6
|
||||
i32.const 16
|
||||
i32.shl
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $2
|
||||
i32.sub
|
||||
i32.const 65535
|
||||
i32.add
|
||||
i32.const 65535
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
i32.const 16
|
||||
i32.shr_u
|
||||
local.set $3
|
||||
local.get $6
|
||||
local.tee $4
|
||||
local.get $3
|
||||
local.tee $7
|
||||
local.get $4
|
||||
local.get $7
|
||||
i32.gt_s
|
||||
select
|
||||
local.set $4
|
||||
local.get $4
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
local.get $3
|
||||
grow_memory
|
||||
i32.const 0
|
||||
i32.lt_s
|
||||
if
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
end
|
||||
local.get $5
|
||||
global.set $~lib/rt/stub/offset
|
||||
local.get $2
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $8
|
||||
local.get $8
|
||||
local.get $1
|
||||
i32.store offset=8
|
||||
local.get $8
|
||||
local.get $0
|
||||
i32.store offset=12
|
||||
local.get $2
|
||||
)
|
||||
(func $~lib/memory/memory.copy (; 2 ;) (type $FUNCSIG$viii) (param $0 i32) (param $1 i32) (param $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
(local $5 i32)
|
||||
(local $6 i32)
|
||||
block $~lib/util/memory/memmove|inlined.0
|
||||
local.get $0
|
||||
local.set $5
|
||||
local.get $1
|
||||
local.set $4
|
||||
local.get $2
|
||||
local.set $3
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.eq
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $5
|
||||
local.get $4
|
||||
i32.lt_u
|
||||
if
|
||||
local.get $4
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $3
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $3
|
||||
block (result i32)
|
||||
local.get $5
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $6
|
||||
end
|
||||
block (result i32)
|
||||
local.get $4
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $4
|
||||
local.get $6
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $5
|
||||
local.get $4
|
||||
i64.load
|
||||
i64.store
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $3
|
||||
local.get $5
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $4
|
||||
i32.const 8
|
||||
i32.add
|
||||
local.set $4
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
local.get $3
|
||||
if
|
||||
block (result i32)
|
||||
local.get $5
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $5
|
||||
local.get $6
|
||||
end
|
||||
block (result i32)
|
||||
local.get $4
|
||||
local.tee $6
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.set $4
|
||||
local.get $6
|
||||
end
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.set $3
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local.get $4
|
||||
i32.const 7
|
||||
i32.and
|
||||
local.get $5
|
||||
i32.const 7
|
||||
i32.and
|
||||
i32.eq
|
||||
if
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.const 7
|
||||
i32.and
|
||||
if
|
||||
local.get $3
|
||||
i32.eqz
|
||||
if
|
||||
br $~lib/util/memory/memmove|inlined.0
|
||||
end
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|3
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|4
|
||||
loop $continue|4
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.ge_u
|
||||
if
|
||||
local.get $3
|
||||
i32.const 8
|
||||
i32.sub
|
||||
local.set $3
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i64.load
|
||||
i64.store
|
||||
br $continue|4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
block $break|5
|
||||
loop $continue|5
|
||||
local.get $3
|
||||
if
|
||||
local.get $5
|
||||
local.get $3
|
||||
i32.const 1
|
||||
i32.sub
|
||||
local.tee $3
|
||||
i32.add
|
||||
local.get $4
|
||||
local.get $3
|
||||
i32.add
|
||||
i32.load8_u
|
||||
i32.store8
|
||||
br $continue|5
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
(func $~lib/rt/stub/__realloc (; 3 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
(local $4 i32)
|
||||
local.get $0
|
||||
i32.const 16
|
||||
i32.sub
|
||||
local.set $2
|
||||
local.get $2
|
||||
i32.load offset=12
|
||||
local.set $3
|
||||
local.get $1
|
||||
local.get $3
|
||||
i32.gt_u
|
||||
if
|
||||
local.get $1
|
||||
local.get $2
|
||||
i32.load offset=8
|
||||
call $~lib/rt/stub/__alloc
|
||||
local.set $4
|
||||
local.get $4
|
||||
local.get $0
|
||||
local.get $3
|
||||
call $~lib/memory/memory.copy
|
||||
local.get $4
|
||||
local.set $0
|
||||
else
|
||||
local.get $2
|
||||
local.get $1
|
||||
i32.store offset=12
|
||||
end
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__free (; 4 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/stub/__retain (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
)
|
||||
(func $~lib/rt/stub/__release (; 6 ;) (type $FUNCSIG$vi) (param $0 i32)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/stub/__collect (; 7 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
(func $~lib/rt/common/__instanceof (; 8 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(export "__instanceof" (func $~lib/rt/__instanceof))
|
||||
(export "__typeinfo" (func $~lib/rt/__typeinfo))
|
||||
(func $~lib/rt/__instanceof (; 1 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
|
||||
(local $2 i32)
|
||||
(local $3 i32)
|
||||
local.get $0
|
||||
@ -377,7 +22,7 @@
|
||||
i32.sub
|
||||
i32.load offset=8
|
||||
local.set $2
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
global.get $~lib/rt/RTTI_BASE
|
||||
local.set $3
|
||||
local.get $2
|
||||
if (result i32)
|
||||
@ -409,9 +54,9 @@
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $~lib/rt/common/__typeinfo (; 9 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(func $~lib/rt/__typeinfo (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
global.get $~lib/builtins/RTTI_BASE
|
||||
global.get $~lib/rt/RTTI_BASE
|
||||
local.set $1
|
||||
local.get $0
|
||||
i32.eqz
|
||||
@ -426,7 +71,7 @@
|
||||
if
|
||||
i32.const 24
|
||||
i32.const 80
|
||||
i32.const 55
|
||||
i32.const 23
|
||||
i32.const 34
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
@ -438,18 +83,6 @@
|
||||
i32.add
|
||||
i32.load
|
||||
)
|
||||
(func $start (; 10 ;) (type $FUNCSIG$v)
|
||||
global.get $~lib/builtins/HEAP_BASE
|
||||
i32.const 15
|
||||
i32.add
|
||||
i32.const 15
|
||||
i32.const -1
|
||||
i32.xor
|
||||
i32.and
|
||||
global.set $~lib/rt/stub/startOffset
|
||||
global.get $~lib/rt/stub/startOffset
|
||||
global.set $~lib/rt/stub/offset
|
||||
)
|
||||
(func $null (; 11 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 3 ;) (type $FUNCSIG$v)
|
||||
)
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
(module
|
||||
(type $FUNCSIG$v (func))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\0e\00\00\00\01\00\00\00\11\00\00\00\0e\00\00\00s\00i\00m\00d\00.\00t\00s\00")
|
||||
(data (i32.const 8) "\0e\00\00\00\01\00\00\00\11\00\00\00\0e\00\00\00s\00i\00m\00d\00.\00t\00s")
|
||||
(export "memory" (memory $0))
|
||||
(func $start (; 0 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
|
@ -1,23 +1,16 @@
|
||||
(module
|
||||
(type $FUNCSIG$i (func (result i32)))
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\1c\00\00\00\01\00\00\00\10\00\00\00\1c\00\00\00s\00t\00a\00t\00i\00c\00-\00t\00h\00i\00s\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $static-this/Foo.bar (mut i32) (i32.const 42))
|
||||
(data (i32.const 8) "\1c\00\00\00\01\00\00\00\10\00\00\00\1c\00\00\00s\00t\00a\00t\00i\00c\00-\00t\00h\00i\00s\00.\00t\00s")
|
||||
(global $static-this/Foo.bar i32 (i32.const 42))
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $static-this/Foo.getBar (; 1 ;) (type $FUNCSIG$i) (result i32)
|
||||
(func $start (; 1 ;) (type $FUNCSIG$v)
|
||||
global.get $static-this/Foo.bar
|
||||
)
|
||||
(func $start:static-this (; 2 ;) (type $FUNCSIG$v)
|
||||
call $static-this/Foo.getBar
|
||||
i32.const 42
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -27,9 +20,7 @@
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 3 ;) (type $FUNCSIG$v)
|
||||
call $start:static-this
|
||||
)
|
||||
(func $null (; 4 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 2 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,174 +4,65 @@
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\12\00\00\00\01\00\00\00\10\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(data (i32.const 8) "\12\00\00\00\01\00\00\00\10\00\00\00\12\00\00\00s\00w\00i\00t\00c\00h\00.\00t\00s")
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $switch/doSwitch (; 1 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case4|0
|
||||
block $case3|0
|
||||
block $case2|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case0|0
|
||||
local.get $1
|
||||
i32.const 0
|
||||
i32.eq
|
||||
br_if $case1|0
|
||||
local.get $1
|
||||
i32.const 2
|
||||
i32.eq
|
||||
br_if $case3|0
|
||||
local.get $1
|
||||
i32.const 3
|
||||
i32.eq
|
||||
br_if $case4|0
|
||||
br $case2|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
return
|
||||
block $case4|0
|
||||
block $case2|0
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
local.get $0
|
||||
i32.eqz
|
||||
br_if $case2|0
|
||||
local.get $0
|
||||
i32.const 2
|
||||
i32.eq
|
||||
br_if $case4|0
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.eq
|
||||
br_if $case4|0
|
||||
br $case2|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
i32.const 23
|
||||
i32.const 0
|
||||
return
|
||||
unreachable
|
||||
end
|
||||
unreachable
|
||||
unreachable
|
||||
i32.const 23
|
||||
)
|
||||
(func $switch/doSwitchDefaultOmitted (; 2 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case2|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case0|0
|
||||
local.get $1
|
||||
i32.const 2
|
||||
i32.eq
|
||||
br_if $case1|0
|
||||
local.get $1
|
||||
i32.const 3
|
||||
i32.eq
|
||||
br_if $case2|0
|
||||
br $break|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
local.get $0
|
||||
i32.const 1
|
||||
i32.ne
|
||||
if
|
||||
local.get $0
|
||||
i32.const 2
|
||||
i32.eq
|
||||
br_if $case2|0
|
||||
local.get $0
|
||||
i32.const 3
|
||||
i32.eq
|
||||
br_if $case2|0
|
||||
br $break|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
i32.const 23
|
||||
return
|
||||
end
|
||||
i32.const 0
|
||||
)
|
||||
(func $switch/doSwitchBreakCase (; 3 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case0|0
|
||||
br $case1|0
|
||||
end
|
||||
br $break|0
|
||||
end
|
||||
i32.const 2
|
||||
return
|
||||
end
|
||||
i32.const 1
|
||||
)
|
||||
(func $switch/doSwitchBreakDefault (; 4 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case0|0
|
||||
br $case1|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
br $break|0
|
||||
end
|
||||
i32.const 2
|
||||
)
|
||||
(func $switch/doSwitchFallThroughCase (; 5 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case1|0
|
||||
br $case0|0
|
||||
end
|
||||
i32.const 2
|
||||
return
|
||||
end
|
||||
end
|
||||
i32.const 1
|
||||
)
|
||||
(func $switch/doSwitchFallThroughDefault (; 6 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
(local $1 i32)
|
||||
block $break|0
|
||||
block $case1|0
|
||||
block $case0|0
|
||||
local.get $0
|
||||
local.set $1
|
||||
local.get $1
|
||||
i32.const 1
|
||||
i32.eq
|
||||
br_if $case0|0
|
||||
br $case1|0
|
||||
end
|
||||
i32.const 1
|
||||
return
|
||||
end
|
||||
end
|
||||
i32.const 2
|
||||
)
|
||||
(func $switch/doSwitchEmpty (; 7 ;) (type $FUNCSIG$ii) (param $0 i32) (result i32)
|
||||
local.get $0
|
||||
drop
|
||||
i32.const 2
|
||||
)
|
||||
(func $start:switch (; 8 ;) (type $FUNCSIG$v)
|
||||
(func $start:switch (; 3 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
call $switch/doSwitch
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -183,8 +74,7 @@
|
||||
i32.const 1
|
||||
call $switch/doSwitch
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -196,8 +86,7 @@
|
||||
i32.const 2
|
||||
call $switch/doSwitch
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -209,8 +98,7 @@
|
||||
i32.const 3
|
||||
call $switch/doSwitch
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -221,9 +109,6 @@
|
||||
end
|
||||
i32.const 4
|
||||
call $switch/doSwitch
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -234,9 +119,6 @@
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitch
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -248,8 +130,7 @@
|
||||
i32.const 1
|
||||
call $switch/doSwitch
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -261,8 +142,7 @@
|
||||
i32.const 2
|
||||
call $switch/doSwitch
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -274,8 +154,7 @@
|
||||
i32.const 3
|
||||
call $switch/doSwitch
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -286,9 +165,6 @@
|
||||
end
|
||||
i32.const 4
|
||||
call $switch/doSwitch
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -299,9 +175,6 @@
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchDefaultOmitted
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -313,8 +186,7 @@
|
||||
i32.const 1
|
||||
call $switch/doSwitchDefaultOmitted
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -326,8 +198,7 @@
|
||||
i32.const 2
|
||||
call $switch/doSwitchDefaultOmitted
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -339,8 +210,7 @@
|
||||
i32.const 3
|
||||
call $switch/doSwitchDefaultOmitted
|
||||
i32.const 23
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -351,9 +221,6 @@
|
||||
end
|
||||
i32.const 4
|
||||
call $switch/doSwitchDefaultOmitted
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -362,205 +229,11 @@
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchBreakCase
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 51
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1
|
||||
call $switch/doSwitchBreakCase
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 52
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
call $switch/doSwitchBreakCase
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 53
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchBreakDefault
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 62
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1
|
||||
call $switch/doSwitchBreakDefault
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 63
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
call $switch/doSwitchBreakDefault
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 64
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchFallThroughCase
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 73
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1
|
||||
call $switch/doSwitchFallThroughCase
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 74
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
call $switch/doSwitchFallThroughCase
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 75
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchFallThroughDefault
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 84
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1
|
||||
call $switch/doSwitchFallThroughDefault
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 85
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
call $switch/doSwitchFallThroughDefault
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 86
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
call $switch/doSwitchEmpty
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 92
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 1
|
||||
call $switch/doSwitchEmpty
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 93
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
call $switch/doSwitchEmpty
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 94
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
)
|
||||
(func $start (; 9 ;) (type $FUNCSIG$v)
|
||||
(func $start (; 4 ;) (type $FUNCSIG$v)
|
||||
call $start:switch
|
||||
)
|
||||
(func $null (; 10 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 5 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
@ -1,545 +1,15 @@
|
||||
(module
|
||||
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\0e\00\00\00\01\00\00\00\10\00\00\00\0e\00\00\00w\00a\00s\00i\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(global $~lib/common/target/Target.WASM32 i32 (i32.const 0))
|
||||
(global $~lib/common/target/Target.WASM64 i32 (i32.const 1))
|
||||
(global $~lib/common/target/Target.JS i32 (i32.const 2))
|
||||
(global $~lib/ASC_TARGET i32 (i32.const 0))
|
||||
(data (i32.const 8) "\0e\00\00\00\01\00\00\00\10\00\00\00\0e\00\00\00w\00a\00s\00i\00.\00t\00s")
|
||||
(global $wasi/sig (mut i32) (i32.const 1))
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start:wasi (; 1 ;) (type $FUNCSIG$v)
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 4
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 5
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 6
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 20
|
||||
i32.const 20
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 7
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 8
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 10
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 11
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 10
|
||||
i32.const 10
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 12
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 13
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 14
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 32
|
||||
i32.const 32
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 15
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 17
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 2
|
||||
i32.const 2
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 18
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 19
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 20
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 21
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 23
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 25
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 20
|
||||
i32.const 20
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 26
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 27
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 32
|
||||
i32.const 32
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 28
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 40
|
||||
i32.const 40
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 29
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 48
|
||||
i32.const 48
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 30
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 56
|
||||
i32.const 56
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 31
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 33
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
block
|
||||
i32.const 4
|
||||
i32.const 4
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 35
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 36
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 44
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 45
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 46
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 24
|
||||
i32.const 24
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 47
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 32
|
||||
i32.const 32
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 48
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 40
|
||||
i32.const 40
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 49
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 48
|
||||
i32.const 48
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 50
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 56
|
||||
i32.const 56
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 51
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 53
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 54
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 16
|
||||
i32.const 16
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 55
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 20
|
||||
i32.const 20
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 56
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 0
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 58
|
||||
i32.const 0
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
block
|
||||
i32.const 4
|
||||
i32.const 4
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 60
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
i32.const 8
|
||||
i32.const 8
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 61
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
end
|
||||
(func $start (; 0 ;) (type $FUNCSIG$v)
|
||||
i32.const 9
|
||||
global.set $wasi/sig
|
||||
)
|
||||
(func $start (; 2 ;) (type $FUNCSIG$v)
|
||||
call $start:wasi
|
||||
)
|
||||
(func $null (; 3 ;) (type $FUNCSIG$v)
|
||||
(func $null (; 1 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
@ -3,9 +3,7 @@
|
||||
(type $FUNCSIG$v (func))
|
||||
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
|
||||
(memory $0 1)
|
||||
(data (i32.const 8) "\10\00\00\00\01\00\00\00\10\00\00\00\10\00\00\00w\00h\00i\00l\00e\00.\00t\00s\00")
|
||||
(table $0 1 funcref)
|
||||
(elem (i32.const 0) $null)
|
||||
(data (i32.const 8) "\10\00\00\00\01\00\00\00\10\00\00\00\10\00\00\00w\00h\00i\00l\00e\00.\00t\00s")
|
||||
(global $while/n (mut i32) (i32.const 10))
|
||||
(global $while/m (mut i32) (i32.const 0))
|
||||
(global $while/o (mut i32) (i32.const 0))
|
||||
@ -13,26 +11,21 @@
|
||||
(start $start)
|
||||
(func $start:while (; 1 ;) (type $FUNCSIG$v)
|
||||
(local $0 i32)
|
||||
block $break|0
|
||||
loop $continue|0
|
||||
loop $continue|0
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/m
|
||||
br $continue|0
|
||||
end
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/m
|
||||
br $continue|0
|
||||
end
|
||||
end
|
||||
global.get $while/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -43,8 +36,7 @@
|
||||
end
|
||||
global.get $while/m
|
||||
i32.const 10
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -57,66 +49,55 @@
|
||||
global.set $while/n
|
||||
i32.const 0
|
||||
global.set $while/m
|
||||
block $break|1
|
||||
loop $continue|1
|
||||
loop $continue|1
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/m
|
||||
loop $continue|2
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/o
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/o
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/m
|
||||
block $break|2
|
||||
loop $continue|2
|
||||
global.get $while/n
|
||||
if
|
||||
global.get $while/n
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
global.get $while/o
|
||||
i32.const 1
|
||||
i32.add
|
||||
global.set $while/o
|
||||
br $continue|2
|
||||
end
|
||||
end
|
||||
end
|
||||
global.get $while/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 21
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $while/o
|
||||
i32.const 9
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 22
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
br $continue|1
|
||||
i32.const 24
|
||||
i32.const 21
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
global.get $while/o
|
||||
i32.const 9
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
i32.const 22
|
||||
i32.const 2
|
||||
call $~lib/builtins/abort
|
||||
unreachable
|
||||
end
|
||||
br $continue|1
|
||||
end
|
||||
end
|
||||
global.get $while/n
|
||||
i32.const 0
|
||||
i32.eq
|
||||
i32.eqz
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -127,8 +108,7 @@
|
||||
end
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -139,8 +119,7 @@
|
||||
end
|
||||
global.get $while/o
|
||||
i32.const 9
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -153,36 +132,29 @@
|
||||
global.set $while/n
|
||||
i32.const 0
|
||||
global.set $while/m
|
||||
block $break|3
|
||||
loop $continue|3
|
||||
block (result i32)
|
||||
global.get $while/n
|
||||
local.tee $0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
local.get $0
|
||||
end
|
||||
if (result i32)
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.tee $0
|
||||
global.set $while/m
|
||||
local.get $0
|
||||
else
|
||||
i32.const 0
|
||||
end
|
||||
if
|
||||
nop
|
||||
br $continue|3
|
||||
end
|
||||
loop $continue|3
|
||||
global.get $while/n
|
||||
local.tee $0
|
||||
i32.const 1
|
||||
i32.sub
|
||||
global.set $while/n
|
||||
local.get $0
|
||||
if
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.add
|
||||
local.tee $0
|
||||
global.set $while/m
|
||||
else
|
||||
i32.const 0
|
||||
local.set $0
|
||||
end
|
||||
local.get $0
|
||||
br_if $continue|3
|
||||
end
|
||||
global.get $while/n
|
||||
i32.const -1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -193,8 +165,7 @@
|
||||
end
|
||||
global.get $while/m
|
||||
i32.const 1
|
||||
i32.eq
|
||||
i32.eqz
|
||||
i32.ne
|
||||
if
|
||||
i32.const 0
|
||||
i32.const 24
|
||||
@ -208,5 +179,6 @@
|
||||
call $start:while
|
||||
)
|
||||
(func $null (; 3 ;) (type $FUNCSIG$v)
|
||||
nop
|
||||
)
|
||||
)
|
||||
|
Reference in New Issue
Block a user