Logo

dev-resources.site

for different kinds of informations.

Wasm3 + TinyGo on PSP

Published at
12/20/2024
Categories
tinygo
psp
webassembly
go
Author
aethiopicuschan
Categories
4 categories in total
tinygo
open
psp
open
webassembly
open
go
open
Author
15 person written this
aethiopicuschan
open
Wasm3 + TinyGo on PSP

I will attach the GitHub repository first: wasm3-tinygo-psp.

Main Topic

For some time now, I have wanted to run Golang on the PSP.

However, native compilation to the PSP is impossible (probably).

Certainly, Golang does support GOARCH=mipsle, but it assumes the presence of an operating system. If you attempt to achieve this, you would likely have to navigate a very difficult and thorny path.

So, I chose another way. In other words, the approach is to convert it into WASM using TinyGo.

Now, let's take a look at the actual code.

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)))
}
Enter fullscreen mode Exit fullscreen mode

Essentially, we are simply calling the functions provided by the runtime. It's just a Hello World example.

About runtime

There was also an option to use Rust and wasmi for the runtime, but although it worked on emulators like PPSSPP, errors occurred on the actual hardware (as shown in the screenshot below).

PSP Error ScreenShot

I suspect it may be related to kernel mode, but since I ultimately couldn't resolve it, I took a different approach.

Ultimately, the combination of C and Wasm3 worked successfully.

Image of a PSP in Operation

Regarding println, which was mentioned in the earlier code, it is defined on the runtime side as follows.

#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] = '\0';

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

    return NULL;
}
Enter fullscreen mode Exit fullscreen mode

Since this is just a demo, this is all for now. However, if you also wrap other functions and make them callable from WASM, you should be able to develop full-fledged applications.

Challenges Faced

Cross-compiling Wasm3

It was necessary to compile Wasm3 using the PSP toolchain.

I created a forked repository to make it easy for everyone to set up the environment, so please take a look for reference: wasm3-for-psp.

TinyGo build options

In the end, I ended up with the command tinygo build -o hello.wasm -target=wasm -no-debug main.go, but it took me quite a bit of time just to arrive at such a simple command. I still have a lot to learn.

Export main function

If you are using -target=wasi, TinyGo exports the main function as _start. But in this case, I had to define and export a separate start function.

And then...

This time, I used TinyGo to compile Golang code into WASM, but if other languages can also be compiled into WASM, I believe they can be executed using a similar method. I am passionate about Golang, so I would be happy if someone could give it a try.

That's all. Thank you for reading.

webassembly Article's
30 articles in total
Favicon
How to Build an Image Processor with React and Transformers.js
Favicon
A Gentle Introduction to WebAssembly in Rust (2025 Edition)
Favicon
How to Build a Speech-to-Text App with React and Transformers.js
Favicon
The Dev Tools Evolution: LLMs, Wasm, and What's Next for 2025
Favicon
Progressive Web Apps: New FE systems
Favicon
Run Python programs easily in the browser.
Favicon
Scaling Spin Apps With KEDA
Favicon
How to Build a Text-to-Image Generator with React and Transformers.js
Favicon
Shocking! AI Instantly Removes Backgrounds in Your Browser-Netizens Exclaim: This is Absolutely Magical!
Favicon
Using SpinKube on Kairos
Favicon
Golang on PSP (and other languages)
Favicon
Introduction to WebAssembly (WASM)
Favicon
Sneak Peek at 2024 Volume 4: Flutter
Favicon
Orchestrating Distributed Apps (Spin/Rust and .NET/C#) with .NET Aspire/Dapr
Favicon
How React and WebAssembly Can Speed Up Your Web Apps in 2025
Favicon
Level Up Your WordPress Skills with WebAssembly
Favicon
The Wasm Component Model and idiomatic codegen
Favicon
The 2024 Highlights
Favicon
Currency converter in Rust + WebAssembly
Favicon
Wasm3 + TinyGo on PSP
Favicon
Is the browser always the right tool for the job?
Favicon
Rust for JavaScript Developers: Your First WebAssembly Module
Favicon
You Are Already Using Wasm In Production
Favicon
Tic Tac Toe in Rust + Webassembly
Favicon
eval() with WASM instead of sandbox with Web Extensions
Favicon
Integrating Spin with Azure services
Favicon
Spin Verman - The Version Manager Plugin
Favicon
Harnessing the Potential of Blazor: Revolutionizing Web Development with C#
Favicon
Building for WebAssembly
Favicon
ALKANES: Smart Contracts on Bitcoin UTXOs

Featured ones: