Skip to content

fix(bytecode): preserve func chunk identity when encoding - #745

Draft
mparrett wants to merge 1 commit into
feat/lgb-compressionfrom
review/pointer-accurate-encoder
Draft

fix(bytecode): preserve func chunk identity when encoding#745
mparrett wants to merge 1 commit into
feat/lgb-compressionfrom
review/pointer-accurate-encoder

Conversation

@mparrett

Copy link
Copy Markdown
Collaborator

Summary

  • carry the ModuleBuilder's live *vm.CodeChunk index into all encoder paths
  • preserve that pointer mapping when writing compressed bundle bodies
  • keep a stricter structural fallback for callers encoding raw Module values
  • add a regression test with structurally identical chunks and regenerate the embedded core bundle

Root cause

Function constants were associated with serialized chunks by scanning for the first chunk with identical bytecode. Distinct functions can legitimately have identical instructions (and stack depth) while carrying different source/debug metadata, so the scan could silently bind a function to the wrong chunk.

The builder already records the exact live pointer-to-index relationship. This change makes that mapping authoritative during encoding, including the compressed path.

Impact

Encoded functions retain the exact chunk selected during module construction instead of potentially aliasing another structurally similar chunk. This keeps source maps and other chunk-specific metadata attached to the correct function.

Validation

  • go test -count=1 ./pkg/bytecode
  • go test -count=1 ./pkg/rt
  • go vet ./pkg/bytecode ./pkg/rt
  • make check-generated-manifest
  • regenerated pkg/rt/core_compiled.lgb twice and confirmed identical SHA-256 output

@mparrett

Copy link
Copy Markdown
Collaborator Author

Self Review:

No findings.

Reviewed 08bf5581 against 575d1ed5 (feat/lgb-compression). The live *vm.CodeChunk map is now the Func→chunk binding on EncodeModule, EncodeCompilationCompressed, and EncodeBundleOrderedCompressed, and the compressed-body encoder copy carries that map. Two funcs can share bytecode and MaxStack while carrying different source maps; the old scan bound both to the first match.

TestEncodeCompilationPreservesFuncChunkIdentity fails on the encoder at 575d1ed5 (second function source = "first.lg" on both plain and compressed) and passes on this head. core_compiled.lgb (+1 byte, first diff after the string/chunk tables) is remapped const-pool chunk indices, not compiler drift.

Production encode paths (lg.go, wasm.go, cmd/lgbgen) all go through the live-index APIs.

Encode() still uses the structural fallback, so Encode(w, b.Build()) still aliases the same collision. That's the documented leftover. GitHub Go CI will not run while this targets feat/lgb-compression (pull_request.branches: [main]).

@mparrett
mparrett requested a review from nnunley August 16, 2026 02:44
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.

1 participant