d使用ldc生成wasm
原文
对如下D代码(wasm.d)生成.wasm文件:
extern(C): // 禁止D混杂
double add(double a, double b) { return a + b; }
// 要求的入口点
void _start() {}
构建wasm.wasm命令:
ldc2 -mtriple=wasm32-unknown-unknown-wasm -betterC wasm.d
如用dub:
dub build --compiler=ldc2 --arch=wasm32-unknown-unknown-wasm
在超文本页面中测试
js加载并调用wasm,a.html内容:
<html>
<head>
<script>
const request = new XMLHttpRequest();
request.open("GET", "wasm.wasm");
request.responseType = "arraybuffer";
request.onload = () => {
console.log("response received");
const bytes = request.response;
const importObject = {};
WebAssembly.instantiate(bytes, importObject).then(result => {
console.log("instantiated");
const { exports } = result.instance;
// 调用`d`的`加`函数.
const r = exports.add(42, -2.5);
console.log("r = " + r);
});
};
request.send();
console.log("request sent");
</script>
</head>
<body>
Test page
</body>
</html>
fetch()不适用本地文件.打开它,在控制台会看见:
request sent
response received
instantiated
r = 39.5
调用外部函数
extern(C): // 禁止混杂
// 从默认`"env"`导入模块名导入`"callback"`函数
void callback(double a, double b, double c);
double add(double a, double b)
{
const c = a + b;
callback(a, b, c);
return c;
}
void _start() {}
加上-L-allow-undefined标志.否则lld由于未定义回调而拒绝链接.
js中实现回调,并在importObject.env中指定:
const callback = (a, b, c) => {
console.log(`callback from D: ${a} + ${b} = ${c}`);
};
// ...
const importObject = {
env: { callback }
};
现在输出:
request sent
response received
instantiated
callback from D: 42 + -2.5 = 39.5
r = 39.5
要从其他模块导入函数或重命名导入函数,我们使用LDC的@llvmAttr.
import ldc.attributes;
extern(C): //
// 从`"math"`模块导入`"add"`函数,并重命名为`"add_numbers"`.
@llvmAttr("wasm-import-module", "math") @llvmAttr("wasm-import-name", "add") {
int add_numbers(int a, int b);
}
// 导出`"hello"`函数
export int hello(int a, int b, int c)
{
int s1 = add_numbers(a, b);
int s2 = add_numbers(s1, c);
return s2;
}
void _start() {}
其他LLVM的wasm功能
如下列出LDC版本LLVM支持的WASM功能,如SIMD或异常处理.
ldc2 -mtriple=wasm32-unknown-unknown-wasm -mattr=help
浙公网安备 33010602011771号