v8go

package module
v0.0.0-...-7f67aab Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: BSD-3-Clause Imports: 14 Imported by: 0

README

Execute JavaScript from Go

Github release Go Report Card Go Reference Test V8 Build V8 Version

V8 Gopher based on original artwork from the amazing Renee French

What this is

v8go lets you execute JavaScript from Go using V8, Google's JavaScript engine. Prebuilt static V8 libraries are shipped for every supported platform, so go get works out of the box — you should not need to build V8 yourself.

Supported platforms

OS amd64 arm64 cgo C compiler
Linux GCC or Clang
macOS Xcode Clang
Windows MinGW-w64 only, never MSVC — see Windows

✅ — a prebuilt static V8 library is committed; nothing is needed at go get time beyond a working cgo C compiler.

cgo is required, so CGO_ENABLED=0 and cross-compiling without a C toolchain for the target are not supported.

Windows needs a MinGW-w64 compiler specifically — MSVC does not work, because cgo has never supported it and no version of Go can link MSVC objects.

What it is based on

This repository is a continuation of the original rogchap/v8go, created by Roger Chapman and the v8go contributors. Upstream has been dormant since April 2023. The project was carried forward by Sebastian Döll at katallaxie/v8go, and this repository continues from there.

Most of the code here is upstream's work. It is distributed under the BSD-3-Clause terms in LICENSE, Copyright (c) 2019 Roger Chapman and the v8go contributors.

What this repository adds
  • Current V8. Tracks recent V8 releases (currently 14.6.202.28)
  • Windows support (amd64 and arm64) via the MinGW-w64 toolchain — see Windows.
  • Value.ArrayBufferViewBytes() []byte — copies the bytes of any ArrayBufferView (typed array or DataView) into a Go-owned slice with a single memcpy, respecting byteOffset/byteLength.
  • Abseil isolation. V8's bundled Abseil is rebuilt into the absl::v8go inline namespace, so it cannot collide at link time with another copy of Abseil in your binary.

Usage

import v8 "github.com/hlvs-apps/v8go"
Running a script
ctx := v8.NewContext() // 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)
One VM, many contexts
iso := v8.NewIsolate() // creates a new JavaScript VM
ctx1 := v8.NewContext(iso) // new context within the VM
ctx1.RunScript("const multiply = (a, b) => a * b", "math.js")

ctx2 := v8.NewContext(iso) // 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
}
JavaScript function with Go callback
iso := v8.NewIsolate() // create a new VM
// a template that represents a JS function
printfn := v8.NewFunctionTemplate(iso, func(info *v8.FunctionCallbackInfo) *v8.Value {
    fmt.Printf("%v", info.Args()) // when the JS function is called this Go callback will execute
    return nil // you can return a value back to the JS caller if required
})
global := v8.NewObjectTemplate(iso) // a template that represents a JS Object
global.Set("print", printfn) // sets the "print" property of the Object to our function
ctx := v8.NewContext(iso, global) // new Context with the global Object set to our object template
ctx.RunScript("print('foo')", "print.js") // will execute the Go callback with a single argunent 'foo'
Update a JavaScript object from Go
ctx := v8.NewContext() // new context with a default VM
obj := ctx.Global() // get the global object from the context
obj.Set("version", "v1.0.0") // set the property "version" on the object
val, _ := ctx.RunScript("version", "version.js") // global object will have the property set within the JS VM
fmt.Printf("version: %s", val)

if obj.Has("version") { // check if a property exists on the object
    obj.Delete("version") // remove the property from the object
}
JavaScript errors
val, err := ctx.RunScript(src, filename)
if err != nil {
  e := err.(*v8.JSError) // JavaScript errors will be returned as the JSError struct
  fmt.Println(e.Message) // the message of the exception thrown
  fmt.Println(e.Location) // the filename, line number and the column where the error occured
  fmt.Println(e.StackTrace) // the full stack trace of the error, if available

  fmt.Printf("javascript error: %v", e) // will format the standard error message
  fmt.Printf("javascript stack trace: %+v", e) // will format the full error stack trace
}
Pre-compile context-independent scripts to speed-up execution times

For scripts that are large or are repeatedly run in different contexts, it is beneficial to compile the script once and used the cached data from that compilation to avoid recompiling every time you want to run it.

source := "const multiply = (a, b) => a * b"
iso1 := v8.NewIsolate() // creates a new JavaScript VM
ctx1 := v8.NewContext(iso1) // new context within the VM
script1, _ := iso1.CompileUnboundScript(source, "math.js", v8.CompileOptions{}) // compile script to get cached data
val, _ := script1.Run(ctx1)

cachedData := script1.CreateCodeCache()

iso2 := v8.NewIsolate() // create a new JavaScript VM
ctx2 := v8.NewContext(iso2) // new context within the VM

script2, _ := iso2.CompileUnboundScript(source, "math.js", v8.CompileOptions{CachedData: cachedData}) // compile script in new isolate with cached data
val, _ = script2.Run(ctx2)
Terminate long running scripts
vals := make(chan *v8.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:
    // success
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
}
CPU Profiler
func createProfile() {
	iso := v8.NewIsolate()
	ctx := v8.NewContext(iso)
	cpuProfiler := v8.NewCPUProfiler(iso)

	cpuProfiler.StartProfiling("my-profile")

	ctx.RunScript(profileScript, "script.js") # this script is defined in cpuprofiler_test.go
	val, _ := ctx.Global().Get("start")
	fn, _ := val.AsFunction()
	fn.Call(ctx.Global())

	cpuProfile := cpuProfiler.StopProfiling("my-profile")

	printTree("", cpuProfile.GetTopDownRoot()) # helper function to print the profile
}

func printTree(nest string, node *v8.CPUProfileNode) {
	fmt.Printf("%s%s %s:%d:%d\n", nest, node.GetFunctionName(), node.GetScriptResourceName(), node.GetLineNumber(), node.GetColumnNumber())
	count := node.GetChildrenCount()
	if count == 0 {
		return
	}
	nest = fmt.Sprintf("%s  ", nest)
	for i := 0; i < count; i++ {
		printTree(nest, node.GetChild(i))
	}
}

// Output
// (root) :0:0
//   (program) :0:0
//   start script.js:23:15
//     foo script.js:15:13
//       delay script.js:12:15
//         loop script.js:1:14
//       bar script.js:13:13
//         delay script.js:12:15
//           loop script.js:1:14
//       baz script.js:14:13
//         delay script.js:12:15
//           loop script.js:1:14
//   (garbage collector) :0:0

Benchmark

Run the benchmarks via make bench.

go vet ./...
go test -bench=. | go tool golang.org/x/perf/cmd/benchstat -
goos: linux
goarch: arm64
pkg: github.com/hlvs-apps/v8go
                        │      -       │
                        │    sec/op    │
Context-8                 117.9µ ± ∞ ¹
IsolateInitialization-8   305.1µ ± ∞ ¹
IsolateInitAndRun-8       434.5µ ± ∞ ¹
IsolateCodeCache-8        420.8µ ± ∞ ¹
geomean                   284.8µ
¹ need >= 6 samples for confidence interval at level 0.95

                        │      -      │
                        │    B/op     │
Context-8                 768.0 ± ∞ ¹
IsolateInitialization-8   152.0 ± ∞ ¹
IsolateInitAndRun-8       921.0 ± ∞ ¹
IsolateCodeCache-8        264.0 ± ∞ ¹
geomean                   410.5
¹ need >= 6 samples for confidence interval at level 0.95

                        │      -      │
                        │  allocs/op  │
Context-8                 18.00 ± ∞ ¹
IsolateInitialization-8   5.000 ± ∞ ¹
IsolateInitAndRun-8       23.00 ± ∞ ¹
IsolateCodeCache-8        12.00 ± ∞ ¹
geomean                   12.55
¹ need >= 6 samples for confidence interval at level 0.95

Documentation

Go Reference & more examples: https://pkg.go.dev/hlvs-apps/v8go

Windows

Windows is supported via the MinGW-w64 toolchain, which is what cgo links with on Windows. A prebuilt static library is included for amd64, so go get works out of the box — but your build environment must use a MinGW-w64 compiler as cgo's CC.

MSVC is not supported, and cannot be. cgo drives the C compiler with GCC semantics (GCC-style flags, and it parses the compiler's DWARF output to derive C type information); cl.exe provides neither. This is a Go limitation, not a choice made here — see golang/go#20982, open since 2017. Even Clang targeting MSVC is blocked, because cgo unconditionally passes the MinGW-only -mthreads (golang/go#80290).

You do not need a full MSYS2 environment to consume this package — only a mingw-w64 compiler on PATH. Any of these work:

  • MSYS2mingw-w64-x86_64-gcc (amd64) or mingw-w64-clang-aarch64-clang (arm64)
  • w64devkit — a single zip, no environment
  • zig ccCC="zig cc -target x86_64-windows-gnu"; Zig bundles the mingw-w64 headers and CRT

MSYS2 is only required to build V8 itself.

Windows on ARM

windows/arm64 is supported and ships a prebuilt library like every other platform. Your cgo compiler must be the CLANGARM64 clang from MSYS2 (mingw-w64-clang-aarch64-clang); the mingw-w64-x86_64-gcc used for amd64 is not an aarch64 compiler.

V8 is built for it natively on GitHub's free windows-11-arm runners, also under CLANGARM64 (build_windows_arm64 in .github/workflows/v8_build.yml). Cross-compiling from x64 is not an option: mingw-w64 ships no aarch64 GCC, and the MinGW GN toolchain invokes a bare clang with no --target.

One consequence of CLANGARM64 worth knowing if you touch deps/build.py: its ar is llvm-ar, not binutils. The two disagree about ar xN. binutils on Windows matches member names case-insensitively, so V8's runtime.o and the inspector's Runtime.o resolve as two occurrences of one name; llvm-ar matches case-sensitively, making them distinct members with one occurrence each. split_ar() probes with ar --version and adjusts, because getting this wrong fails only at the very end of an hour-long build.

How the library is built

The V8 static library is built in CI (the build_windows* jobs in .github/workflows/v8_build.yml) from the patches under patches/windows/, which are vendored from the actively-maintained MSYS2 mingw-w64-v8 package and track the same V8 version this project pins — including its arm64 support. deps/build.py applies them (see apply_mingw_patches()) on top of the gclient-fetched V8 tree when invoked with --os windows. Those patches are BSD-3-Clause; see patches/windows/LICENSE.

Historical note: Windows support was previously removed upstream in rogchap/v8go#234 and reintroduced here on the MinGW-w64 toolchain.

V8 dependency

V8 version: 14.6.202.28 (March 2026)

In order to make v8go usable as a standard Go package, prebuilt static libraries of V8 are included for Linux, macOS and Windows on both amd64 and arm64, so you should not need to build V8 yourself. Each platform's library lives in its own Go module under deps/<os>_<arch>/, split into libv8-N.a parts to stay under GitHub's 100 MiB file size limit.

Due to security concerns of binary blobs hiding malicious code, the V8 binary is built via CI ONLY.

Project Goals

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.

Development

Recompile V8 with debug info and debug checks

Aside from data races, Go should be memory-safe and v8go should preserve this property by adding the necessary checks to return an error or panic on these unsupported code paths. Release builds of v8go don't include debugging information for the V8 library since it significantly adds to the binary size, slows down compilation and shouldn't be needed by users of v8go. However, if a v8go bug causes a crash (e.g. during new feature development) then it can be helpful to build V8 with debugging information to get a C++ backtrace with line numbers. The following steps will not only do that, but also enable V8 debug checking, which can help with catching misuse of the V8 API.

  1. Make sure to clone the projects submodules (ie. the V8's depot_tools project): git submodule update --init --recursive
  2. Build the V8 binary for your OS: deps/build.py --debug. V8 is a large project, and building the binary can take up to 30 minutes.
  3. Build the executable to debug, using go build for commands or go test -c for tests. You may need to add the -ldflags=-compressdwarf=false option to disable debug information compression so this information can be read by the debugger (e.g. lldb that comes with Xcode v12.5.1, the latest Xcode released at the time of writing)
  4. Run the executable with a debugger (e.g. lldb -- ./v8go.test -test.run TestThatIsCrashing, run to start execution then use bt to print a bracktrace after it breaks on a crash), since backtraces printed by Go or V8 don't currently include line number information.
Upgrading the V8 binaries

We have the v8_upgrade workflow. The workflow is triggered every day or manually.

If the current v8_hash is different from the latest stable version, the workflow takes care of fetching the latest stable v8 files and copying them into deps/include. The last step of the workflow opens a new PR with the branch name v8_upgrade/<v8-version> with all the changes.

The next steps are:

  1. The build is not yet triggered automatically. To trigger it manually, go to the V8 Build Github Action, Select "Run workflow", and select your pushed branch eg. v8_upgrade/<v8-version>.

  2. Once built, this opens a PR against your branch for each supported platform — Linux, macOS and Windows on both amd64 and arm64 — adding that platform's static library under deps/<os>_<arch>/. GitHub's hard file size limit is 100 MiB, so each library is committed as a set of split archive parts (libv8-0.a, libv8-1.a, …) listed in that directory's libmanifest; deps/build.py (see split_ar()) produces them and cgo links the parts. Merge these PRs into your branch.

  3. Re-pin the deps/* modules. Each deps/<os>_<arch> directory is its own Go module, and the root go.mod requires all six at a pseudo-version. Bump those six lines to a commit that contains every deps/*/go.mod together with the newly built binaries — normally the commit that merged the last platform PR. Be careful here: the replace ... => ./deps/... directives hide a wrong pin during local development, because a replace only applies while v8go is the main module. A consumer running go get github.com/hlvs-apps/v8go@main resolves the pseudo-versions for real and fails with invalid version: missing .../go.mod at revision ... if the pinned commit predates a platform. Verify from outside the repo before releasing:

    cd $(mktemp -d) && go mod init check
    go get github.com/hlvs-apps/v8go@main
    

You are now ready to raise the PR against main with the latest version of V8.

CI build caching

Every platform in the V8 Build workflow compiles through ccache, restored from the GitHub Actions cache. A cold V8 build takes 40 minutes to over two hours per platform; a warm one is typically under ten.

Two details matter if you touch the cache configuration:

  • The cache key must not include the V8 version. ccache is content-addressed — it hashes the preprocessed source together with the compiler, so a cache carried across a V8 bump cannot produce a stale object; it simply misses on the files that actually changed. Keying the cache blob by deps/v8_hash discards a mostly-valid cache on every upgrade, which is exactly when you least want a two-hour rebuild.
  • The size limit must fit a whole V8 build. V8 compiles roughly 1,700 objects, well over a gigabyte before compression. hendrikmuhs/ccache-action defaults to 500 MB, which silently evicts most of the cache mid-build and produces almost no speedup. Linux and macOS run at max-size: 2G, Windows at CCACHE_MAXSIZE: 3G.

CCACHE_COMPILERCHECK=content is set on every job, because V8's toolchain is re-downloaded by the gclient hooks on each run and ccache's default mtime check would treat every object as a miss.

The build_windows_arm64 job is continue-on-error. Windows arm64 is not yet wired into go.mod, so its failure cannot break a consumer — but without this a failing arm64 job skips the commit job and discards every other platform's build.

Flushing after C/C++ standard library printing for debugging

When using the C/C++ standard library functions for printing (e.g. printf), then the output will be buffered by default. This can cause some confusion, especially because the test binary (created through go test) does not flush the buffer at exit (at the time of writing). When standard output is the terminal, then it will use line buffering and flush when a new line is printed, otherwise (e.g. if the output is redirected to a pipe or file) it will be fully buffered and not even flush at the end of a line. When the test binary is executed through go test . (e.g. instead of separately compiled with go test -c and run with ./v8go.test) Go may redirect standard output internally, resulting in standard output being fully buffered.

A simple way to avoid this problem is to flush the standard output stream after printing with the fflush(stdout); statement. Not relying on the flushing at exit can also help ensure the output is printed before a crash.

Local leak checking

Leak checking is automatically done in CI, but it can be useful to do locally to debug leaks.

Leak checking is done using the Leak Sanitizer which is a part of LLVM. As such, compiling with clang as the C/C++ compiler seems to produce more complete backtraces (unfortunately still only of the system stack at the time of writing).

For instance, on a Debian-based Linux system, you can use sudo apt-get install clang-12 to install a recent version of clang. Then CC and CXX environment variables are needed to use that compiler. With that compiler, the tests can be run as follows

CC=clang-12 CXX=clang++-12 go test -c --tags leakcheck && ./v8go.test

The separate compile and link commands are currently needed to get line numbers in the backtrace.

On macOS, leak checking isn't available with the version of clang that comes with Xcode, so a separate compiler installation is needed. For example, with homebrew, brew install llvm will install a version of clang with support for this. The ASAN_OPTIONS environment variable will also be needed to run the code with leak checking enabled, since it isn't enabled by default on macOS. E.g. with the homebrew installation of llvm, the tests can be run with

CXX=/usr/local/opt/llvm/bin/clang++ CC=/usr/local/opt/llvm/bin/clang go test -c --tags leakcheck -ldflags=-compressdwarf=false
ASAN_OPTIONS=detect_leaks=1 ./v8go.test

The -ldflags=-compressdwarf=false is currently (with clang 13) needed to get line numbers in the backtrace.

Formatting

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.

License

v8go is distributed under the BSD-3-Clause terms in LICENSE.

This repository also redistributes prebuilt static libraries of V8 under deps/<os>_<arch>/ and vendors V8's public headers under deps/include/. Those artifacts carry code from V8 (BSD-3-Clause) and the third-party libraries V8 bundles — Abseil (Apache-2.0), zlib, Highway, simdutf and others. Their notices are reproduced in THIRD_PARTY_LICENSES.md, and each deps/<os>_<arch>/ module ships a THIRD_PARTY_NOTICES file generated by deps/build.py from the exact V8 tree that produced its binary.

The Windows build patches under patches/windows/ come from the MSYS2 mingw-w64-v8 package and are redistributed under its BSD-3-Clause license, reproduced at patches/windows/LICENSE.

No MinGW-w64 or GCC code is vendored here or present in the shipped archives. On Windows, -static links libstdc++/libgcc into your binary from your own toolchain; those carry the GCC Runtime Library Exception, which permits this without imposing GPL terms. Nothing in this distribution is copyleft-encumbered.

Credits

v8go was created by Roger Chapman and the v8go contributors at rogchap/v8go, and carried forward by Sebastian Döll at katallaxie/v8go. See LICENSE for the terms this project is distributed under.

Documentation

Overview

Package v8go provides an API to execute JavaScript.

Index

Examples

Constants

View Source
const (
	SpanStaged uint32 = C.GAV8_SPAN_STAGED
	SpanPinned uint32 = C.GAV8_SPAN_PINNED
)

Span kinds. A leaf's bytes are either staged into Payload.Buf — Off is a byte offset into it — or left where they are and pinned, in which case Off indexes Payload.Ptrs. A producer picks per value against a size threshold, so a single payload normally carries both.

View Source
const (
	// OpEnd terminates the program. Exactly one value must remain on the
	// stack, and it is the root.
	OpEnd uint32 = C.GAV8_OP_END
	// OpNull pushes null.
	OpNull uint32 = C.GAV8_OP_NULL
	// OpUndef pushes undefined.
	OpUndef uint32 = C.GAV8_OP_UNDEF
	// OpTrue pushes true.
	OpTrue uint32 = C.GAV8_OP_TRUE
	// OpFalse pushes false.
	OpFalse uint32 = C.GAV8_OP_FALSE
	// OpBool pushes the next Nums entry as a boolean (0 is false).
	OpBool uint32 = C.GAV8_OP_BOOL
	// OpInt pushes the next Nums entry as a number.
	OpInt uint32 = C.GAV8_OP_INT
	// OpF64 pushes the next Floats entry.
	OpF64 uint32 = C.GAV8_OP_F64
	// OpStr pushes a string from the next value Span.
	OpStr uint32 = C.GAV8_OP_STR
	// OpBytes pushes a Uint8Array from the next value Span.
	OpBytes uint32 = C.GAV8_OP_BYTES
	// OpObj is followed by a shape id. It pops that shape's key count off the
	// stack, in shape order, and pushes the object. Every key in the shape
	// gets a property, whatever its value; only [OpObjOmit] reads anything
	// into an undefined.
	OpObj uint32 = C.GAV8_OP_OBJ
	// OpMark remembers the current stack depth.
	OpMark uint32 = C.GAV8_OP_MARK
	// OpArrFromMark pops everything pushed since the matching OpMark into an
	// array.
	OpArrFromMark uint32 = C.GAV8_OP_ARR_FROM_MARK
	// OpRepeat is followed by a body length in words. It takes n from the next
	// Counts entry and runs that many words n times before continuing after
	// them. Bodies may nest. n == 0 skips the body and leaves every other
	// cursor untouched, so an empty slice costs nothing. The body may not be
	// empty.
	OpRepeat uint32 = C.GAV8_OP_REPEAT
	// OpNullable is followed by a body length in words. It takes a flag from
	// the next Counts entry — only zero is null, any other value is present —
	// and either pushes null and skips the body, or runs the body, which must
	// push exactly one value.
	//
	// This is how a *T is encoded, and nothing else expresses it: OpRepeat with
	// a count of 0 or 1 gives "the value or nothing", but OpObj pops a fixed
	// arity from its shape, so a skipped push does not yield null — it takes
	// the previous field's value and shifts every field after it.
	//
	// On the null path only the flag is consumed. Nums, Floats, Spans and the
	// rest of Counts stay where they were, because a producer stages no payload
	// for a value it is not sending; consuming one would desynchronise every
	// leaf that follows. The body must also be self-contained: it may nest
	// anything, including OpRepeat, OpObj and further OpNullable, but it may
	// not pop values pushed before it or close an OpMark from outside it. Both
	// are errors, since either would make the tree depend on the flag in a way
	// the generator did not write.
	OpNullable uint32 = C.GAV8_OP_NULLABLE
	// OpOptional is [OpNullable] with a different absent value: the flag comes
	// from the next Counts entry, zero pushes undefined instead of null, and
	// everything else — the skipped body, the untouched cursors, the
	// exactly-one-value contract, the self-containment rules — is identical.
	//
	// It is how an ABSENT object key is encoded, and null cannot stand in for
	// it: {"note":null} and {} are different values, and a producer whose
	// field is conditionally emitted is asking for exactly that distinction.
	// Pair it with [OpObjOmit], which reads the sentinel.
	OpOptional uint32 = C.GAV8_OP_OPTIONAL
	// OpObjOmit is followed by a shape id. It pops the same fixed arity as
	// [OpObj] and builds an object from only the pairs whose value is not
	// undefined, in shape order; all of them undefined yields {}.
	//
	// Undefined is the omit sentinel because it cannot occur as a legitimate
	// value: null, booleans, numbers, strings, Uint8Array, arrays and objects
	// are the whole of what a leaf can be, so nothing but [OpUndef] and an
	// absent [OpOptional] produces one. A presence bitmask would instead be a
	// second source of truth, and a producer whose bit and whose staged value
	// disagreed would build a valid object with its fields shifted.
	OpObjOmit uint32 = C.GAV8_OP_OBJ_OMIT
)

Opcodes for a build program. See BuildValue for what a program is and why it is shaped this way.

These values are the ABI: a producer in another package (or another language) emits them as plain uint32 words, so they may be added to but never renumbered.

View Source
const (
	// InvalidLocalRef is returned by every LocalRef builder that fails.
	InvalidLocalRef LocalRef = C.GAV8_INVALID
	// InvalidShapeRef is returned by [BatchScope.Shape] when it fails.
	InvalidShapeRef ShapeRef = C.GAV8_INVALID
)

Variables

Functions

func BuildCallCount

func BuildCallCount() uint64

BuildCallCount reports how many times the C entry point behind BuildValue has been entered, successfully or not, since the process started or since ResetBuildCallCount.

It is a diagnostic, and the one that matters: building a tree in a single crossing is the whole reason this API exists, so a test can measure it rather than assume it. The counter is process-wide, so a test that asserts an exact value must not run in parallel with another that builds.

func JSONStringify

func JSONStringify(ctx *Context, val Valuer) (string, error)

JSONStringify tries to stringify the JSON-serializable object value and returns it as string.

Example
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	ctx := v8.NewContext()
	defer ctx.Isolate().Dispose()
	defer ctx.Close()
	val, _ := v8.JSONParse(ctx, `{
		"a": 1,
		"b": "foo"
	}`)
	jsonStr, _ := v8.JSONStringify(ctx, val)
	fmt.Println(jsonStr)
}
Output:
{"a":1,"b":"foo"}

func ResetBuildCallCount

func ResetBuildCallCount()

ResetBuildCallCount zeroes the counter BuildCallCount reports.

func SetFlags

func SetFlags(flags ...string)

SetFlags sets flags for V8. For possible flags: https://github.com/v8/v8/blob/master/src/flags/flag-definitions.h Flags are expected to be prefixed with `--`, for example: `--harmony`. Flags can be reverted using the `--no` prefix equivalent, for example: `--use_strict` vs `--nouse_strict`. Flags will affect all Isolates created, even after creation.

func Version

func Version() string

Version returns the version of the V8 Engine with the -v8go suffix.

Types

type BatchScope

type BatchScope struct {
	// contains filtered or unexported fields
}

BatchScope builds a whole JavaScript value tree in a single cgo crossing per node, without a tracked value per node.

The Object/Value API creates a v8::Global for every value it makes, and registers it with the Context so it can be released later: a malloc, a GC-root registration and a hash-map insert, before any V8 work happens. That is affordable for a handful of values and roughly an order of magnitude slower than JSON.parse for a tree of a few thousand. A BatchScope instead holds one v8::HandleScope open for its lifetime and hands back uint32 indices into a handle table, so a node costs a v8::Local and nothing else. Exactly one tracked value is ever created: the root that BatchScope.Result returns.

A scope holds the isolate's lock the whole time it is open, so nothing else can enter that isolate meanwhile — build and close promptly. It also pins its goroutine to the OS thread it started on, because the lock belongs to the thread that took it; BatchScope.Close unpins.

A BatchScope is not safe for concurrent use, and must be closed on the goroutine that opened it.

func NewBatchScope

func NewBatchScope(ctx *Context) *BatchScope

NewBatchScope opens a value-building scope on ctx. The caller must Close it, normally with defer:

s := v8.NewBatchScope(ctx)
defer s.Close()

It panics if ctx is nil or already closed.

func (*BatchScope) Array

func (s *BatchScope) Array(elems []LocalRef) LocalRef

Array builds a JS array from elems.

func (*BatchScope) Bool

func (s *BatchScope) Bool(v bool) LocalRef

Bool adds a JS boolean to the scope.

func (*BatchScope) Bytes

func (s *BatchScope) Bytes(v []byte) LocalRef

Bytes adds a JS Uint8Array holding a copy of v to the scope. This is what lets binary payloads — crypto output, compressed blocks, file and response bodies, SQL blob cells — reach JS without a base64 round trip.

The slice is copied into V8 during the call; V8 never retains a pointer into Go memory.

func (*BatchScope) Close

func (s *BatchScope) Close()

Close destroys the scope's HandleScope, which frees every value it built at once, and unpins the goroutine. All LocalRefs and ShapeRefs from this scope become invalid; values already handed out by Result are unaffected.

Close is idempotent and must run on the goroutine that opened the scope.

func (*BatchScope) Float64

func (s *BatchScope) Float64(v float64) LocalRef

Float64 adds a JS number to the scope.

func (*BatchScope) Int32

func (s *BatchScope) Int32(v int32) LocalRef

Int32 adds a JS number to the scope, as a V8 integer.

func (*BatchScope) Null

func (s *BatchScope) Null() LocalRef

Null adds the JS null value to the scope.

func (*BatchScope) Object

func (s *BatchScope) Object(shape ShapeRef, vals []LocalRef) LocalRef

Object builds a JS object with the shape's keys and the given values, in shape order. len(vals) must equal the number of keys in the shape; Object returns InvalidLocalRef otherwise.

The object gets the context's Object.prototype, so it is structurally indistinguishable from the same data parsed out of JSON.

It is not, however, indistinguishable in performance. V8's bulk object constructor produces dictionary-mode ("slow properties") objects, where JSON.parse produces hidden-class ones, and JS reads from these roughly 11x slower — a difference that only starts to matter after about 70 full passes over the data, which is why it is still the right trade for a result set rendered once. See the comment on gav8_obj in gav8_values.cc for the measurement and for the alternative.

func (*BatchScope) Result

func (s *BatchScope) Result(root LocalRef) (*Value, error)

Result wraps root as a *Value owned by the scope's Context, the way any other v8go value is owned, and returns it. The value outlives the scope; every other node in the tree is freed by Close.

Result does not close the scope. It returns an error if root is invalid, or if any builder call on this scope failed — a tree with a hole in it never reaches the caller as a value.

func (*BatchScope) Shape

func (s *BatchScope) Shape(keys []string) ShapeRef

Shape interns keys once and returns a handle to be reused for every object that has those keys in that order. Interning once per shape instead of once per object is what lets V8 build the hidden class once and share it across them, which is the whole reason this is faster than setting properties one by one.

Keys must be unique; Shape returns InvalidShapeRef if they are not.

func (*BatchScope) Size

func (s *BatchScope) Size() uint32

Size reports how many values the scope has created. A test that knows how many nodes its tree has can assert on this: a number larger than the node count means something is allocating per node behind the caller's back.

func (*BatchScope) String

func (s *BatchScope) String(v string) LocalRef

String adds a JS string to the scope. The bytes are UTF-8 and length-delimited, so an interior NUL is a character like any other rather than a terminator.

The string's bytes are read, and copied into V8, during the call; V8 never retains a pointer into Go memory.

func (*BatchScope) Undefined

func (s *BatchScope) Undefined() LocalRef

Undefined adds the JS undefined value to the scope.

type CPUProfile

type CPUProfile struct {
	// contains filtered or unexported fields
}

func (*CPUProfile) Delete

func (c *CPUProfile) Delete()

Deletes the profile and removes it from CpuProfiler's list. All pointers to nodes previously returned become invalid.

func (*CPUProfile) GetDuration

func (c *CPUProfile) GetDuration() time.Duration

Returns the duration of the profile.

func (*CPUProfile) GetTitle

func (c *CPUProfile) GetTitle() string

Returns CPU profile title.

func (*CPUProfile) GetTopDownRoot

func (c *CPUProfile) GetTopDownRoot() *CPUProfileNode

Returns the root node of the top down call tree.

type CPUProfileNode

type CPUProfileNode struct {
	// contains filtered or unexported fields
}

func (*CPUProfileNode) GetBailoutReason

func (c *CPUProfileNode) GetBailoutReason() string

Returns the bailout reason for the function if the optimization was disabled for it.

func (*CPUProfileNode) GetChild

func (c *CPUProfileNode) GetChild(index int) *CPUProfileNode

Retrieves a child node by index.

func (*CPUProfileNode) GetChildrenCount

func (c *CPUProfileNode) GetChildrenCount() int

func (*CPUProfileNode) GetColumnNumber

func (c *CPUProfileNode) GetColumnNumber() int

Returns number of the column where the function originates.

func (*CPUProfileNode) GetFunctionName

func (c *CPUProfileNode) GetFunctionName() string

Returns function name (empty string for anonymous functions.)

func (*CPUProfileNode) GetHitCount

func (c *CPUProfileNode) GetHitCount() int

Returns count of samples where the function was currently executing.

func (*CPUProfileNode) GetLineNumber

func (c *CPUProfileNode) GetLineNumber() int

Returns number of the line where the function originates.

func (*CPUProfileNode) GetNodeId

func (c *CPUProfileNode) GetNodeId() int

Returns node id.

func (*CPUProfileNode) GetParent

func (c *CPUProfileNode) GetParent() *CPUProfileNode

Retrieves the ancestor node, or nil if the root.

func (*CPUProfileNode) GetScriptId

func (c *CPUProfileNode) GetScriptId() int

Returns id for script from where the function originates.

func (*CPUProfileNode) GetScriptResourceName

func (c *CPUProfileNode) GetScriptResourceName() string

Returns resource name for script from where the function originates.

type CPUProfiler

type CPUProfiler struct {
	// contains filtered or unexported fields
}

func NewCPUProfiler

func NewCPUProfiler(iso *Isolate) *CPUProfiler

CPUProfiler is used to control CPU profiling.

func (*CPUProfiler) Dispose

func (c *CPUProfiler) Dispose()

Dispose will dispose the profiler.

func (*CPUProfiler) StartProfiling

func (c *CPUProfiler) StartProfiling(title string)

StartProfiling starts collecting a CPU profile. Title may be an empty string. Several profiles may be collected at once. Attempts to start collecting several profiles with the same title are silently ignored.

func (*CPUProfiler) StopProfiling

func (c *CPUProfiler) StopProfiling(title string) *CPUProfile

Stops collecting CPU profile with a given title and returns it. If the title given is empty, finishes the last profile started.

type CompileMode

type CompileMode C.int

type CompileOptions

type CompileOptions struct {
	CachedData *CompilerCachedData

	Mode CompileMode
}

type CompilerCachedData

type CompilerCachedData struct {
	Bytes    []byte
	Rejected bool
}

type ConsoleAPIMessage

type ConsoleAPIMessage struct {
	ErrorLevel   MessageErrorLevel
	Message      string
	Url          string
	LineNumber   uint
	ColumnNumber uint
	// contains filtered or unexported fields
}

ConsoleAPIMessage contains the information from v8 from console function calls.

The fields correspond to the arguments for the C++ function v8_inspector::InspectorClient::consoleAPIMessage

Note: Stack traces are not supported.

See also: https://v8.github.io/api/head/classv8__inspector_1_1V8InspectorClient.html

type ConsoleAPIMessageHandler

type ConsoleAPIMessageHandler interface {
	ConsoleAPIMessage(message ConsoleAPIMessage)
}

A ConsoleAPIMessageHandler will receive JavaScript `console` API calls.

type Context

type Context struct {
	// contains filtered or unexported fields
}

Context is a global root execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8.

Example
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	ctx := v8.NewContext()
	defer ctx.Isolate().Dispose()
	defer ctx.Close()
	ctx.RunScript("const add = (a, b) => a + b", "math.js")
	ctx.RunScript("const result = add(3, 4)", "main.js")
	val, _ := ctx.RunScript("result", "value.js")
	fmt.Println(val)
}
Output:
7
Example (GlobalTemplate)
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	obj := v8.NewObjectTemplate(iso)
	obj.Set("version", "v1.0.0")
	ctx := v8.NewContext(iso, obj)
	defer ctx.Close()
	val, _ := ctx.RunScript("version", "main.js")
	fmt.Println(val)
}
Output:
v1.0.0
Example (Isolate)
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	ctx1 := v8.NewContext(iso)
	defer ctx1.Close()
	ctx1.RunScript("const foo = 'bar'", "context_one.js")
	val, _ := ctx1.RunScript("foo", "foo.js")
	fmt.Println(val)

	ctx2 := v8.NewContext(iso)
	defer ctx2.Close()
	_, err := ctx2.RunScript("foo", "context_two.js")
	fmt.Println(err)
}
Output:
bar
ReferenceError: foo is not defined

func NewContext

func NewContext(opt ...ContextOption) *Context

NewContext creates a new JavaScript context; if no Isolate is passed as a ContextOption than a new Isolate will be created.

func (*Context) Close

func (c *Context) Close()

Close will dispose the context and free the memory. Access to any values associated with the context after calling Close may panic.

func (*Context) Global

func (c *Context) Global() *Object

Global returns the global proxy object. Global proxy object is a thin wrapper whose prototype points to actual context's global object with the properties like Object, etc. This is done that way for security reasons. Please note that changes to global proxy object prototype most probably would break the VM — V8 expects only global object as a prototype of global proxy object.

func (*Context) Isolate

func (c *Context) Isolate() *Isolate

Isolate gets the current context's parent isolate.

func (*Context) PerformMicrotaskCheckpoint

func (c *Context) PerformMicrotaskCheckpoint()

PerformMicrotaskCheckpoint runs the default MicrotaskQueue until empty. This is used to make progress on Promises.

func (*Context) RetainedValueCount

func (c *Context) RetainedValueCount() int

func (*Context) RunScript

func (c *Context) RunScript(source, origin string) (*Value, error)

RunScript executes the source JavaScript; origin (a.k.a. filename) provides a reference for the script and used in the stack trace if there is an error. error will be of type `JSError` if not nil.

type ContextOption

type ContextOption interface {
	// contains filtered or unexported methods
}

ContextOption sets options such as Isolate and Global Template to the NewContext.

type Exception

type Exception struct {
	*Value
}

An Exception is a JavaScript exception.

func NewError

func NewError(iso *Isolate, msg string) *Exception

NewError creates an Error, which is the common thing to throw from user code.

func NewRangeError

func NewRangeError(iso *Isolate, msg string) *Exception

NewRangeError creates a RangeError.

func NewReferenceError

func NewReferenceError(iso *Isolate, msg string) *Exception

NewReferenceError creates a ReferenceError.

func NewSyntaxError

func NewSyntaxError(iso *Isolate, msg string) *Exception

NewSyntaxError creates a SyntaxError.

func NewTypeError

func NewTypeError(iso *Isolate, msg string) *Exception

NewTypeError creates a TypeError.

func NewWasmCompileError

func NewWasmCompileError(iso *Isolate, msg string) *Exception

NewWasmCompileError creates a WasmCompileError.

func NewWasmLinkError

func NewWasmLinkError(iso *Isolate, msg string) *Exception

NewWasmLinkError creates a WasmLinkError.

func NewWasmRuntimeError

func NewWasmRuntimeError(iso *Isolate, msg string) *Exception

NewWasmRuntimeError creates a WasmRuntimeError.

func (*Exception) As

func (e *Exception) As(target interface{}) bool

As provides support for errors.As.

func (*Exception) Error

func (e *Exception) Error() string

Error implements error.

func (*Exception) Is

func (e *Exception) Is(err error) bool

Is provides support for errors.Is.

func (*Exception) String

func (e *Exception) String() string

String implements fmt.Stringer.

type Function

type Function struct {
	*Value
}

Function is a JavaScript function.

func (*Function) Call

func (fn *Function) Call(recv Valuer, args ...Valuer) (*Value, error)

Call this JavaScript function with the given arguments.

func (*Function) NewInstance

func (fn *Function) NewInstance(args ...Valuer) (*Object, error)

Invoke a constructor function to create an object instance.

func (*Function) SourceMapUrl

func (fn *Function) SourceMapUrl() *Value

Return the source map url for a function.

type FunctionCallback

type FunctionCallback func(info *FunctionCallbackInfo) *Value

FunctionCallback is a callback that is executed in Go when a function is executed in JS.

type FunctionCallbackInfo

type FunctionCallbackInfo struct {
	// contains filtered or unexported fields
}

FunctionCallbackInfo is the argument that is passed to a FunctionCallback.

func (*FunctionCallbackInfo) Args

func (i *FunctionCallbackInfo) Args() []*Value

Args returns a slice of the value arguments that are passed to the JS function.

func (*FunctionCallbackInfo) Context

func (i *FunctionCallbackInfo) Context() *Context

Context is the current context that the callback is being executed in.

func (*FunctionCallbackInfo) Release

func (i *FunctionCallbackInfo) Release()

func (*FunctionCallbackInfo) This

func (i *FunctionCallbackInfo) This() *Object

This returns the receiver object "this".

type FunctionCallbackWithError

type FunctionCallbackWithError func(info *FunctionCallbackInfo) (*Value, error)

FunctionCallbackWithError is a callback that is executed in Go when a function is executed in JS. If a ValueError is returned, its value will be thrown as an exception in V8, otherwise Error() is invoked, and the string is thrown.

type FunctionTemplate

type FunctionTemplate struct {
	// contains filtered or unexported fields
}

FunctionTemplate is used to create functions at runtime. There can only be one function created from a FunctionTemplate in a context. The lifetime of the created function is equal to the lifetime of the context.

A FunctionTemplate can be used to create "constructors", and add methods to the "class". FunctionTemplate.PrototypeTemplate can be used to add normal methods on the class, and FunctionTemplate.InstanceTemplate can be used to add fields automatically to new instances of a class.

V8 API Docs: https://v8.github.io/api/head/classv8_1_1FunctionTemplate.html

Example
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	global := v8.NewObjectTemplate(iso)
	printfn := v8.NewFunctionTemplate(iso, func(info *v8.FunctionCallbackInfo) *v8.Value {
		fmt.Printf("%+v\n", info.Args())
		return nil
	})
	global.Set("print", printfn, v8.ReadOnly)
	ctx := v8.NewContext(iso, global)
	defer ctx.Close()
	ctx.RunScript("print('foo', 'bar', 0, 1)", "")
}
Output:
[foo bar 0 1]
Example (Fetch)
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	global := v8.NewObjectTemplate(iso)

	fetchfn := v8.NewFunctionTemplate(iso, func(info *v8.FunctionCallbackInfo) *v8.Value {
		args := info.Args()
		url := args[0].String()

		resolver, _ := v8.NewPromiseResolver(info.Context())

		go func() {
			res, _ := http.Get(url) //nolint:gosec,noctx,bodyclose
			body, _ := io.ReadAll(res.Body)
			val, _ := v8.NewValue(iso, string(body))
			resolver.Resolve(val)
		}()
		return resolver.GetPromise().Value
	})
	global.Set("fetch", fetchfn, v8.ReadOnly)

	ctx := v8.NewContext(iso, global)
	defer ctx.Close()
	val, _ := ctx.RunScript("fetch('https://rogchap.com/v8go')", "")
	prom, _ := val.AsPromise()

	// wait for the promise to resolve
	for prom.State() == v8.Pending {
		continue
	}
	fmt.Printf("%s\n", strings.Split(prom.Result().String(), "\n")[0])
}
Output:
<!DOCTYPE html>

func NewFunctionTemplate

func NewFunctionTemplate(iso *Isolate, callback FunctionCallback) *FunctionTemplate

NewFunctionTemplate creates a FunctionTemplate for a given callback. Prefer using NewFunctionTemplateWithError.

func NewFunctionTemplateWithError

func NewFunctionTemplateWithError(
	iso *Isolate,
	callback FunctionCallbackWithError,
) *FunctionTemplate

NewFunctionTemplateWithError creates a FunctionTemplate for a given callback. If the callback returns an error, it will be thrown as a JS error.

func (*FunctionTemplate) GetFunction

func (tmpl *FunctionTemplate) GetFunction(ctx *Context) *Function

GetFunction returns an instance of this function template bound to the given context.

func (*FunctionTemplate) Inherit

func (tmpl *FunctionTemplate) Inherit(base *FunctionTemplate)

func (*FunctionTemplate) InstanceTemplate

func (tmpl *FunctionTemplate) InstanceTemplate() *ObjectTemplate

InstanceTemplate gets the ObjectTemplate that is used for new object instances created when this function is used as a constructor.

You can add functions and values to new instance using ObjectTemplate.Set and ObjectTemplate.SetSymbol. Those values will become own properties on the instance, not the prototype.

Adding a function to an instance template corresponds to the following JavaScript:

class Example() {
	constructor() {
		this.foo = function() { /* creates a function on the instance */ }
	}
}

func (*FunctionTemplate) PrototypeTemplate

func (tmpl *FunctionTemplate) PrototypeTemplate() *ObjectTemplate

PrototypeTemplate gets the ObjectTemplate that is used to create the prototype object associated with the function.

You can call ObjectTemplate.Set or ObjectTemplate.SetSymbol, passing a FunctionTemplate to add a "method" to the class.

Adding a function to a prototype template corresponds normal method on a JavaScript "class":

class Example {
	foo() { /* this is a method on the prototype */ }
}

Or the old-school way

function Example() {}
Example.prototype.foo = function() { }

The function becomes an own property on the prototype, not the instance.

func (FunctionTemplate) Set

func (t FunctionTemplate) Set(name string, val interface{}, attributes ...PropertyAttribute) error

Set adds a property to each instance created by this template. The property must be defined either as a primitive value, or a template. If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a value will be created and set as the value property.

func (FunctionTemplate) SetSymbol

func (t FunctionTemplate) SetSymbol(key *Symbol, val interface{}, attributes ...PropertyAttribute) error

SetSymbol adds a property to each instance created by this template. The property must be defined either as a primitive value, or a template. If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a value will be created and set as the value property.

type HeapStatistics

type HeapStatistics struct {
	TotalHeapSize            uint64
	TotalHeapSizeExecutable  uint64
	TotalPhysicalSize        uint64
	TotalAvailableSize       uint64
	UsedHeapSize             uint64
	HeapSizeLimit            uint64
	MallocedMemory           uint64
	ExternalMemory           uint64
	PeakMallocedMemory       uint64
	NumberOfNativeContexts   uint64
	NumberOfDetachedContexts uint64
}

HeapStatistics represents V8 isolate heap statistics.

type Injector

type Injector interface {
	// Inject is called when the isolate is created and allows
	// for injecting a custom implementation to the isolate.
	Inject(*Isolate, *ObjectTemplate) error
}

Injector is an interface that allows for injecting a custom implementation to the v8go isolate.

type Inspector

type Inspector struct {
	// contains filtered or unexported fields
}

An Inspector in v8 provides access to internals of the engine, such as console output

To receive console output, you need to first create an InspectorClient which will handle the interaction for a specific Context.

After a Context is created, you need to register it with the Inspector using Inspector.ContextCreated, and cleanup using Inspector.ContextDestroyed.

See also: https://v8.github.io/api/head/classv8__inspector_1_1V8Inspector.html

func NewInspector

func NewInspector(iso *Isolate, client *InspectorClient) *Inspector

NewInspector creates an Inspector for a specific Isolate iso communicating with the InspectorClient client.

Before disposing the iso, be sure to dispose the inspector using Inspector.Dispose.

func (*Inspector) ContextCreated

func (i *Inspector) ContextCreated(ctx *Context)

ContextCreated tells the inspector that a new Context has been created. This must be called before the InspectorClient can be used.

func (*Inspector) ContextDestroyed

func (i *Inspector) ContextDestroyed(ctx *Context)

ContextDestroyed must be called before a Context is closed.

func (*Inspector) Dispose

func (i *Inspector) Dispose()

Dispose the Inspector. Call this before disposing the Isolate and the InspectorClient that this is connected to.

type InspectorClient

type InspectorClient struct {
	// contains filtered or unexported fields
}

An InspectorClient is the bridge from the Inspector to your code.

func NewInspectorClient

func NewInspectorClient(handler ConsoleAPIMessageHandler) *InspectorClient

Create a new InspectorClient passing a handler that will receive the callbacks from v8.

func (*InspectorClient) Dispose

func (c *InspectorClient) Dispose()

Dispose frees up resources taken up by the InspectorClient. Be sure to call this after calling Inspector.Dispose.

type Isolate

type Isolate struct {
	// contains filtered or unexported fields
}

Isolate is a JavaScript VM instance with its own heap and garbage collector. Most applications will create one isolate with many V8 contexts for execution.

func NewIsolate

func NewIsolate(opts ...IsolateOption) *Isolate

NewIsolate creates a new V8 isolate with the provided options. Only one thread may access a given isolate at a time, but different threads may access different isolates simultaneously. When an isolate is no longer used its resources should be freed by calling iso.Dispose(). An *Isolate can be used as a v8go.ContextOption to create a new Context, rather than creating a new default Isolate.

func (*Isolate) Close deprecated

func (i *Isolate) Close()

Deprecated: use `iso.Dispose()`.

func (*Isolate) CompileUnboundScript

func (i *Isolate) CompileUnboundScript(
	source, origin string,
	opts CompileOptions,
) (*UnboundScript, error)

CompileUnboundScript will create an UnboundScript (i.e. context-indepdent) using the provided source JavaScript, origin (a.k.a. filename), and options. If options contain a non-null CachedData, compilation of the script will use that code cache. error will be of type `JSError` if not nil.

func (*Isolate) Dispose

func (i *Isolate) Dispose()

Dispose will dispose the Isolate VM; subsequent calls will panic.

func (*Isolate) GetHeapStatistics

func (i *Isolate) GetHeapStatistics() HeapStatistics

GetHeapStatistics returns heap statistics for an isolate.

func (*Isolate) IsExecutionTerminating

func (i *Isolate) IsExecutionTerminating() bool

IsExecutionTerminating returns whether V8 is currently terminating Javascript execution. If true, there are still JavaScript frames on the stack and the termination exception is still active.

func (*Isolate) TerminateExecution

func (i *Isolate) TerminateExecution()

TerminateExecution terminates forcefully the current thread of JavaScript execution in the given isolate.

func (*Isolate) ThrowException

func (i *Isolate) ThrowException(value *Value) *Value

ThrowException schedules an exception to be thrown when returning to JavaScript. When an exception has been scheduled it is illegal to invoke any JavaScript operation; the caller must return immediately and only after the exception has been handled does it become legal to invoke JavaScript operations.

type IsolateOption

type IsolateOption func(*isolateConfig)

IsolateOption configures an Isolate on creation.

func WithResourceConstraints

func WithResourceConstraints(initialHeapSizeInBytes, maxHeapSizeInBytes uint64) IsolateOption

WithResourceConstraints sets memory constraints for the isolate. If constraints are set, v8go will try to call `TerminateExecution` when the hard limit is hit.

type JSError

type JSError struct {
	Message    string
	Location   string
	StackTrace string
}

JSError is an error that is returned if there is are any JavaScript exceptions handled in the context. When used with the fmt verb `%+v`, will output the JavaScript stack trace, if available.

func (*JSError) Error

func (e *JSError) Error() string

func (*JSError) Format

func (e *JSError) Format(s fmt.State, verb rune)

Format implements the fmt.Formatter interface to provide a custom formatter primarily to output the javascript stack trace with %+v.

type LocalRef

type LocalRef uint32

LocalRef identifies one value inside a BatchScope. It is an index into the scope's handle table, not a pointer, so it cannot dangle: closing the scope invalidates every ref at once. Refs from one scope are meaningless in another.

A builder that fails returns InvalidLocalRef instead of an error, and every method that consumes a ref propagates an invalid one rather than panicking. That lets a caller build an entire tree unchecked and find out at BatchScope.Result, which reports what actually went wrong.

type MessageErrorLevel

type MessageErrorLevel uint8

Represents the level of console output from JavaScript. E.g., `console.log`, `console.error`, etc.

The values reflect the values of v8::Isolate::MessageErrorLevel

See also: https://v8.github.io/api/head/classv8_1_1Isolate.html

const (
	ErrorLevelLog MessageErrorLevel = 1 << iota
	ErrorLevelDebug
	ErrorLevelInfo
	ErrorLevelError
	ErrorLevelWarning
	ErrorLevelAll = ErrorLevelLog | ErrorLevelDebug | ErrorLevelInfo | ErrorLevelError | ErrorLevelWarning
)

func (MessageErrorLevel) String

func (lvl MessageErrorLevel) String() string

type Object

type Object struct {
	*Value
}

Object is a JavaScript object (ECMA-262, 4.3.3).

Example (Global)
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	ctx := v8.NewContext(iso)
	defer ctx.Close()
	global := ctx.Global()

	console := v8.NewObjectTemplate(iso)
	logfn := v8.NewFunctionTemplate(iso, func(info *v8.FunctionCallbackInfo) *v8.Value {
		fmt.Println(info.Args()[0])
		return nil
	})
	console.Set("log", logfn)
	consoleObj, _ := console.NewInstance(ctx)

	global.Set("console", consoleObj)
	ctx.RunScript("console.log('foo')", "")
}
Output:
foo

func (*Object) Delete

func (o *Object) Delete(key string) bool

Delete returns true if successful in deleting a named property on the object.

func (*Object) DeleteIdx

func (o *Object) DeleteIdx(idx uint32) bool

DeleteIdx returns true if successful in deleting a value at a given index of the object.

func (*Object) DeleteSymbol

func (o *Object) DeleteSymbol(key *Symbol) bool

DeleteSymbol returns true if successful in deleting a named property on the object.

func (*Object) Get

func (o *Object) Get(key string) (*Value, error)

Get tries to get a Value for a given Object property key.

func (*Object) GetIdx

func (o *Object) GetIdx(idx uint32) (*Value, error)

GetIdx tries to get a Value at a give Object index.

func (*Object) GetInternalField

func (o *Object) GetInternalField(idx uint32) *Value

GetInternalField gets the Value set by SetInternalField for the given index or the JS undefined value if the index hadn't been set. Panics if given an out of range index, or the field contains a Data other than a Value.

func (*Object) GetSymbol

func (o *Object) GetSymbol(key *Symbol) (*Value, error)

GetSymbol tries to get a Value for a given Object property key.

func (*Object) Has

func (o *Object) Has(key string) bool

Has calls the abstract operation HasProperty(O, P) described in ECMA-262, 7.3.10. Returns true, if the object has the property, either own or on the prototype chain.

func (*Object) HasIdx

func (o *Object) HasIdx(idx uint32) bool

HasIdx returns true if the object has a value at the given index.

func (*Object) HasSymbol

func (o *Object) HasSymbol(key *Symbol) bool

HasSymbol calls the abstract operation HasProperty(O, P) described in ECMA-262, 7.3.10. Returns true, if the object has the property, either own or on the prototype chain.

func (*Object) InternalFieldCount

func (o *Object) InternalFieldCount() uint32

InternalFieldCount returns the number of internal fields this Object has.

func (*Object) MethodCall

func (o *Object) MethodCall(methodName string, args ...Valuer) (*Value, error)

func (*Object) Set

func (o *Object) Set(key string, val interface{}) error

Set will set a property on the Object to a given value. Supports all value types, eg: Object, Array, Date, Set, Map etc If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a *Value will be created and set as the value property.

func (*Object) SetIdx

func (o *Object) SetIdx(idx uint32, val interface{}) error

Set will set a given index on the Object to a given value. Supports all value types, eg: Object, Array, Date, Set, Map etc If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a *Value will be created and set as the value property.

func (*Object) SetInternalField

func (o *Object) SetInternalField(idx uint32, val interface{}) error

SetInternalField sets the value of an internal field for an ObjectTemplate instance. Panics if the index isn't in the range set by (*ObjectTemplate).SetInternalFieldCount.

func (*Object) SetSymbol

func (o *Object) SetSymbol(key *Symbol, val interface{}) error

SetSymbol will set a property on the Object to a given value. Supports all value types, eg: Object, Array, Date, Set, Map etc If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a *Value will be created and set as the value property.

type ObjectTemplate

type ObjectTemplate struct {
	// contains filtered or unexported fields
}

ObjectTemplate is used to create objects at runtime. Properties added to an ObjectTemplate are added to each object created from the ObjectTemplate.

func NewObjectTemplate

func NewObjectTemplate(iso *Isolate) *ObjectTemplate

NewObjectTemplate creates a new ObjectTemplate. The *ObjectTemplate can be used as a v8go.ContextOption to create a global object in a Context.

func (*ObjectTemplate) InternalFieldCount

func (o *ObjectTemplate) InternalFieldCount() uint32

InternalFieldCount returns the number of internal fields that instances of this template will have.

func (*ObjectTemplate) MarkAsUndetectable

func (o *ObjectTemplate) MarkAsUndetectable()

MarkAsUndetectable marks object instances of the template as undetectable. Undetectable objects behave like undefined, but you can access properties defined on undetectable objects.

Note: Undetectable objects MUST have a CallAsFunctionHandler, see ObjectTemplate.SetCallAsFunctionHandler.

func (*ObjectTemplate) NewInstance

func (o *ObjectTemplate) NewInstance(ctx *Context) (*Object, error)

NewInstance creates a new Object based on the template.

func (ObjectTemplate) Set

func (t ObjectTemplate) Set(name string, val interface{}, attributes ...PropertyAttribute) error

Set adds a property to each instance created by this template. The property must be defined either as a primitive value, or a template. If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a value will be created and set as the value property.

func (*ObjectTemplate) SetAccessorProperty

func (o *ObjectTemplate) SetAccessorProperty(
	key string,
	get *FunctionTemplate,
	set *FunctionTemplate,
	attributes PropertyAttribute,
)

SetAccessorProperty creates a named accessor property, i.e., a property that is implemented as a function call. Arguments get and set represents the getter and setter, and can both be nil.

Note: The ReadOnly should not be used with a readonly property. If set is nil, the property will be readonly, and passing None is a sensible default.

This corresponds to ObjectTemplate::SetAccessorProperty in the C++ API.

Example
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	tmpl := v8.NewObjectTemplate(iso)
	tmpl.SetAccessorProperty(
		"prop",
		// Getter
		v8.NewFunctionTemplateWithError(
			iso,
			func(*v8.FunctionCallbackInfo) (*v8.Value, error) {
				return v8.NewValue(iso, "Value")
			},
		),
		nil, // Setter
		v8.None,
	)

	global := v8.NewObjectTemplate(iso)
	global.Set("obj", tmpl)
	ctx := v8.NewContext(iso, global)
	defer ctx.Close()

	value, _ := ctx.RunScript("obj.prop", "")
	fmt.Printf("Property value: %s\n", value.String())
}
Output:
Property value: Value
Example (Helpers)
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

// SetObjectTemplateAccessorProperty shows an example of a helper that client
// code could optionally introduce.
//
// ObjectTemplate.SetAccessorProperty requires FunctionTemplate instances as
// arguments, but you rarely need the actual function template outside the
// scope of setting an accessor property.
//
// If many accessor properties must be created, this example could reduce
// repetitive trivial code.
func SetObjectTemplateAccessorProperty(
	iso *v8.Isolate,
	templ *v8.ObjectTemplate,
	key string,
	get v8.FunctionCallbackWithError,
	set v8.FunctionCallbackWithError,
	attributes v8.PropertyAttribute,
) {
	var (
		v8get *v8.FunctionTemplate
		v8set *v8.FunctionTemplate
	)
	if get != nil {
		v8get = v8.NewFunctionTemplateWithError(iso, get)
	}
	if set != nil {
		v8set = v8.NewFunctionTemplateWithError(iso, set)
	}
	templ.SetAccessorProperty(key, v8get, v8set, attributes)
}

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	tmpl := v8.NewObjectTemplate(iso)

	current, _ := v8.NewValue(iso, "current")
	SetObjectTemplateAccessorProperty(iso, tmpl,
		"prop",
		// Getter
		func(*v8.FunctionCallbackInfo) (*v8.Value, error) {
			return current, nil
		},
		// Setter
		func(info *v8.FunctionCallbackInfo) (*v8.Value, error) {
			current = info.Args()[0]
			return nil, nil
		},
		v8.None,
	)

	global := v8.NewObjectTemplate(iso)
	global.Set("obj", tmpl)
	ctx := v8.NewContext(iso, global)
	defer ctx.Close()

	value, _ := ctx.RunScript("obj.prop", "")
	fmt.Printf("Property value before set: %s\n", value.String())

	value, _ = ctx.RunScript("obj.prop = 'new value'; obj.prop", "")
	fmt.Printf("Property value after set: %s\n", value.String())

}
Output:
Property value before set: current
Property value after set: new value

func (*ObjectTemplate) SetCallAsFunctionHandler

func (o *ObjectTemplate) SetCallAsFunctionHandler(callback FunctionCallbackWithError)

SetCallAsFunctionHandler sets the callback to be used when calling instances created from this template. If no callback is set, instances behave like normal JavaScript objects that cannot be called as a function.

func (*ObjectTemplate) SetInternalFieldCount

func (o *ObjectTemplate) SetInternalFieldCount(fieldCount uint32)

SetInternalFieldCount sets the number of internal fields that instances of this template will have.

func (ObjectTemplate) SetSymbol

func (t ObjectTemplate) SetSymbol(key *Symbol, val interface{}, attributes ...PropertyAttribute) error

SetSymbol adds a property to each instance created by this template. The property must be defined either as a primitive value, or a template. If the value passed is a Go supported primitive (string, int32, uint32, int64, uint64, float64, big.Int) then a value will be created and set as the value property.

type Payload

type Payload struct {
	// Ops is the program. See [BuildValue].
	Ops []uint32
	// Shapes are the object shapes the program's OpObj operands index.
	Shapes []ShapeDef
	// Buf holds the bytes of every staged string and byte slice, concatenated.
	Buf []byte
	// Spans locates each string and byte-slice leaf.
	Spans []Span
	// KeySpans is how many leading entries of Spans are shape keys.
	KeySpans int
	// Ptrs holds the backing pointers of leaves that were pinned rather than
	// staged, indexed by a pinned Span's Off. Only the first len(Ptrs) entries
	// are read; a pooled backing array may hold anything past that. See
	// [BuildValue] for the pinning rule.
	Ptrs []unsafe.Pointer
	// Nums holds the int64 scalars, positionally. Booleans ride here as 0/1.
	Nums []int64
	// Floats holds the float64 scalars, positionally.
	Floats []float64
	// Counts holds the program's control-flow values in execution order: one
	// entry per OpRepeat executed, holding the length of that region, and one
	// per OpNullable or OpOptional executed, holding its present/absent flag.
	Counts []int32
}

Payload is the data half of a build: flat arrays the program indexes with implicitly advancing cursors, in the order a producer filled them.

Spans is one array with two regions. Spans[:KeySpans] are the shape keys and Spans[KeySpans:] are the values, so the value cursor starts at KeySpans; keys live in the same array to avoid a second buffer.

Nothing here is retained past the call: every leaf is copied into V8 while the call runs. See BuildValue for the pinning rule that applies to Ptrs.

type Promise

type Promise struct {
	*Object
}

Promise is the JavaScript promise object defined in ES6.

func (*Promise) Catch

func (p *Promise) Catch(cb FunctionCallback) *Promise

Catch invokes the given function if the promise is rejected. See Then for other details.

func (*Promise) CatchWithError

func (p *Promise) CatchWithError(cb FunctionCallbackWithError) *Promise

func (*Promise) Result

func (p *Promise) Result() *Value

Result is the value result of the Promise. The Promise must NOT be in a Pending state, otherwise may panic. Call promise.State() to validate state before calling for the result.

func (*Promise) State

func (p *Promise) State() PromiseState

State returns the current state of the Promise.

func (*Promise) Then

func (p *Promise) Then(cbs ...FunctionCallback) *Promise

Then accepts 1 or 2 callbacks. The first is invoked when the promise has been fulfilled. The second is invoked when the promise has been rejected. The returned Promise resolves after the callback finishes execution.

V8 only invokes the callback when processing "microtasks". The default MicrotaskPolicy processes them when the call depth decreases to 0. Call (*Context).PerformMicrotaskCheckpoint to trigger it manually.

func (*Promise) ThenWithError

func (p *Promise) ThenWithError(cbs ...FunctionCallbackWithError) *Promise

type PromiseResolver

type PromiseResolver struct {
	*Object
	// contains filtered or unexported fields
}

PromiseResolver is the resolver object for the promise. Most cases will create a new PromiseResolver and return the associated Promise from the resolver.

func NewPromiseResolver

func NewPromiseResolver(ctx *Context) (*PromiseResolver, error)

NewPromiseResolver creates a new Promise resolver for the given context. The associated Promise will be in a Pending state.

func (*PromiseResolver) GetPromise

func (r *PromiseResolver) GetPromise() *Promise

GetPromise returns the associated Promise object for this resolver. The Promise object is unique to the resolver and returns the same object on multiple calls.

func (*PromiseResolver) Reject

func (r *PromiseResolver) Reject(err *Value) bool

Reject invokes the Promise reject state with the given value. The Promise state will transition from Pending to Rejected.

func (*PromiseResolver) Resolve

func (r *PromiseResolver) Resolve(val Valuer) bool

Resolve invokes the Promise resolve state with the given value. The Promise state will transition from Pending to Fulfilled.

type PromiseState

type PromiseState int

PromiseState is the state of the Promise.

const (
	Pending PromiseState = iota
	Fulfilled
	Rejected
)

type PropertyAttribute

type PropertyAttribute uint8

PropertyAttribute are the attribute flags for a property on an Object. Typical usage when setting an Object or TemplateObject property, and can also be validated when accessing a property.

const (
	// None.
	None PropertyAttribute = 0
	// ReadOnly, ie. not writable.
	ReadOnly PropertyAttribute = 1 << iota
	// DontEnum, ie. not enumerable.
	DontEnum
	// DontDelete, ie. not configurable.
	DontDelete
)

type ShapeDef

type ShapeDef struct {
	First uint32
	N     uint32
}

ShapeDef names one object shape as a run of key spans: its keys are Payload.Spans[First : First+N], which must lie inside the key region.

type ShapeRef

type ShapeRef uint32

ShapeRef identifies one interned key set inside a BatchScope. See BatchScope.Shape.

type Span

type Span struct {
	Off  uint32
	Len  uint32
	Kind uint32
	// contains filtered or unexported fields
}

Span locates one string or byte-slice leaf, either in Payload.Buf or through Payload.Ptrs. See SpanStaged and SpanPinned.

The layout is part of the ABI — 16 bytes, fields at offsets 0, 4 and 8 — because a producer may write these as a flat array without going through this type.

type Symbol

type Symbol struct {
	*Value
}

A Symbol represents a JavaScript symbol (ECMA-262 edition 6).

func SymbolAsyncIterator

func SymbolAsyncIterator(
	iso *Isolate,
) *Symbol

func SymbolHasInstance

func SymbolHasInstance(iso *Isolate) *Symbol

func SymbolIsConcatSpreadable

func SymbolIsConcatSpreadable(iso *Isolate) *Symbol

func SymbolIterator

func SymbolIterator(iso *Isolate) *Symbol

func SymbolMatch

func SymbolMatch(iso *Isolate) *Symbol

func SymbolReplace

func SymbolReplace(iso *Isolate) *Symbol

func SymbolSearch

func SymbolSearch(iso *Isolate) *Symbol

func SymbolSplit

func SymbolSplit(iso *Isolate) *Symbol

func SymbolToPrimitive

func SymbolToPrimitive(iso *Isolate) *Symbol

func SymbolToStringTag

func SymbolToStringTag(iso *Isolate) *Symbol

func SymbolUnscopables

func SymbolUnscopables(iso *Isolate) *Symbol

func (*Symbol) Description

func (sym *Symbol) Description() string

Description returns the string representation of the symbol, e.g. "Symbol.asyncIterator".

func (*Symbol) String

func (sym *Symbol) String() string

String returns Description().

type UnboundScript

type UnboundScript struct {
	// contains filtered or unexported fields
}

func (*UnboundScript) CreateCodeCache

func (u *UnboundScript) CreateCodeCache() *CompilerCachedData

Create a code cache from the unbound script.

func (*UnboundScript) Run

func (u *UnboundScript) Run(ctx *Context) (*Value, error)

Run will bind the unbound script to the provided context and run it. If the context provided does not belong to the same isolate that the script was compiled in, Run will panic. If an error occurs, it will be of type `JSError`.

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value represents all Javascript values and objects.

func BuildValue

func BuildValue(ctx *Context, p *Payload) (val *Value, err error)

BuildValue constructs a whole JavaScript value tree in a single cgo crossing and returns its root, owned by ctx the way any other v8go value is.

A program, not a serialization. p.Ops is a stack machine's instruction stream, and it encodes the shape of the data rather than the data itself: OpRepeat runs a body n times, so a marshaller that knows the Go type emits the loop as a loop. A []struct{ID int64; Name, Email string} is seven ops whether it holds one row or a million:

OpMark
OpRepeat, 4     // n comes from Counts
  OpInt         // from Nums
  OpStr         // from Spans
  OpStr
  OpObj, shape  // pops 3, pushes the object
OpArrFromMark
OpEnd

That is what makes this cheap. The alternative — a cgo call per node — costs ~64-84ns a time, so a 20-column, 1000-row result set spends over a millisecond on boundary crossings alone, more than JSON.parse needs to build the same tree from scratch. Here the per-node cost is a C switch dispatch, about 2ns.

Exactly one tracked value is created, for the root; every interior node lives and dies as a v8::Local inside the call.

It is safe to call from inside a FunctionTemplate callback, which is the shape the builder exists for: the host native receives a call from JS and answers it with a value rather than with JSON. V8 is already entered there — locked, in a HandleScope, in a Context::Scope, with a call in flight — and nesting another set of those is fine. What is NOT fine there is panicking: a Go panic unwinds out through V8's C++ frames without running their destructors, so the isolate is left entered and the process aborts at the next Isolate::Dispose, reported as a teardown fault far from its cause. BuildValue therefore reports everything, including a recovered panic, as an error.

Pinning. Everything in p is read, and copied into V8, during the call, and none of it is retained. The one caller obligation is p.Ptrs: each entry that the spans actually reference must point either to non-Go memory or to a Go object the caller has pinned with a runtime.Pinner that outlives the call. Only the first len(p.Ptrs) entries are read, and the addresses cross as addresses — a pooled backing array may hold whatever it likes in the slots past len.

A malformed program is an error, never a crash: every index is checked against its array before it is used, and a failure builds nothing.

func JSONParse

func JSONParse(ctx *Context, str string) (*Value, error)

JSONParse tries to parse the string and returns it as *Value if successful. Any JS errors will be returned as `JSError`.

Example
package main

import (
	"fmt"

	v8 "github.com/hlvs-apps/v8go"
)

func main() {
	ctx := v8.NewContext()
	defer ctx.Isolate().Dispose()
	defer ctx.Close()
	val, _ := v8.JSONParse(ctx, `{"foo": "bar"}`)
	fmt.Println(val)
}
Output:
[object Object]

func NewValue

func NewValue(iso *Isolate, val interface{}) (*Value, error)

NewValue will create a primitive value. Supported values types to create are:

string -> V8::String
int32 -> V8::Integer
uint32 -> V8::Integer
int64 -> V8::BigInt
uint64 -> V8::BigInt
bool -> V8::Boolean
*big.Int -> V8::BigInt

func Null

func Null(iso *Isolate) *Value

Null returns the `null` JS value.

func Undefined

func Undefined(iso *Isolate) *Value

Undefined returns the `undefined` JS value.

func (*Value) ArrayBufferViewBytes

func (v *Value) ArrayBufferViewBytes() []byte

ArrayBufferViewBytes copies the bytes viewed by this value into a new, Go-owned byte slice and returns it. The value must be an ArrayBufferView — for example a Uint8Array, any other typed array, or a DataView. If it is not, ArrayBufferViewBytes returns nil.

Unlike SharedArrayBufferGetContents, the returned slice is an independent copy that does not alias V8-managed memory: it stays valid after the value (or its context) is released and needs no cleanup. It performs a single memcpy out of V8 and is binary-safe — every byte value round-trips exactly.

func (*Value) ArrayIndex

func (v *Value) ArrayIndex() (idx uint32, ok bool)

ArrayIndex attempts to converts a string to an array index. Returns ok false if conversion fails.

func (*Value) AsException

func (v *Value) AsException() (*Exception, error)

func (*Value) AsFunction

func (v *Value) AsFunction() (*Function, error)

func (*Value) AsObject

func (v *Value) AsObject() (*Object, error)

AsObject will cast the value to the Object type. If the value is not an Object then an error is returned. Use `value.Object()` to do the JS equivalent of `Object(value)`.

func (*Value) AsPromise

func (v *Value) AsPromise() (*Promise, error)

func (*Value) AsSymbol

func (v *Value) AsSymbol() (*Symbol, error)

AsSymbol will cast the value to the Symbol type. If the value is not a Symbol then an error is returned.

func (*Value) BigInt

func (v *Value) BigInt() *big.Int

BigInt perform the equivalent of `BigInt(value)` in JS.

func (*Value) Boolean

func (v *Value) Boolean() bool

Boolean perform the equivalent of `Boolean(value)` in JS. This can never fail.

func (*Value) DetailString

func (v *Value) DetailString() string

DetailString provide a string representation of this value usable for debugging.

func (*Value) Format

func (v *Value) Format(s fmt.State, verb rune)

Format implements the fmt.Formatter interface to provide a custom formatter primarily to output the detail string (for debugging) with `%+v` verb.

func (*Value) Int32

func (v *Value) Int32() int32

Int32 perform the equivalent of `Number(value)` in JS and convert the result to a signed 32-bit integer by performing the steps in https://tc39.es/ecma262/#sec-toint32.

func (*Value) Integer

func (v *Value) Integer() int64

Integer perform the equivalent of `Number(value)` in JS and convert the result to an integer. Negative values are rounded up, positive values are rounded down. NaN is converted to 0. Infinite values yield undefined results.

func (*Value) IsArgumentsObject

func (v *Value) IsArgumentsObject() bool

IsArgumentsObject returns true if this value is an Arguments object.

func (*Value) IsArray

func (v *Value) IsArray() bool

IsArray returns true if this value is an array. Note that it will return false for a `Proxy` of an array.

func (*Value) IsArrayBuffer

func (v *Value) IsArrayBuffer() bool

IsArrayBuffer returns true if this value is an `ArrayBuffer`.

func (*Value) IsArrayBufferView

func (v *Value) IsArrayBufferView() bool

IsArrayBufferView returns true if this value is an `ArrayBufferView`.

func (*Value) IsAsyncFunction

func (v *Value) IsAsyncFunction() bool

IsAsyncFunc returns true if this value is an async function.

func (*Value) IsBigInt

func (v *Value) IsBigInt() bool

IsBigInt returns true if this value is a bigint. This is equivalent to `typeof value === 'bigint'` in JS.

func (*Value) IsBigInt64Array

func (v *Value) IsBigInt64Array() bool

IsBigInt64Array returns true if this value is a `BigInt64Array`.

func (*Value) IsBigIntObject

func (v *Value) IsBigIntObject() bool

IsBigIntObject returns true if this value is a BigInt object.

func (*Value) IsBigUint64Array

func (v *Value) IsBigUint64Array() bool

IsBigUint64Array returns true if this value is a BigUint64Array`.

func (*Value) IsBoolean

func (v *Value) IsBoolean() bool

IsBoolean returns true if this value is boolean. This is equivalent to `typeof value === 'boolean'` in JS.

func (*Value) IsDataView

func (v *Value) IsDataView() bool

IsDataView returns true if this value is a `DataView`.

func (*Value) IsDate

func (v *Value) IsDate() bool

IsDate returns true if this value is a `Date`.

func (*Value) IsExternal

func (v *Value) IsExternal() bool

IsExternal returns true if this value is an `External` object.

func (*Value) IsFalse

func (v *Value) IsFalse() bool

IsFalse returns true if this value is false. This is not the same as `!BooleanValue()`. The latter performs a conversion to boolean, i.e. the result of `!Boolean(value)` in JS, whereas this checks `value === false`.

func (*Value) IsFloat32Array

func (v *Value) IsFloat32Array() bool

IsFloat32Array returns true if this value is a `Float32Array`.

func (*Value) IsFloat64Array

func (v *Value) IsFloat64Array() bool

IsFloat64Array returns true if this value is a `Float64Array`.

func (*Value) IsFunction

func (v *Value) IsFunction() bool

IsFunction returns true if this value is a function. This is equivalent to `typeof value === 'function'` in JS.

func (*Value) IsGeneratorFunction

func (v *Value) IsGeneratorFunction() bool

Is IsGeneratorFunc returns true if this value is a Generator function.

func (*Value) IsGeneratorObject

func (v *Value) IsGeneratorObject() bool

IsGeneratorObject returns true if this value is a Generator object (iterator).

func (*Value) IsInt8Array

func (v *Value) IsInt8Array() bool

IsInt8Array returns true if this value is an `Int8Array`.

func (*Value) IsInt16Array

func (v *Value) IsInt16Array() bool

IsInt16Array returns true if this value is an `Int16Array`.

func (*Value) IsInt32

func (v *Value) IsInt32() bool

IsInt32 returns true if this value is a 32-bit signed integer.

func (*Value) IsInt32Array

func (v *Value) IsInt32Array() bool

IsInt32Array returns true if this value is an `Int32Array`.

func (*Value) IsMap

func (v *Value) IsMap() bool

IsMap returns true if this value is a `Map`.

func (*Value) IsMapIterator

func (v *Value) IsMapIterator() bool

IsMapIterator returns true if this value is a `Map` Iterator.

func (*Value) IsModuleNamespaceObject

func (v *Value) IsModuleNamespaceObject() bool

IsModuleNamespaceObject returns true if the value is a `Module` Namespace `Object`.

func (*Value) IsName

func (v *Value) IsName() bool

IsName returns true if this value is a symbol or a string. This is equivalent to `typeof value === 'string' || typeof value === 'symbol'` in JS.

func (*Value) IsNativeError

func (v *Value) IsNativeError() bool

IsNativeError returns true if this value is a NativeError.

func (*Value) IsNull

func (v *Value) IsNull() bool

IsNull returns true if this value is the null value. See ECMA-262 4.3.11.

func (*Value) IsNullOrUndefined

func (v *Value) IsNullOrUndefined() bool

IsNullOrUndefined returns true if this value is either the null or the undefined value. See ECMA-262 4.3.11. and 4.3.12 This is equivalent to `value == null` in JS.

func (*Value) IsNumber

func (v *Value) IsNumber() bool

IsNumber returns true if this value is a number. This is equivalent to `typeof value === 'number'` in JS.

func (*Value) IsNumberObject

func (v *Value) IsNumberObject() bool

IsNumberObject returns true if this value is a `Number` object.

func (*Value) IsObject

func (v *Value) IsObject() bool

IsObject returns true if this value is an object.

func (*Value) IsPromise

func (v *Value) IsPromise() bool

IsPromise returns true if this value is a `Promise`.

func (*Value) IsProxy

func (v *Value) IsProxy() bool

IsProxy returns true if this value is a JavaScript `Proxy`.

func (*Value) IsRegExp

func (v *Value) IsRegExp() bool

IsRegExp returns true if this value is a `RegExp`.

func (*Value) IsSet

func (v *Value) IsSet() bool

IsSet returns true if this value is a `Set`.

func (*Value) IsSetIterator

func (v *Value) IsSetIterator() bool

IsSetIterator returns true if this value is a `Set` Iterator.

func (*Value) IsSharedArrayBuffer

func (v *Value) IsSharedArrayBuffer() bool

IsSharedArrayBuffer returns true if this value is a `SharedArrayBuffer`.

func (*Value) IsString

func (v *Value) IsString() bool

IsString returns true if this value is an instance of the String type. See ECMA-262 8.4. This is equivalent to `typeof value === 'string'` in JS.

func (*Value) IsStringObject

func (v *Value) IsStringObject() bool

IsStringObject returns true if this value is a `String` object.

func (*Value) IsSymbol

func (v *Value) IsSymbol() bool

IsSymbol returns true if this value is a symbol. This is equivalent to `typeof value === 'symbol'` in JS.

func (*Value) IsSymbolObject

func (v *Value) IsSymbolObject() bool

IsSymbolObject returns true if this value is a `Symbol` object.

func (*Value) IsTrue

func (v *Value) IsTrue() bool

IsTrue returns true if this value is true. This is not the same as `BooleanValue()`. The latter performs a conversion to boolean, i.e. the result of `Boolean(value)` in JS, whereas this checks `value === true`.

func (*Value) IsTypedArray

func (v *Value) IsTypedArray() bool

IsTypedArray returns true if this value is one of TypedArrays.

func (*Value) IsUint8Array

func (v *Value) IsUint8Array() bool

IsUint8Array returns true if this value is an `Uint8Array`.

func (*Value) IsUint8ClampedArray

func (v *Value) IsUint8ClampedArray() bool

IsUint8ClampedArray returns true if this value is an `Uint8ClampedArray`.

func (*Value) IsUint16Array

func (v *Value) IsUint16Array() bool

IsUint16Array returns true if this value is an `Uint16Array`.

func (*Value) IsUint32

func (v *Value) IsUint32() bool

IsUint32 returns true if this value is a 32-bit unsigned integer.

func (*Value) IsUint32Array

func (v *Value) IsUint32Array() bool

IsUint32Array returns true if this value is an `Uint32Array`.

func (*Value) IsUndefined

func (v *Value) IsUndefined() bool

IsUndefined returns true if this value is the undefined value. See ECMA-262 4.3.10.

func (*Value) IsWasmModuleObject

func (v *Value) IsWasmModuleObject() bool

IsWasmModuleObject returns true if this value is a `WasmModuleObject`.

func (*Value) IsWeakMap

func (v *Value) IsWeakMap() bool

IsWeakMap returns true if this value is a `WeakMap`.

func (*Value) IsWeakSet

func (v *Value) IsWeakSet() bool

IsWeakSet returns true if this value is a `WeakSet`.

func (*Value) MarshalJSON

func (v *Value) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface.

func (*Value) Number

func (v *Value) Number() float64

Number perform the equivalent of `Number(value)` in JS.

func (*Value) Object

func (v *Value) Object() *Object

Object perform the equivalent of Object(value) in JS. To just cast this value as an Object use AsObject() instead.

func (*Value) Release

func (v *Value) Release()

Release this value. Using the value after calling this function will result in undefined behavior.

func (*Value) SameValue

func (v *Value) SameValue(other *Value) bool

SameValue returns true if the other value is the same value. This is equivalent to `Object.is(v, other)` in JS.

func (*Value) SharedArrayBufferGetContents

func (v *Value) SharedArrayBufferGetContents() ([]byte, func(), error)

func (*Value) StrictEquals

func (v *Value) StrictEquals(other *Value) bool

func (*Value) String

func (v *Value) String() string

String perform the equivalent of `String(value)` in JS. Primitive values are returned as-is, objects will return `[object Object]` and functions will print their definition.

func (*Value) TypeOf

func (v *Value) TypeOf() string

func (*Value) Uint32

func (v *Value) Uint32() uint32

Uint32 perform the equivalent of `Number(value)` in JS and convert the result to an unsigned 32-bit integer by performing the steps in https://tc39.es/ecma262/#sec-touint32.

type ValueError

type ValueError interface {
	error
	Valuer
}

A ValueError can be returned from a FunctionCallbackWithError, and its value will be thrown as an exception in V8.

type Valuer

type Valuer interface {
	// contains filtered or unexported methods
}

Valuer is an interface that reperesents anything that extends from a Value eg. Object, Array, Date etc.

Directories

Path Synopsis
deps
darwin_amd64 module
darwin_arm64 module
linux_amd64 module
linux_arm64 module
windows_amd64 module
windows_arm64 module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL