All Projects → rogchap → V8go

rogchap / V8go

Licence: bsd-3-clause
Execute JavaScript from Go

Programming Languages

javascript
184084 projects - #8 most used programming language
go
31211 projects - #10 most used programming language
golang
3204 projects

Labels

Projects that are alternatives of or similar to V8go

Memeye
👀 The eye of memory. A lightweight memory monitor and dashboard for Node.js application on development.
Stars: ✭ 332 (-72.45%)
Mutual labels:  v8
Liquidcore
Node.js virtual machine for Android and iOS
Stars: ✭ 765 (-36.51%)
Mutual labels:  v8
Bytenode
A minimalist bytecode compiler for Node.js
Stars: ✭ 1,012 (-16.02%)
Mutual labels:  v8
Javascript Idiosyncrasies
A bunch of Javascript idiosyncrasies to beginners.
Stars: ✭ 353 (-70.71%)
Mutual labels:  v8
Type Profile
Collect runtime type information 😻 of your JavaScript code.
Stars: ✭ 518 (-57.01%)
Mutual labels:  v8
V8 Bailout Reasons
🔧 A list of Crankshaft bailout reasons with examples
Stars: ✭ 861 (-28.55%)
Mutual labels:  v8
V8.js.cn
V8 官方网站中文翻译
Stars: ✭ 308 (-74.44%)
Mutual labels:  v8
Puerts
Write your game with TypeScript in UE4 or Unity. Puerts can be read as pu-erh TS(普洱TS)
Stars: ✭ 1,139 (-5.48%)
Mutual labels:  v8
V8.dev
The source code of v8.dev, the official website of the V8 project.
Stars: ✭ 567 (-52.95%)
Mutual labels:  v8
Rust V8worker2
Minimal Rust binding to V8 (based on ry/libv8worker2)
Stars: ✭ 33 (-97.26%)
Mutual labels:  v8
Deep Into Node
深入理解Node.js:核心思想与源码分析
Stars: ✭ 4,005 (+232.37%)
Mutual labels:  v8
React Native V8
Opt-in V8 runtime for React Native Android
Stars: ✭ 514 (-57.34%)
Mutual labels:  v8
Monomorphist
monomorphist - a JavaScript performance companion
Stars: ✭ 30 (-97.51%)
Mutual labels:  v8
V8eval
Multi-language bindings to JavaScript engine V8
Stars: ✭ 332 (-72.45%)
Mutual labels:  v8
V8 Source Read
V8 探秘
Stars: ✭ 43 (-96.43%)
Mutual labels:  v8
Jk
Configuration as Code with ECMAScript
Stars: ✭ 322 (-73.28%)
Mutual labels:  v8
Cef4delphi
CEF4Delphi is an open source project to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC for Windows, Linux and MacOS.
Stars: ✭ 785 (-34.85%)
Mutual labels:  v8
Deep Into Code
Node.js / Libuv / V8 引擎源代码学习笔记
Stars: ✭ 66 (-94.52%)
Mutual labels:  v8
V8 Javascript Memory
V8 JavaScript 内存占用分析
Stars: ✭ 46 (-96.18%)
Mutual labels:  v8
V8 Cffi
Embed the V8 Javascript Interpreter into Python
Stars: ✭ 31 (-97.43%)
Mutual labels:  v8

Execute JavaScript from Go

Github release Go Report Card Go Reference CI V8 Build codecov FOSSA Status #v8go Slack Channel

V8 Gopher based on original artwork from the amazing Renee French

Usage

import "rogchap.com/v8go"

Running a script

ctx, _ := v8go.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, _ := v8go.NewIsolate() // creates a new JavaScript VM
ctx1, _ := v8go.NewContext(iso) // new context within the VM
ctx1.RunScript("const multiply = (a, b) => a * b", "math.js")

ctx2, _ := v8go.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, _ := v8go.NewIsolate() // create a new VM
// a template that represents a JS function
printfn, _ := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.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, _ := v8go.NewObjectTemplate(iso) // a template that represents a JS Object
global.Set("print", printfn) // sets the "print" property of the Object to our function
ctx, _ := v8go.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, _ := v8go.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 {
  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
}

Terminate long running scripts

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
}

Documentation

Go Reference & more examples: https://pkg.go.dev/rogchap.com/v8go

Support

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!

Windows

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:

  1. Install MSYS2 (https://www.msys2.org/)
  2. Add the Mingw-w64 bin to your PATH environment variable (C:\msys64\mingw64\bin by default)
  3. Open MSYS2 MSYS and execute pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-v8
  4. This will allow building projects that depend on v8go, but, in order to actually run them, you will need to copy the snapshot_blob.bin file from the Mingw-w64 bin folder to your program's working directory (which is typically wherever main.go is)

V8 requires 64-bit on Windows, therefore will not work on 32-bit systems.

V8 dependency

V8 version: 8.9.255.20 (March 2021)

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.

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.

License

FOSSA Status

Development

Upgrading the V8 binaries

This process is non-trivial, and hopefully we can automate more of this in the future.

  1. Make sure to clone the projects submodules (ie. the V8's depot_tools project): git submodule update --init --recursive
  2. Add the depot_tools folder to your PATH eg: export PATH=~/Development/rogchap/v8go/deps/depot_tools:$PATH
  3. From the deps folder run fetch v8; you only need to do this once, if you don't already have the V8 source.
  4. Find the current stable release (v8_version) here: https://omahaproxy.appspot.com
  5. Create a new git branch from master eg. git checkout -b v8_7_upgrade
  6. Enter the v8 folder and fetch all the latest git branches: cd deps/v8 && git fetch
  7. Find the right branch-heads/** to checkout, for example if the v8_version is 8.7.220.31 then you want to git checkout branch-heads/8.7. You can check all the branch-heads with git branch --remotes | grep branch-heads/
  8. Copy all the contents of deps/v8/include to deps/include making sure not to delete any of the vendor.go files, which are required for users that are using go mod vendor. If there are any new folders added, make sure to create new vendor.go files in each folder within deps/include and update cgo.go.
  9. 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 via go test -v .
  10. 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.
  11. 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.
  12. 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 against master with the latest version of V8.

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.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].