Fix WASM templates after lld --stack-first default change (#2906)

Co-authored-by: Chalouati Med Rayen <chalouatirayen11@gmail.com>
This commit is contained in:
Jissoho
2026-05-04 16:18:07 +01:00
committed by GitHub
parent b26132791e
commit 2a601907fa
12 changed files with 47 additions and 19 deletions
+6 -5
View File
@@ -1,5 +1,8 @@
const std = @import("std");
const tic80_reserved_memory = 96 * 1024;
const tic80_stack_size = 8 * 1024;
pub fn build(b: *std.Build) !void {
const optimize = b.standardOptimizeOption(.{});
const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
@@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void {
exe.rdynamic = true;
exe.entry = .disabled;
exe.import_memory = true;
exe.stack_size = 8192;
// TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
// inside the stack region and leave 8 KiB of actual stack above it.
exe.stack_size = tic80_reserved_memory + tic80_stack_size;
exe.initial_memory = 65536 * 4;
exe.max_memory = 65536 * 4;
exe.export_table = true;
// all the memory below 96kb is reserved for TIC and memory mapped I/O
// so our own usage must start above the 96kb mark
exe.global_base = 96 * 1024;
b.installArtifact(exe);
}
+6 -5
View File
@@ -1,5 +1,8 @@
const std = @import("std");
const tic80_reserved_memory = 96 * 1024;
const tic80_stack_size = 8 * 1024;
pub fn build(b: *std.Build) !void {
const optimize = b.standardOptimizeOption(.{});
const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
@@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void {
exe.rdynamic = true;
exe.entry = .disabled;
exe.import_memory = true;
exe.stack_size = 8192;
// TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
// inside the stack region and leave 8 KiB of actual stack above it.
exe.stack_size = tic80_reserved_memory + tic80_stack_size;
exe.initial_memory = 65536 * 4;
exe.max_memory = 65536 * 4;
exe.export_table = true;
// all the memory below 96kb is reserved for TIC and memory mapped I/O
// so our own usage must start above the 96kb mark
exe.global_base = 96 * 1024;
b.installArtifact(exe);
}
+4 -2
View File
@@ -21,8 +21,10 @@ else
endif
# Linker flags
LDFLAGS = -Wl,-zstack-size=8192,--no-entry,--import-memory -mexec-model=reactor \
-Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304
# TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
# inside the stack region and leave 8 KiB of actual stack above it.
LDFLAGS = -Wl,-zstack-size=106496,--stack-first,--no-entry,--import-memory -mexec-model=reactor \
-Wl,--initial-memory=262144,--max-memory=262144
ifeq ($(DEBUG), 1)
LDFLAGS += -Wl,--export-all,--no-gc-sections
else
+3 -1
View File
@@ -16,6 +16,8 @@
Define the environment variable WASI_SDK_PATH; e.g., if you installed WASI
into ```$HOME/wasi-sdk```, then ```export WASI_SDK_PATH=$HOME/wasi-sdk```.
The default linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack.
Edit ```src/main.c``` to implement your game. You are of course free to
organize your code in more than one C source file.
@@ -48,4 +50,4 @@ You can then run your cartridge as follows:
The script ```buildcart.sh``` does the above steps as a convenience.
## Additional Notes
TIC-80 API functions that merely duplicate standard library functionality are not imported. Please use the `memcpy` and `memset` functions provided by the C standard library instead.
TIC-80 API functions that merely duplicate standard library functionality are not imported. Please use the `memcpy` and `memset` functions provided by the C standard library instead.
+2
View File
@@ -36,6 +36,8 @@ drwxr-xr-x 3 pierce pierce 4096 Apr 24 16:19 share/
Define the environment variable WASI_SDK_PATH; e.g., if you installed WASI
libc into ```$HOME/wasi-sdk/share/wasi-sysroot```, then ```export WASI_SDK_PATH=$HOME/wasi-sdk```.
The default linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack.
Edit ```src/main.d``` to implement your game. You are of course free to
organize your code in more than one D source file.
+8
View File
@@ -11,6 +11,10 @@
"--strip-all",
"--allow-undefined",
"--stack-first",
"-zstack-size=106496",
"--import-memory",
"--initial-memory=262144",
"--max-memory=262144",
"--no-entry"
]
},
@@ -25,6 +29,10 @@
"--strip-all",
"--allow-undefined",
"--stack-first",
"-zstack-size=106496",
"--import-memory",
"--initial-memory=262144",
"--max-memory=262144",
"--no-entry",
"$WASI_SDK_PATH/share/wasi-sysroot/lib/wasm32-wasi/libc.a"
]
+2
View File
@@ -3,6 +3,8 @@
This is a Nim / TIC-80 starter template. To build wasm binary and import it into
the 'cart.tic' file, ensure you have a Nim compiler, Wasi-SDK and Tic-80 on your system and run:
The linker settings reserve TIC-80's first 96 KiB of linear memory by using a stack-first layout with `96 KiB + 8 KiB` of configured stack.
```
nimble buildcart
```
+3 -1
View File
@@ -34,7 +34,9 @@ switch("clang.linkerexe", wasi / "bin" / "clang")
switch("passC", "--sysroot=" & (wasi / "share" / "wasi-sysroot"))
switch("passL", "-Wl,-zstack-size=8192,--no-entry,--import-memory -mexec-model=reactor -Wl,--initial-memory=262144,--max-memory=262144,--global-base=98304")
# TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
# inside the stack region and leave 8 KiB of actual stack above it.
switch("passL", "-Wl,-zstack-size=106496,--stack-first,--no-entry,--import-memory -mexec-model=reactor -Wl,--initial-memory=262144,--max-memory=262144")
when not defined(release):
switch("assertions", "off")
+3
View File
@@ -3,6 +3,9 @@ target = "wasm32-unknown-unknown"
[target.wasm32-unknown-unknown]
rustflags = [
# TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
# inside the stack region and leave 8 KiB of actual stack above it.
"-C", "link-arg=--stack-first",
"-C", "link-arg=--import-memory",
"-C", "link-arg=--initial-memory=262144",
"-C", "link-arg=--max-memory=262144",
+2
View File
@@ -3,6 +3,8 @@
## Important Note
Don't access TIC-80's I/O memory by dereferencing raw pointers. The optimiser will ruin attempts to do this, because Rust has no equivalent to C's `volatile` for direct access. Instead, use [`std::ptr::read_volatile`](https://doc.rust-lang.org/std/ptr/fn.read_volatile.html) and [`std::ptr::write_volatile`](https://doc.rust-lang.org/std/ptr/fn.write_volatile.html), or just use the standard TIC-80 `peek`/`poke`.
This template also reserves TIC-80's first 96 KiB of linear memory by forcing a stack-first layout and inflating the configured stack size to `96 KiB + 8 KiB`.
This is a Rust / TIC-80 starter template. Before using it, make sure you have installed the `wasm32-unknown-unknown` target using rustup:
```
rustup target add wasm32-unknown-unknown
+2
View File
@@ -2,6 +2,8 @@
This is a ZIG / TIC-80 starter template. To build it, ensure you have the latest development release (`0.14.0-dev.1421+f87dd43c1` or newer), then run:
The build reserves TIC-80's first 96 KiB of linear memory by folding that space into the configured stack size and leaving 8 KiB of actual stack above it.
```
zig build --release=small
```
+6 -5
View File
@@ -1,5 +1,8 @@
const std = @import("std");
const tic80_reserved_memory = 96 * 1024;
const tic80_stack_size = 8 * 1024;
pub fn build(b: *std.Build) !void {
const optimize = b.standardOptimizeOption(.{});
const target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
@@ -13,14 +16,12 @@ pub fn build(b: *std.Build) !void {
exe.rdynamic = true;
exe.entry = .disabled;
exe.import_memory = true;
exe.stack_size = 8192;
// TIC-80 reserves the first 96 KiB of linear memory, so reserve that space
// inside the stack region and leave 8 KiB of actual stack above it.
exe.stack_size = tic80_reserved_memory + tic80_stack_size;
exe.initial_memory = 65536 * 4;
exe.max_memory = 65536 * 4;
exe.export_table = true;
// all the memory below 96kb is reserved for TIC and memory mapped I/O
// so our own usage must start above the 96kb mark
exe.global_base = 96 * 1024;
b.installArtifact(exe);
}