You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AssemblyScript字符串函数报错,i32函数正常,如何修复?

问题描述

编写了一个AssemblyScript的parse函数,用于接收并返回字符串类型值,对应的NodeJS导入运行代码执行时出现错误:TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object。但当函数使用i32类型参数和返回值时,代码可正常运行并输出结果。需要修复该问题以支持字符串处理。

字符串版本代码(报错)

AssemblyScript代码

export function parse(x: string): string {
  return x;
}

NodeJS代码

import { readFileSync } from 'fs';

export default async function compile(raw) {
  return WebAssembly.instantiate(
    readFileSync('./src/.assembly/engine.wasm') // 编译后的AssemblyScript WASM文件
  ).then(mod => {
    const { parse } = mod.instance.exports;
    return parse(raw);
  });
}

compile('test').then(res => {
  console.log(res);
});

错误信息

node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object]

Node.js v18.15.0
error Command failed with exit code 1.

i32版本代码(正常运行)

AssemblyScript代码

export function parse(x: i32): i32 {
  return x;
}

NodeJS代码

import { readFileSync } from 'fs';

export default async function compile(raw) {
  return WebAssembly.instantiate(
    readFileSync('./src/.assembly/engine.wasm') // 编译后的AssemblyScript WASM文件
  ).then(mod => {
    const { parse } = mod.instance.exports;
    return parse(raw);
  });
}

compile(44).then(res => {
  console.log(res);
});

运行结果

44
问题原因

WebAssembly本身没有原生字符串类型,AssemblyScript的字符串是通过内存中存储UTF-8编码数据+长度的方式实现的,这依赖AssemblyScript的运行时来处理内存分配、字符串编码转换等逻辑。当处理字符串时,WASM模块需要宿主环境(NodeJS)提供对应的导入对象来支持这些运行时功能;而i32是WASM原生支持的数值类型,无需额外依赖,因此可以直接运行。

修复方案

推荐使用AssemblyScript官方提供的@assemblyscript/loader库来简化WASM模块的加载和字符串类型的转换,该库会自动处理运行时依赖和类型转换逻辑。

步骤1:安装依赖

npm install @assemblyscript/loader

步骤2:修改NodeJS代码

import { readFileSync } from 'fs';
import loader from '@assemblyscript/loader';

export default async function compile(raw) {
  // 使用loader加载WASM模块,自动处理运行时导入
  const wasmModule = await loader.instantiate(
    readFileSync('./src/.assembly/engine.wasm'),
    {} // 如需自定义导入可在此添加,默认空对象即可满足基础字符串处理需求
  );

  // 从WASM导出中获取必要的方法:业务函数parse,以及字符串转换工具函数
  const { parse, __newString, __getString } = wasmModule.exports;

  // 1. 将JS字符串转换为WASM可识别的字符串引用(分配内存并写入UTF-8数据)
  const wasmStringRef = __newString(raw);
  // 2. 调用parse函数,返回WASM字符串引用
  const resultRef = parse(wasmStringRef);
  // 3. 将WASM字符串引用转换回JS字符串(从内存读取UTF-8数据并解码)
  const result = __getString(resultRef);

  return result;
}

compile('test').then(res => {
  console.log(res); // 输出:test
});

注意事项

  • 编译AssemblyScript时不要添加--noRuntime参数,默认编译会包含必要的运行时代码,确保WASM模块能正常处理字符串等复杂类型。
  • 如果需要手动实现导入对象(不使用loader),需要自行提供内存管理、字符串处理相关的导入函数,这会非常繁琐,因此推荐使用官方loader。

内容的提问来源于stack exchange,提问作者user21392777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:57:50