-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6b4ccc3
Showing
32 changed files
with
5,743 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Compiled Object files, Static and Dynamic libs (Shared Objects) | ||
*.o | ||
*.a | ||
*.so | ||
|
||
# Folders | ||
_obj | ||
_test | ||
|
||
# Architecture specific extensions/prefixes | ||
*.[568vq] | ||
[568vq].out | ||
|
||
*.cgo1.go | ||
*.cgo2.c | ||
_cgo_defun.c | ||
_cgo_gotypes.go | ||
_cgo_export.* | ||
|
||
_testmain.go | ||
|
||
*.exe | ||
*.test | ||
*.prof | ||
include | ||
libv8 | ||
v8/build/.gclient | ||
v8/build/.gclient_entries |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# The default build environment is Ubuntu 12.04 (very old!) which doesn't | ||
# support c++11, which we need for our bindings. Instead, use the newer trusty | ||
# (14.04) distribution. | ||
sudo: required | ||
dist: trusty | ||
|
||
language: go | ||
go: | ||
- "1.10.x" | ||
- "1.9" | ||
|
||
# Indicate which versions of v8 to run the test suite against. | ||
env: | ||
- V8_VERSION=6.3.292.48.1 | ||
# Anything before 6.3 will break because of new ldflags definitions. | ||
# - V8_VERSION=6.2.414.42.1 | ||
# - V8_VERSION=6.0.286.54.3 | ||
|
||
go_import_path: github.com/augustoroman/v8 | ||
|
||
# Need to download & compile v8 libraries before running the tests. | ||
install: ./travis-install-linux.sh | ||
|
||
notifications: | ||
email: | ||
on_failure: change |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
ARG V8_VERSION | ||
ARG V8_SOURCE_IMAGE=augustoroman/v8-lib | ||
|
||
# ------------ Import the v8 libraries -------------------------------------- | ||
# The v8 library & include files are taken from a pre-built docker image that | ||
# is expected to be called v8-lib. You can build that locally using: | ||
# docker build --build-arg V8_VERSION=6.7.77 --tag augustoroman/v8-lib:6.7.77 docker-v8-lib/ | ||
# or you can use a previously built image from: | ||
# https://hub.docker.com/r/augustoroman/v8-lib/ | ||
# | ||
# Once that is available, build this docker image using: | ||
# docker build --build-arg V8_VERSION=6.7.77 -t v8-runjs . | ||
# and then run the interactive js using: | ||
# docker run -it --rm v8-runjs | ||
FROM ${V8_SOURCE_IMAGE}:${V8_VERSION} as v8 | ||
|
||
# ------------ Build go v8 library and run tests ---------------------------- | ||
FROM golang as builder | ||
# Copy the v8 code from the local disk, similar to: | ||
# RUN go get github.com/augustoroman/v8 ||: | ||
# but this allows using any local modifications. | ||
ARG GO_V8_DIR=/go/src/github.com/augustoroman/v8/ | ||
ADD *.go *.h *.cc $GO_V8_DIR | ||
ADD cmd $GO_V8_DIR/cmd/ | ||
ADD v8console $GO_V8_DIR/v8console/ | ||
|
||
# Copy the pre-compiled library & include files for the desired v8 version. | ||
COPY --from=v8 /v8/lib $GO_V8_DIR/libv8/ | ||
COPY --from=v8 /v8/include $GO_V8_DIR/include/ | ||
|
||
# Install the go code and run tests. | ||
WORKDIR $GO_V8_DIR | ||
RUN go get ./... | ||
RUN go test ./... | ||
|
||
# ------------ Build the final container for v8-runjs ----------------------- | ||
# TODO(aroman) find a smaller container for the executable! For some reason, | ||
# scratch, alpine, and busybox don't work. I wonder if it has something to do | ||
# with cgo? | ||
FROM ubuntu:16.04 | ||
COPY --from=builder /go/bin/v8-runjs /v8-runjs | ||
CMD /v8-runjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2020 jviksne | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# V8 Bindings for Go [![Build Status](https://travis-ci.org/augustoroman/v8.svg?branch=master)](https://travis-ci.org/augustoroman/v8) [![Go Report Card](https://goreportcard.com/badge/github.com/augustoroman/v8)](https://goreportcard.com/report/github.com/augustoroman/v8) [![GoDoc](https://godoc.org/github.com/augustoroman/v8?status.svg)](https://godoc.org/github.com/augustoroman/v8) | ||
|
||
The v8 bindings allow a user to execute javascript from within a go executable. | ||
|
||
The bindings are tested to work with several recent v8 builds matching the | ||
Chrome builds 54 - 60 (see the .travis.yml file for specific versions). For | ||
example, Chrome 59 (dev branch) uses v8 5.9.211.4 when this was written. | ||
|
||
Note that v8 releases match the Chrome release timeline: | ||
Chrome 48 corresponds to v8 4.8.\*, Chrome 49 matches v8 4.9.\*. You can see | ||
the table of current chrome and the associated v8 releases at: | ||
|
||
http://omahaproxy.appspot.com/ | ||
|
||
# Using a pre-compiled v8 | ||
|
||
v8 is very slow to compile, it's a large project. If you want to go that route, there are building instructions below. | ||
|
||
Fortunately, there's a project that pre-builds v8 for various platforms. It's packaged as a ruby gem called [libv8](https://rubygems.org/gems/libv8). | ||
|
||
```bash | ||
# Find the appropriate gem version for your OS, | ||
# visit: https://rubygems.org/gems/libv8/versions | ||
|
||
# Download the gem | ||
# MacOS Sierra is darwin-16, for v8 6.3.292.48.1 it looks like: | ||
curl https://rubygems.org/downloads/libv8-6.3.292.48.1-x86_64-darwin-16.gem > libv8.gem | ||
|
||
# Extract the gem (it's a tarball) | ||
tar -xf libv8.gem | ||
|
||
# Extract the `data.tar.gz` within | ||
cd libv8-6.3.292.48.1-x86_64-darwin-16 | ||
tar -xzf data.tar.gz | ||
|
||
# Symlink the compiled libraries and includes | ||
ln -s $(pwd)/data/vendor/v8/include $GOPATH/src/github.com/augustoroman/v8/include | ||
ln -s $(pwd)/data/vendor/v8/out/x64.release $GOPATH/src/github.com/augustoroman/v8/libv8 | ||
|
||
# Run the tests to make sure everything works | ||
cd $GOPATH/src/github.com/augustoroman/v8 | ||
go test | ||
``` | ||
|
||
# Using docker (linux only) | ||
|
||
For linux builds, you can use pre-built libraries or build your own. | ||
|
||
## Pre-built versions | ||
|
||
To use a pre-built library, select the desired v8 version from https://hub.docker.com/r/augustoroman/v8-lib/tags/ and then run: | ||
|
||
```bash | ||
# Select the v8 version to use: | ||
export V8_VERSION=6.7.77 | ||
docker pull augustoroman/v8-lib:$V8_VERSION # Download the image, updating if necessary. | ||
docker rm v8 ||: # Cleanup from before if necessary. | ||
docker run --name v8 augustoroman/v8-lib:$V8_VERSION # Run the image to provide access to the files. | ||
docker cp v8:/v8/include include/ # Copy the include files. | ||
docker cp v8:/v8/lib libv8/ # Copy the library fiels. | ||
``` | ||
|
||
## Build your own via docker | ||
|
||
This takes a lot longer, but is still easy: | ||
|
||
```bash | ||
export V8_VERSION=6.7.77 | ||
docker build --build-arg V8_VERSION=$V8_VERSION --tag augustoroman/v8-lib:$V8_VERSION docker-v8-lib/ | ||
``` | ||
|
||
and then extract the files as above: | ||
|
||
```bash | ||
docker rm v8 ||: # Cleanup from before if necessary. | ||
docker run --name v8 augustoroman/v8-lib:$V8_VERSION # Run the image to provide access to the files. | ||
docker cp v8:/v8/include include/ # Copy the include files. | ||
docker cp v8:/v8/lib libv8/ # Copy the library fiels. | ||
``` | ||
|
||
# Building v8 | ||
|
||
## Prep | ||
|
||
You need to build v8 statically and place it in a location cgo knows about. This requires special tooling and a build directory. Using the [official instructions](https://github.com/v8/v8/wiki/Building-from-Source) as a guide, the general steps of this process are: | ||
|
||
1. `go get` the binding library (this library) | ||
1. Create a v8 build directory | ||
1. [Install depot tools](http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up) | ||
1. Configure environment | ||
1. Download v8 | ||
1. Build v8 | ||
1. Copy or symlink files to the go library path | ||
1. Build the bindings | ||
|
||
``` | ||
go get github.com/augustoroman/v8 | ||
export V8_GO=$GOPATH/src/github.com/augustoroman/v8 | ||
export V8_BUILD=$V8_GO/v8/build #or wherever you like | ||
mkdir -p $V8_BUILD | ||
cd $V8_BUILD | ||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git | ||
export PATH=$PATH:$V8_BUILD/depot_tools | ||
fetch v8 #pull down v8 (this will take some time) | ||
cd v8 | ||
git checkout 6.7.77 | ||
gclient sync | ||
``` | ||
|
||
## Linux | ||
|
||
``` | ||
./build/install-build-deps.sh #only needed once | ||
gn gen out.gn/golib --args="strip_debug_info=true v8_use_external_startup_data=false v8_enable_i18n_support=false v8_enable_gdbjit=false v8_static_library=true symbol_level=0 v8_experimental_extra_library_files=[] v8_extra_library_files=[]" | ||
ninja -C out.gn/golib | ||
# go get some coffee | ||
``` | ||
|
||
## OSX | ||
|
||
``` | ||
gn gen out.gn/golib --args="is_official_build=true strip_debug_info=true v8_use_external_startup_data=false v8_enable_i18n_support=false v8_enable_gdbjit=false v8_static_library=true symbol_level=0 v8_experimental_extra_library_files=[] v8_extra_library_files=[]" | ||
ninja -C out.gn/golib | ||
# go get some coffee | ||
``` | ||
|
||
## Symlinking | ||
|
||
Now you can create symlinks so that cgo can associate the v8 binaries with the go library. | ||
|
||
``` | ||
cd $V8_GO | ||
./symlink.sh $V8_BUILD/v8 | ||
``` | ||
|
||
## Verifying | ||
|
||
You should be done! Try running `go test` | ||
|
||
# Reference | ||
|
||
Also relevant is the v8 API release changes doc: | ||
|
||
https://docs.google.com/document/d/1g8JFi8T_oAE_7uAri7Njtig7fKaPDfotU6huOa1alds/edit | ||
|
||
# Credits | ||
|
||
This work is based off of several existing libraries: | ||
|
||
* https://github.com/fluxio/go-v8 | ||
* https://github.com/kingland/go-v8 | ||
* https://github.com/mattn/go-v8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package v8 | ||
|
||
import "testing" | ||
|
||
func BenchmarkGetValue(b *testing.B) { | ||
ctx := NewIsolate().NewContext() | ||
|
||
_, err := ctx.Eval(`var hello = "test"`, "bench.js") | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
|
||
glob := ctx.Global() | ||
|
||
b.ResetTimer() | ||
for n := 0; n < b.N; n++ { | ||
if _, err := glob.Get("hello"); err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
} | ||
|
||
func BenchmarkGetNumberValue(b *testing.B) { | ||
ctx := NewIsolate().NewContext() | ||
val, err := ctx.Eval(`(157)`, "bench.js") | ||
if err != nil { | ||
b.Fatal(err) | ||
} | ||
b.ResetTimer() | ||
for n := 0; n < b.N; n += 2 { | ||
if res := val.Int64(); res != 157 { | ||
b.Fatal("Wrong value: ", res) | ||
} | ||
if res := val.Float64(); res != 157 { | ||
b.Fatal("Wrong value: ", res) | ||
} | ||
} | ||
} | ||
|
||
func BenchmarkContextCreate(b *testing.B) { | ||
ctx := NewIsolate().NewContext() | ||
|
||
b.ResetTimer() | ||
for n := 0; n < b.N; n++ { | ||
if _, err := ctx.Create(map[string]interface{}{}); err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
} | ||
|
||
func BenchmarkEval(b *testing.B) { | ||
iso := NewIsolate() | ||
ctx := iso.NewContext() | ||
|
||
script := `"hello"` | ||
|
||
b.ResetTimer() | ||
for n := 0; n < b.N; n++ { | ||
if _, err := ctx.Eval(script, "bench-eval.js"); err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
} | ||
|
||
func BenchmarkCallback(b *testing.B) { | ||
ctx := NewIsolate().NewContext() | ||
ctx.Global().Set("cb", ctx.Bind("cb", func(in CallbackArgs) (*Value, error) { | ||
return nil, nil | ||
})) | ||
|
||
script := `cb()` | ||
|
||
b.ResetTimer() | ||
for n := 0; n < b.N; n++ { | ||
if _, err := ctx.Eval(script, "bench-cb.js"); err != nil { | ||
b.Fatal(err) | ||
} | ||
} | ||
} |
Oops, something went wrong.