Experimenting with inline-assembler-ish explicit builtins

Starting with explicit loads and stores as part of the respective type namespaces. Might become handy for use with portable code, because these can be polyfilled, while load<T> and store<T> can't.
This commit is contained in:
dcodeIO 2018-04-27 00:08:41 +02:00
parent d445608467
commit 06f99406be
18 changed files with 2234 additions and 1143 deletions

View File

@ -803,12 +803,9 @@ function printStats(stats, output) {
exports.printStats = printStats; exports.printStats = printStats;
var allocBuffer = null; var allocBuffer = typeof global !== "undefined" && global.Buffer
if (typeof global !== "undefined" && global.Buffer) { ? global.Buffer.allocUnsafe || function(len) { return new global.Buffer(len); }
allocBuffer = function (len) { return Buffer.allocUnsafe(len) }; : function(len) { return new Uint8Array(len) };
} else {
allocBuffer = function (len) { return new Uint8Array(len) };
}
/** Creates a memory stream that can be used in place of stdout/stderr. */ /** Creates a memory stream that can be used in place of stdout/stderr. */
function createMemoryStream(fn) { function createMemoryStream(fn) {

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
// see: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life // see: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
// Configuration imported from JS. On the WASM side, colors are handled in ABGR order (alpha, blue, // Configuration imported from JS. On the WASM side, 32-bit color values are modified in ABGR order
// green, red) because WASM is little endian. Doing so makes it possible to just copy the entire // (alpha, blue, green, red) because WASM is little endian. This results in RGBA in memory, which is
// ABGR memory in little endian byte order to the RGBA image buffer in big endian byte order. // exactly what the image buffer, composed of 8-bit components, expects on the JS side.
declare const BGR_ALIVE: u32; declare const BGR_ALIVE: u32;
declare const BGR_DEAD: u32; declare const BGR_DEAD: u32;
declare const BIT_ROT: u32; declare const BIT_ROT: u32;

View File

@ -79,7 +79,6 @@
"no-require-imports": { "no-require-imports": {
"severity": "error" "severity": "error"
}, },
"no-shadowed-variable": {},
"no-sparse-arrays": {}, "no-sparse-arrays": {},
"no-string-literal": { "no-string-literal": {
"severity": "error" "severity": "error"

744
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -19,18 +19,18 @@
"ts-node": "^5.0.1" "ts-node": "^5.0.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^9.6.4", "@types/node": "^9.6.6",
"browser-process-hrtime": "^0.1.2", "browser-process-hrtime": "^0.1.2",
"chalk": "^2.3.2", "chalk": "^2.4.1",
"diff": "^3.5.0", "diff": "^3.5.0",
"source-map-support": "^0.5.4", "source-map-support": "^0.5.5",
"ts-loader": "^4.2.0", "ts-loader": "^4.2.0",
"tslint": "^5.9.1", "tslint": "^5.9.1",
"typedoc": "^0.11.1", "typedoc": "^0.11.1",
"typedoc-plugin-external-module-name": "^1.1.1", "typedoc-plugin-external-module-name": "^1.1.1",
"typescript": "^2.8.1", "typescript": "^2.8.3",
"webpack": "^4.5.0", "webpack": "^4.6.0",
"webpack-cli": "^2.0.14" "webpack-cli": "^2.0.15"
}, },
"main": "index.js", "main": "index.js",
"types": "index.d.ts", "types": "index.d.ts",

View File

@ -87,6 +87,14 @@ export function compileCall(
? module.createI32(1) ? module.createI32(1)
: module.createI32(0); : module.createI32(0);
} }
case "isSigned": { // isSigned<T!>() / isSigned<T?>(value: T) -> bool
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
compiler.currentType = Type.bool;
if (!type) return module.createUnreachable();
return type.is(TypeFlags.SIGNED)
? module.createI32(1)
: module.createI32(0);
}
case "isReference": { // isReference<T!>() / isReference<T?>(value: T) -> bool case "isReference": { // isReference<T!>() / isReference<T?>(value: T) -> bool
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode); let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
compiler.currentType = Type.bool; compiler.currentType = Type.bool;
@ -1668,6 +1676,29 @@ export function compileCall(
} }
} }
} }
case "i32.load8_s": return compileLoadInstruction(compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.load8_u": return compileLoadInstruction(compiler, Type.u8, operands, Type.u32, reportNode);
case "i32.load16_s": return compileLoadInstruction(compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.load16_u": return compileLoadInstruction(compiler, Type.u16, operands, Type.u32, reportNode);
case "i32.load": return compileLoadInstruction(compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.load8_s": return compileLoadInstruction(compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.load8_u": return compileLoadInstruction(compiler, Type.u8, operands, Type.u64, reportNode);
case "i64.load16_s": return compileLoadInstruction(compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.load16_u": return compileLoadInstruction(compiler, Type.u16, operands, Type.u64, reportNode);
case "i64.load32_s": return compileLoadInstruction(compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.load32_u": return compileLoadInstruction(compiler, Type.u32, operands, Type.u64, reportNode);
case "i64.load": return compileLoadInstruction(compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.load": return compileLoadInstruction(compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.load": return compileLoadInstruction(compiler, Type.f64, operands, Type.f64, reportNode);
case "i32.store8": return compileStoreInstruction(compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.store16": return compileStoreInstruction(compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.store": return compileStoreInstruction(compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.store8": return compileStoreInstruction(compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.store16": return compileStoreInstruction(compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.store32": return compileStoreInstruction(compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.store": return compileStoreInstruction(compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.store": return compileStoreInstruction(compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.store": return compileStoreInstruction(compiler, Type.f64, operands, Type.f64, reportNode);
// control flow // control flow
@ -2487,3 +2518,29 @@ export function compileAbort(
module.createUnreachable() module.createUnreachable()
]); ]);
} }
/** Explicitly compiles a specific load instruction. */
export function compileLoadInstruction(
compiler: Compiler,
loadType: Type,
loadOperands: Expression[],
valueType: Type,
reportNode: Node
): ExpressionRef { // transform to a `<valueType>load<loadType>(offset)` call
var loadPrototype = assert(compiler.program.elementsLookup.get("load"));
assert(loadPrototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>loadPrototype, [ loadType ], loadOperands, valueType, reportNode);
}
/** Explicitly compiles a specific store instruction. */
export function compileStoreInstruction(
compiler: Compiler,
storeType: Type,
storeOperands: Expression[],
valueType: Type,
reportNode: Node
): ExpressionRef { // transform to a `store<storeType>(offset, <valueType>value)` call
var storePrototype = assert(compiler.program.elementsLookup.get("store"));
assert(storePrototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>storePrototype, [ storeType ], storeOperands, valueType, reportNode);
}

View File

@ -478,6 +478,7 @@ export class Program extends DiagnosticEmitter {
var parentNode = declaration.parent; var parentNode = declaration.parent;
if ( if (
(element.hasDecorator(DecoratorFlags.GLOBAL)) || (element.hasDecorator(DecoratorFlags.GLOBAL)) ||
(declaration.range.source.is(CommonFlags.BUILTIN)) ||
( (
declaration.range.source.isLibrary && declaration.range.source.isLibrary &&
element.is(CommonFlags.EXPORT) && element.is(CommonFlags.EXPORT) &&
@ -489,17 +490,15 @@ export class Program extends DiagnosticEmitter {
) )
) )
) { ) {
let simpleName = declaration.name.text; let globalName = declaration.programLevelInternalName;
if (this.elementsLookup.has(simpleName)) { if (this.elementsLookup.has(globalName)) {
this.error( this.error(
DiagnosticCode.Duplicate_identifier_0, DiagnosticCode.Duplicate_identifier_0,
declaration.name.range, element.internalName declaration.name.range, element.internalName
); );
} else { } else {
this.elementsLookup.set(simpleName, element); this.elementsLookup.set(globalName, element);
if (element.is(CommonFlags.BUILTIN)) { if (element.is(CommonFlags.BUILTIN)) element.internalName = globalName;
element.internalName = simpleName;
}
} }
} }
} }
@ -1281,11 +1280,12 @@ export class Program extends DiagnosticEmitter {
queuedExports, queuedImports queuedExports, queuedImports
); );
} }
} else if (statement.namespaceName) { } else if (statement.namespaceName) { // import * as simpleName from "file"
let simpleName = statement.namespaceName.text;
let internalName = ( let internalName = (
statement.range.source.internalPath + statement.range.source.internalPath +
PATH_DELIMITER + PATH_DELIMITER +
statement.namespaceName.text simpleName
); );
if (this.elementsLookup.has(internalName)) { if (this.elementsLookup.has(internalName)) {
this.error( this.error(
@ -1327,7 +1327,7 @@ export class Program extends DiagnosticEmitter {
} }
// otherwise queue it // otherwise queue it
var indexPart = PATH_DELIMITER + "index"; const indexPart = PATH_DELIMITER + "index";
var queuedImport = new QueuedImport(); var queuedImport = new QueuedImport();
queuedImport.internalName = internalName; queuedImport.internalName = internalName;
if (internalPath.endsWith(indexPart)) { if (internalPath.endsWith(indexPart)) {

64
std/assembly.d.ts vendored
View File

@ -55,6 +55,22 @@ declare namespace i32 {
export const MIN_VALUE: i32; export const MIN_VALUE: i32;
/** Largest representable value. */ /** Largest representable value. */
export const MAX_VALUE: i32; export const MAX_VALUE: i32;
/** Loads an 8-bit signed integer from memory and returns it as a 32-bit integer. */
export function load8_s(offset: usize, constantOffset?: usize): i32;
/** Loads an 8-bit unsigned integer from memory and returns it as a 32-bit integer. */
export function load8_u(offset: usize, constantOffset?: usize): i32;
/** Loads a 16-bit signed integer from memory and returns it as a 32-bit integer. */
export function load16_s(offset: usize, constantOffset?: usize): i32;
/** Loads a 16-bit unsigned integer from memory and returns it as a 32-bit integer. */
export function load16_u(offset: usize, constantOffset?: usize): i32;
/** Loads a 32-bit integer from memory. */
export function load(offset: usize, constantOffset?: usize): i32;
/** Stores a 32-bit integer to memory as an 8-bit integer. */
export function store8(offset: usize, value: i32, constantOffset?: usize): void;
/** Stores a 32-bit integer to memory as a 16-bit integer. */
export function store16(offset: usize, value: i32, constantOffset?: usize): void;
/** Stores a 32-bit integer to memory. */
export function store(offset: usize, value: i32, constantOffset?: usize): void;
} }
/** Converts any other numeric value to a 64-bit signed integer. */ /** Converts any other numeric value to a 64-bit signed integer. */
declare function i64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64; declare function i64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
@ -63,15 +79,31 @@ declare namespace i64 {
export const MIN_VALUE: i64; export const MIN_VALUE: i64;
/** Largest representable value. */ /** Largest representable value. */
export const MAX_VALUE: i64; export const MAX_VALUE: i64;
/** Loads an 8-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load8_s(offset: usize, constantOffset?: usize): i64;
/** Loads an 8-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load8_u(offset: usize, constantOffset?: usize): u64;
/** Loads a 16-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load16_s(offset: usize, constantOffset?: usize): i64;
/** Loads a 16-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load16_u(offset: usize, constantOffset?: usize): u64;
/** Loads a 32-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load32_s(offset: usize, constantOffset?: usize): i64;
/** Loads a 32-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load32_u(offset: usize, constantOffset?: usize): u64;
/** Loads a 64-bit unsigned integer from memory. */
export function load(offset: usize, constantOffset?: usize): i64;
/** Stores a 64-bit integer to memory as an 8-bit integer. */
export function store8(offset: usize, value: i64, constantOffset?: usize): void;
/** Stores a 64-bit integer to memory as a 16-bit integer. */
export function store16(offset: usize, value: i64, constantOffset?: usize): void;
/** Stores a 64-bit integer to memory as a 32-bit integer. */
export function store32(offset: usize, value: i64, constantOffset?: usize): void;
/** Stores a 64-bit integer to memory. */
export function store(offset: usize, value: i64, constantOffset?: usize): void;
} }
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */ /** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */
declare function isize(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): isize; declare var isize: i32 | i64;
declare namespace isize {
/** Smallest representable value. */
export const MIN_VALUE: isize;
/** Largest representable value. */
export const MAX_VALUE: isize;
}
/** Converts any other numeric value to an 8-bit unsigned integer. */ /** Converts any other numeric value to an 8-bit unsigned integer. */
declare function u8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8; declare function u8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
declare namespace u8 { declare namespace u8 {
@ -105,13 +137,7 @@ declare namespace u64 {
export const MAX_VALUE: u64; export const MAX_VALUE: u64;
} }
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */ /** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */
declare function usize(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): isize; declare var usize: u32 | u64;
declare namespace usize {
/** Smallest representable value. */
export const MIN_VALUE: usize;
/** Largesst representable value. */
export const MAX_VALUE: usize;
}
/** Converts any other numeric value to a 1-bit unsigned integer. */ /** Converts any other numeric value to a 1-bit unsigned integer. */
declare function bool(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): bool; declare function bool(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): bool;
declare namespace bool { declare namespace bool {
@ -139,6 +165,10 @@ declare namespace f32 {
export function mod(x: f32, y: f32): f32; export function mod(x: f32, y: f32): f32;
/** Returns the floating-point remainder of `x / y` (rounded to nearest). */ /** Returns the floating-point remainder of `x / y` (rounded to nearest). */
export function rem(x: f32, y: f32): f32; export function rem(x: f32, y: f32): f32;
/** Loads a 32-bit float from memory. */
export function load(offset: usize, constantOffset?: usize): f32;
/** Stores a 32-bit float to memory. */
export function store(offset: usize, value: f32, constantOffset?: usize): void;
} }
/** Converts any other numeric value to a 64-bit float. */ /** Converts any other numeric value to a 64-bit float. */
declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64; declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64;
@ -155,6 +185,10 @@ declare namespace f64 {
export const MAX_SAFE_INTEGER: f64; export const MAX_SAFE_INTEGER: f64;
/** Difference between 1 and the smallest representable value greater than 1. */ /** Difference between 1 and the smallest representable value greater than 1. */
export const EPSILON: f64; export const EPSILON: f64;
/** Loads a 64-bit float from memory. */
export function load(offset: usize, constantOffset?: usize): f64;
/** Stores a 64-bit float to memory. */
export function store(offset: usize, value: f64, constantOffset?: usize): void;
} }
// Built-ins // Built-ins
@ -241,6 +275,8 @@ declare function isFinite<T = f32 | f64>(value: T): bool;
declare function isInteger<T>(value?: any): value is number; declare function isInteger<T>(value?: any): value is number;
/** Tests if the specified expression is of a float type. Compiles to a constant. */ /** Tests if the specified expression is of a float type. Compiles to a constant. */
declare function isFloat<T>(value?: any): value is number; declare function isFloat<T>(value?: any): value is number;
/** Tests if the specified expression can represent negative numbers. Compiles to a constant. */
declare function isSigned<T>(value?: any): value is number;
/** Tests if the specified expression is of a reference type. Compiles to a constant. */ /** Tests if the specified expression is of a reference type. Compiles to a constant. */
declare function isReference<T>(value?: any): value is object | string; declare function isReference<T>(value?: any): value is object | string;
/** Tests if the specified expression can be used ass a string. Compiles to a constant. */ /** Tests if the specified expression can be used ass a string. Compiles to a constant. */

View File

@ -2,6 +2,8 @@ export declare function isInteger<T>(value?: T): bool;
export declare function isFloat<T>(value?: T): bool; export declare function isFloat<T>(value?: T): bool;
export declare function isSigned<T>(value?: T): bool;
export declare function isReference<T>(value?: T): bool; export declare function isReference<T>(value?: T): bool;
export declare function isString<T>(value?: T): bool; export declare function isString<T>(value?: T): bool;
@ -52,7 +54,7 @@ export declare function trunc<T>(value: T): T;
export declare function load<T>(offset: usize, constantOffset?: usize): T; export declare function load<T>(offset: usize, constantOffset?: usize): T;
export declare function store<T>(offset: usize, value: void, constantOffset?: usize): T; export declare function store<T>(offset: usize, value: void, constantOffset?: usize): void;
export declare function sizeof<T>(): usize; // | u32 / u64 export declare function sizeof<T>(): usize; // | u32 / u64
@ -101,12 +103,31 @@ export declare function i32(value: void): i32;
export namespace i32 { export namespace i32 {
export const MIN_VALUE: i32 = -2147483648; export const MIN_VALUE: i32 = -2147483648;
export const MAX_VALUE: i32 = 2147483647; export const MAX_VALUE: i32 = 2147483647;
export declare function load8_s(offset: usize, constantOffset?: usize): i32;
export declare function load8_u(offset: usize, constantOffset?: usize): i32;
export declare function load16_s(offset: usize, constantOffset?: usize): i32;
export declare function load16_u(offset: usize, constantOffset?: usize): i32;
export declare function load(offset: usize, constantOffset?: usize): i32;
export declare function store8(offset: usize, value: i32, constantOffset?: usize): void;
export declare function store16(offset: usize, value: i32, constantOffset?: usize): void;
export declare function store(offset: usize, value: i32, constantOffset?: usize): void;
} }
export declare function i64(value: void): i64; export declare function i64(value: void): i64;
export namespace i64 { export namespace i64 {
export const MIN_VALUE: i64 = -9223372036854775808; export const MIN_VALUE: i64 = -9223372036854775808;
export const MAX_VALUE: i64 = 9223372036854775807; export const MAX_VALUE: i64 = 9223372036854775807;
export declare function load8_s(offset: usize, constantOffset?: usize): i64;
export declare function load8_u(offset: usize, constantOffset?: usize): u64;
export declare function load16_s(offset: usize, constantOffset?: usize): i64;
export declare function load16_u(offset: usize, constantOffset?: usize): u64;
export declare function load32_s(offset: usize, constantOffset?: usize): i64;
export declare function load32_u(offset: usize, constantOffset?: usize): u64;
export declare function load(offset: usize, constantOffset?: usize): i64;
export declare function store8(offset: usize, value: i64, constantOffset?: usize): void;
export declare function store16(offset: usize, value: i64, constantOffset?: usize): void;
export declare function store32(offset: usize, value: i64, constantOffset?: usize): void;
export declare function store(offset: usize, value: i64, constantOffset?: usize): void;
} }
export declare function isize(value: void): isize; export declare function isize(value: void): isize;
@ -165,6 +186,8 @@ export namespace f32 {
export const MIN_SAFE_INTEGER: f32 = -16777215; export const MIN_SAFE_INTEGER: f32 = -16777215;
export const MAX_SAFE_INTEGER: f32 = 16777215; export const MAX_SAFE_INTEGER: f32 = 16777215;
export const EPSILON = reinterpret<f32>(0x34000000); // 0x1p-23f export const EPSILON = reinterpret<f32>(0x34000000); // 0x1p-23f
export declare function load(offset: usize, constantOffset?: usize): f32;
export declare function store(offset: usize, value: f32, constantOffset?: usize): void;
} }
export declare function f64(value: void): f64; export declare function f64(value: void): f64;
@ -175,6 +198,8 @@ export namespace f64 {
export const MIN_SAFE_INTEGER: f64 = -9007199254740991; export const MIN_SAFE_INTEGER: f64 = -9007199254740991;
export const MAX_SAFE_INTEGER: f64 = 9007199254740991; export const MAX_SAFE_INTEGER: f64 = 9007199254740991;
export const EPSILON = reinterpret<f64>(0x3CB0000000000000); // 0x1p-52 export const EPSILON = reinterpret<f64>(0x3CB0000000000000); // 0x1p-52
export declare function load(offset: usize, constantOffset?: usize): f64;
export declare function store(offset: usize, value: f64, constantOffset?: usize): void;
} }
export declare const HEAP_BASE: usize; export declare const HEAP_BASE: usize;

View File

@ -784,6 +784,112 @@
(i32.const 8) (i32.const 8)
(i64.const 1) (i64.const 1)
) )
(drop
(i32.load8_s
(i32.const 8)
)
)
(drop
(i32.load8_u
(i32.const 8)
)
)
(drop
(i32.load16_s
(i32.const 8)
)
)
(drop
(i32.load16_u
(i32.const 8)
)
)
(drop
(i32.load
(i32.const 8)
)
)
(drop
(i64.load8_s
(i32.const 8)
)
)
(drop
(i64.load8_s
(i32.const 8)
)
)
(drop
(i64.load16_s
(i32.const 8)
)
)
(drop
(i64.load16_u
(i32.const 8)
)
)
(drop
(i64.load32_s
(i32.const 8)
)
)
(drop
(i64.load32_u
(i32.const 8)
)
)
(drop
(i64.load
(i32.const 8)
)
)
(drop
(f32.load
(i32.const 8)
)
)
(drop
(f64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(f32.store
(i32.const 8)
(f32.const 1)
)
(f64.store
(i32.const 8)
(f64.const 1)
)
(set_global $builtins/i (set_global $builtins/i
(i32.const 1067450368) (i32.const 1067450368)
) )
@ -840,7 +946,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 261) (i32.const 288)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -856,7 +962,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 262) (i32.const 289)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -870,7 +976,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 263) (i32.const 290)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -884,7 +990,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 264) (i32.const 291)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -898,7 +1004,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 265) (i32.const 292)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -912,7 +1018,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 266) (i32.const 293)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -928,7 +1034,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 267) (i32.const 294)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -944,7 +1050,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 4) (i32.const 4)
(i32.const 268) (i32.const 295)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)

View File

@ -196,6 +196,33 @@ store<i64>(8, <i64>1);
store<i64>(8, <i32>1); // must extend store<i64>(8, <i32>1); // must extend
// explicit load and store
i32.load8_s(8);
i32.load8_u(8);
i32.load16_s(8);
i32.load16_u(8);
i32.load(8);
i64.load8_s(8);
i64.load8_s(8);
i64.load16_s(8);
i64.load16_u(8);
i64.load32_s(8);
i64.load32_u(8);
i64.load(8);
f32.load(8);
f64.load(8);
i32.store8(8, 1);
i32.store16(8, 1);
i32.store(8, 1);
i64.store8(8, 1);
i64.store16(8, 1);
i64.store32(8, 1);
i64.store(8, 1);
f32.store(8, 1);
f64.store(8, 1);
// reinterpretation // reinterpretation
reinterpret<i32>(1.25); reinterpret<i32>(1.25);

File diff suppressed because it is too large Load Diff

View File

@ -7031,6 +7031,112 @@
(i32.const 8) (i32.const 8)
(i64.const 1) (i64.const 1)
) )
(drop
(i32.load8_s
(i32.const 8)
)
)
(drop
(i32.load8_u
(i32.const 8)
)
)
(drop
(i32.load16_s
(i32.const 8)
)
)
(drop
(i32.load16_u
(i32.const 8)
)
)
(drop
(i32.load
(i32.const 8)
)
)
(drop
(i64.load8_s
(i32.const 8)
)
)
(drop
(i64.load8_s
(i32.const 8)
)
)
(drop
(i64.load16_s
(i32.const 8)
)
)
(drop
(i64.load16_u
(i32.const 8)
)
)
(drop
(i64.load32_s
(i32.const 8)
)
)
(drop
(i64.load32_u
(i32.const 8)
)
)
(drop
(i64.load
(i32.const 8)
)
)
(drop
(f32.load
(i32.const 8)
)
)
(drop
(f64.load
(i32.const 8)
)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i32.store8
(i32.const 8)
(i32.const 1)
)
(i32.store16
(i32.const 8)
(i32.const 1)
)
(i32.store
(i32.const 8)
(i32.const 1)
)
(i64.store
(i32.const 8)
(i64.const 1)
)
(f32.store
(i32.const 8)
(f32.const 1)
)
(f64.store
(i32.const 8)
(f64.const 1)
)
(set_global $builtins/i (set_global $builtins/i
(i32.const 1067450368) (i32.const 1067450368)
) )
@ -7087,7 +7193,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 261) (i32.const 288)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7103,7 +7209,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 262) (i32.const 289)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7117,7 +7223,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 263) (i32.const 290)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7131,7 +7237,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 264) (i32.const 291)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7145,7 +7251,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 265) (i32.const 292)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7159,7 +7265,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 266) (i32.const 293)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7175,7 +7281,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 267) (i32.const 294)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)
@ -7191,7 +7297,7 @@
(call $abort (call $abort
(i32.const 0) (i32.const 0)
(i32.const 28) (i32.const 28)
(i32.const 268) (i32.const 295)
(i32.const 0) (i32.const 0)
) )
(unreachable) (unreachable)

File diff suppressed because it is too large Load Diff