使用AssemblyScript在360浏览器下报错 SyntaxError: Unexpected reserved word
背景
最近在一个项目中使用了AssemblyScript,它能将类似于TypeScript的代码编译为WebAssembly,在其他浏览器都能正常使用,然而在360浏览器上却会报错:SyntaxError: Unexpected reserved word。
原因
先看index.ts,里面有一个简单的add方法,add里面调用了console.log
export function add(a: i32, b: i32): i32 {
console.log((a + b).toString());
return a + b;
}
编译后生成的release.js
async function instantiate(module, imports = {}) {
const adaptedImports = {
env: Object.assign(Object.create(globalThis), imports.env || {}, {
abort(message, fileName, lineNumber, columnNumber) {
// ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
message = __liftString(message >>> 0);
fileName = __liftString(fileName >>> 0);
lineNumber = lineNumber >>> 0;
columnNumber = columnNumber >>> 0;
(() => {
// @external.js
throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);
})();
},
"console.log"(text) {
// ~lib/bindings/dom/console.log(~lib/string/String) => void
text = __liftString(text >>> 0);
console.log(text);
},
}),
};
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
const memory = exports.memory || imports.env.memory;
function __liftString(pointer) {
if (!pointer) return null;
const
end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
memoryU16 = new Uint16Array(memory.buffer);
let
start = pointer >>> 1,
string = "";
while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024));
return string + String.fromCharCode(...memoryU16.subarray(start, end));
}
return exports;
}
export const {
memory,
add
} = await (async url => instantiate(
await (async () => {
try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
})(), {
}
))(new URL("release.wasm", import.meta.url));
360浏览器报错锁定在await这一行
} = await (async url => instantiate(
查看360浏览器的内核版本,发现是86.0.4240.198,360浏览器已经是最新的版本了。
而支持在模块顶层使用await的chrome最低版本是89,点这里查看
所以出现了这个错误~
所以,有没有什么解决方法呢?
解决方法
不使用await就行了,用Promise代替await。
修改release.js,根据自己的代码进行修改,不能直接照抄
function instantiate(module, imports = {}) {
return new Promise((resolve) => {
// 如果有 __lowerString 需要先在这里定义
let __liftString = function () {};
const adaptedImports = {
env: Object.assign(Object.create(globalThis), imports.env || {}, {
abort(message, fileName, lineNumber, columnNumber) {
// ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
message = __liftString(message >>> 0);
fileName = __liftString(fileName >>> 0);
lineNumber = lineNumber >>> 0;
columnNumber = columnNumber >>> 0;
(() => {
// @external.js
throw Error(
`${message} in ${fileName}:${lineNumber}:${columnNumber}`
);
})();
},
"console.log"(text) {
// ~lib/bindings/dom/console.log(~lib/string/String) => void
text = __liftString(text >>> 0);
console.log(text);
},
}),
};
WebAssembly.instantiate(module, adaptedImports).then((res) => {
const { exports } = res;
const memory = exports.memory || imports.env.memory;
__liftString = function (pointer) {
if (!pointer) return null;
const end =
(pointer + new Uint32Array(memory.buffer)[(pointer - 4) >>> 2]) >>>
1,
memoryU16 = new Uint16Array(memory.buffer);
let start = pointer >>> 1,
string = "";
while (end - start > 1024)
string += String.fromCharCode(
...memoryU16.subarray(start, (start += 1024))
);
return string + String.fromCharCode(...memoryU16.subarray(start, end));
};
resolve(exports);
});
});
}
export const exports = new Promise((resolve, reject) => {
globalThis.WebAssembly.compileStreaming(
globalThis.fetch(new URL("release.wasm", import.meta.url))
).then((module) => {
instantiate(module, {})
.then((res) => resolve(res))
.catch((err) => {
console.error(err);
reject(err);
});
});
});
引入
<script type="module">
import { exports } from "./release.js";
exports.then((res) => {
// add方法
const { add } = res;
add(12, 34);
});
</script>
完美。