From 3001a20e3d8df12522275b37201fe20b5cdf7370 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sun, 31 Oct 2021 18:21:40 +0200 Subject: [PATCH 01/16] slightly optimize utf8 ops for binaryen interop --- src/module.ts | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/module.ts b/src/module.ts index f4ab962eb4..7cf64b0f24 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3080,17 +3080,15 @@ function stringLengthUTF8(str: string): usize { var len = 0; for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i); - if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - } if (u <= 0x7F) { len += 1; } else if (u <= 0x7FF) { len += 2; - } else if (u <= 0xFFFF) { - len += 3; - } else { + } else if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); len += 4; + } else { + len += 3; } } return len; @@ -3103,27 +3101,27 @@ function allocString(str: string | null): usize { var idx = ptr; for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i); - if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - } if (u <= 0x7F) { binaryen.__i32_store8(idx++, u as u8); } else if (u <= 0x7FF) { binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else if (u <= 0xFFFF) { - binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else { - assert(u < 0x200000, "Invalid Unicode code point during allocString"); - binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + if (u <= 0xFFFF) { + binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else { + assert(u < 0x200000, "Invalid Unicode code point during allocString"); + binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } } } - binaryen.__i32_store8(idx, 0); + binaryen.__i32_store8(idx, 0); // \0 return ptr; } From 1d058ec2a42ea9c13dd49fca65218f8af48f9a70 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sun, 31 Oct 2021 18:26:43 +0200 Subject: [PATCH 02/16] better --- src/module.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/module.ts b/src/module.ts index 7cf64b0f24..3571682cce 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3106,8 +3106,10 @@ function allocString(str: string | null): usize { } else if (u <= 0x7FF) { binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } else if (u >= 0xD800 && u <= 0xDFFF) { + if (i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } if (u <= 0xFFFF) { binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); From d417bd19980a010e1c872c30b533a6a6b019b521 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sun, 31 Oct 2021 18:55:21 +0200 Subject: [PATCH 03/16] force to unsigned for charCodeAt --- src/module.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/module.ts b/src/module.ts index 3571682cce..ce46c094b6 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3079,7 +3079,7 @@ export function allocPtrArray(ptrs: usize[] | null): usize { function stringLengthUTF8(str: string): usize { var len = 0; for (let i = 0, k = str.length; i < k; ++i) { - let u = str.charCodeAt(i); + let u = str.charCodeAt(i) >>> 0; if (u <= 0x7F) { len += 1; } else if (u <= 0x7FF) { @@ -3096,11 +3096,12 @@ function stringLengthUTF8(str: string): usize { function allocString(str: string | null): usize { if (str === null) return 0; - var ptr = binaryen._malloc(stringLengthUTF8(str) + 1) >>> 0; + var len = stringLengthUTF8(str); + var ptr = binaryen._malloc(len + 1) >>> 0; // the following is based on Emscripten's stringToUTF8Array var idx = ptr; for (let i = 0, k = str.length; i < k; ++i) { - let u = str.charCodeAt(i); + let u = str.charCodeAt(i) >>> 0; if (u <= 0x7F) { binaryen.__i32_store8(idx++, u as u8); } else if (u <= 0x7FF) { From 944db4525672a33dac4daec1c68a58e67da88c54 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Sun, 31 Oct 2021 21:04:03 +0200 Subject: [PATCH 04/16] Add fast path for all latin1 chars in allocString --- src/module.ts | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/module.ts b/src/module.ts index ce46c094b6..7538e8d7d3 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3098,29 +3098,38 @@ function allocString(str: string | null): usize { if (str === null) return 0; var len = stringLengthUTF8(str); var ptr = binaryen._malloc(len + 1) >>> 0; - // the following is based on Emscripten's stringToUTF8Array var idx = ptr; - for (let i = 0, k = str.length; i < k; ++i) { - let u = str.charCodeAt(i) >>> 0; - if (u <= 0x7F) { + if (len === str.length) { + // fast path when all chars are latin1 + for (let i = 0, k = str.length; i < k; ++i) { + // TODO: optimize this more + let u = str.charCodeAt(i) >>> 0; binaryen.__i32_store8(idx++, u as u8); - } else if (u <= 0x7FF) { - binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else if (u >= 0xD800 && u <= 0xDFFF) { - if (i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - } - if (u <= 0xFFFF) { - binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else { - assert(u < 0x200000, "Invalid Unicode code point during allocString"); - binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + } + } else { + // the following is based on Emscripten's stringToUTF8Array + for (let i = 0, k = str.length; i < k; ++i) { + let u = str.charCodeAt(i) >>> 0; + if (u <= 0x7F) { + binaryen.__i32_store8(idx++, u as u8); + } else if (u <= 0x7FF) { + binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else if (u >= 0xD800 && u <= 0xDFFF) { + if (i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } + if (u <= 0xFFFF) { + binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else { + assert(u < 0x200000, "Invalid Unicode code point during allocString"); + binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } } } } From 380a6e98c45e8fd98468ac9adf326dbde26d8b36 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 00:16:25 +0200 Subject: [PATCH 05/16] Use fast heap copy for JS target --- src/glue/binaryen.d.ts | 4 +++ src/module.ts | 62 ++++++++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/src/glue/binaryen.d.ts b/src/glue/binaryen.d.ts index 45adb16939..435ce6fd43 100644 --- a/src/glue/binaryen.d.ts +++ b/src/glue/binaryen.d.ts @@ -643,6 +643,10 @@ export declare function _BinaryenSetAllowInliningFunctionsWithLoops(enabled: boo // Helpers +export declare const HEAPU8: Uint8Array; +export declare const HEAPU32: Uint32Array; +export declare const HEAP32: Int32Array; + export declare function _malloc(size: usize): usize; export declare function _free(ptr: usize): void; export declare function __i32_store8(ptr: usize, value: number): void; diff --git a/src/module.ts b/src/module.ts index 7538e8d7d3..8f0aab0458 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3029,8 +3029,12 @@ function allocU8Array(u8s: Uint8Array | null): usize { if (!u8s) return 0; var len = u8s.length; var ptr = binaryen._malloc(len); - for (let i = 0; i < len; ++i) { - binaryen.__i32_store8(ptr + i, u8s[i]); + if ((ASC_TARGET | 0) == 0) { + binaryen.HEAPU8.set(u8s, ptr); + } else { + for (let i = 0; i < len; ++i) { + binaryen.__i32_store8(ptr + i, u8s[i]); + } } return ptr; } @@ -3039,11 +3043,15 @@ function allocI32Array(i32s: i32[] | null): usize { if (!i32s) return 0; var len = i32s.length; var ptr = binaryen._malloc(len << 2); - var idx = ptr; - for (let i = 0; i < len; ++i) { - let val = i32s[i]; - binaryen.__i32_store(idx, val); - idx += 4; + if ((ASC_TARGET | 0) == 0) { + binaryen.HEAP32.set(i32s, ptr >>> 2); + } else { + var idx = ptr; + for (let i = 0; i < len; ++i) { + let val = i32s[i]; + binaryen.__i32_store(idx, val); + idx += 4; + } } return ptr; } @@ -3052,11 +3060,15 @@ function allocU32Array(u32s: u32[] | null): usize { if (!u32s) return 0; var len = u32s.length; var ptr = binaryen._malloc(len << 2); - var idx = ptr; - for (let i = 0; i < len; ++i) { - let val = u32s[i]; - binaryen.__i32_store(idx, val); - idx += 4; + if ((ASC_TARGET | 0) == 0) { + binaryen.HEAPU32.set(u32s, ptr >>> 2); + } else { + var idx = ptr; + for (let i = 0; i < len; ++i) { + let val = u32s[i]; + binaryen.__i32_store(idx, val); + idx += 4; + } } return ptr; } @@ -3067,11 +3079,15 @@ export function allocPtrArray(ptrs: usize[] | null): usize { assert(ASC_TARGET != Target.WASM64); var len = ptrs.length; var ptr = binaryen._malloc(len << 2); - var idx = ptr; - for (let i = 0, k = len; i < k; ++i) { - let val = ptrs[i]; - binaryen.__i32_store(idx, val); - idx += 4; + if ((ASC_TARGET | 0) == 0) { + binaryen.HEAPU32.set(ptrs, ptr >>> 2); + } else { + var idx = ptr; + for (let i = 0, k = len; i < k; ++i) { + let val = ptrs[i]; + binaryen.__i32_store(idx, val); + idx += 4; + } } return ptr; } @@ -3138,11 +3154,15 @@ function allocString(str: string | null): usize { } function readBuffer(ptr: usize, len: i32): Uint8Array { - var ret = new Uint8Array(len); - for (let i = 0; i < len; ++i) { - ret[i] = binaryen.__i32_load8_u(ptr + i); + if ((ASC_TARGET | 0) == 0) { + return binaryen.HEAPU8.slice(ptr, ptr + len); + } else { + var ret = new Uint8Array(len); + for (let i = 0; i < len; ++i) { + ret[i] = binaryen.__i32_load8_u(ptr + i); + } + return ret; } - return ret; } export function readString(ptr: usize): string | null { From d4ce639423af61bb567c048721cc08e51fcab475 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 00:33:19 +0200 Subject: [PATCH 06/16] use Target.JS --- src/module.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/module.ts b/src/module.ts index 8f0aab0458..d96798526d 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3029,7 +3029,7 @@ function allocU8Array(u8s: Uint8Array | null): usize { if (!u8s) return 0; var len = u8s.length; var ptr = binaryen._malloc(len); - if ((ASC_TARGET | 0) == 0) { + if ((ASC_TARGET | 0) == Target.JS) { binaryen.HEAPU8.set(u8s, ptr); } else { for (let i = 0; i < len; ++i) { @@ -3043,7 +3043,7 @@ function allocI32Array(i32s: i32[] | null): usize { if (!i32s) return 0; var len = i32s.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == 0) { + if ((ASC_TARGET | 0) == Target.JS) { binaryen.HEAP32.set(i32s, ptr >>> 2); } else { var idx = ptr; @@ -3060,7 +3060,7 @@ function allocU32Array(u32s: u32[] | null): usize { if (!u32s) return 0; var len = u32s.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == 0) { + if ((ASC_TARGET | 0) == Target.JS) { binaryen.HEAPU32.set(u32s, ptr >>> 2); } else { var idx = ptr; @@ -3079,7 +3079,7 @@ export function allocPtrArray(ptrs: usize[] | null): usize { assert(ASC_TARGET != Target.WASM64); var len = ptrs.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == 0) { + if ((ASC_TARGET | 0) == Target.JS) { binaryen.HEAPU32.set(ptrs, ptr >>> 2); } else { var idx = ptr; From 349779c896298abf488e0ed871eab0733004b017 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 01:02:04 +0200 Subject: [PATCH 07/16] use heap for fast path in allocString --- src/module.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/module.ts b/src/module.ts index d96798526d..fec0e6117d 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3117,13 +3117,19 @@ function allocString(str: string | null): usize { var idx = ptr; if (len === str.length) { // fast path when all chars are latin1 - for (let i = 0, k = str.length; i < k; ++i) { - // TODO: optimize this more - let u = str.charCodeAt(i) >>> 0; - binaryen.__i32_store8(idx++, u as u8); + if ((ASC_TARGET | 0) == Target.JS) { + for (let i = 0, k = str.length; i < k; ++i) { + binaryen.HEAPU8[idx++] = str.charCodeAt(i); + } + } else { + for (let i = 0, k = str.length; i < k; ++i) { + let u = str.charCodeAt(i) >>> 0; + binaryen.__i32_store8(idx++, u as u8); + } } } else { // the following is based on Emscripten's stringToUTF8Array + var idx = ptr; for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i) >>> 0; if (u <= 0x7F) { From 65e42f7d85ace515af45a0666b530219706dd097 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 01:36:59 +0200 Subject: [PATCH 08/16] fix --- src/module.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index fec0e6117d..55d20fc273 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3129,7 +3129,6 @@ function allocString(str: string | null): usize { } } else { // the following is based on Emscripten's stringToUTF8Array - var idx = ptr; for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i) >>> 0; if (u <= 0x7F) { From 37bfd284c961ae41e9425f4c82aaa24b07800d1d Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 01:56:31 +0200 Subject: [PATCH 09/16] minor --- src/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index 55d20fc273..d18eb24f69 100644 --- a/src/module.ts +++ b/src/module.ts @@ -2501,7 +2501,7 @@ export class Module { // avoid quite a bit of unnecessary garbage. if (ptr == 0) return null; var cached = this.cachedPointersToStrings; - if (cached.has(ptr)) return changetype(this.cachedPointersToStrings.get(ptr)); + if (cached.has(ptr)) return changetype(cached.get(ptr)); var str = readString(ptr); cached.set(ptr, str); return str; From 9246ee901aca9cefd9503a784c7c5be2506b26df Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 13:36:52 +0200 Subject: [PATCH 10/16] better --- src/module.ts | 64 ++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/module.ts b/src/module.ts index d18eb24f69..68aee96df9 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3114,42 +3114,44 @@ function allocString(str: string | null): usize { if (str === null) return 0; var len = stringLengthUTF8(str); var ptr = binaryen._malloc(len + 1) >>> 0; - var idx = ptr; - if (len === str.length) { - // fast path when all chars are latin1 - if ((ASC_TARGET | 0) == Target.JS) { - for (let i = 0, k = str.length; i < k; ++i) { - binaryen.HEAPU8[idx++] = str.charCodeAt(i); + if (len) { + var idx = ptr; + if (len === str.length && str.charCodeAt(0) <= 0x7F) { + // fast path when all chars are latin1 + if ((ASC_TARGET | 0) == Target.JS) { + for (let i = 0, k = str.length; i < k; ++i) { + binaryen.HEAPU8[idx++] = str.charCodeAt(i); + } + } else { + for (let i = 0, k = str.length; i < k; ++i) { + let u = str.charCodeAt(i) >>> 0; + binaryen.__i32_store8(idx++, u as u8); + } } } else { + // the following is based on Emscripten's stringToUTF8Array for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i) >>> 0; - binaryen.__i32_store8(idx++, u as u8); - } - } - } else { - // the following is based on Emscripten's stringToUTF8Array - for (let i = 0, k = str.length; i < k; ++i) { - let u = str.charCodeAt(i) >>> 0; - if (u <= 0x7F) { - binaryen.__i32_store8(idx++, u as u8); - } else if (u <= 0x7FF) { - binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else if (u >= 0xD800 && u <= 0xDFFF) { - if (i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - } - if (u <= 0xFFFF) { - binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else { - assert(u < 0x200000, "Invalid Unicode code point during allocString"); - binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + if (u <= 0x7F) { + binaryen.__i32_store8(idx++, u as u8); + } else if (u <= 0x7FF) { + binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else if (u >= 0xD800 && u <= 0xDFFF) { + if (i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } + if (u <= 0xFFFF) { + binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else { + assert(u < 0x200000, "Invalid Unicode code point during allocString"); + binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } } } } From 12264b4f5932ca8b7d7fdf33a9b9264715378d60 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 13:37:39 +0200 Subject: [PATCH 11/16] fix --- src/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index 68aee96df9..a5e8c4c99f 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3114,8 +3114,8 @@ function allocString(str: string | null): usize { if (str === null) return 0; var len = stringLengthUTF8(str); var ptr = binaryen._malloc(len + 1) >>> 0; + var idx = ptr; if (len) { - var idx = ptr; if (len === str.length && str.charCodeAt(0) <= 0x7F) { // fast path when all chars are latin1 if ((ASC_TARGET | 0) == Target.JS) { From 688f5bbe0c9096c6c701d3523a54d445e71bbf07 Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 13:52:25 +0200 Subject: [PATCH 12/16] revert. This unnecessary --- src/module.ts | 62 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/module.ts b/src/module.ts index a5e8c4c99f..d18eb24f69 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3115,43 +3115,41 @@ function allocString(str: string | null): usize { var len = stringLengthUTF8(str); var ptr = binaryen._malloc(len + 1) >>> 0; var idx = ptr; - if (len) { - if (len === str.length && str.charCodeAt(0) <= 0x7F) { - // fast path when all chars are latin1 - if ((ASC_TARGET | 0) == Target.JS) { - for (let i = 0, k = str.length; i < k; ++i) { - binaryen.HEAPU8[idx++] = str.charCodeAt(i); - } - } else { - for (let i = 0, k = str.length; i < k; ++i) { - let u = str.charCodeAt(i) >>> 0; - binaryen.__i32_store8(idx++, u as u8); - } + if (len === str.length) { + // fast path when all chars are latin1 + if ((ASC_TARGET | 0) == Target.JS) { + for (let i = 0, k = str.length; i < k; ++i) { + binaryen.HEAPU8[idx++] = str.charCodeAt(i); } } else { - // the following is based on Emscripten's stringToUTF8Array for (let i = 0, k = str.length; i < k; ++i) { let u = str.charCodeAt(i) >>> 0; - if (u <= 0x7F) { - binaryen.__i32_store8(idx++, u as u8); - } else if (u <= 0x7FF) { - binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); + binaryen.__i32_store8(idx++, u as u8); + } + } + } else { + // the following is based on Emscripten's stringToUTF8Array + for (let i = 0, k = str.length; i < k; ++i) { + let u = str.charCodeAt(i) >>> 0; + if (u <= 0x7F) { + binaryen.__i32_store8(idx++, u as u8); + } else if (u <= 0x7FF) { + binaryen.__i32_store8(idx++, (0xC0 | (u >>> 6) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else if (u >= 0xD800 && u <= 0xDFFF) { + if (i + 1 < k) { + u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); + } + if (u <= 0xFFFF) { + binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); + } else { + assert(u < 0x200000, "Invalid Unicode code point during allocString"); + binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); + binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else if (u >= 0xD800 && u <= 0xDFFF) { - if (i + 1 < k) { - u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF); - } - if (u <= 0xFFFF) { - binaryen.__i32_store8(idx++, (0xE0 | (u >>> 12) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } else { - assert(u < 0x200000, "Invalid Unicode code point during allocString"); - binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); - binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); - } } } } From b097da70fceeed24040e5ab37d84876ae8e22eca Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 13:54:37 +0200 Subject: [PATCH 13/16] refactorings --- src/module.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/module.ts b/src/module.ts index d18eb24f69..9e5d826e10 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3029,7 +3029,7 @@ function allocU8Array(u8s: Uint8Array | null): usize { if (!u8s) return 0; var len = u8s.length; var ptr = binaryen._malloc(len); - if ((ASC_TARGET | 0) == Target.JS) { + if (!ASC_TARGET) { binaryen.HEAPU8.set(u8s, ptr); } else { for (let i = 0; i < len; ++i) { @@ -3043,7 +3043,7 @@ function allocI32Array(i32s: i32[] | null): usize { if (!i32s) return 0; var len = i32s.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == Target.JS) { + if (!ASC_TARGET) { binaryen.HEAP32.set(i32s, ptr >>> 2); } else { var idx = ptr; @@ -3060,7 +3060,7 @@ function allocU32Array(u32s: u32[] | null): usize { if (!u32s) return 0; var len = u32s.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == Target.JS) { + if (!ASC_TARGET) { binaryen.HEAPU32.set(u32s, ptr >>> 2); } else { var idx = ptr; @@ -3079,7 +3079,7 @@ export function allocPtrArray(ptrs: usize[] | null): usize { assert(ASC_TARGET != Target.WASM64); var len = ptrs.length; var ptr = binaryen._malloc(len << 2); - if ((ASC_TARGET | 0) == Target.JS) { + if (!ASC_TARGET) { binaryen.HEAPU32.set(ptrs, ptr >>> 2); } else { var idx = ptr; @@ -3116,7 +3116,7 @@ function allocString(str: string | null): usize { var ptr = binaryen._malloc(len + 1) >>> 0; var idx = ptr; if (len === str.length) { - // fast path when all chars are latin1 + // fast path when all chars are ascii if ((ASC_TARGET | 0) == Target.JS) { for (let i = 0, k = str.length; i < k; ++i) { binaryen.HEAPU8[idx++] = str.charCodeAt(i); From ca529eaa1f80aa95b48a7cf734c532c77f1d8c3f Mon Sep 17 00:00:00 2001 From: MaxGraey Date: Mon, 1 Nov 2021 13:56:33 +0200 Subject: [PATCH 14/16] more --- src/module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module.ts b/src/module.ts index 9e5d826e10..86b30957e4 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3117,7 +3117,7 @@ function allocString(str: string | null): usize { var idx = ptr; if (len === str.length) { // fast path when all chars are ascii - if ((ASC_TARGET | 0) == Target.JS) { + if (!ASC_TARGET) { for (let i = 0, k = str.length; i < k; ++i) { binaryen.HEAPU8[idx++] = str.charCodeAt(i); } @@ -3159,7 +3159,7 @@ function allocString(str: string | null): usize { } function readBuffer(ptr: usize, len: i32): Uint8Array { - if ((ASC_TARGET | 0) == 0) { + if (!ASC_TARGET) { return binaryen.HEAPU8.slice(ptr, ptr + len); } else { var ret = new Uint8Array(len); From 78687b5e9fbddb37d6987096a78c922b5f192a64 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Mon, 1 Nov 2021 14:09:23 +0200 Subject: [PATCH 15/16] Update src/glue/binaryen.d.ts Co-authored-by: dcode --- src/glue/binaryen.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/glue/binaryen.d.ts b/src/glue/binaryen.d.ts index 435ce6fd43..a0f520d8d6 100644 --- a/src/glue/binaryen.d.ts +++ b/src/glue/binaryen.d.ts @@ -643,6 +643,7 @@ export declare function _BinaryenSetAllowInliningFunctionsWithLoops(enabled: boo // Helpers +// Binaryen.js only (ASC_TARGET = 0) export declare const HEAPU8: Uint8Array; export declare const HEAPU32: Uint32Array; export declare const HEAP32: Int32Array; From da0f0a322c8781d543c1c05e1e944456862e0459 Mon Sep 17 00:00:00 2001 From: Max Graey Date: Mon, 1 Nov 2021 15:22:25 +0200 Subject: [PATCH 16/16] Update src/module.ts Co-authored-by: dcode --- src/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module.ts b/src/module.ts index 86b30957e4..8b25ba82cf 100644 --- a/src/module.ts +++ b/src/module.ts @@ -3145,7 +3145,7 @@ function allocString(str: string | null): usize { binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8); binaryen.__i32_store8(idx++, (0x80 | ( u & 63)) as u8); } else { - assert(u < 0x200000, "Invalid Unicode code point during allocString"); + assert(u <= 0x10FFFF, "Invalid Unicode code point during allocString"); binaryen.__i32_store8(idx++, (0xF0 | (u >>> 18) ) as u8); binaryen.__i32_store8(idx++, (0x80 | ((u >>> 12) & 63)) as u8); binaryen.__i32_store8(idx++, (0x80 | ((u >>> 6) & 63)) as u8);