initial __runtime_instanceof

This commit is contained in:
dcode 2019-04-02 21:30:47 +02:00
parent d85a43892f
commit a639a42f0d
66 changed files with 654 additions and 157 deletions

View File

@ -54,7 +54,6 @@ import {
import {
ElementKind,
FunctionPrototype,
Class,
Field,
Global,
DecoratorFlags
@ -479,6 +478,7 @@ export namespace BuiltinSymbols {
// std/runtime.ts
export const runtime_id = "~lib/runtime/__runtime_id";
export const runtime_instanceof = "~lib/runtime/__runtime_instanceof";
export const runtime_allocate = "~lib/runtime/runtime.allocate";
export const runtime_reallocate = "~lib/runtime/runtime.reallocate";
export const runtime_register = "~lib/runtime/runtime.register";
@ -3652,6 +3652,20 @@ export function compileCall(
}
return module.createI32(classReference.ensureId());
}
case BuiltinSymbols.runtime_instanceof: {
if (
checkTypeAbsent(typeArguments, reportNode, prototype) |
checkArgsRequired(operands, 2, reportNode, compiler)
) {
compiler.currentType = Type.void;
return module.createUnreachable();
}
let arg0 = compiler.compileExpression(operands[0], Type.u32, ConversionKind.IMPLICIT, WrapMode.NONE);
let arg1 = compiler.compileExpression(operands[1], Type.u32, ConversionKind.IMPLICIT, WrapMode.NONE);
compiler.needsInstanceOf = true;
compiler.currentType = Type.bool;
return module.createCall(BuiltinSymbols.runtime_instanceof, [ arg0, arg1 ], NativeType.I32);
}
case BuiltinSymbols.gc_mark_roots: {
if (
checkTypeAbsent(typeArguments, reportNode, prototype) |
@ -3660,7 +3674,7 @@ export function compileCall(
compiler.currentType = Type.void;
return module.createUnreachable();
}
compiler.needsTraverse = true;
compiler.needsMark = true;
compiler.currentType = Type.void;
return module.createCall(BuiltinSymbols.gc_mark_roots, null, NativeType.None);
}
@ -3674,7 +3688,7 @@ export function compileCall(
}
let arg0 = compiler.compileExpression(operands[0], Type.u32, ConversionKind.IMPLICIT, WrapMode.NONE);
let arg1 = compiler.compileExpression(operands[1], compiler.options.usizeType, ConversionKind.IMPLICIT, WrapMode.NONE);
compiler.needsTraverse = true;
compiler.needsMark = true;
compiler.currentType = Type.void;
return module.createCall(BuiltinSymbols.gc_mark_members, [ arg0, arg1 ], NativeType.None);
}
@ -4061,7 +4075,7 @@ export function compileAbort(
]);
}
/** Compiles the mark_roots function if required. */
/** Compiles the `__gc_mark_roots` function. */
export function compileMarkRoots(compiler: Compiler): void {
var module = compiler.module;
var exprs = new Array<ExpressionRef>();
@ -4113,6 +4127,7 @@ export function compileMarkRoots(compiler: Compiler): void {
);
}
/** Compiles the `__gc_mark_members` function. */
export function compileMarkMembers(compiler: Compiler): void {
var program = compiler.program;
var module = compiler.module;
@ -4221,6 +4236,81 @@ export function compileMarkMembers(compiler: Compiler): void {
module.addFunction(BuiltinSymbols.gc_mark_members, ftype, [ nativeSizeType ], current);
}
/** Compiles the `__runtime_instanceof` function. */
export function compileInstanceOf(compiler: Compiler): void {
var program = compiler.program;
var module = compiler.module;
var managedClasses = program.managedClasses;
var ftype = compiler.ensureFunctionType([ Type.i32, Type.i32 ], Type.i32); // $0 instanceof $1 -> bool
// NOTE: There are multiple ways to model this. The one chosen here is to compute
// all possibilities in a branchless expression, growing linearly with the number
// of chained base classes.
//
// switch ($0) {
// case ANIMAL_ID: {
// return ($1 == ANIMAL_ID);
// }
// case CAT_ID: {
// return ($1 == CAT_ID) | ($1 == ANIMAL_ID);
// }
// case BLACKCAT_ID: {
// return ($1 == BLACKCAT_ID) | ($1 == CAT_ID) | ($1 == ANIMAL_ID);
// }
// }
// return false;
//
// Another one would be an inner br_table, but class id distribution in larger
// programs in unclear, possibly leading to lots of holes in that table that
// could either degenerate into multiple ifs when compiling for size or to
// huge tables when compiling for speed.
//
// Maybe a combination of both could be utilized, like statically analyzing the
// ids and make a decision based on profiling experience?
var names: string[] = [ "nope" ];
var blocks = new Array<ExpressionRef[]>();
for (let [id, instance] of managedClasses) {
names.push(instance.internalName);
let condition = module.createBinary(BinaryOp.EqI32,
module.createGetLocal(1, NativeType.I32),
module.createI32(id)
);
let base = instance.base;
while (base) {
condition = module.createBinary(BinaryOp.OrI32,
condition,
module.createBinary(BinaryOp.EqI32,
module.createGetLocal(1, NativeType.I32),
module.createI32(base.ensureId())
)
);
base = base.base;
}
blocks.push([
module.createReturn(condition)
]);
}
var current: ExpressionRef;
if (blocks.length) {
current = module.createBlock(names[1], [
module.createSwitch(names, "nope", module.createGetLocal(0, NativeType.I32))
]);
for (let i = 0, k = blocks.length; i < k; ++i) {
blocks[i].unshift(current);
current = module.createBlock(i == k - 1 ? "nope" : names[i + 2], blocks[i]);
}
current = module.createBlock(null, [
current,
module.createReturn(module.createI32(0))
]);
} else {
current = module.createReturn(module.createI32(0));
}
module.addFunction(BuiltinSymbols.runtime_instanceof, ftype, null, current);
}
// Helpers
/** Evaluates the constant type of a type argument *or* expression. */

View File

@ -8,6 +8,7 @@ import {
compileAbort,
compileMarkRoots,
compileMarkMembers,
compileInstanceOf,
BuiltinSymbols
} from "./builtins";
@ -310,8 +311,10 @@ export class Compiler extends DiagnosticEmitter {
argcVar: GlobalRef = 0;
/** Argument count helper setter. */
argcSet: FunctionRef = 0;
/** Indicates whether the traverseRoots function must be generated. */
needsTraverse: bool = false;
/** Indicates whether the __gc_mark_* functions must be generated. */
needsMark: bool = false;
/** Indicates whether the __runtime_instanceof function must be generated. */
needsInstanceOf: bool = false;
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
static compile(program: Program, options: Options | null = null): Module {
@ -393,12 +396,17 @@ export class Compiler extends DiagnosticEmitter {
if (!explicitStartFunction) module.setStart(funcRef);
}
// compile gc integration if necessary
if (this.needsTraverse) {
// compile gc features if utilized
if (this.needsMark) {
compileMarkRoots(this);
compileMarkMembers(this);
}
// compile runtime features if utilized
if (this.needsInstanceOf) {
compileInstanceOf(this);
}
// update the heap base pointer
var memoryOffset = this.memoryOffset;
memoryOffset = i64_align(memoryOffset, options.usizeType.byteSize);

View File

@ -812,11 +812,16 @@ export class Flow {
// overflows if the call does not return a wrapped value or the conversion does
case ExpressionId.Call: {
let program = this.parentFunction.program;
let instance = assert(program.instancesByName.get(assert(getCallTarget(expr))));
assert(instance.kind == ElementKind.FUNCTION);
let returnType = (<Function>instance).signature.returnType;
return !(<Function>instance).flow.is(FlowFlags.RETURNS_WRAPPED)
|| canConversionOverflow(returnType, type);
let instancesByName = program.instancesByName;
let instanceName = assert(getCallTarget(expr));
if (instancesByName.has(instanceName)) {
let instance = instancesByName.get(instanceName)!;
assert(instance.kind == ElementKind.FUNCTION);
let returnType = (<Function>instance).signature.returnType;
return !(<Function>instance).flow.is(FlowFlags.RETURNS_WRAPPED)
|| canConversionOverflow(returnType, type);
}
return false; // assume no overflow for builtins
}
// doesn't technically overflow

View File

@ -10,6 +10,11 @@ import { ArrayBufferView } from "./arraybuffer";
@unsafe @builtin
export declare function __runtime_id<T>(): u32;
/** Tests if a managed class is the same as or a superclass of another. */
// @ts-ignore: decorator
@unsafe @builtin
export declare function __runtime_instanceof(id: u32, superId: u32): bool;
/** Runtime implementation. */
export namespace runtime {

View File

@ -106,7 +106,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -121,7 +121,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -139,7 +139,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -156,7 +156,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -1283,7 +1283,7 @@
if
i32.const 0
i32.const 88
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -1298,7 +1298,7 @@
if
i32.const 0
i32.const 88
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -1563,7 +1563,7 @@
if
i32.const 0
i32.const 88
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -1580,7 +1580,7 @@
if
i32.const 0
i32.const 88
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -146,7 +146,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -161,7 +161,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -192,7 +192,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -209,7 +209,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -184,7 +184,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -199,7 +199,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2250,7 +2250,7 @@
if
i32.const 0
i32.const 24
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -2285,7 +2285,7 @@
if
i32.const 0
i32.const 24
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -2299,7 +2299,7 @@
if
i32.const 0
i32.const 24
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -203,7 +203,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -220,7 +220,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2841,7 +2841,7 @@
if
i32.const 0
i32.const 24
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -2883,7 +2883,7 @@
if
i32.const 0
i32.const 24
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -2900,7 +2900,7 @@
if
i32.const 0
i32.const 24
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -137,7 +137,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -152,7 +152,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -182,7 +182,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -199,7 +199,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -136,7 +136,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -151,7 +151,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -181,7 +181,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -198,7 +198,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -341,7 +341,7 @@
if
i32.const 0
i32.const 128
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -356,7 +356,7 @@
if
i32.const 0
i32.const 128
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -1859,7 +1859,7 @@
if
i32.const 0
i32.const 128
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable

View File

@ -390,7 +390,7 @@
if
i32.const 0
i32.const 128
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -407,7 +407,7 @@
if
i32.const 0
i32.const 128
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2466,7 +2466,7 @@
if
i32.const 0
i32.const 128
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable

View File

@ -143,7 +143,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -158,7 +158,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -180,7 +180,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -197,7 +197,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -139,7 +139,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -154,7 +154,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -178,7 +178,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -195,7 +195,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -85,7 +85,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -100,7 +100,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -141,7 +141,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -158,7 +158,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -131,7 +131,7 @@
if
i32.const 0
i32.const 48
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -146,7 +146,7 @@
if
i32.const 0
i32.const 48
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -405,7 +405,7 @@
if
i32.const 0
i32.const 48
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -422,7 +422,7 @@
if
i32.const 0
i32.const 48
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -303,7 +303,7 @@
if
i32.const 0
i32.const 464
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -318,7 +318,7 @@
if
i32.const 0
i32.const 464
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2451,7 +2451,7 @@
if
i32.const 0
i32.const 464
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -2465,7 +2465,7 @@
if
i32.const 0
i32.const 464
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -399,7 +399,7 @@
if
i32.const 0
i32.const 464
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -416,7 +416,7 @@
if
i32.const 0
i32.const 464
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -3534,7 +3534,7 @@
if
i32.const 0
i32.const 464
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -3551,7 +3551,7 @@
if
i32.const 0
i32.const 464
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -100,7 +100,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -115,7 +115,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -148,7 +148,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -165,7 +165,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -0,0 +1,5 @@
{
"asc_flags": [
"--runtime arena"
]
}

View File

@ -0,0 +1,159 @@
(module
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$v (func))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
(memory $0 1)
(data (i32.const 8) "\02\00\00\00*\00\00\00r\00u\00n\00t\00i\00m\00e\00/\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s")
(table $0 1 funcref)
(elem (i32.const 0) $null)
(export "memory" (memory $0))
(export "table" (table $0))
(start $start)
(func $start:runtime/instanceof (; 1 ;) (type $FUNCSIG$v)
i32.const 1
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 7
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 14
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 21
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 3
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 28
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 3
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 35
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 3
call $~lib/runtime/__runtime_instanceof
if
i32.const 0
i32.const 16
i32.const 42
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 4
call $~lib/runtime/__runtime_instanceof
if
i32.const 0
i32.const 16
i32.const 49
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 4
call $~lib/runtime/__runtime_instanceof
if
i32.const 0
i32.const 16
i32.const 56
i32.const 0
call $~lib/env/abort
unreachable
end
)
(func $start (; 2 ;) (type $FUNCSIG$v)
call $start:runtime/instanceof
)
(func $~lib/runtime/__runtime_instanceof (; 3 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
block $nope
block $runtime/instanceof/BlackCat
block $runtime/instanceof/Cat
block $~lib/string/String
block $runtime/instanceof/Animal
local.get $0
i32.const 1
i32.sub
br_table $runtime/instanceof/Animal $~lib/string/String $runtime/instanceof/Cat $runtime/instanceof/BlackCat $nope
end
local.get $1
i32.const 1
i32.eq
return
end
local.get $1
i32.const 2
i32.eq
return
end
local.get $1
i32.const 3
i32.eq
local.get $1
i32.const 1
i32.eq
i32.or
return
end
local.get $1
i32.const 4
i32.eq
local.get $1
i32.const 3
i32.eq
i32.or
local.get $1
i32.const 1
i32.eq
i32.or
return
end
i32.const 0
)
(func $null (; 4 ;) (type $FUNCSIG$v)
nop
)
)

View File

@ -0,0 +1,61 @@
import { __runtime_id, __runtime_instanceof } from "runtime";
class Animal {}
class Cat extends Animal {}
class BlackCat extends Cat {}
assert( // Animal is an Animal
__runtime_instanceof(
__runtime_id<Animal>(),
__runtime_id<Animal>()
)
);
assert( // Cat is an Animal
__runtime_instanceof(
__runtime_id<Cat>(),
__runtime_id<Animal>()
)
);
assert( // BlackCat is an Animal
__runtime_instanceof(
__runtime_id<BlackCat>(),
__runtime_id<Animal>()
)
);
assert( // Cat is a Cat
__runtime_instanceof(
__runtime_id<Cat>(),
__runtime_id<Cat>()
)
);
assert( // BlackCat is a Cat
__runtime_instanceof(
__runtime_id<BlackCat>(),
__runtime_id<Cat>()
)
);
assert(! // Animal isn't necessarily a Cat
__runtime_instanceof(
__runtime_id<Animal>(),
__runtime_id<Cat>()
)
);
assert(! // Animal isn't necessarily a BlackCat
__runtime_instanceof(
__runtime_id<Animal>(),
__runtime_id<BlackCat>()
)
);
assert(! // Cat isn't necessarily a BlackCat
__runtime_instanceof(
__runtime_id<Cat>(),
__runtime_id<BlackCat>()
)
);

View File

@ -0,0 +1,164 @@
(module
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$v (func))
(type $FUNCSIG$iii (func (param i32 i32) (result i32)))
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
(memory $0 1)
(data (i32.const 8) "\02\00\00\00*\00\00\00r\00u\00n\00t\00i\00m\00e\00/\00i\00n\00s\00t\00a\00n\00c\00e\00o\00f\00.\00t\00s\00")
(table $0 1 funcref)
(elem (i32.const 0) $null)
(global $~lib/memory/HEAP_BASE i32 (i32.const 60))
(export "memory" (memory $0))
(export "table" (table $0))
(start $start)
(func $start:runtime/instanceof (; 1 ;) (type $FUNCSIG$v)
i32.const 1
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 7
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 14
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 1
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 21
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 3
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 28
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 4
i32.const 3
call $~lib/runtime/__runtime_instanceof
i32.eqz
if
i32.const 0
i32.const 16
i32.const 35
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 3
call $~lib/runtime/__runtime_instanceof
i32.eqz
i32.eqz
if
i32.const 0
i32.const 16
i32.const 42
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 1
i32.const 4
call $~lib/runtime/__runtime_instanceof
i32.eqz
i32.eqz
if
i32.const 0
i32.const 16
i32.const 49
i32.const 0
call $~lib/env/abort
unreachable
end
i32.const 3
i32.const 4
call $~lib/runtime/__runtime_instanceof
i32.eqz
i32.eqz
if
i32.const 0
i32.const 16
i32.const 56
i32.const 0
call $~lib/env/abort
unreachable
end
)
(func $start (; 2 ;) (type $FUNCSIG$v)
call $start:runtime/instanceof
)
(func $~lib/runtime/__runtime_instanceof (; 3 ;) (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32)
block $nope
block $runtime/instanceof/BlackCat
block $runtime/instanceof/Cat
block $~lib/string/String
block $runtime/instanceof/Animal
local.get $0
br_table $nope $runtime/instanceof/Animal $~lib/string/String $runtime/instanceof/Cat $runtime/instanceof/BlackCat $nope
end
local.get $1
i32.const 1
i32.eq
return
end
local.get $1
i32.const 2
i32.eq
return
end
local.get $1
i32.const 3
i32.eq
local.get $1
i32.const 1
i32.eq
i32.or
return
end
local.get $1
i32.const 4
i32.eq
local.get $1
i32.const 3
i32.eq
i32.or
local.get $1
i32.const 1
i32.eq
i32.or
return
end
i32.const 0
return
)
(func $null (; 4 ;) (type $FUNCSIG$v)
)
)

View File

@ -177,7 +177,7 @@
if
i32.const 0
i32.const 296
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -192,7 +192,7 @@
if
i32.const 0
i32.const 296
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -233,7 +233,7 @@
if
i32.const 0
i32.const 296
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -250,7 +250,7 @@
if
i32.const 0
i32.const 296
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -787,7 +787,7 @@
if
i32.const 0
i32.const 80
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -802,7 +802,7 @@
if
i32.const 0
i32.const 80
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2340,7 +2340,7 @@
if
i32.const 0
i32.const 80
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -6323,7 +6323,7 @@
if
i32.const 0
i32.const 80
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -6337,7 +6337,7 @@
if
i32.const 0
i32.const 80
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -684,7 +684,7 @@
if
i32.const 0
i32.const 80
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -701,7 +701,7 @@
if
i32.const 0
i32.const 80
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -2859,7 +2859,7 @@
if
i32.const 0
i32.const 80
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -9604,7 +9604,7 @@
if
i32.const 0
i32.const 80
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -9621,7 +9621,7 @@
if
i32.const 0
i32.const 80
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -327,7 +327,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -342,7 +342,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -407,7 +407,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -424,7 +424,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -165,7 +165,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -180,7 +180,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -413,7 +413,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -430,7 +430,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -89,7 +89,7 @@
if
i32.const 0
i32.const 48
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -104,7 +104,7 @@
if
i32.const 0
i32.const 48
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -148,7 +148,7 @@
if
i32.const 0
i32.const 48
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -165,7 +165,7 @@
if
i32.const 0
i32.const 48
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -135,7 +135,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -150,7 +150,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -166,7 +166,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -183,7 +183,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -84,7 +84,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -99,7 +99,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -141,7 +141,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -158,7 +158,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -118,7 +118,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -133,7 +133,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -153,7 +153,7 @@
if
i32.const 0
i32.const 64
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -170,7 +170,7 @@
if
i32.const 0
i32.const 64
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -167,7 +167,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -182,7 +182,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -209,7 +209,7 @@
if
i32.const 0
i32.const 16
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -226,7 +226,7 @@
if
i32.const 0
i32.const 16
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -2560,7 +2560,7 @@
if
i32.const 0
i32.const 232
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -2597,7 +2597,7 @@
if
i32.const 0
i32.const 232
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -2612,7 +2612,7 @@
if
i32.const 0
i32.const 232
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable
@ -2628,7 +2628,7 @@
if
i32.const 0
i32.const 232
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -2643,7 +2643,7 @@
if
i32.const 0
i32.const 232
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -3288,7 +3288,7 @@
if
i32.const 0
i32.const 232
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -3330,7 +3330,7 @@
if
i32.const 0
i32.const 232
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -3347,7 +3347,7 @@
if
i32.const 0
i32.const 232
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable
@ -3364,7 +3364,7 @@
if
i32.const 0
i32.const 232
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -3381,7 +3381,7 @@
if
i32.const 0
i32.const 232
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -131,7 +131,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -146,7 +146,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -166,7 +166,7 @@
if
i32.const 0
i32.const 24
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -183,7 +183,7 @@
if
i32.const 0
i32.const 24
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -1437,7 +1437,7 @@
if
i32.const 0
i32.const 280
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable

View File

@ -1928,7 +1928,7 @@
if
i32.const 0
i32.const 280
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable

View File

@ -1464,7 +1464,7 @@
if
i32.const 0
i32.const 136
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -1479,7 +1479,7 @@
if
i32.const 0
i32.const 136
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -1929,7 +1929,7 @@
if
i32.const 0
i32.const 136
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -1946,7 +1946,7 @@
if
i32.const 0
i32.const 136
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -444,7 +444,7 @@
if
i32.const 0
i32.const 184
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -459,7 +459,7 @@
if
i32.const 0
i32.const 184
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -3235,7 +3235,7 @@
if
i32.const 0
i32.const 184
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -5177,7 +5177,7 @@
if
i32.const 0
i32.const 184
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -5191,7 +5191,7 @@
if
i32.const 0
i32.const 184
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -379,7 +379,7 @@
if
i32.const 0
i32.const 184
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -396,7 +396,7 @@
if
i32.const 0
i32.const 184
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable
@ -3850,7 +3850,7 @@
if
i32.const 0
i32.const 184
i32.const 64
i32.const 69
i32.const 10
call $~lib/env/abort
unreachable
@ -6549,7 +6549,7 @@
if
i32.const 0
i32.const 184
i32.const 89
i32.const 94
i32.const 6
call $~lib/env/abort
unreachable
@ -6566,7 +6566,7 @@
if
i32.const 0
i32.const 184
i32.const 91
i32.const 96
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -144,7 +144,7 @@
if
i32.const 0
i32.const 72
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -159,7 +159,7 @@
if
i32.const 0
i32.const 72
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -200,7 +200,7 @@
if
i32.const 0
i32.const 72
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -217,7 +217,7 @@
if
i32.const 0
i32.const 72
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -439,7 +439,7 @@
if
i32.const 0
i32.const 136
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -454,7 +454,7 @@
if
i32.const 0
i32.const 136
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable

View File

@ -497,7 +497,7 @@
if
i32.const 0
i32.const 136
i32.const 102
i32.const 107
i32.const 6
call $~lib/env/abort
unreachable
@ -514,7 +514,7 @@
if
i32.const 0
i32.const 136
i32.const 104
i32.const 109
i32.const 6
call $~lib/env/abort
unreachable