Skip to content

Make host callback import opt-in#24

Open
mt211211 wants to merge 10 commits into
6over3:mainfrom
mt211211:fix-default-wasi-imports
Open

Make host callback import opt-in#24
mt211211 wants to merge 10 commits into
6over3:mainfrom
mt211211:fix-default-wasi-imports

Conversation

@mt211211

Copy link
Copy Markdown

Summary

Fixes #23.

The current default build always imports env.call_host_function, because host_call_function is declared as a required import even when the browser/runtime never uses zeroperl_register_function or zeroperl_register_method.

That makes a README-built zeroperl.wasm fail in wrappers that instantiate the hosted zeroperl-1.0.0.wasm with only WASI imports, including the metadata.jp wrapper path described in the issue.

This PR makes host callbacks opt-in:

  • adds ENABLE_HOST_CALLBACKS=false as the default build arg
  • compiles the env.call_host_function import only when that build arg is true
  • keeps callback builds supported via --build-arg ENABLE_HOST_CALLBACKS=true
  • updates the manual build workflow input and README docs

Verification

I compared the known-working hosted artifact used by the browser wrapper:

js const bytes = fs.readFileSync('C:/tmp/zeroperl-1.0.0.wasm'); const mod = new WebAssembly.Module(bytes); console.log(WebAssembly.Module.imports(mod));

It imports only wasi_snapshot_preview1.* functions and no env.call_host_function.

I also ran:

�ash git diff --check

I could not run the full Docker build locally in this Windows environment because Docker is not installed here, but the change is limited to the existing build flags and C preprocessor guards.

@mt211211

Copy link
Copy Markdown
Author

/claim #23

@ikg1hd

ikg1hd commented May 20, 2026

Copy link
Copy Markdown

Thanks for your changes.
However, with the image now built a different error is reported: instance.exports._start is undefined
What could be the cause?

@mt211211

Copy link
Copy Markdown
Author

Thanks for testing it and for catching the _start mismatch. I pushed a follow-up commit that keeps zeroperl.wasm as the reactor/API artifact and adds zeroperl_command.wasm as a command-compatible artifact for loaders that expect instance.exports._start, such as drop-in replacements for the hosted perl.objex.ai/zeroperl-1.0.0.wasm path. The new artifact is copied into /artifacts, uploaded by the workflow, and documented in the README.

@ikg1hd

ikg1hd commented May 21, 2026

Copy link
Copy Markdown

Thanks again for the changes.
However, now another error is reported:
unreachable executed
Additionally, the image is much bigger (25 MB) than zeroperl-1.0.0.wasm (19 MB), but it was this big already without the changes of this PR. No idea, how the zeroperl-1.0.0.wasm was created.

@mt211211

Copy link
Copy Markdown
Author

Thanks for retesting. I pushed another follow-up for the unreachable executed case.

The previous zeroperl_command.wasm path was still linked as a normal WASI command-style entrypoint, so returning from main could still depend on the host proc_exit behavior. Some browser/WASI shims implement proc_exit as a simple returning stub, which then falls through to a Wasm unreachable trap.

The latest commit changes zeroperl_command.wasm to export a returnable _start from a reactor/no-entry build. It still reads the WASI arguments and runs the same Perl init path, but it returns normally instead of relying on proc_exit after completion. I also updated the README wording to document that behavior.

On the size difference: I think that is separate from this PR, since you saw it before these changes too. This patch is focused on matching the hosted artifact's loader behavior more closely: no extra env.call_host_function import, an _start export for the metadata.jp-style path, and no trap from the host exit shim.

@ikg1hd

ikg1hd commented May 23, 2026

Copy link
Copy Markdown

Hi, unfortunately, there is a different error now:
Invalid async state 2, expected 0.
The effort to fix this is quite unexpected to me, thanks for spending so much time on it!

@mt211211

Copy link
Copy Markdown
Author

Thanks for testing again, and thanks for the kind note.

I pushed another fix that targets the Invalid async state 2, expected 0 path directly. The issue was that Asyncify replay can re-enter _start / exported API entrypoints while the normal initialization globals are already set. The fast-path guards I added earlier could then return before replay reached its matching asyncify_stop_rewind(), leaving Binaryen's Asyncify state at 2.

The latest commits track rewind locally around asyncify_start_rewind() / asyncify_stop_rewind() and skip those early returns while replay is active. I also removed the attempted asyncify.get_state import, since Binaryen rejects that import during the Asyncify transform.

I verified the branch with a temporary GitHub-hosted Docker workflow: it built the image, extracted zeroperl_command.wasm, ran the Node WASI smoke test, and checked that asyncify_get_state() returns to 0 after _start completes. The passing run is here: https://github.com/mt211211/zeroperl/actions/runs/26341688431

While wiring that up I also fixed the build blockers that were preventing the workflow path from reaching the runtime smoke test (zlib fossil URL and ExifTool module/default-version handling), so this should be covered by CI now rather than just local manual testing.

@ikg1hd

ikg1hd commented May 26, 2026

Copy link
Copy Markdown

Thanks again. Now there is another error:
indirect call to null
Could you please check?

@sureshchouksey8

Copy link
Copy Markdown

I opened #28 as a clean follow-up branch for the latest indirect call to null report. It keeps the direction from this PR, credits @mt211211's existing work, and adds the command-wrapper teardown avoidance so _start does not immediately call Perl global shutdown after the one-shot script path returns. I could run git diff --check and static wrapper assertions here, but not the Docker/browser reproduction because this machine has no container runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error "import object field 'call_host_function' is not a Function" for self-built zeroperl.wasm

3 participants