From 914599d5e04dbaf1c05b3a993d48b1a2ac7a1ab9 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 21:59:35 +0300 Subject: [PATCH 1/9] Fix uvwasi and RISC-V CI builds --- CMakeLists.txt | 2 +- source/m3_env.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3911a33d..de732488 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ elseif(BUILD_WASI MATCHES "uvwasi") FetchContent_Declare( uvwasi GIT_REPOSITORY https://github.com/vshymanskyy/uvwasi.git - GIT_TAG master + GIT_TAG 0820128569533c855d60c0f6382acbb14aa62ad2 ) FetchContent_MakeAvailable(libuv) FetchContent_MakeAvailable(uvwasi) diff --git a/source/m3_env.c b/source/m3_env.c index 8f0ca937..cb81c758 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -1536,7 +1536,12 @@ static u32 SnapshotCountModules (IM3Runtime runtime) static IM3Module SnapshotGetModule (IM3Runtime runtime, u32 index) { - for (IM3Module m = runtime ? runtime->modules : NULL; m; m = m->next, index--) if (index == 0) return m; return NULL; + for (IM3Module m = runtime ? runtime->modules : NULL; m; m = m->next, index--) + { + if (index == 0) + return m; + } + return NULL; } static bool SnapshotFunctionIndex (IM3Function f, u32 * moduleIndex, u32 * functionIndex) From 58af1332e15dc00efd94bd48242b18dc9ed2635a Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:09:57 +0300 Subject: [PATCH 2/9] Fix remaining embedded CI builds --- CMakeLists.txt | 1 + README.md | 5 ++++ platforms/embedded/arduino/platformio.ini | 1 + source/CMakeLists.txt | 4 +++ source/m3_config.h | 6 +++++ source/m3_env.c | 33 +++++++++++++++++++++-- 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de732488..7abff446 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set_property(CACHE BUILD_WASI PROPERTY STRINGS none simple uvwasi metawasi) option(BUILD_NATIVE "Build with machine-specific optimisations" ON) option(BUILD_FUEL_TEST "Build the fuel/resume regression test" OFF) +option(BUILD_SNAPSHOT "Build runtime snapshot support" ON) option(BUILD_M3C "Build optional .m3c persistent metacode support" OFF) option(BUILD_DYLINK "Build optional dylink.0 runtime linker support" OFF) diff --git a/README.md b/README.md index 9a8eca68..f67c5311 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,11 @@ Calling `m3_Call()` on a suspended runtime returns `m3Err_runtimeSuspended`. ## Runtime snapshots +Snapshot support is enabled by default. Small embedded builds can define +`d_m3HasSnapshot=0`, or configure CMake with `BUILD_SNAPSHOT=OFF`, to compile +out the implementation; the public snapshot functions then return +`m3Err_snapshotUnsupported`. + Snapshots can only be saved from suspended runtimes. A snapshot stores enough runtime state to recreate the runtime later and continue execution from the same suspended point. diff --git a/platforms/embedded/arduino/platformio.ini b/platforms/embedded/arduino/platformio.ini index dceda85e..e52fa402 100644 --- a/platforms/embedded/arduino/platformio.ini +++ b/platforms/embedded/arduino/platformio.ini @@ -54,6 +54,7 @@ board = wildfirev3 src_build_flags = -Dd_m3CodePageAlignSize=512 + -Dd_m3HasSnapshot=0 -Os -Wfatal-errors -flto diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 16dc9bc1..cea49160 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -24,6 +24,10 @@ target_include_directories(m3 PUBLIC .) target_compile_features(m3 PRIVATE c_std_99) +if(DEFINED BUILD_SNAPSHOT AND NOT BUILD_SNAPSHOT) + target_compile_definitions(m3 PUBLIC d_m3HasSnapshot=0) +endif() + if(BUILD_M3C) target_compile_definitions(m3 PUBLIC d_m3HasM3C=1) endif() diff --git a/source/m3_config.h b/source/m3_config.h index 846b9c7c..4ba0727f 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -139,6 +139,12 @@ # define d_m3HasFloat 1 // implement floating point ops # endif +// Runtime snapshots are enabled by default, but small embedded targets may +// compile the implementation out while retaining unsupported API stubs. +# ifndef d_m3HasSnapshot +# define d_m3HasSnapshot 1 +# endif + // Optional persistent wasm3 metacode cache (.m3c). The implementation is // completely compiled out unless explicitly enabled by the embedding project. # ifndef d_m3HasM3C diff --git a/source/m3_env.c b/source/m3_env.c index cb81c758..03c0d74c 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -892,8 +892,7 @@ M3Result m3_FindFunctionInModule (IM3Function * o_function, if (not i_module->runtime) return m3Err_moduleNotLinked; - function = (IM3Function) v_FindFunction (i_module, - (void *) i_functionName); + function = (IM3Function) v_FindFunction (i_module, i_functionName); #if d_m3HasDylink function = m3d_ResolveFunction (function); #endif @@ -1494,6 +1493,8 @@ M3BacktraceInfo * m3_GetBacktrace (IM3Runtime i_runtime) } +#if d_m3HasSnapshot + // Snapshot v1 is a process-local, same-binary/same-module continuation format. // It avoids serializing raw stack, memory, function, and code pointers: continuation PCs // are encoded as function identities plus offsets; SP is a stack-slot offset; memory @@ -1700,3 +1701,31 @@ M3Result m3_LoadRuntimeSnapshot (IM3Runtime runtime, const uint8_t * buffer, uin runtime->numContinuationFrames = h.frameCount; runtime->suspendedFunction = &sm->functions[h.suspendedFunctionIndex]; runtime->lastCalled = NULL; return m3Err_none; } + +#else + +M3Result m3_GetRuntimeSnapshotSize (IM3Runtime runtime, uint32_t * out_size) +{ + (void) runtime; + (void) out_size; + return m3Err_snapshotUnsupported; +} + +M3Result m3_SaveRuntimeSnapshot (IM3Runtime runtime, uint8_t * buffer, uint32_t buffer_size, uint32_t * out_size) +{ + (void) runtime; + (void) buffer; + (void) buffer_size; + (void) out_size; + return m3Err_snapshotUnsupported; +} + +M3Result m3_LoadRuntimeSnapshot (IM3Runtime runtime, const uint8_t * buffer, uint32_t buffer_size) +{ + (void) runtime; + (void) buffer; + (void) buffer_size; + return m3Err_snapshotUnsupported; +} + +#endif From 354789d4ae85c56c954aaae56513c8051c0a6cfb Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:13:52 +0300 Subject: [PATCH 3/9] Apply snapshot flag to AVR library build --- platforms/embedded/arduino/platformio.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platforms/embedded/arduino/platformio.ini b/platforms/embedded/arduino/platformio.ini index e52fa402..5d2f08a5 100644 --- a/platforms/embedded/arduino/platformio.ini +++ b/platforms/embedded/arduino/platformio.ini @@ -52,9 +52,11 @@ src_build_flags = platform = atmelavr board = wildfirev3 +build_flags = + -Dd_m3HasSnapshot=0 + src_build_flags = -Dd_m3CodePageAlignSize=512 - -Dd_m3HasSnapshot=0 -Os -Wfatal-errors -flto From 5c9e7de4f3ab8f6198c2765da90f9512e8025d87 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:23:39 +0300 Subject: [PATCH 4/9] Stabilize optional CI checks --- .github/workflows/tests.yml | 12 +++++++++--- test/run-wasi-test.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 75e5ce8e..9289edd7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -496,20 +496,26 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 if: "github.event_name == 'push'" + env: + PARTICLE_TOKEN: ${{ secrets.PARTICLE_TOKEN }} steps: - uses: actions/checkout@v7 - name: Set up Particle CLI + if: env.PARTICLE_TOKEN != '' run: sudo npm install -g particle-cli - name: Log in - env: - PARTICLE_TOKEN: ${{ secrets.PARTICLE_TOKEN }} - run: particle login --token $PARTICLE_TOKEN + if: env.PARTICLE_TOKEN != '' + run: particle login --token "$PARTICLE_TOKEN" - name: Build Photon + if: env.PARTICLE_TOKEN != '' run: | cd platforms/embedded/particle particle compile --followSymlinks photon particle compile --followSymlinks argon + - name: Skip Particle build without credentials + if: env.PARTICLE_TOKEN == '' + run: echo "PARTICLE_TOKEN is not configured; skipping Particle cloud builds" esp-idf: runs-on: ubuntu-latest diff --git a/test/run-wasi-test.py b/test/run-wasi-test.py index 246754a7..1f0ccb0d 100755 --- a/test/run-wasi-test.py +++ b/test/run-wasi-test.py @@ -94,7 +94,7 @@ }, { "name": "CoreMark", "wasm": "./wasi/coremark/coremark.wasm", - "expect_pattern": "*Correct operation validated.*CoreMark 1.0 : * / Clang* / STATIC*" + "expect_pattern": "*Compiler version : Clang*Memory location : STATIC*crcfinal : 0x33ff*" } ] From 575814cdd31b82161f5ae559082a0192fe305293 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:34:31 +0300 Subject: [PATCH 5/9] Fix AVR library flags and wasm dispatch stack --- platforms/embedded/arduino/mega1284.py | 10 ++++++++++ platforms/embedded/arduino/platformio.ini | 5 ++--- source/m3_config_platforms.h | 13 +++++++++++++ source/m3_exec.h | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 platforms/embedded/arduino/mega1284.py diff --git a/platforms/embedded/arduino/mega1284.py b/platforms/embedded/arduino/mega1284.py new file mode 100644 index 00000000..313d68ec --- /dev/null +++ b/platforms/embedded/arduino/mega1284.py @@ -0,0 +1,10 @@ +Import("env") + +# PRE scripts update the global construction environment before PlatformIO +# clones it for dependent libraries such as wasm3. +env.Append( + CPPDEFINES=[ + ("d_m3CodePageAlignSize", 512), + ("d_m3HasSnapshot", 0), + ] +) diff --git a/platforms/embedded/arduino/platformio.ini b/platforms/embedded/arduino/platformio.ini index 5d2f08a5..fe510701 100644 --- a/platforms/embedded/arduino/platformio.ini +++ b/platforms/embedded/arduino/platformio.ini @@ -52,11 +52,10 @@ src_build_flags = platform = atmelavr board = wildfirev3 -build_flags = - -Dd_m3HasSnapshot=0 +extra_scripts = + pre:mega1284.py src_build_flags = - -Dd_m3CodePageAlignSize=512 -Os -Wfatal-errors -flto diff --git a/source/m3_config_platforms.h b/source/m3_config_platforms.h index 14954f03..eb5282d8 100644 --- a/source/m3_config_platforms.h +++ b/source/m3_config_platforms.h @@ -82,6 +82,19 @@ # endif # endif +// A separate dispatcher saves native flash, but WebAssembly engines cannot +// universally eliminate the extra tail-call frame. Inline it for wasm builds +// so long-running guests do not consume one host frame per instruction. +# if defined(__wasm__) +# if M3_COMPILER_HAS_ATTRIBUTE(always_inline) +# define M3_FUEL_DISPATCH_ATTR inline __attribute__((always_inline)) +# else +# define M3_FUEL_DISPATCH_ATTR inline +# endif +# else +# define M3_FUEL_DISPATCH_ATTR M3_NOINLINE +# endif + # if !defined(M3_HAS_TAIL_CALL) # if defined(__EMSCRIPTEN__) # define M3_HAS_TAIL_CALL 0 diff --git a/source/m3_exec.h b/source/m3_exec.h index adb0f16e..e7c22dc7 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -107,10 +107,10 @@ m3ret_t FuelPushFrame (IM3Runtime runtime, pc_t pc, m3stack_t sp, M3MemoryHead } # if (d_m3EnableOpProfiling || d_m3EnableOpTracing) -M3_NOINLINE +M3_FUEL_DISPATCH_ATTR m3ret_t vectorcall FuelDispatch (d_m3OpSig, cstr_t i_operationName) # else -M3_NOINLINE +M3_FUEL_DISPATCH_ATTR m3ret_t vectorcall FuelDispatch (d_m3OpSig) # endif { From be6106ff0e9e9f0733307b678f2181e7930dd2e7 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:37:00 +0300 Subject: [PATCH 6/9] Validate CoreMark independent of iteration count --- test/run-wasi-test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/run-wasi-test.py b/test/run-wasi-test.py index 1f0ccb0d..97670276 100755 --- a/test/run-wasi-test.py +++ b/test/run-wasi-test.py @@ -94,7 +94,7 @@ }, { "name": "CoreMark", "wasm": "./wasi/coremark/coremark.wasm", - "expect_pattern": "*Compiler version : Clang*Memory location : STATIC*crcfinal : 0x33ff*" + "expect_pattern": "*Compiler version : Clang*Memory location : STATIC*Correct operation validated.*" } ] From a11e2fd6e14dbce675576746d6f438616c1da5a7 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 22:57:55 +0300 Subject: [PATCH 7/9] Fix AVR and self-hosted CI limits --- .github/workflows/tests.yml | 4 ++-- README.md | 8 ++++---- platforms/embedded/arduino/mega1284.py | 10 ---------- platforms/embedded/arduino/platformio.ini | 4 +--- source/m3_config.h | 9 +++++++-- source/m3_config_platforms.h | 13 ------------- source/m3_exec.h | 4 ++-- 7 files changed, 16 insertions(+), 36 deletions(-) delete mode 100644 platforms/embedded/arduino/mega1284.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9289edd7..1d4aef80 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -242,11 +242,11 @@ jobs: - name: Test WebAssembly spec (in Wasm3, self-hosting) run: | cd test - python3 run-spec-test.py --exec "../build/wasm3 --stack-size 2097152 wasm3.wasm --repl" + python3 run-spec-test.py --exec "../build/wasm3 --stack-size 8388608 wasm3.wasm --repl" - name: Test WASI apps (in Wasm3, self-hosting) run: | cd test - python3 run-wasi-test.py --fast --exec "../build/wasm3 --stack-size 2097152 wasm3.wasm" + python3 run-wasi-test.py --fast --exec "../build/wasm3 --stack-size 8388608 wasm3.wasm" ios: runs-on: macos-latest diff --git a/README.md b/README.md index f67c5311..fa156d9c 100644 --- a/README.md +++ b/README.md @@ -217,10 +217,10 @@ Calling `m3_Call()` on a suspended runtime returns `m3Err_runtimeSuspended`. ## Runtime snapshots -Snapshot support is enabled by default. Small embedded builds can define -`d_m3HasSnapshot=0`, or configure CMake with `BUILD_SNAPSHOT=OFF`, to compile -out the implementation; the public snapshot functions then return -`m3Err_snapshotUnsupported`. +Snapshot support is enabled by default, except on flash-constrained AVR targets. +Define `d_m3HasSnapshot` explicitly to override the platform default. CMake +builds can use `BUILD_SNAPSHOT=OFF` to compile the implementation out. The +public snapshot functions then return `m3Err_snapshotUnsupported`. Snapshots can only be saved from suspended runtimes. diff --git a/platforms/embedded/arduino/mega1284.py b/platforms/embedded/arduino/mega1284.py deleted file mode 100644 index 313d68ec..00000000 --- a/platforms/embedded/arduino/mega1284.py +++ /dev/null @@ -1,10 +0,0 @@ -Import("env") - -# PRE scripts update the global construction environment before PlatformIO -# clones it for dependent libraries such as wasm3. -env.Append( - CPPDEFINES=[ - ("d_m3CodePageAlignSize", 512), - ("d_m3HasSnapshot", 0), - ] -) diff --git a/platforms/embedded/arduino/platformio.ini b/platforms/embedded/arduino/platformio.ini index fe510701..dceda85e 100644 --- a/platforms/embedded/arduino/platformio.ini +++ b/platforms/embedded/arduino/platformio.ini @@ -52,10 +52,8 @@ src_build_flags = platform = atmelavr board = wildfirev3 -extra_scripts = - pre:mega1284.py - src_build_flags = + -Dd_m3CodePageAlignSize=512 -Os -Wfatal-errors -flto diff --git a/source/m3_config.h b/source/m3_config.h index 4ba0727f..c8960a00 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -139,10 +139,15 @@ # define d_m3HasFloat 1 // implement floating point ops # endif -// Runtime snapshots are enabled by default, but small embedded targets may -// compile the implementation out while retaining unsupported API stubs. +// Runtime snapshots are enabled by default. AVR builds default to disabled +// because the implementation does not fit on the supported flash-constrained +// boards; either default can be overridden by defining d_m3HasSnapshot. # ifndef d_m3HasSnapshot +# if defined(__AVR__) +# define d_m3HasSnapshot 0 +# else # define d_m3HasSnapshot 1 +# endif # endif // Optional persistent wasm3 metacode cache (.m3c). The implementation is diff --git a/source/m3_config_platforms.h b/source/m3_config_platforms.h index eb5282d8..14954f03 100644 --- a/source/m3_config_platforms.h +++ b/source/m3_config_platforms.h @@ -82,19 +82,6 @@ # endif # endif -// A separate dispatcher saves native flash, but WebAssembly engines cannot -// universally eliminate the extra tail-call frame. Inline it for wasm builds -// so long-running guests do not consume one host frame per instruction. -# if defined(__wasm__) -# if M3_COMPILER_HAS_ATTRIBUTE(always_inline) -# define M3_FUEL_DISPATCH_ATTR inline __attribute__((always_inline)) -# else -# define M3_FUEL_DISPATCH_ATTR inline -# endif -# else -# define M3_FUEL_DISPATCH_ATTR M3_NOINLINE -# endif - # if !defined(M3_HAS_TAIL_CALL) # if defined(__EMSCRIPTEN__) # define M3_HAS_TAIL_CALL 0 diff --git a/source/m3_exec.h b/source/m3_exec.h index e7c22dc7..adb0f16e 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -107,10 +107,10 @@ m3ret_t FuelPushFrame (IM3Runtime runtime, pc_t pc, m3stack_t sp, M3MemoryHead } # if (d_m3EnableOpProfiling || d_m3EnableOpTracing) -M3_FUEL_DISPATCH_ATTR +M3_NOINLINE m3ret_t vectorcall FuelDispatch (d_m3OpSig, cstr_t i_operationName) # else -M3_FUEL_DISPATCH_ATTR +M3_NOINLINE m3ret_t vectorcall FuelDispatch (d_m3OpSig) # endif { From e2c0e9a531836ce49848861744fab2164ce01da8 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 23:12:30 +0300 Subject: [PATCH 8/9] Trim ATmega1284P runtime build --- README.md | 4 ++ platforms/embedded/arduino/platformio.ini | 4 ++ source/m3_config.h | 10 ++++ source/m3_env.c | 57 +++++++++++++++++++++++ source/m3_exec.h | 22 +++++++++ 5 files changed, 97 insertions(+) diff --git a/README.md b/README.md index fa156d9c..ae544e8d 100644 --- a/README.md +++ b/README.md @@ -193,6 +193,10 @@ Fuel accounting runs in one shared metacode dispatcher instead of being inlined into every operation handler. This keeps the compiled interpreter smaller without changing fuel, suspension, or resume semantics. +Fuel/resume support is compiled in by default. Flash-constrained ATmega1284P +builds default to `d_m3HasFuel=0`; define it explicitly to override that +platform default. + If wasm3 can capture the current continuation, the runtime becomes suspended and can later be resumed with `m3_Resume()`. Use `m3_SetFuel()` to set a new fuel value. diff --git a/platforms/embedded/arduino/platformio.ini b/platforms/embedded/arduino/platformio.ini index dceda85e..9f1d3a8c 100644 --- a/platforms/embedded/arduino/platformio.ini +++ b/platforms/embedded/arduino/platformio.ini @@ -52,6 +52,10 @@ src_build_flags = platform = atmelavr board = wildfirev3 +build_flags = + -mcall-prologues + -Wl,--relax + src_build_flags = -Dd_m3CodePageAlignSize=512 -Os -Wfatal-errors diff --git a/source/m3_config.h b/source/m3_config.h index c8960a00..5cc2269b 100644 --- a/source/m3_config.h +++ b/source/m3_config.h @@ -139,6 +139,16 @@ # define d_m3HasFloat 1 // implement floating point ops # endif +// Fuel/resume is enabled by default. The ATmega1284P example is already at +// its flash limit, so it opts out unless the embedding project overrides it. +# ifndef d_m3HasFuel +# if defined(__AVR_ATmega1284P__) +# define d_m3HasFuel 0 +# else +# define d_m3HasFuel 1 +# endif +# endif + // Runtime snapshots are enabled by default. AVR builds default to disabled // because the implementation does not fit on the supported flash-constrained // boards; either default can be overridden by defining d_m3HasSnapshot. diff --git a/source/m3_env.c b/source/m3_env.c index 03c0d74c..9183ef4b 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -1021,6 +1021,8 @@ u8 * GetStackPointerForArgs (IM3Function i_function) +#if d_m3HasFuel + void m3_SetFuel (IM3Runtime runtime, uint64_t fuel) { if (runtime) { runtime->fuel = fuel; runtime->fuelEnabled = true; } @@ -1103,6 +1105,51 @@ M3Result m3_Resume (IM3Runtime runtime) return m3Err_none; } +#else + +void m3_SetFuel (IM3Runtime runtime, uint64_t fuel) +{ + (void) runtime; + (void) fuel; +} + +void m3_AddFuel (IM3Runtime runtime, uint64_t fuel) +{ + (void) runtime; + (void) fuel; +} + +void m3_DisableFuel (IM3Runtime runtime) +{ + (void) runtime; +} + +uint64_t m3_GetFuel (IM3Runtime runtime) +{ + (void) runtime; + return 0; +} + +uint32_t m3_IsFuelEnabled (IM3Runtime runtime) +{ + (void) runtime; + return 0; +} + +uint32_t m3_IsSuspended (IM3Runtime runtime) +{ + (void) runtime; + return 0; +} + +M3Result m3_Resume (IM3Runtime runtime) +{ + (void) runtime; + return m3Err_runtimeSuspended; +} + +#endif // d_m3HasFuel + M3Result m3_CallV (IM3Function i_function, ...) { va_list ap; @@ -1130,7 +1177,9 @@ M3Result m3_CallVL (IM3Function i_function, va_list i_args) M3Result result = m3Err_none; u8* s = NULL; +#if d_m3HasFuel if (runtime->suspended) return m3Err_runtimeSuspended; +#endif if (!i_function->compiled) { return m3Err_missingCompiledCode; @@ -1166,7 +1215,9 @@ _ (checkStartFunction(i_function->module)) # endif ReportNativeStackUsage (); +#if d_m3HasFuel if (result == m3Err_fuelExhausted) runtime->suspendedFunction = i_function; +#endif runtime->lastCalled = result ? NULL : i_function; _catch: return result; @@ -1179,7 +1230,9 @@ M3Result m3_Call (IM3Function i_function, uint32_t i_argc, const void * i_argp M3Result result = m3Err_none; u8* s = NULL; +#if d_m3HasFuel if (runtime->suspended) return m3Err_runtimeSuspended; +#endif if (i_argc != ftype->numArgs) { @@ -1220,7 +1273,9 @@ _ (checkStartFunction(i_function->module)) ReportNativeStackUsage (); +#if d_m3HasFuel if (result == m3Err_fuelExhausted) runtime->suspendedFunction = i_function; +#endif runtime->lastCalled = result ? NULL : i_function; _catch: return result; @@ -1271,7 +1326,9 @@ _ (checkStartFunction(i_function->module)) ReportNativeStackUsage (); +#if d_m3HasFuel if (result == m3Err_fuelExhausted) runtime->suspendedFunction = i_function; +#endif runtime->lastCalled = result ? NULL : i_function; _catch: return result; diff --git a/source/m3_exec.h b/source/m3_exec.h index adb0f16e..36bb3b2e 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -36,6 +36,8 @@ d_m3BeginExternC +#if d_m3HasFuel + m3ret_t FuelInsertFrameEx (IM3Runtime runtime, u32 index, pc_t pc, m3stack_t sp, M3MemoryHeader * mem, m3reg_t r0, bool allowInternalControlFlow # if d_m3HasFloat , f64 fp0 @@ -106,6 +108,8 @@ m3ret_t FuelPushFrame (IM3Runtime runtime, pc_t pc, m3stack_t sp, M3MemoryHead ); } +#endif // d_m3HasFuel + # if (d_m3EnableOpProfiling || d_m3EnableOpTracing) M3_NOINLINE m3ret_t vectorcall FuelDispatch (d_m3OpSig, cstr_t i_operationName) @@ -116,6 +120,7 @@ m3ret_t vectorcall FuelDispatch (d_m3OpSig) { // Keep fuel accounting in this shared dispatcher. Inlining it into every // metacode operation substantially increases the interpreter's flash size. +#if d_m3HasFuel if (M3_UNLIKELY(_runtime and _runtime->fuelEnabled)) { if (M3_UNLIKELY(_runtime->fuel == 0)) @@ -126,6 +131,7 @@ m3ret_t vectorcall FuelDispatch (d_m3OpSig) ); _runtime->fuel--; } +#endif # if (d_m3EnableOpProfiling || d_m3EnableOpTracing) M3_MUSTTAIL return ((IM3Operation)(*_pc))(_runtime, _pc + 1, d_m3OpArgs, i_operationName); @@ -644,7 +650,9 @@ d_m3Op (Call) IM3Memory memory = m3MemInfo (_mem); m3stack_t sp = _sp + stackOffset; +#if d_m3HasFuel u32 frameDepth = _runtime->numContinuationFrames; +#endif # if (d_m3EnableOpProfiling || d_m3EnableOpTracing) m3ret_t r = Call (_runtime, callPC, sp, _mem, d_m3OpDefaultArgs, d_m3BaseCstr); @@ -658,6 +666,7 @@ d_m3Op (Call) nextOp (); else { +#if d_m3HasFuel if (r == m3Err_fuelExhausted) { m3ret_t parentResult = FuelInsertFrame (_runtime, frameDepth, _pc, _sp, _mem, _r0 @@ -669,6 +678,7 @@ d_m3Op (Call) forwardTrap (parentResult); } else +#endif pushBacktraceFrame (); forwardTrap (r); } @@ -684,7 +694,9 @@ d_m3Op (CallLinked) IM3Function function = m3d_ResolveFunction (importFunction); m3stack_t sp = _sp + stackOffset; +#if d_m3HasFuel u32 frameDepth = _runtime->numContinuationFrames; +#endif m3ret_t r = m3Err_none; if (M3_UNLIKELY(not function or not function->module)) @@ -710,6 +722,7 @@ d_m3Op (CallLinked) nextOp (); else { +#if d_m3HasFuel if (r == m3Err_fuelExhausted) { m3ret_t parentResult = FuelInsertFrame (_runtime, frameDepth, _pc, @@ -722,6 +735,7 @@ d_m3Op (CallLinked) forwardTrap (parentResult); } else +#endif pushBacktraceFrame (); forwardTrap (r); } @@ -738,7 +752,9 @@ d_m3Op (CallIndirect) IM3Memory memory = m3MemInfo (_mem); m3stack_t sp = _sp + stackOffset; +#if d_m3HasFuel u32 frameDepth = _runtime->numContinuationFrames; +#endif m3ret_t r = m3Err_none; @@ -779,6 +795,7 @@ d_m3Op (CallIndirect) nextOpDirect (); else { +#if d_m3HasFuel if (r == m3Err_fuelExhausted) { m3ret_t parentResult = FuelInsertFrame (_runtime, frameDepth, _pc, _sp, _mem, _r0 @@ -790,6 +807,7 @@ d_m3Op (CallIndirect) forwardTrap (parentResult); } else +#endif pushBacktraceFrame (); forwardTrap (r); } @@ -1057,7 +1075,9 @@ d_m3Op (Loop) d_m3ClearRegisters m3ret_t r; +#if d_m3HasFuel u32 frameDepth = _runtime->numContinuationFrames; +#endif IM3Memory memory = m3MemInfo (_mem); @@ -1076,6 +1096,7 @@ d_m3Op (Loop) // linear memory pointer needs refreshed here because the block it's looping over // can potentially invoke the grow operation. _mem = memory->mallocated; +#if d_m3HasFuel if (r == m3Err_fuelExhausted) { m3ret_t loopResult = FuelInsertFrameEx (_runtime, frameDepth, _pc - 1, _sp, _mem, _r0, true @@ -1087,6 +1108,7 @@ d_m3Op (Loop) forwardTrap (loopResult); forwardTrap (r); } +#endif } while (r == _pc); From 87cdfce84c97681f7935d116241d0137c0932753 Mon Sep 17 00:00:00 2001 From: esp_maniac <91507465+espmaniac@users.noreply.github.com> Date: Tue, 11 Aug 2026 23:20:33 +0300 Subject: [PATCH 9/9] Validate CoreMark with deterministic CRCs --- test/run-wasi-test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/run-wasi-test.py b/test/run-wasi-test.py index 97670276..e194ba57 100755 --- a/test/run-wasi-test.py +++ b/test/run-wasi-test.py @@ -94,7 +94,7 @@ }, { "name": "CoreMark", "wasm": "./wasi/coremark/coremark.wasm", - "expect_pattern": "*Compiler version : Clang*Memory location : STATIC*Correct operation validated.*" + "expect_pattern": "*Compiler version : Clang*Memory location : STATIC*seedcrc : 0xe9f5*[[]0[]]crclist : 0xe714*[[]0[]]crcmatrix : 0x1fd7*[[]0[]]crcstate : 0x8e3a*" } ]