From 0fb5da725890b6011ea344c54a0f3bb542ea7d59 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 30 Jun 2022 14:15:53 +0300 Subject: [PATCH 1/5] init --- src/bindings/js.ts | 21 +++++++++++++++------ tests/compiler/bindings/esm.debug.d.ts | 10 ++++++++++ tests/compiler/bindings/esm.debug.js | 10 ++++++++++ tests/compiler/bindings/esm.debug.wat | 9 +++++++++ tests/compiler/bindings/esm.js | 3 +++ tests/compiler/bindings/esm.release.d.ts | 10 ++++++++++ tests/compiler/bindings/esm.release.js | 10 ++++++++++ tests/compiler/bindings/esm.release.wat | 11 ++++++++++- tests/compiler/bindings/esm.ts | 8 ++++++++ 9 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/bindings/js.ts b/src/bindings/js.ts index 52f0e6d08d..981fdf3a08 100644 --- a/src/bindings/js.ts +++ b/src/bindings/js.ts @@ -949,6 +949,7 @@ export class JSBuilder extends ExportsWalker { /** Lifts a WebAssembly value to a JavaScript value. */ makeLiftFromValue(name: string, type: Type, sb: string[] = this.sb): void { if (type.isInternalReference) { + // Lift reference types const clazz = assert(type.getClassOrWrapper(this.program)); if (clazz.extends(this.program.arrayBufferInstance.prototype)) { sb.push("__liftBuffer("); @@ -1005,11 +1006,17 @@ export class JSBuilder extends ExportsWalker { } sb.push(")"); } else { - sb.push(name); - if (type.isUnsignedIntegerValue && type.size == 32) { - sb.push(" >>> 0"); - } else if (type == Type.bool) { - sb.push(" != 0"); + // Lift basic plain types + if (type.isUnsignedIntegerValue && type.size == 64) { + sb.push(`BigInt.asUintN(64, ${name})`); + } else { + if (type == Type.bool) { + sb.push(`${name} != 0`); + } else if (type.isUnsignedIntegerValue) { + sb.push(`${name} >>> 0`); + } else { + sb.push(name); + } } } } @@ -1017,6 +1024,7 @@ export class JSBuilder extends ExportsWalker { /** Lowers a JavaScript value to a WebAssembly value. */ makeLowerToValue(name: string, type: Type, sb: string[] = this.sb): void { if (type.isInternalReference) { + // Lower reference types const clazz = assert(type.getClass()); if (clazz.extends(this.program.arrayBufferInstance.prototype)) { sb.push("__lowerBuffer("); @@ -1082,6 +1090,7 @@ export class JSBuilder extends ExportsWalker { sb.push(" || __notnull()"); } } else { + // Lower basic types sb.push(name); // basic value if (type.isIntegerValue && type.size == 64) { sb.push(" || 0n"); @@ -1284,7 +1293,7 @@ function isPlainValue(type: Type, kind: Mode): bool { if (type == Type.bool) return false; } else { // requires coercion from signed to unsigned - if (type.isUnsignedIntegerValue && type.size == 32) return false; + if (type.isUnsignedIntegerValue) return false; // requires coercion from 1/0 to true/false if (type == Type.bool) return false; } diff --git a/tests/compiler/bindings/esm.debug.d.ts b/tests/compiler/bindings/esm.debug.d.ts index a9d795fee1..6406fe41e7 100644 --- a/tests/compiler/bindings/esm.debug.d.ts +++ b/tests/compiler/bindings/esm.debug.d.ts @@ -52,6 +52,16 @@ export declare function plainFunction(a: number, b: number): number; * @returns `i64` */ export declare function plainFunction64(a: bigint, b: bigint): bigint; +/** + * bindings/esm/plainFunctionGetUnsigned32 + * @returns `u32` + */ +export declare function plainFunctionGetUnsigned32(): number; +/** + * bindings/esm/plainFunctionGetUnsigned64 + * @returns `u64` + */ +export declare function plainFunctionGetUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/esm.debug.js b/tests/compiler/bindings/esm.debug.js index ad6cfd1467..cd47978d57 100644 --- a/tests/compiler/bindings/esm.debug.js +++ b/tests/compiler/bindings/esm.debug.js @@ -86,6 +86,14 @@ async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, + plainFunctionGetUnsigned32() { + // bindings/esm/plainFunctionGetUnsigned32() => u32 + return exports.plainFunctionGetUnsigned32() >>> 0; + }, + plainFunctionGetUnsigned64() { + // bindings/esm/plainFunctionGetUnsigned64() => u64 + return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer a = __retain(__lowerBuffer(a) || __notnull()); @@ -360,6 +368,8 @@ export const { ConstEnum, plainFunction, plainFunction64, + plainFunctionGetUnsigned32, + plainFunctionGetUnsigned64, bufferFunction, stringFunction, stringFunctionOptional, diff --git a/tests/compiler/bindings/esm.debug.wat b/tests/compiler/bindings/esm.debug.wat index e811a94fe6..283239019d 100644 --- a/tests/compiler/bindings/esm.debug.wat +++ b/tests/compiler/bindings/esm.debug.wat @@ -12,6 +12,7 @@ (type $i32_i32_f64_f64_f64_f64_f64_=>_none (func (param i32 i32 f64 f64 f64 f64 f64))) (type $f64_=>_f64 (func (param f64) (result f64))) (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) + (type $none_=>_i64 (func (result i64))) (type $i32_i32_i64_=>_none (func (param i32 i32 i64))) (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $i32_f32_=>_none (func (param i32 f32))) @@ -91,6 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) + (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) + (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -118,6 +121,12 @@ local.get $1 i64.add ) + (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) + i32.const -2 + ) + (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) + i64.const -2 + ) (func $~lib/arraybuffer/ArrayBuffer#get:byteLength (param $0 i32) (result i32) local.get $0 i32.const 20 diff --git a/tests/compiler/bindings/esm.js b/tests/compiler/bindings/esm.js index b279d8e09d..ab7770af45 100644 --- a/tests/compiler/bindings/esm.js +++ b/tests/compiler/bindings/esm.js @@ -35,6 +35,9 @@ export async function postInstantiate(instance) { assert.strictEqual(exports.Enum.TWO, 2); assert.strictEqual(exports.Enum[2], "TWO"); + assert.strictEqual(exports.plainFunctionGetUnsigned32(), 4294967294); + assert.strictEqual(exports.plainFunctionGetUnsigned64(), 18446744073709551614n); + assert.strictEqual(exports.plainFunction(1, 2), 3); { diff --git a/tests/compiler/bindings/esm.release.d.ts b/tests/compiler/bindings/esm.release.d.ts index a9d795fee1..6406fe41e7 100644 --- a/tests/compiler/bindings/esm.release.d.ts +++ b/tests/compiler/bindings/esm.release.d.ts @@ -52,6 +52,16 @@ export declare function plainFunction(a: number, b: number): number; * @returns `i64` */ export declare function plainFunction64(a: bigint, b: bigint): bigint; +/** + * bindings/esm/plainFunctionGetUnsigned32 + * @returns `u32` + */ +export declare function plainFunctionGetUnsigned32(): number; +/** + * bindings/esm/plainFunctionGetUnsigned64 + * @returns `u64` + */ +export declare function plainFunctionGetUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/esm.release.js b/tests/compiler/bindings/esm.release.js index f2b51c2895..eba9c24590 100644 --- a/tests/compiler/bindings/esm.release.js +++ b/tests/compiler/bindings/esm.release.js @@ -86,6 +86,14 @@ async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, + plainFunctionGetUnsigned32() { + // bindings/esm/plainFunctionGetUnsigned32() => u32 + return exports.plainFunctionGetUnsigned32() >>> 0; + }, + plainFunctionGetUnsigned64() { + // bindings/esm/plainFunctionGetUnsigned64() => u64 + return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer a = __retain(__lowerBuffer(a) || __notnull()); @@ -360,6 +368,8 @@ export const { ConstEnum, plainFunction, plainFunction64, + plainFunctionGetUnsigned32, + plainFunctionGetUnsigned64, bufferFunction, stringFunction, stringFunctionOptional, diff --git a/tests/compiler/bindings/esm.release.wat b/tests/compiler/bindings/esm.release.wat index 333923028d..c30a486f47 100644 --- a/tests/compiler/bindings/esm.release.wat +++ b/tests/compiler/bindings/esm.release.wat @@ -1,13 +1,14 @@ (module (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_none (func (param i32))) - (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) + (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $i32_i32_f64_f64_f64_f64_f64_=>_none (func (param i32 i32 f64 f64 f64 f64 f64))) (type $f64_=>_f64 (func (param f64) (result f64))) (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) + (type $none_=>_i64 (func (result i64))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_i32_i64_=>_none (func (param i32 i32 i64))) (type $i32_=>_i32 (func (param i32) (result i32))) @@ -91,6 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) + (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) + (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -118,6 +121,12 @@ local.get $1 i64.add ) + (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) + i32.const -2 + ) + (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) + i64.const -2 + ) (func $~lib/rt/itcms/visitRoots (local $0 i32) (local $1 i32) diff --git a/tests/compiler/bindings/esm.ts b/tests/compiler/bindings/esm.ts index 944e35d859..19d34ab7a3 100644 --- a/tests/compiler/bindings/esm.ts +++ b/tests/compiler/bindings/esm.ts @@ -26,6 +26,14 @@ export function plainFunction64(a: i64, b: i64): i64 { return a + b; } +export function plainFunctionGetUnsigned32(): u32 { + return -2; // 4294967294 +} + +export function plainFunctionGetUnsigned64(): u64 { + return -2; // 18446744073709551614n +} + export function bufferFunction(a: ArrayBuffer, b: ArrayBuffer): ArrayBuffer { var aByteLength = a.byteLength; var bByteLength = b.byteLength; From 8c186d987dc022a90d6cef2813b97202e915c601 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 30 Jun 2022 14:57:03 +0300 Subject: [PATCH 2/5] update raw as well --- tests/compiler/bindings/raw.debug.d.ts | 10 ++++++++++ tests/compiler/bindings/raw.debug.js | 8 ++++++++ tests/compiler/bindings/raw.debug.wat | 9 +++++++++ tests/compiler/bindings/raw.release.d.ts | 10 ++++++++++ tests/compiler/bindings/raw.release.js | 8 ++++++++ tests/compiler/bindings/raw.release.wat | 11 ++++++++++- 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/tests/compiler/bindings/raw.debug.d.ts b/tests/compiler/bindings/raw.debug.d.ts index 14bc6d53ec..2f1121e4d6 100644 --- a/tests/compiler/bindings/raw.debug.d.ts +++ b/tests/compiler/bindings/raw.debug.d.ts @@ -53,6 +53,16 @@ declare namespace __AdaptedExports { * @returns `i64` */ export function plainFunction64(a: bigint, b: bigint): bigint; + /** + * bindings/esm/plainFunctionGetUnsigned32 + * @returns `u32` + */ + export function plainFunctionGetUnsigned32(): number; + /** + * bindings/esm/plainFunctionGetUnsigned64 + * @returns `u64` + */ + export function plainFunctionGetUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/raw.debug.js b/tests/compiler/bindings/raw.debug.js index dabcb032b9..cf04e3a0bb 100644 --- a/tests/compiler/bindings/raw.debug.js +++ b/tests/compiler/bindings/raw.debug.js @@ -86,6 +86,14 @@ export async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, + plainFunctionGetUnsigned32() { + // bindings/esm/plainFunctionGetUnsigned32() => u32 + return exports.plainFunctionGetUnsigned32() >>> 0; + }, + plainFunctionGetUnsigned64() { + // bindings/esm/plainFunctionGetUnsigned64() => u64 + return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer a = __retain(__lowerBuffer(a) || __notnull()); diff --git a/tests/compiler/bindings/raw.debug.wat b/tests/compiler/bindings/raw.debug.wat index f987fcf6b2..e4f0738bc8 100644 --- a/tests/compiler/bindings/raw.debug.wat +++ b/tests/compiler/bindings/raw.debug.wat @@ -12,6 +12,7 @@ (type $i32_i32_f64_f64_f64_f64_f64_=>_none (func (param i32 i32 f64 f64 f64 f64 f64))) (type $f64_=>_f64 (func (param f64) (result f64))) (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) + (type $none_=>_i64 (func (result i64))) (type $i32_i32_i64_=>_none (func (param i32 i32 i64))) (type $i32_i32_=>_f32 (func (param i32 i32) (result f32))) (type $i32_f32_=>_none (func (param i32 f32))) @@ -91,6 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) + (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) + (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -121,6 +124,12 @@ local.get $1 i64.add ) + (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) + i32.const -2 + ) + (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) + i64.const -2 + ) (func $~lib/arraybuffer/ArrayBuffer#get:byteLength (param $0 i32) (result i32) local.get $0 i32.const 20 diff --git a/tests/compiler/bindings/raw.release.d.ts b/tests/compiler/bindings/raw.release.d.ts index 14bc6d53ec..2f1121e4d6 100644 --- a/tests/compiler/bindings/raw.release.d.ts +++ b/tests/compiler/bindings/raw.release.d.ts @@ -53,6 +53,16 @@ declare namespace __AdaptedExports { * @returns `i64` */ export function plainFunction64(a: bigint, b: bigint): bigint; + /** + * bindings/esm/plainFunctionGetUnsigned32 + * @returns `u32` + */ + export function plainFunctionGetUnsigned32(): number; + /** + * bindings/esm/plainFunctionGetUnsigned64 + * @returns `u64` + */ + export function plainFunctionGetUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/raw.release.js b/tests/compiler/bindings/raw.release.js index dabcb032b9..cf04e3a0bb 100644 --- a/tests/compiler/bindings/raw.release.js +++ b/tests/compiler/bindings/raw.release.js @@ -86,6 +86,14 @@ export async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, + plainFunctionGetUnsigned32() { + // bindings/esm/plainFunctionGetUnsigned32() => u32 + return exports.plainFunctionGetUnsigned32() >>> 0; + }, + plainFunctionGetUnsigned64() { + // bindings/esm/plainFunctionGetUnsigned64() => u64 + return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer a = __retain(__lowerBuffer(a) || __notnull()); diff --git a/tests/compiler/bindings/raw.release.wat b/tests/compiler/bindings/raw.release.wat index f5f70ccc7a..a05a0cac69 100644 --- a/tests/compiler/bindings/raw.release.wat +++ b/tests/compiler/bindings/raw.release.wat @@ -1,13 +1,14 @@ (module (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) (type $i32_=>_none (func (param i32))) - (type $none_=>_none (func)) (type $none_=>_i32 (func (result i32))) + (type $none_=>_none (func)) (type $i32_i32_=>_none (func (param i32 i32))) (type $i32_i32_i32_=>_none (func (param i32 i32 i32))) (type $i32_i32_f64_f64_f64_f64_f64_=>_none (func (param i32 i32 f64 f64 f64 f64 f64))) (type $f64_=>_f64 (func (param f64) (result f64))) (type $i64_i64_=>_i64 (func (param i64 i64) (result i64))) + (type $none_=>_i64 (func (result i64))) (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32))) (type $i32_i32_i64_=>_none (func (param i32 i32 i64))) (type $i32_=>_i32 (func (param i32) (result i32))) @@ -91,6 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) + (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) + (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -118,6 +121,12 @@ local.get $1 i64.add ) + (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) + i32.const -2 + ) + (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) + i64.const -2 + ) (func $~lib/rt/itcms/visitRoots (local $0 i32) (local $1 i32) From 9115d5bf93c67b8edf8e66b9edb6ed0917687a76 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 30 Jun 2022 15:41:21 +0300 Subject: [PATCH 3/5] simplify --- src/bindings/js.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/bindings/js.ts b/src/bindings/js.ts index 981fdf3a08..f2db00e816 100644 --- a/src/bindings/js.ts +++ b/src/bindings/js.ts @@ -1007,16 +1007,12 @@ export class JSBuilder extends ExportsWalker { sb.push(")"); } else { // Lift basic plain types - if (type.isUnsignedIntegerValue && type.size == 64) { - sb.push(`BigInt.asUintN(64, ${name})`); + if (type == Type.bool) { + sb.push(`${name} != 0`); + } else if (type.isUnsignedIntegerValue && type.size >= 32) { + sb.push(type.size == 64 ? `BigInt.asUintN(64, ${name})` : `${name} >>> 0`); } else { - if (type == Type.bool) { - sb.push(`${name} != 0`); - } else if (type.isUnsignedIntegerValue) { - sb.push(`${name} >>> 0`); - } else { - sb.push(name); - } + sb.push(name); } } } From 220fb34992e97da7887cd89fd4e4c02eebbed8b9 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Thu, 30 Jun 2022 16:19:18 +0300 Subject: [PATCH 4/5] refactor tests --- tests/compiler/bindings/esm.debug.d.ts | 8 ++++---- tests/compiler/bindings/esm.debug.js | 16 ++++++++-------- tests/compiler/bindings/esm.debug.wat | 14 ++++++++------ tests/compiler/bindings/esm.js | 4 ++-- tests/compiler/bindings/esm.release.d.ts | 8 ++++---- tests/compiler/bindings/esm.release.js | 16 ++++++++-------- tests/compiler/bindings/esm.release.wat | 12 ++++++------ tests/compiler/bindings/esm.ts | 8 ++++---- tests/compiler/bindings/raw.debug.d.ts | 8 ++++---- tests/compiler/bindings/raw.debug.js | 12 ++++++------ tests/compiler/bindings/raw.debug.wat | 14 ++++++++------ tests/compiler/bindings/raw.release.d.ts | 8 ++++---- tests/compiler/bindings/raw.release.js | 12 ++++++------ tests/compiler/bindings/raw.release.wat | 12 ++++++------ 14 files changed, 78 insertions(+), 74 deletions(-) diff --git a/tests/compiler/bindings/esm.debug.d.ts b/tests/compiler/bindings/esm.debug.d.ts index 6406fe41e7..cbf52b0406 100644 --- a/tests/compiler/bindings/esm.debug.d.ts +++ b/tests/compiler/bindings/esm.debug.d.ts @@ -53,15 +53,15 @@ export declare function plainFunction(a: number, b: number): number; */ export declare function plainFunction64(a: bigint, b: bigint): bigint; /** - * bindings/esm/plainFunctionGetUnsigned32 + * bindings/esm/getMaxUnsigned32 * @returns `u32` */ -export declare function plainFunctionGetUnsigned32(): number; +export declare function getMaxUnsigned32(): number; /** - * bindings/esm/plainFunctionGetUnsigned64 + * bindings/esm/getMaxUnsigned64 * @returns `u64` */ -export declare function plainFunctionGetUnsigned64(): bigint; +export declare function getMaxUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/esm.debug.js b/tests/compiler/bindings/esm.debug.js index cd47978d57..21ebe81e62 100644 --- a/tests/compiler/bindings/esm.debug.js +++ b/tests/compiler/bindings/esm.debug.js @@ -86,13 +86,13 @@ async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, - plainFunctionGetUnsigned32() { - // bindings/esm/plainFunctionGetUnsigned32() => u32 - return exports.plainFunctionGetUnsigned32() >>> 0; + getMaxUnsigned32() { + // bindings/esm/getMaxUnsigned32() => u32 + return exports.getMaxUnsigned32() >>> 0; }, - plainFunctionGetUnsigned64() { - // bindings/esm/plainFunctionGetUnsigned64() => u64 - return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + getMaxUnsigned64() { + // bindings/esm/getMaxUnsigned64() => u64 + return BigInt.asUintN(64, exports.getMaxUnsigned64()); }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer @@ -368,8 +368,8 @@ export const { ConstEnum, plainFunction, plainFunction64, - plainFunctionGetUnsigned32, - plainFunctionGetUnsigned64, + getMaxUnsigned32, + getMaxUnsigned64, bufferFunction, stringFunction, stringFunctionOptional, diff --git a/tests/compiler/bindings/esm.debug.wat b/tests/compiler/bindings/esm.debug.wat index 283239019d..f045953ecc 100644 --- a/tests/compiler/bindings/esm.debug.wat +++ b/tests/compiler/bindings/esm.debug.wat @@ -35,6 +35,8 @@ (global $bindings/esm/ConstEnum.ONE i32 (i32.const 1)) (global $bindings/esm/ConstEnum.TWO i32 (i32.const 2)) (global $bindings/esm/ConstEnum.THREE i32 (i32.const 3)) + (global $~lib/builtins/u32.MAX_VALUE i32 (i32.const -1)) + (global $~lib/builtins/u64.MAX_VALUE i64 (i64.const -1)) (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) @@ -92,8 +94,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) - (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) - (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) + (export "getMaxUnsigned32" (func $bindings/esm/getMaxUnsigned32)) + (export "getMaxUnsigned64" (func $bindings/esm/getMaxUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -121,11 +123,11 @@ local.get $1 i64.add ) - (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) - i32.const -2 + (func $bindings/esm/getMaxUnsigned32 (result i32) + global.get $~lib/builtins/u32.MAX_VALUE ) - (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) - i64.const -2 + (func $bindings/esm/getMaxUnsigned64 (result i64) + global.get $~lib/builtins/u64.MAX_VALUE ) (func $~lib/arraybuffer/ArrayBuffer#get:byteLength (param $0 i32) (result i32) local.get $0 diff --git a/tests/compiler/bindings/esm.js b/tests/compiler/bindings/esm.js index ab7770af45..63c6fc8792 100644 --- a/tests/compiler/bindings/esm.js +++ b/tests/compiler/bindings/esm.js @@ -35,8 +35,8 @@ export async function postInstantiate(instance) { assert.strictEqual(exports.Enum.TWO, 2); assert.strictEqual(exports.Enum[2], "TWO"); - assert.strictEqual(exports.plainFunctionGetUnsigned32(), 4294967294); - assert.strictEqual(exports.plainFunctionGetUnsigned64(), 18446744073709551614n); + assert.strictEqual(exports.getMaxUnsigned32(), 4294967295); + assert.strictEqual(exports.getMaxUnsigned64(), 18446744073709551615n); assert.strictEqual(exports.plainFunction(1, 2), 3); diff --git a/tests/compiler/bindings/esm.release.d.ts b/tests/compiler/bindings/esm.release.d.ts index 6406fe41e7..cbf52b0406 100644 --- a/tests/compiler/bindings/esm.release.d.ts +++ b/tests/compiler/bindings/esm.release.d.ts @@ -53,15 +53,15 @@ export declare function plainFunction(a: number, b: number): number; */ export declare function plainFunction64(a: bigint, b: bigint): bigint; /** - * bindings/esm/plainFunctionGetUnsigned32 + * bindings/esm/getMaxUnsigned32 * @returns `u32` */ -export declare function plainFunctionGetUnsigned32(): number; +export declare function getMaxUnsigned32(): number; /** - * bindings/esm/plainFunctionGetUnsigned64 + * bindings/esm/getMaxUnsigned64 * @returns `u64` */ -export declare function plainFunctionGetUnsigned64(): bigint; +export declare function getMaxUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/esm.release.js b/tests/compiler/bindings/esm.release.js index eba9c24590..8285c32a1c 100644 --- a/tests/compiler/bindings/esm.release.js +++ b/tests/compiler/bindings/esm.release.js @@ -86,13 +86,13 @@ async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, - plainFunctionGetUnsigned32() { - // bindings/esm/plainFunctionGetUnsigned32() => u32 - return exports.plainFunctionGetUnsigned32() >>> 0; + getMaxUnsigned32() { + // bindings/esm/getMaxUnsigned32() => u32 + return exports.getMaxUnsigned32() >>> 0; }, - plainFunctionGetUnsigned64() { - // bindings/esm/plainFunctionGetUnsigned64() => u64 - return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + getMaxUnsigned64() { + // bindings/esm/getMaxUnsigned64() => u64 + return BigInt.asUintN(64, exports.getMaxUnsigned64()); }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer @@ -368,8 +368,8 @@ export const { ConstEnum, plainFunction, plainFunction64, - plainFunctionGetUnsigned32, - plainFunctionGetUnsigned64, + getMaxUnsigned32, + getMaxUnsigned64, bufferFunction, stringFunction, stringFunctionOptional, diff --git a/tests/compiler/bindings/esm.release.wat b/tests/compiler/bindings/esm.release.wat index c30a486f47..76483b93d9 100644 --- a/tests/compiler/bindings/esm.release.wat +++ b/tests/compiler/bindings/esm.release.wat @@ -92,8 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) - (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) - (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) + (export "getMaxUnsigned32" (func $bindings/esm/getMaxUnsigned32)) + (export "getMaxUnsigned64" (func $bindings/esm/getMaxUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -121,11 +121,11 @@ local.get $1 i64.add ) - (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) - i32.const -2 + (func $bindings/esm/getMaxUnsigned32 (result i32) + i32.const -1 ) - (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) - i64.const -2 + (func $bindings/esm/getMaxUnsigned64 (result i64) + i64.const -1 ) (func $~lib/rt/itcms/visitRoots (local $0 i32) diff --git a/tests/compiler/bindings/esm.ts b/tests/compiler/bindings/esm.ts index 19d34ab7a3..3a000c534a 100644 --- a/tests/compiler/bindings/esm.ts +++ b/tests/compiler/bindings/esm.ts @@ -26,12 +26,12 @@ export function plainFunction64(a: i64, b: i64): i64 { return a + b; } -export function plainFunctionGetUnsigned32(): u32 { - return -2; // 4294967294 +export function getMaxUnsigned32(): u32 { + return u32.MAX_VALUE; // 4294967295 } -export function plainFunctionGetUnsigned64(): u64 { - return -2; // 18446744073709551614n +export function getMaxUnsigned64(): u64 { + return u64.MAX_VALUE; // 18446744073709551615 } export function bufferFunction(a: ArrayBuffer, b: ArrayBuffer): ArrayBuffer { diff --git a/tests/compiler/bindings/raw.debug.d.ts b/tests/compiler/bindings/raw.debug.d.ts index 2f1121e4d6..15e2360189 100644 --- a/tests/compiler/bindings/raw.debug.d.ts +++ b/tests/compiler/bindings/raw.debug.d.ts @@ -54,15 +54,15 @@ declare namespace __AdaptedExports { */ export function plainFunction64(a: bigint, b: bigint): bigint; /** - * bindings/esm/plainFunctionGetUnsigned32 + * bindings/esm/getMaxUnsigned32 * @returns `u32` */ - export function plainFunctionGetUnsigned32(): number; + export function getMaxUnsigned32(): number; /** - * bindings/esm/plainFunctionGetUnsigned64 + * bindings/esm/getMaxUnsigned64 * @returns `u64` */ - export function plainFunctionGetUnsigned64(): bigint; + export function getMaxUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/raw.debug.js b/tests/compiler/bindings/raw.debug.js index cf04e3a0bb..1091069c5b 100644 --- a/tests/compiler/bindings/raw.debug.js +++ b/tests/compiler/bindings/raw.debug.js @@ -86,13 +86,13 @@ export async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, - plainFunctionGetUnsigned32() { - // bindings/esm/plainFunctionGetUnsigned32() => u32 - return exports.plainFunctionGetUnsigned32() >>> 0; + getMaxUnsigned32() { + // bindings/esm/getMaxUnsigned32() => u32 + return exports.getMaxUnsigned32() >>> 0; }, - plainFunctionGetUnsigned64() { - // bindings/esm/plainFunctionGetUnsigned64() => u64 - return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + getMaxUnsigned64() { + // bindings/esm/getMaxUnsigned64() => u64 + return BigInt.asUintN(64, exports.getMaxUnsigned64()); }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer diff --git a/tests/compiler/bindings/raw.debug.wat b/tests/compiler/bindings/raw.debug.wat index e4f0738bc8..863c18d4e5 100644 --- a/tests/compiler/bindings/raw.debug.wat +++ b/tests/compiler/bindings/raw.debug.wat @@ -35,6 +35,8 @@ (global $bindings/esm/ConstEnum.ONE i32 (i32.const 1)) (global $bindings/esm/ConstEnum.TWO i32 (i32.const 2)) (global $bindings/esm/ConstEnum.THREE i32 (i32.const 3)) + (global $~lib/builtins/u32.MAX_VALUE i32 (i32.const -1)) + (global $~lib/builtins/u64.MAX_VALUE i64 (i64.const -1)) (global $~lib/shared/runtime/Runtime.Stub i32 (i32.const 0)) (global $~lib/shared/runtime/Runtime.Minimal i32 (i32.const 1)) (global $~lib/shared/runtime/Runtime.Incremental i32 (i32.const 2)) @@ -92,8 +94,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) - (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) - (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) + (export "getMaxUnsigned32" (func $bindings/esm/getMaxUnsigned32)) + (export "getMaxUnsigned64" (func $bindings/esm/getMaxUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -124,11 +126,11 @@ local.get $1 i64.add ) - (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) - i32.const -2 + (func $bindings/esm/getMaxUnsigned32 (result i32) + global.get $~lib/builtins/u32.MAX_VALUE ) - (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) - i64.const -2 + (func $bindings/esm/getMaxUnsigned64 (result i64) + global.get $~lib/builtins/u64.MAX_VALUE ) (func $~lib/arraybuffer/ArrayBuffer#get:byteLength (param $0 i32) (result i32) local.get $0 diff --git a/tests/compiler/bindings/raw.release.d.ts b/tests/compiler/bindings/raw.release.d.ts index 2f1121e4d6..15e2360189 100644 --- a/tests/compiler/bindings/raw.release.d.ts +++ b/tests/compiler/bindings/raw.release.d.ts @@ -54,15 +54,15 @@ declare namespace __AdaptedExports { */ export function plainFunction64(a: bigint, b: bigint): bigint; /** - * bindings/esm/plainFunctionGetUnsigned32 + * bindings/esm/getMaxUnsigned32 * @returns `u32` */ - export function plainFunctionGetUnsigned32(): number; + export function getMaxUnsigned32(): number; /** - * bindings/esm/plainFunctionGetUnsigned64 + * bindings/esm/getMaxUnsigned64 * @returns `u64` */ - export function plainFunctionGetUnsigned64(): bigint; + export function getMaxUnsigned64(): bigint; /** * bindings/esm/bufferFunction * @param a `~lib/arraybuffer/ArrayBuffer` diff --git a/tests/compiler/bindings/raw.release.js b/tests/compiler/bindings/raw.release.js index cf04e3a0bb..1091069c5b 100644 --- a/tests/compiler/bindings/raw.release.js +++ b/tests/compiler/bindings/raw.release.js @@ -86,13 +86,13 @@ export async function instantiate(module, imports = {}) { b = b || 0n; return exports.plainFunction64(a, b); }, - plainFunctionGetUnsigned32() { - // bindings/esm/plainFunctionGetUnsigned32() => u32 - return exports.plainFunctionGetUnsigned32() >>> 0; + getMaxUnsigned32() { + // bindings/esm/getMaxUnsigned32() => u32 + return exports.getMaxUnsigned32() >>> 0; }, - plainFunctionGetUnsigned64() { - // bindings/esm/plainFunctionGetUnsigned64() => u64 - return BigInt.asUintN(64, exports.plainFunctionGetUnsigned64()); + getMaxUnsigned64() { + // bindings/esm/getMaxUnsigned64() => u64 + return BigInt.asUintN(64, exports.getMaxUnsigned64()); }, bufferFunction(a, b) { // bindings/esm/bufferFunction(~lib/arraybuffer/ArrayBuffer, ~lib/arraybuffer/ArrayBuffer) => ~lib/arraybuffer/ArrayBuffer diff --git a/tests/compiler/bindings/raw.release.wat b/tests/compiler/bindings/raw.release.wat index a05a0cac69..b4c9560f48 100644 --- a/tests/compiler/bindings/raw.release.wat +++ b/tests/compiler/bindings/raw.release.wat @@ -92,8 +92,8 @@ (export "ConstEnum.THREE" (global $bindings/esm/ConstEnum.THREE)) (export "plainFunction" (func $bindings/esm/plainFunction)) (export "plainFunction64" (func $bindings/esm/plainFunction64)) - (export "plainFunctionGetUnsigned32" (func $bindings/esm/plainFunctionGetUnsigned32)) - (export "plainFunctionGetUnsigned64" (func $bindings/esm/plainFunctionGetUnsigned64)) + (export "getMaxUnsigned32" (func $bindings/esm/getMaxUnsigned32)) + (export "getMaxUnsigned64" (func $bindings/esm/getMaxUnsigned64)) (export "newInternref" (func $bindings/esm/newInternref)) (export "__new" (func $~lib/rt/itcms/__new)) (export "__pin" (func $~lib/rt/itcms/__pin)) @@ -121,11 +121,11 @@ local.get $1 i64.add ) - (func $bindings/esm/plainFunctionGetUnsigned32 (result i32) - i32.const -2 + (func $bindings/esm/getMaxUnsigned32 (result i32) + i32.const -1 ) - (func $bindings/esm/plainFunctionGetUnsigned64 (result i64) - i64.const -2 + (func $bindings/esm/getMaxUnsigned64 (result i64) + i64.const -1 ) (func $~lib/rt/itcms/visitRoots (local $0 i32) From 500b8b517f6f200ec647e2fbc9750483734c40ca Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 4 Jul 2022 07:49:14 +0300 Subject: [PATCH 5/5] minor refactorings / optimizations --- src/bindings/js.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bindings/js.ts b/src/bindings/js.ts index f2db00e816..a38d90c4ec 100644 --- a/src/bindings/js.ts +++ b/src/bindings/js.ts @@ -1283,15 +1283,16 @@ enum Mode { function isPlainValue(type: Type, kind: Mode): bool { if (kind == Mode.IMPORT) { - // requires coercion of undefined to 0n - if (type.isIntegerValue && type.size == 64) return false; // may be stored to an Uint8Array, make sure to store 1/0 if (type == Type.bool) return false; + // requires coercion of undefined to 0n + if (type.isIntegerValue && type.size == 64) return false; } else { - // requires coercion from signed to unsigned - if (type.isUnsignedIntegerValue) return false; // requires coercion from 1/0 to true/false if (type == Type.bool) return false; + // requires coercion from signed to unsigned for u32 and u64. + // Note, u8 and u16 doesn't overflow in native type so mark as plain + if (type.isUnsignedIntegerValue && type.size >= 32) return false; } return !type.isInternalReference; } @@ -1299,10 +1300,10 @@ function isPlainValue(type: Type, kind: Mode): bool { function isPlainFunction(signature: Signature, mode: Mode): bool { var parameterTypes = signature.parameterTypes; var inverseMode = mode == Mode.IMPORT ? Mode.EXPORT : Mode.IMPORT; + if (!isPlainValue(signature.returnType, mode)) return false; for (let i = 0, k = parameterTypes.length; i < k; ++i) { if (!isPlainValue(parameterTypes[i], inverseMode)) return false; } - if (!isPlainValue(signature.returnType, mode)) return false; return true; }