Skip to content

Fix allocator lookup for anonymous WASM modules#2

Merged
wolfy-j merged 3 commits intomainfrom
fix/allocator-lookup-anonymous-modules
Apr 6, 2026
Merged

Fix allocator lookup for anonymous WASM modules#2
wolfy-j merged 3 commits intomainfrom
fix/allocator-lookup-anonymous-modules

Conversation

@skhaz
Copy link
Copy Markdown
Contributor

@skhaz skhaz commented Apr 5, 2026

Summary

  • Fix cabi_realloc lookup returning nil for core WASM modules instantiated with WithName("") (anonymous)
  • Add null pointer guards on allocator return values to prevent passing ptr=0 to WASM modules

Root Cause

When a core WASM module is instantiated anonymously via wazero.NewModuleConfig().WithName(""), wazero's FunctionDefinition.Name() returns an empty string instead of the export name. The allocator caching code was doing:

allocFnDef := instance.ExportedFunctionDefinitions()["cabi_realloc"]  // finds it
wazInst.allocFn = instance.ExportedFunction(allocFnDef.Name())        // Name() = "" → nil

This caused allocFn to be silently nil, making every string parameter encoding fail with "failed to allocate N bytes for string data".

Fix

Use the map key (the export name we searched for) for ExportedFunction lookup instead of FunctionDefinition.Name():

allExports := instance.ExportedFunctionDefinitions()
allocFnDef := allExports[CabiRealloc]
allocName := CabiRealloc
// ...
wazInst.allocFn = instance.ExportedFunction(allocName)

Also added null pointer checks on cabi_realloc return values in both wazeroAllocator.Alloc and AllocatorWrapper.Alloc to surface allocation failures early instead of passing ptr=0 to the WASM guest (which causes NonNull::new_unchecked panics in Rust wit-bindgen bindings).

Reproduction

Any core WASM module (non-component) with string parameters compiled from Rust using wit-bindgen would fail. For example, a module exporting html-to-markdown: func(html: string) -> string built with scraper/html5ever would crash with:

encode params: [encode] invalid_data at param[0]: failed to encode parameter 0:
  [encode] allocation: failed to allocate 4 bytes for string data

Files Changed

  • engine/wazero.go — allocator lookup fix + null pointer guards in wazeroAllocator.Alloc
  • linker/internal/memory/wrapper.go — null pointer guard in AllocatorWrapper.Alloc

skhaz added 3 commits April 4, 2026 23:22
FunctionDefinition.Name() returns empty string for modules instantiated
with WithName("") (anonymous), causing ExportedFunction("") to return
nil even though cabi_realloc is exported. This silently broke all string
parameter encoding for core WASM modules.

Fix: use the export name map key instead of FunctionDefinition.Name()
when looking up the allocator function.

Also add null pointer guards on cabi_realloc return values to surface
allocation failures early instead of passing ptr=0 to the WASM module,
which causes NonNull::new_unchecked panics in Rust bindings.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes allocator resolution for anonymous core WASM module instances (e.g., instantiated with an empty module name) and adds explicit null-pointer guards to fail fast when cabi_realloc returns 0 for non-zero allocations.

Changes:

  • Fix allocator caching to look up cabi_realloc via the export-map key rather than FunctionDefinition.Name() (which can be empty for anonymous modules).
  • Add ptr==0 && size>0 guards in allocator wrappers to surface allocation failures early.
  • Add regression tests for anonymous-module allocator lookup and null allocator behavior (plus a couple of small builder formatting refactors).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
engine/wazero.go Fix allocator lookup for anonymous modules; add null-pointer allocation guards.
engine/allocator_lookup_test.go New regression tests covering anonymous-module allocator lookup and null allocator return handling.
linker/internal/memory/wrapper.go Add null-pointer guard in AllocatorWrapper.Alloc.
linker/internal/memory/wrapper_test.go Add test ensuring null allocator return becomes an error for non-zero size.
errors/errors.go Refactor builder formatting to avoid fmt.Sprintf allocation.
cmd/run/interactive.go Refactor builder formatting to avoid fmt.Sprintf allocation.
transcoder/internal/types/kind_test.go Remove //nolint:revive from package declaration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +9
package engine

import (
"context"
"testing"

"github.com/wippyai/wasm-runtime/wat"
"go.bytecodealliance.org/wit"
)
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description (Summary/Files Changed) doesn't mention the addition of this new engine-level test file (and there are also unrelated formatting changes in other packages). Please update the PR description to reflect all modified files, or split the non-allocator changes into a separate PR to keep the scope focused.

Copilot uses AI. Check for mistakes.
@wolfy-j wolfy-j merged commit b118ce0 into main Apr 6, 2026
7 checks passed
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.

3 participants