import "rogchap.com/v8go"
ctx, _ := v8go.NewContext(nil) // creates a new V8 context with a new Isolate aka VM
ctx.RunScript("const add = (a, b) => a + b", "math.js") // executes a script on the global context
ctx.RunScript("const result = add(3, 4)", "main.js") // any functions previously added to the context can be called
val, _ := ctx.RunScript("result", "value.js") // return a value in JavaScript back to Go
fmt.Printf("addition result: %s", val)
vm, _ := v8go.NewIsolate() // creates a new JavaScript VM
ctx1, _ := v8go.NewContext(vm) // new context within the VM
ctx1.RunScript("const multiply = (a, b) => a * b", "math.js")
ctx2, _ := v8go.NewContext(vm) // another context on the same VM
if _, err := ctx2.RunScript("multiply(3, 4)", "main.js"); err != nil {
// this will error as multiply is not defined in this context
}
val, err := ctx.RunScript(src, filename)
if err != nil {
err = err.(v8go.JSError) // JavaScript errors will be returned as the JSError struct
fmt.Println(err.Message) // the message of the exception thrown
fmt.Println(err.Location) // the filename, line number and the column where the error occured
fmt.Println(err.StackTrace) // the full stack trace of the error, if available
fmt.Printf("javascript error: %v", err) // will format the standard error message
fmt.Printf("javascript stack trace: %+v", err) // will format the full error stack trace
}
vals := make(chan *v8go.Value, 1)
errs := make(chan error, 1)
go func() {
val, err := ctx.RunScript(script, "forever.js") // exec a long running script
if err != nil {
errs <- err
return
}
vals <- val
}()
select {
case val := <- vals:
// sucess
case err := <- errs:
// javascript error
case <- time.After(200 * time.Milliseconds):
vm, _ := ctx.Isolate() // get the Isolate from the context
vm.TerminateExecution() // terminate the execution
err := <- errs // will get a termination error back from the running script
}
Go Reference: https://pkg.go.dev/rogchap.com/v8go
If you would like to ask questions about this library or want to keep up-to-date with the latest changes and releases, please join the #v8go channel on Gophers Slack. Click here to join the Gophers Slack community!
While no prebuilt static V8 library is included for Windows, MSYS2 provides a package containing a dynamically linked V8 library that works.
To set this up:
- Install MSYS2 (https://www.msys2.org/)
- Add the Mingw-w64 bin to your PATH environment variable (
C:\msys64\mingw64\bin
by default) - Open MSYS2 MSYS and execute
pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-v8
- This will allow building projects that depend on
v8go
, but, in order to actually run them, you will need to copy thesnapshot_blob.bin
file from the Mingw-w64 bin folder to your program's working directory (which is typically wherevermain.go
is)
V8 requires 64-bit on Windows, therefore will not work on 32-bit systems.
V8 version: 8.7.220.31 (October 2020)
In order to make v8go
usable as a standard Go package, prebuilt static libraries of V8
are included for Linux and macOS ie. you should not require to build V8 yourself.
Due to security concerns of binary blobs hiding malicious code, the V8 binary is built via CI ONLY.
To provide a high quality, idiomatic, Go binding to the V8 C++ API.
The API should match the original API as closely as possible, but with an API that Gophers (Go enthusiasts) expect. For example: using multiple return values to return both result and error from a function, rather than throwing an exception.
This project also aims to keep up-to-date with the latest (stable) release of V8.
This process is non-trivial, and hopefully we can automate more of this in the future.
- Make sure to clone the projects submodules (ie. the V8 project):
git submodule update --init --recursive
- Find the current stable release (
v8_version
) here: https://omahaproxy.appspot.com - Create a new git branch from
master
eg.git checkout -b v8_7_upgrade
- Enter the v8 folder and fetch all the latest git branches:
cd deps/v8 && git fetch
- Find the right
branch-heads/**
to checkout, for example if thev8_version
is 8.7.220.31 then you want togit checkout branch-heads/8.7
. You can check all thebranch-heads
withgit branch --remotes | grep branch-heads/
- Copy all the contents of
deps/v8/include
todeps/include
making sure not to delete any of thevendor.go
files, which are required for users that are usinggo mod vendor
. If there are any new folders added, make sure to create newvendor.go
files in each folder withindeps/include
and updatecgo.go
. - Optionally build the V8 binary for your OS:
cd deps && ./build.py
. V8 is a large project, and building the binary can take up to 30 minutes. Once built all the tests should still pass viago test -v .
- Commit your changes, making sure that the git submodules have been updated to the new checksum for the version of V8. Make sure NOT to add your build of the binary, as this will be build via CI.
- Because the build is so long, this is not automatically triggered. Go to the V8
Build Github Action, Select "Run workflow",
and select your pushed branch eg.
v8_7_upgrade
. - Once built, this should open 2 PRs against your branch to add the
libv8.a
for both macOS and linux; merge these PRs into your branch. You are now ready to raise the PR againstmaster
with the latest version of V8.
Go has go fmt
, C has clang-format
. Any changes to the v8go.h|cc
should be formated with clang-format
with the
"Chromium" Coding style. This can be done easily by running the go generate
command.
brew install clang-format
to install on macOS.
V8 Gopher image based on original artwork from the amazing Renee French.