• 2022-07-20 发现 build 出的 .wasm 文件无法在手机端浏览器(chrome & safari)运行
      • 暂不确定是文件 release.js 文件导致还是 .wasm 本身无法运行
      • PC 端 chrome 103.0.5060.114 正常运行

    https://www.assemblyscript.org/getting-started.html

    1. 官方 quick start 运行 npm run build 报错 SyntaxError: missing ) after argument list
      1. google 检索到一个 相关 issue 猜测可能是 nodejs 版本不正确
        1. https://github.com/AssemblyScript/assemblyscript/issues/2248
        2. issue 中描述升级 16.x 后解决
        3. 本机 node 14.x
        4. 由于vue3-cli 跑起来需要 14.x 版本(在16.x 会报错),故我需要一个 node 版本管理工具 nvm
      2. 安装 windows 上的 nvm https://zhuanlan.zhihu.com/p/503547214
        1. nvm-setup.zip
        2. 安装完毕运行 nvm install 16.16.0 一切顺利
        3. 运行 nvm use 16.16.0 报错 exit status 1: Access is denied.
        4. 解决方式 https://blog.csdn.net/qq_41715885/article/details/120449480
          1. C:\Windows\System32\cmd.exe 以管理员身份运行 cmd.exe 再执行 nvm use 16.16.0 成功运行
          2. nvm 再安装一个 14.x 版本 nvm install 14.19.3
          3. 在 以管理员身份运行的 cmd.exenvm use 14.19.3
          4. 运行 vue3-cli 项目 yarn serve 命令失效,改为 npm run serve OK 项目成功运行,回头再来研究 yarn 失效问题
      3. 运行 nvm use 16.16.0 切换正确版本号继续操作
    2. 解决完 node 版本问题后来到项目目录 npm run asbuild OK
    3. npm test OK
    4. /assembly/index.ts 添加方法 str

      1. export function str(a: string, b: string): string {
      2. return a + b;
      3. }
    5. 运行 npm run asbuild OK

    6. 运行 npm test 报错 TypeError: exports.__new is not a function
      1. 查找 issue https://github.com/AssemblyScript/assemblyscript/issues/2244 发现相同问题
      2. issue 中描述了 添加 --exportRuntime 方式来解决,但是我不知道要加到哪
      3. 在 issue 中的一个评论里找到一个 demo,查看其 package.json 后明白添加 --exportRuntime 方式 https://gitlab.com/everyonecancontribute/dev/learn-wasm-assemblyscript/-/blob/main/package.json
      4. 照做后问题解决
    7. /assembly/index.ts 添加map 方法

      1. export function map(arr: i32[]): string {
      2. return arr.map((i: i32) => i * 2).join('|')
      3. }
      1. 运行 npm run asbuild 报错
        image.png
    8. 再次检索 issue 发现有人遇到相同问题 https://github.com/AssemblyScript/assemblyscript/issues/2221

      1. 按照评论中的解决方案修改代码后解决问题,npm run asbuild 通过
        1. export function map(arr: i32[]): string {
        2. return arr.map<i32>((i: i32) => i * 2).join('|')
        3. }
    9. 闭包问题 https://github.com/AssemblyScript/assemblyscript/issues/798

      1. assemblyscript 中没有闭包,这一点与 JS 很不一样,编码过程中需要特别留意
    10. 数据类型没有 number 取而代之的可以用 u32i32 代替
    11. 部分作用域作用原理也与 js 不同
      1. 如下两种写法产生的结果是不同的,具体原因暂未知晓 ```typescript

    // 写法 1 let i = 0 let j = 0

    for (; i < lineLen + 1; i++) { // … for (; j < group.length; j++) { // … } }

    // 写法2 for (let i = 0; i < lineLen + 1; i++) { // … for (let j = 0; j < group.length; j++) { // … } }

    1. 13. 通过 assemblyscript build `.wasm` 文件,引用方式比较特殊,参考build 后得到的 `release.js` 经改造后得到如下文件
    2. ```javascript
    3. /**
    4. * 加载 `.wasm` 文件
    5. */
    6. export default async (url) => {
    7. const module = await WebAssembly.compileStreaming(fetch(url))
    8. const { exports } = await WebAssembly.instantiate(module, {
    9. env: {
    10. // eslint-disable-next-line
    11. abort: console.log,
    12. },
    13. })
    14. const memory = exports.memory
    15. const adaptedExports = Object.setPrototypeOf(
    16. {
    17. encode(str) {
    18. // assembly/index/encode(~lib/string/String) => ~lib/string/String
    19. str = __lowerString(str) || __notnull()
    20. return __liftString(exports.encode(str) >>> 0)
    21. },
    22. decode(str) {
    23. // assembly/index/decode(~lib/string/String) => ~lib/string/String
    24. str = __lowerString(str) || __notnull()
    25. return __liftString(exports.decode(str) >>> 0)
    26. },
    27. },
    28. exports
    29. )
    30. function __liftString(pointer) {
    31. if (!pointer) return null
    32. const end =
    33. (pointer + new Uint32Array(memory.buffer)[(pointer - 4) >>> 2]) >>> 1,
    34. memoryU16 = new Uint16Array(memory.buffer)
    35. let start = pointer >>> 1,
    36. string = ''
    37. while (end - start > 1024)
    38. string += String.fromCharCode(
    39. ...memoryU16.subarray(start, (start += 1024))
    40. )
    41. return string + String.fromCharCode(...memoryU16.subarray(start, end))
    42. }
    43. function __lowerString(value) {
    44. if (value == null) return 0
    45. const length = value.length,
    46. pointer = exports.__new(length << 1, 1) >>> 0,
    47. memoryU16 = new Uint16Array(memory.buffer)
    48. for (let i = 0; i < length; ++i)
    49. memoryU16[(pointer >>> 1) + i] = value.charCodeAt(i)
    50. return pointer
    51. }
    52. function __notnull() {
    53. throw TypeError('value must not be null')
    54. }
    55. return adaptedExports
    56. }

    该文件中直接包含了 export 出的 encodedecode 方法名,比较特殊