首页 > 后端开发 > Golang > PSP 上的 Wasm TinyGo

PSP 上的 Wasm TinyGo

Susan Sarandon
发布: 2024-12-29 03:23:10
原创
721 人浏览过

我将首先附加 GitHub 存储库:wasm3-tinygo-psp。

主要议题

一段时间以来,我一直想在 PSP 上运行 Golang。

但是,原生编译到 PSP 是不可能的(可能)。

当然,Golang 确实支持 GOARCH=mipsle,但它假设存在操作系统。如果您试图实现这一目标,您可能必须走一条非常困难且布满荆棘的道路。

所以,我选择了另一种方式。换句话说,方法就是使用TinyGo将其转换为WASM。

现在,让我们看一下实际的代码。

package main

import "unsafe"

//go:wasmimport debug println
func println(ptr unsafe.Pointer, len int32)

//export start
func start() {
    main()
}

func main() {
    message := "Hello, WebAssembly, from Golang!"
    println(unsafe.Pointer(unsafe.StringData(message)), int32(len(message)))
}
登录后复制

本质上,我们只是调用运行时提供的函数。这只是一个 Hello World 示例。

关于运行时

还有一个选项是在运行时使用 Rust 和 wasmi,但尽管它可以在 PPSSPP 这样的模拟器上运行,但在实际硬件上会出现错误(如下面的屏幕截图所示)。

Wasm TinyGo on PSP

我怀疑它可能与内核模式有关,但由于我最终无法解决它,所以我采取了不同的方法。

最终,C 和 Wasm3 的结合成功了。

Wasm TinyGo on PSP

关于前面代码中提到的println,它在运行时端的定义如下。

#define printf pspDebugScreenPrintf

static const void* host_debug_println(IM3Runtime runtime, IM3ImportContext ctx, uint64_t *stack, void *mem)
{
    uint32_t ptr = (uint32_t) stack[0];
    uint32_t length = (uint32_t) stack[1];

    uint8_t* bytes = (uint8_t*)mem + ptr;

    char buffer[256];
    if (length >= sizeof(buffer)) {
        length = sizeof(buffer)-1;
    }
    memcpy(buffer, bytes, length);
    buffer[length] = '';

    printf("%s\n", buffer);

    return NULL;
}
登录后复制

由于这只是一个演示,所以现在就这些了。但是,如果您还包装其他函数并使其可从 WASM 调用,那么您应该能够开发成熟的应用程序。

面临的挑战

交叉编译 Wasm3

需要使用PSP工具链编译Wasm3。

我创建了一个fork的仓库,方便大家搭建环境,请参考:wasm3-for-psp。

TinyGo 构建选项

最后,我得到了tinygo build -o hello.wasm -target=wasm -no-debug main.go 命令,但我花了相当多的时间才得到这样一个简单的命令。我还有很多东西要学。

导出主函数

如果您使用-target=wasi,TinyGo 将 main 函数导出为 _start。但在这种情况下,我必须定义并导出一个单独的启动函数。

进而...

这次我使用TinyGo将Golang代码编译成WASM,但如果其他语言也可以编译成WASM,相信也可以用类似的方法执行。我对 Golang 充满热情,所以如果有人可以尝试一下,我会很高兴。

仅此而已。感谢您的阅读。

以上是PSP 上的 Wasm TinyGo的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板