Recent

Author Topic: [SOLVED] WASM import error  (Read 445 times)

lebao3105

  • New Member
  • *
  • Posts: 26
[SOLVED] WASM import error
« on: July 12, 2026, 07:26:53 pm »
Hi,

So I am attempting to add WASM to my Github Page. Started with this simple test library:

Code: Pascal  [Select][+][-]
  1. library test;
  2. uses sysutils;
  3.  
  4. procedure hello;
  5. begin
  6.     writeln(Format('hello world from FPC %s for %s', [ {$I %FPCVERSION%}, {$I %FPCTARGETCPU%} ]));
  7.     writeln(Format('compiled on %s %s', [ {$I %DATE%}, {$I %TIME%} ]));
  8. end;
  9.  
  10. exports
  11.     hello;
  12. end.
  13.  

Compiled with WASI Preview 1 (target "OS") + WASM32 (target platform) cross-compiler.

The browser instead throws this error: WebAssembly.instantiate(): Import #0 "wasi_snapshot_preview1": module is not an object or function.

The JavaScript part (I think the second parameter is not really correct):

Code: Javascript  [Select][+][-]
  1. const res = fetch("test.wasm");
  2. await WebAssembly.instantiateStreaming(res, {
  3.        test: {
  4.              hello: () => {
  5.                    console.log("?");
  6.              }
  7.        },
  8. });
  9.  

Edit: I know that one can use Pas2JS to create an environment that can be used to load WASM, but is there any other way? Pas2JS returned this error:

C:\fpcupdeluxe\fpcsrc\rtl\win64\windows.pp(19,13) Error: Illegal compiler directive "PackSet"

Its config file is:

Code: Text  [Select][+][-]
  1. -vwnh
  2. -Sc
  3.  
  4. -FuC:\fpcupdeluxe\fpcsrc\rtl\win\
  5. -FuC:\fpcupdeluxe\fpcsrc\rtl\win64\
  6. -FuC:\fpcupdeluxe\fpcsrc\packages\*\src
  7. -JiC:\fpcupdeluxe\fpcsrc\utils\pas2js\dist\rtl.js
  8.  

Edit 2: Fixed Pas2JS errors. Turns out it uses a separate set of units and RTL.
« Last Edit: July 15, 2026, 10:20:42 am by lebao3105 »
My GitHub+GitLab username: lebao3105.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1081
  • Behold, I bring salvation - Unleashed Pascal
    • fibo.gg
Re: WASM import error
« Reply #1 on: July 12, 2026, 09:30:47 pm »
The browser instead throws this error: WebAssembly.instantiate(): Import #0 "wasi_snapshot_preview1": module is not an object or function.

Your import object is the issue. The second arg to instantiate is what the module wants to *import* from the host - it has nothing to do with exports. hello is an export, so putting it there does nothing. What the module actually imports is wasi_snapshot_preview1, because writeln calls the fd_write syscall and the host must supply it. You provided the wrong module name and omitted the required one, so instantiation fails.

You need a WASI shim JS-side - in the browser, e.g. @bjorn3/browser_wasi_shim. And since a library is a reactor, call wasi.initialize() before calling the export.

Code: Javascript  [Select][+][-]
  1. <script type="module">
  2. import { WASI, OpenFile, File, ConsoleStdout } from 'https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.3.0/dist/index.js';
  3.  
  4. const wasi = new WASI([], [], [
  5.   new OpenFile(new File([])),
  6.   ConsoleStdout.lineBuffered(console.log),
  7.   ConsoleStdout.lineBuffered(console.warn),
  8. ]);
  9.  
  10. const bytes = await (await fetch('test.wasm')).arrayBuffer();
  11. const { instance } = await WebAssembly.instantiate(bytes, { wasi_snapshot_preview1: wasi.wasiImport });
  12.  
  13. wasi.initialize(instance);
  14. instance.exports.hello();
  15. </script>

FYI: fetch+arrayBuffer instead of instantiateStreaming so it works even when the server doesn't send Content-Type: application/wasm.
« Last Edit: July 12, 2026, 09:36:06 pm by Fibonacci »
Unleashed Pascal: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

lebao3105

  • New Member
  • *
  • Posts: 26
Re: WASM import error
« Reply #2 on: July 13, 2026, 01:48:17 pm »
Your import object is the issue. The second arg to instantiate is what the module wants to *import* from the host - it has nothing to do with exports. hello is an export, so putting it there does nothing. What the module actually imports is wasi_snapshot_preview1, because writeln calls the fd_write syscall and the host must supply it. You provided the wrong module name and omitted the required one, so instantiation fails.

You need a WASI shim JS-side - in the browser, e.g. @bjorn3/browser_wasi_shim. And since a library is a reactor, call wasi.initialize() before calling the export.

Code: Javascript  [Select][+][-]
  1. <script type="module">
  2. import { WASI, OpenFile, File, ConsoleStdout } from 'https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.3.0/dist/index.js';
  3.  
  4. const wasi = new WASI([], [], [
  5.   new OpenFile(new File([])),
  6.   ConsoleStdout.lineBuffered(console.log),
  7.   ConsoleStdout.lineBuffered(console.warn),
  8. ]);
  9.  
  10. const bytes = await (await fetch('test.wasm')).arrayBuffer();
  11. const { instance } = await WebAssembly.instantiate(bytes, { wasi_snapshot_preview1: wasi.wasiImport });
  12.  
  13. wasi.initialize(instance);
  14. instance.exports.hello();
  15. </script>

FYI: fetch+arrayBuffer instead of instantiateStreaming so it works even when the server doesn't send Content-Type: application/wasm.

Hi, it worked. Almost.

instance.exports does not have hello as exported. But as I fixed Pas2JS, I can consider using it now.

Thanks for helping.
My GitHub+GitLab username: lebao3105.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1081
  • Behold, I bring salvation - Unleashed Pascal
    • fibo.gg
Re: WASM import error
« Reply #3 on: July 13, 2026, 02:09:49 pm »
Looks like you're on Windows with fpcupdeluxe (going by your C:\fpcupdeluxe\... paths), so you can just use my wasip1 build script.

Save it as build_wasip1.bat in the folder where FPC is installed - the top-level install folder, next to fpcupdeluxe.ini (for you that's C:\fpcupdeluxe). Run it, wait for it to finish, and from then on you can compile for wasm32 + wasip1. Your library will build fine and actually expose the hello export.

Code: Text  [Select][+][-]
  1. @echo off
  2. setlocal
  3.  
  4. rem detect install root (directory where this script lives)
  5. set "MYROOT=%~dp0"
  6. if "%MYROOT:~-1%"=="\" set "MYROOT=%MYROOT:~0,-1%"
  7.  
  8. set "MYSRC=%MYROOT%\fpcsrc"
  9. set "MYBOOT=%MYROOT%\fpc\bin\x86_64-win64"
  10. set "MYDEST=%MYROOT%\fpc"
  11.  
  12. rem clear env vars that would override GNU make internals
  13. set INSTALL=
  14. set PREFIX=
  15. set FPCDIR=
  16.  
  17. echo ROOT:        %MYROOT%
  18. echo FPCSRC:      %MYSRC%
  19. echo BOOTSTRAP:   %MYBOOT%
  20. echo INSTALL_DIR: %MYDEST%
  21. echo.
  22.  
  23. if not exist "%MYSRC%\Makefile" (
  24.   echo ERROR: Makefile not found in %MYSRC%
  25.   exit /b 1
  26. )
  27. if not exist "%MYBOOT%\make.exe" (
  28.   echo ERROR: make.exe not found in %MYBOOT%
  29.   exit /b 1
  30. )
  31. if not exist "%MYBOOT%\ppcx64.exe" (
  32.   echo ERROR: ppcx64.exe not found in %MYBOOT%
  33.   exit /b 1
  34. )
  35.  
  36. set "PATH=%MYBOOT%;%PATH%"
  37.  
  38. pushd "%MYSRC%" || exit /b 1
  39.  
  40. echo [1/3] make clean
  41. call make clean CPU_TARGET=wasm32 OS_TARGET=wasip1 || goto :fail
  42.  
  43. echo [2/3] make all
  44. call make all CPU_TARGET=wasm32 OS_TARGET=wasip1 || goto :fail
  45.  
  46. echo [3/3] make crossinstall
  47. call make crossinstall CPU_TARGET=wasm32 OS_TARGET=wasip1 INSTALL_PREFIX=%MYDEST% || goto :fail
  48.  
  49. popd
  50. echo.
  51. echo DONE.
  52. echo   ppcrosswasm32.exe: %MYDEST%\bin\x86_64-win64
  53. echo   units:             %MYDEST%\units\wasm32-wasip1
  54. exit /b 0
  55.  
  56. :fail
  57. echo.
  58. echo BUILD FAILED at step above.
  59. popd
  60. exit /b 1
Unleashed Pascal: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

lebao3105

  • New Member
  • *
  • Posts: 26
Re: WASM import error
« Reply #4 on: July 13, 2026, 03:14:12 pm »
Looks like you're on Windows with fpcupdeluxe (going by your C:\fpcupdeluxe\... paths), so you can just use my wasip1 build script.

Save it as build_wasip1.bat in the folder where FPC is installed - the top-level install folder, next to fpcupdeluxe.ini (for you that's C:\fpcupdeluxe). Run it, wait for it to finish, and from then on you can compile for wasm32 + wasip1. Your library will build fine and actually expose the hello export.

Code: Text  [Select][+][-]
  1. @echo off
  2. setlocal
  3.  
  4. rem detect install root (directory where this script lives)
  5. set "MYROOT=%~dp0"
  6. if "%MYROOT:~-1%"=="\" set "MYROOT=%MYROOT:~0,-1%"
  7.  
  8. set "MYSRC=%MYROOT%\fpcsrc"
  9. set "MYBOOT=%MYROOT%\fpc\bin\x86_64-win64"
  10. set "MYDEST=%MYROOT%\fpc"
  11.  
  12. rem clear env vars that would override GNU make internals
  13. set INSTALL=
  14. set PREFIX=
  15. set FPCDIR=
  16.  
  17. echo ROOT:        %MYROOT%
  18. echo FPCSRC:      %MYSRC%
  19. echo BOOTSTRAP:   %MYBOOT%
  20. echo INSTALL_DIR: %MYDEST%
  21. echo.
  22.  
  23. if not exist "%MYSRC%\Makefile" (
  24.   echo ERROR: Makefile not found in %MYSRC%
  25.   exit /b 1
  26. )
  27. if not exist "%MYBOOT%\make.exe" (
  28.   echo ERROR: make.exe not found in %MYBOOT%
  29.   exit /b 1
  30. )
  31. if not exist "%MYBOOT%\ppcx64.exe" (
  32.   echo ERROR: ppcx64.exe not found in %MYBOOT%
  33.   exit /b 1
  34. )
  35.  
  36. set "PATH=%MYBOOT%;%PATH%"
  37.  
  38. pushd "%MYSRC%" || exit /b 1
  39.  
  40. echo [1/3] make clean
  41. call make clean CPU_TARGET=wasm32 OS_TARGET=wasip1 || goto :fail
  42.  
  43. echo [2/3] make all
  44. call make all CPU_TARGET=wasm32 OS_TARGET=wasip1 || goto :fail
  45.  
  46. echo [3/3] make crossinstall
  47. call make crossinstall CPU_TARGET=wasm32 OS_TARGET=wasip1 INSTALL_PREFIX=%MYDEST% || goto :fail
  48.  
  49. popd
  50. echo.
  51. echo DONE.
  52. echo   ppcrosswasm32.exe: %MYDEST%\bin\x86_64-win64
  53. echo   units:             %MYDEST%\units\wasm32-wasip1
  54. exit /b 0
  55.  
  56. :fail
  57. echo.
  58. echo BUILD FAILED at step above.
  59. popd
  60. exit /b 1

I explicitly used wasm+wasip1 before creating this topic.
My GitHub+GitLab username: lebao3105.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1081
  • Behold, I bring salvation - Unleashed Pascal
    • fibo.gg
Re: WASM import error
« Reply #5 on: July 13, 2026, 04:53:35 pm »
Well - your code works here, zero modifications: hello is exported and both lines show up in the console. That's why I figured something was off with your wasip1 build.
Unleashed Pascal: async/await, parallel for, match, tuples, string interpolation, inline vars, autofree, no-RTTI & tons more. Star on GitHub

lebao3105

  • New Member
  • *
  • Posts: 26
Re: WASM import error
« Reply #6 on: July 13, 2026, 05:51:47 pm »
Well - your code works here, zero modifications: hello is exported and both lines show up in the console. That's why I figured something was off with your wasip1 build.

It somehow reappear now? I honestly don't know why, but as all things are resolved by now, I may mark this topic as resolved.

Thank you, once again!

My GitHub+GitLab username: lebao3105.

 

TinyPortal © 2005-2018