Skip to content

Move to V8 15.6.8, and fetch the monolith from where it is built - #30

Merged
ResurrectedTrader merged 3 commits into
mainfrom
v8-15
Sep 18, 2026
Merged

ResurrectedTrader merged 3 commits into
mainfrom
v8-15

Conversation

@ResurrectedTrader

Copy link
Copy Markdown
Owner

Moves the engine to V8 15.6.8, and stops CI depending on a file that was uploaded by hand.

Where the library comes from

The monolith was previously a v8-libs.zip attached to a release in this repository. Nothing produced it reproducibly, and a rebuilt V8 only reached CI when someone remembered to upload it again.

It now comes from v8-static-win, which builds the monolith for 32-bit Windows against the static CRT and publishes all four configurations. The coordinates live in one env block per workflow:

env:
  V8_REPO: ResurrectedTrader/v8-static-win
  V8_RELEASE: v8-15.6.8
  V8_ASSET: v8-15.6.8-x86-release-*.zip

Moving V8 is those three lines plus the vendored headers, which have to agree with the library or the link fails on changed symbols.

Two deliberate choices:

  • Pinned, not floating. A V8 release can change the embedder API, so moving to one should fail in the pull request that does it, not in the next unrelated build.
  • Matched by pattern. The asset name carries the MSVC toolset it was built with, and that changes when the publishing runner does. The toolset is a floor, not a match - any toolset at least that new links it.

The source repo is public, so GH_TOKEN: ${{ github.token }} is enough and no PAT secret is involved. That also keeps the step working in a fork PR, where secrets would not be available.

What 15.6.8 required of the bindings

removed / changed replacement
PropertyCallbackInfo::This() Holder()
External::New / External::Value now take an explicit type tag
Get/SetAlignedPointerInInternalField now take an embedder data type tag
AccessorNameSetterCallback AccessorNameSetterCallbackV2, returning through PropertyCallbackInfo<v8::Boolean> rather than void
Object::GetIsolate(), Function::GetIsolate() isolate comes from the caller

Consuming the published monolith also needs /DV8_GN_HEADER - that is how the public headers pick up the bundled v8-gn.h and lay objects out the way the library does, so it is an ABI requirement rather than a convenience - and ntdll, userenv and bcrypt on the link line, which Rust's standard library pulled in when Temporal brought Rust into the archive.

Verification

  • The DLL was built against the published x86-release archive: compiles and links with no further project change, and imports no dynamic CRT (no vcruntime / msvcp / msvcr / api-ms-win-crt / ucrtbase), with ntdll and bcrypt present as expected.
  • The vendored headers are byte-identical to the ones in the published archive - same 124 files, same digests.
  • The fetch step body was run verbatim against the live release: the glob matches exactly one asset (not the debug or x64 ones), and the library lands at dependencies/v8/libs/x86-release/v8_monolith.lib, verified 32-bit by its COFF machine type.
  • Both workflows parse, and the env context is valid in a cache key per GitHub's context-availability table.

README.md is updated to match: where to get the libraries, the toolset floor, and the two compile/link requirements.

Note for reviewers

CI never builds Debug, so only the x86-release asset is fetched. A local Debug build still needs x86-debug/v8_monolith.lib from the matching archive.

ResurrectedTrader and others added 3 commits September 18, 2026 20:59
The V8 the engine builds against jumps from 14.0.264.0 to 15.6.8, and CI stops
depending on a file somebody uploaded by hand.

The library was previously a v8-libs.zip attached to a release in this
repository. Nothing produced it reproducibly, and a rebuilt V8 only reached CI
when someone remembered to upload it again. It now comes from v8-static-win,
which builds the monolith for 32-bit Windows against the static CRT and
publishes all four configurations. The release tag, repository and asset pattern
sit in one env block per workflow; moving V8 is those three lines plus the
vendored headers, which have to agree with the library or the link fails.

The tag is pinned rather than resolved to whatever is newest. A V8 release can
change the embedder API, so moving to one should fail in the pull request that
does it, not in the next unrelated build. The asset is matched by pattern
because its name carries the MSVC toolset it was built with, and that changes
when the publishing runner does; the toolset is a floor, not a match, so any
toolset at least that new links it.

What 15.6.8 required of the bindings:

  PropertyCallbackInfo::This() is gone - Holder() replaces it.
  External::New and External::Value take an explicit type tag, as do the
  aligned-pointer internal field accessors.
  AccessorNameSetterCallback is replaced by its V2 form, whose callbacks return
  through PropertyCallbackInfo<v8::Boolean> rather than void.
  Object::GetIsolate() and Function::GetIsolate() are gone; the isolate comes
  from the caller.

V8_GN_HEADER has to be defined when compiling against the published monolith -
it is how the public headers pick up the bundled v8-gn.h and lay objects out the
way the library does, so it is an ABI requirement rather than a convenience -
and ntdll, userenv and bcrypt have to be linked, which Rust's standard library
pulled in when Temporal brought Rust into the archive.

Verified by building the DLL against the published x86 Release archive: it
compiles and links with no further project change, and imports no dynamic CRT.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The signature changes run past the column limit in a few places - the setter
callbacks in particular, which grew a return type and a wider info parameter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A V8 bump rewrites sixty-odd vendored headers, which is most of the file count
of any change that includes one and none of what a reviewer is there to read.
Marking them generated collapses them in pull request diffs, and vendored keeps
them out of the language statistics. Both are display-only - git still tracks
and diffs them normally.

The file carries no text= or eol= rule on purpose: this repository has mixed
line endings and core.autocrlf=false, and adding one would renormalise files
nothing to do with the change that added it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ResurrectedTrader
ResurrectedTrader merged commit 7f6bad0 into main Sep 18, 2026
1 check passed
@ResurrectedTrader
ResurrectedTrader deleted the v8-15 branch September 18, 2026 21:19
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