v8eval 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CMakeLists.txt +64 -0
- data/LICENSE +21 -0
- data/README.md +115 -0
- data/build.sh +110 -0
- data/ruby/Gemfile +6 -0
- data/ruby/Rakefile +28 -0
- data/ruby/build.sh +43 -0
- data/ruby/example/js_add.rb +9 -0
- data/ruby/ext/v8eval/extconf.rb +53 -0
- data/ruby/lib/setup/extension_builder.rb +30 -0
- data/ruby/lib/v8eval.rb +60 -0
- data/ruby/spec/spec_helper.rb +96 -0
- data/ruby/spec/v8eval_spec.rb +58 -0
- data/src/v8eval.cxx +185 -0
- data/src/v8eval.h +64 -0
- data/src/v8eval.i +9 -0
- data/v8eval.gemspec +26 -0
- metadata +113 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1b41852421cf3a98adc4bb3085e0167502f3ac7d
|
|
4
|
+
data.tar.gz: 87cc44407a717ac6df88cee14a139d57e98fefe6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 180f31e8c88ff8ef3368132c6a6fce6e1d732f46fc8d078d587d6b72c14b68e572914f13975a9e6ce94142eafdc750d5f39c46f72b6d4aca08b362aa50a83bad
|
|
7
|
+
data.tar.gz: 65a8814312d975007a0db7932d628622bcb946809324a8011c62b0cc0c930c0b4e4e2c34aca211da76fc094da8b4344f3f29db6b460d06eef5fb79922676a177
|
data/CMakeLists.txt
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 2.8)
|
|
2
|
+
|
|
3
|
+
project(v8eval)
|
|
4
|
+
|
|
5
|
+
option(V8EVAL_TEST "Build tests" OFF)
|
|
6
|
+
|
|
7
|
+
if(COMMAND cmake_policy)
|
|
8
|
+
cmake_policy(SET CMP0015 NEW)
|
|
9
|
+
endif(COMMAND cmake_policy)
|
|
10
|
+
|
|
11
|
+
include_directories(
|
|
12
|
+
v8
|
|
13
|
+
v8/include
|
|
14
|
+
v8/third_party/icu/source/i18n
|
|
15
|
+
v8/third_party/icu/source/common
|
|
16
|
+
src
|
|
17
|
+
test/googletest/googletest/include
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
if(APPLE)
|
|
21
|
+
link_directories(
|
|
22
|
+
v8/out/x64.release
|
|
23
|
+
)
|
|
24
|
+
endif(APPLE)
|
|
25
|
+
|
|
26
|
+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
27
|
+
link_directories(
|
|
28
|
+
v8/out/x64.release/obj.target/tools/gyp
|
|
29
|
+
v8/out/x64.release/obj.target/third_party/icu
|
|
30
|
+
)
|
|
31
|
+
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
32
|
+
|
|
33
|
+
add_library(v8eval STATIC
|
|
34
|
+
src/v8eval.cxx
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
set(v8eval-cflags
|
|
38
|
+
-Wall
|
|
39
|
+
-Wendif-labels
|
|
40
|
+
-Werror
|
|
41
|
+
-Wno-missing-field-initializers
|
|
42
|
+
-Wno-unused-parameter
|
|
43
|
+
-Wshorten-64-to-32
|
|
44
|
+
-fPIC
|
|
45
|
+
-fno-exceptions
|
|
46
|
+
-fno-rtti
|
|
47
|
+
-fno-strict-aliasing
|
|
48
|
+
-fno-threadsafe-statics
|
|
49
|
+
-fstrict-aliasing
|
|
50
|
+
-fvisibility=hidden
|
|
51
|
+
-fvisibility-inlines-hidden
|
|
52
|
+
-gdwarf-2
|
|
53
|
+
-std=c++11
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
string(REPLACE ";" " " v8eval-cflags "${v8eval-cflags}")
|
|
57
|
+
|
|
58
|
+
set_target_properties(v8eval PROPERTIES
|
|
59
|
+
COMPILE_FLAGS "${v8eval-cflags}"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if(V8EVAL_TEST)
|
|
63
|
+
add_subdirectory(test)
|
|
64
|
+
endif(V8EVAL_TEST)
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright 2015 Sony Corporation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# v8eval
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/sony/v8eval)
|
|
4
|
+
[](http://badge.fury.io/py/v8eval)
|
|
5
|
+
[](http://godoc.org/github.com/sony/v8eval/go/v8eval)
|
|
6
|
+
[](https://badge.fury.io/rb/v8eval)
|
|
7
|
+
|
|
8
|
+
Multi-language bindings to JavaScript engine V8.
|
|
9
|
+
|
|
10
|
+
Currently v8eval provides Go, Python and Ruby bindings to the latest V8 4.7 and supports Linux and Mac OS X.
|
|
11
|
+
v8eval uses SWIG and can be extended easily for other languages.
|
|
12
|
+
|
|
13
|
+
## Pre-installation
|
|
14
|
+
|
|
15
|
+
#### Linux
|
|
16
|
+
|
|
17
|
+
See [Dockerfile](https://github.com/sony/v8eval/blob/master/Dockerfile).
|
|
18
|
+
|
|
19
|
+
#### Mac
|
|
20
|
+
|
|
21
|
+
See [.travis.yml](https://github.com/sony/v8eval/blob/master/.travis.yml).
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
The installation takes several tens of minutes due to V8 build.
|
|
26
|
+
|
|
27
|
+
#### Go
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
git clone https://github.com/sony/v8eval.git $GOPATH/src/github.com/sony/v8eval
|
|
31
|
+
$GOPATH/src/github.com/sony/v8eval/go/build.sh install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
#### Python
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
pip install v8eval
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Ruby
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
gem install v8eval
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Documentation
|
|
48
|
+
|
|
49
|
+
#### Go
|
|
50
|
+
|
|
51
|
+
See [godoc.org](http://godoc.org/github.com/sony/v8eval/go/v8eval).
|
|
52
|
+
|
|
53
|
+
#### Python
|
|
54
|
+
|
|
55
|
+
You can create the Sphinx documentation under python/docs.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
python/build.sh docs
|
|
59
|
+
```
|
|
60
|
+
#### Ruby
|
|
61
|
+
|
|
62
|
+
You can create the YARD documentation under ruby/doc.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
ruby/build.sh docs
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## Examples
|
|
70
|
+
|
|
71
|
+
#### Go
|
|
72
|
+
|
|
73
|
+
```go
|
|
74
|
+
import "github.com/sony/v8eval/go/v8eval"
|
|
75
|
+
|
|
76
|
+
func Add(x, y int) int {
|
|
77
|
+
var v8 = v8eval.NewV8()
|
|
78
|
+
v8.Eval("var add = (x, y) => x + y;", nil)
|
|
79
|
+
|
|
80
|
+
var sum int;
|
|
81
|
+
v8.Call("add", []int{x, y}, &sum)
|
|
82
|
+
return sum
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Python
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import v8eval
|
|
90
|
+
|
|
91
|
+
def add(x, y):
|
|
92
|
+
v8 = v8eval.V8()
|
|
93
|
+
v8.eval('var add = (x, y) => x + y;')
|
|
94
|
+
return v8.call('add', [x, y])
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### Ruby
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
require 'v8eval'
|
|
101
|
+
|
|
102
|
+
def add(x, y)
|
|
103
|
+
v8 = V8Eval::V8.new
|
|
104
|
+
v8.eval('function add(x, y) { return x + y; }')
|
|
105
|
+
v8.call('add', [x, y])
|
|
106
|
+
end
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
## License
|
|
112
|
+
|
|
113
|
+
The MIT License (MIT)
|
|
114
|
+
|
|
115
|
+
See [LICENSE](https://github.com/sony/v8eval/blob/master/LICENSE) for details.
|
data/build.sh
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
V8EVAL_ROOT=`cd $(dirname $0) && pwd`
|
|
4
|
+
|
|
5
|
+
if [ `uname` = "Linux" ] ; then
|
|
6
|
+
export CC=$V8EVAL_ROOT/v8/third_party/llvm-build/Release+Asserts/bin/clang
|
|
7
|
+
export CXX=$V8EVAL_ROOT/v8/third_party/llvm-build/Release+Asserts/bin/clang++
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
if [ `uname` = "Darwin" ]; then
|
|
11
|
+
export CC=`which clang`
|
|
12
|
+
export CXX=`which clang++`
|
|
13
|
+
export CPP="`which clang` -E"
|
|
14
|
+
export LINK="`which clang++`"
|
|
15
|
+
export CC_host=`which clang`
|
|
16
|
+
export CXX_host=`which clang++`
|
|
17
|
+
export CPP_host="`which clang` -E"
|
|
18
|
+
export LINK_host=`which clang++`
|
|
19
|
+
export GYP_DEFINES="clang=1 mac_deployment_target=10.10"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
install_depot_tools() {
|
|
23
|
+
export PATH=$V8EVAL_ROOT/depot_tools:$PATH
|
|
24
|
+
if [ -d $V8EVAL_ROOT/depot_tools ]; then
|
|
25
|
+
return 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
cd $V8EVAL_ROOT
|
|
29
|
+
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
install_googletest() {
|
|
33
|
+
if [ -d $V8EVAL_ROOT/test/googletest ]; then
|
|
34
|
+
return 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
cd $V8EVAL_ROOT/test
|
|
38
|
+
git clone https://github.com/google/googletest.git
|
|
39
|
+
git checkout release-1.7.0
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
install_v8() {
|
|
43
|
+
if [ -d $V8EVAL_ROOT/v8 ]; then
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
cd $V8EVAL_ROOT
|
|
48
|
+
fetch v8
|
|
49
|
+
cd v8
|
|
50
|
+
git checkout 4.7.68
|
|
51
|
+
CFLAGS="-fPIC" CXXFLAGS="-fPIC" make x64.release V=1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
build() {
|
|
55
|
+
install_depot_tools
|
|
56
|
+
install_v8
|
|
57
|
+
|
|
58
|
+
cd $V8EVAL_ROOT
|
|
59
|
+
mkdir -p build
|
|
60
|
+
cd build
|
|
61
|
+
cmake -DCMAKE_BUILD_TYPE=Release -DV8EVAL_TEST=OFF ..
|
|
62
|
+
make VERBOSE=1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
build_go() {
|
|
66
|
+
$V8EVAL_ROOT/go/build.sh
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
build_python() {
|
|
70
|
+
$V8EVAL_ROOT/python/build.sh
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
build_ruby() {
|
|
74
|
+
$V8EVAL_ROOT/ruby/build.sh
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
docs() {
|
|
78
|
+
cd $V8EVAL_ROOT/docs
|
|
79
|
+
rm -rf ./html
|
|
80
|
+
doxygen
|
|
81
|
+
|
|
82
|
+
$V8EVAL_ROOT/python/build.sh docs
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
test() {
|
|
86
|
+
build
|
|
87
|
+
install_googletest
|
|
88
|
+
|
|
89
|
+
cd $V8EVAL_ROOT/build
|
|
90
|
+
cmake -DCMAKE_BUILD_TYPE=Release -DV8EVAL_TEST=ON ..
|
|
91
|
+
make VERBOSE=1
|
|
92
|
+
./test/v8eval-test || exit 1
|
|
93
|
+
|
|
94
|
+
cd ..
|
|
95
|
+
./go/build.sh test || exit 1
|
|
96
|
+
./python/build.sh test || exit 1
|
|
97
|
+
./ruby/build.sh test || exit 1
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# dispatch subcommand
|
|
101
|
+
SUBCOMMAND="$1";
|
|
102
|
+
case "${SUBCOMMAND}" in
|
|
103
|
+
"" ) build ;;
|
|
104
|
+
"go" ) build_go ;;
|
|
105
|
+
"python" ) build_python ;;
|
|
106
|
+
"ruby" ) build_ruby ;;
|
|
107
|
+
"docs" ) docs ;;
|
|
108
|
+
"test" ) test ;;
|
|
109
|
+
* ) echo "unknown subcommand: ${SUBCOMMAND}"; exit 1 ;;
|
|
110
|
+
esac
|
data/ruby/Gemfile
ADDED
data/ruby/Rakefile
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Rakefile
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'rake/clean'
|
|
4
|
+
require_relative 'lib/setup/extension_builder'
|
|
5
|
+
|
|
6
|
+
CLEAN.include('ext/**/*{.o,.log,.so,.bundle}')
|
|
7
|
+
CLEAN.include('ext/**/Makefile')
|
|
8
|
+
|
|
9
|
+
# set path variable
|
|
10
|
+
v8eval_root = File.expand_path('..', Dir.pwd)
|
|
11
|
+
|
|
12
|
+
# make instance of BuildTool class
|
|
13
|
+
tool = BuildTool.new(v8eval_root)
|
|
14
|
+
|
|
15
|
+
desc 'task to prepare for the build'
|
|
16
|
+
task :prepare_build do
|
|
17
|
+
tool.run_swig
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc 'install v8 and build libv8eval.a'
|
|
21
|
+
task :install_v8 do
|
|
22
|
+
tool.install_v8
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc 'build v8eval{.so,.dll,.bundle}'
|
|
26
|
+
task :build_ext do
|
|
27
|
+
tool.build_ext
|
|
28
|
+
end
|
data/ruby/build.sh
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
V8EVAL_ROOT=`cd $(dirname $0)/.. && pwd`
|
|
4
|
+
|
|
5
|
+
build() {
|
|
6
|
+
cd $V8EVAL_ROOT/ruby && rake prepare_build
|
|
7
|
+
cd $V8EVAL_ROOT && gem build v8eval.gemspec
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
install() {
|
|
12
|
+
cd $V8EVAL_ROOT
|
|
13
|
+
gem install v8eval-*.gem
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
docs() {
|
|
17
|
+
cd $V8EVAL_ROOT/ruby
|
|
18
|
+
rm -rf ./doc
|
|
19
|
+
mkdir ./doc
|
|
20
|
+
yardoc --main ../README.md lib/v8eval.rb
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
test() {
|
|
24
|
+
build
|
|
25
|
+
|
|
26
|
+
gem install bundle
|
|
27
|
+
cd $V8EVAL_ROOT/ruby
|
|
28
|
+
bundle install
|
|
29
|
+
|
|
30
|
+
rake install_v8 && rake build_ext
|
|
31
|
+
rspec
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# dispatch subcommand
|
|
36
|
+
SUBCOMMAND="$1";
|
|
37
|
+
case "${SUBCOMMAND}" in
|
|
38
|
+
"" ) build ;;
|
|
39
|
+
"install" ) install ;;
|
|
40
|
+
"docs" ) docs ;;
|
|
41
|
+
"test" ) test ;;
|
|
42
|
+
* ) echo "unknown subcommand: ${SUBCOMMAND}"; exit 1 ;;
|
|
43
|
+
esac
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# extconf.rb
|
|
2
|
+
require 'rbconfig'
|
|
3
|
+
require 'mkmf'
|
|
4
|
+
require_relative '../../lib/setup/extension_builder'
|
|
5
|
+
|
|
6
|
+
# set path variables
|
|
7
|
+
v8eval_root = File.expand_path('../../..', Dir.pwd)
|
|
8
|
+
v8_dir = v8eval_root + '/v8'
|
|
9
|
+
|
|
10
|
+
# make instance of BuildTool class
|
|
11
|
+
tool = BuildTool.new(v8eval_root)
|
|
12
|
+
|
|
13
|
+
# install v8 and build libv8eval.a
|
|
14
|
+
tool.install_v8
|
|
15
|
+
|
|
16
|
+
# generate v8eval_wrap.cxx
|
|
17
|
+
tool.run_swig
|
|
18
|
+
|
|
19
|
+
LIBDIR = RbConfig::CONFIG['libdir']
|
|
20
|
+
INCLUDEDIR = RbConfig::CONFIG['includedir']
|
|
21
|
+
|
|
22
|
+
HEADER_DIRS = [
|
|
23
|
+
v8_dir,
|
|
24
|
+
v8_dir + '/include',
|
|
25
|
+
INCLUDEDIR
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
LIB_DIRS = [
|
|
29
|
+
v8eval_root + '/build',
|
|
30
|
+
LIBDIR
|
|
31
|
+
]
|
|
32
|
+
if RUBY_PLATFORM =~ /darwin/
|
|
33
|
+
LIB_DIRS += [
|
|
34
|
+
v8_dir + '/out/x64.release'
|
|
35
|
+
]
|
|
36
|
+
elsif RUBY_PLATFORM =~ /linux/
|
|
37
|
+
LIB_DIRS += [
|
|
38
|
+
v8_dir + '/out/x64.release/obj.target/tools/gyp',
|
|
39
|
+
v8_dir + '/out/x64.release/obj.target/third_party/icu'
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
dir_config('', HEADER_DIRS, LIB_DIRS)
|
|
44
|
+
|
|
45
|
+
$LDFLAGS << ' -lv8eval -lv8_libplatform -lv8_base -lv8_libbase -lv8_nosnapshot -licui18n -licuuc -licudata'
|
|
46
|
+
if RUBY_PLATFORM =~ /linux/
|
|
47
|
+
$LDFLAGS << ' -ldl -lpthread'
|
|
48
|
+
$CPPFLAGS << ' -g -O3 -std=c++11'
|
|
49
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
|
50
|
+
$CXXFLAGS << ' -g -O3 -std=c++11'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
create_makefile('v8eval/v8eval')
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# BuildTool is a util class that is used to do some build tasks
|
|
2
|
+
class BuildTool
|
|
3
|
+
def initialize(path)
|
|
4
|
+
@v8eval_root = path
|
|
5
|
+
@rb_dir = @v8eval_root + '/ruby'
|
|
6
|
+
@rb_ext_dir = @rb_dir + '/ext'
|
|
7
|
+
@rb_ext_v8eval_dir = @rb_ext_dir + '/v8eval'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def install_v8
|
|
11
|
+
Dir.chdir @v8eval_root do
|
|
12
|
+
system('./build.sh')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run_swig
|
|
17
|
+
system('cp ' + @v8eval_root + '/src/v8eval.h ' + @rb_ext_v8eval_dir)
|
|
18
|
+
system('swig -c++ -ruby -autorename -outdir ' + @rb_ext_v8eval_dir +
|
|
19
|
+
' -o ' + @rb_ext_v8eval_dir + '/v8eval_wrap.cxx ' + @v8eval_root +
|
|
20
|
+
'/src/v8eval.i')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def build_ext
|
|
24
|
+
Dir.chdir @rb_ext_v8eval_dir do
|
|
25
|
+
system('ruby extconf.rb')
|
|
26
|
+
system('make')
|
|
27
|
+
system('make install')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/ruby/lib/v8eval.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# require 'v8eval/v8eval' loads the V8eval module built by swig-generated extension
|
|
2
|
+
require 'v8eval/v8eval'
|
|
3
|
+
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module V8Eval
|
|
7
|
+
# Represents a V8 instance.
|
|
8
|
+
class V8
|
|
9
|
+
def initialize
|
|
10
|
+
@v8 = V8eval::V8.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Evaluates JavaScript code.
|
|
14
|
+
# @param [String] src JavaScript code.
|
|
15
|
+
# @return
|
|
16
|
+
# The result of the JavaScript code. The result is marshalled/unmarshalled by using JSON.
|
|
17
|
+
# @raise [TypeError] If src is not a string.
|
|
18
|
+
# @raise [RuntimeError] If some JavaScript exception happens.
|
|
19
|
+
def eval(src)
|
|
20
|
+
fail TypeError unless src.is_a?(String)
|
|
21
|
+
res = @v8.eval(src)
|
|
22
|
+
if res == 'undefined'
|
|
23
|
+
return nil
|
|
24
|
+
else
|
|
25
|
+
begin
|
|
26
|
+
return JSON.load(res)
|
|
27
|
+
rescue StandardError => e
|
|
28
|
+
raise e.message
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Calls a JavaScript function.
|
|
34
|
+
# @param [String] func Name of a JavaScript function.
|
|
35
|
+
# @param [Array] args Argument list to pass.
|
|
36
|
+
# @return
|
|
37
|
+
# The result of the JavaScript code. The result is marshalled/unmarshalled by using JSON.
|
|
38
|
+
# @raise [TypeError] If either func is not a string or args is not a array.
|
|
39
|
+
# @raise [RuntimeError] If some JavaScript exception happens.
|
|
40
|
+
def call(func, args)
|
|
41
|
+
fail TypeError unless func.is_a?(String)
|
|
42
|
+
fail TypeError unless args.is_a?(Array)
|
|
43
|
+
|
|
44
|
+
args_str = JSON.dump(args)
|
|
45
|
+
res = @v8.call(func, args_str)
|
|
46
|
+
if res == 'undefined'
|
|
47
|
+
return nil
|
|
48
|
+
else
|
|
49
|
+
begin
|
|
50
|
+
return JSON.load(res)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
raise e.message
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# initialize the V8 runtime environment
|
|
60
|
+
V8eval.initialize
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
|
5
|
+
# files.
|
|
6
|
+
#
|
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
|
13
|
+
# it.
|
|
14
|
+
#
|
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
|
16
|
+
# users commonly want.
|
|
17
|
+
#
|
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
19
|
+
RSpec.configure do |config|
|
|
20
|
+
# rspec-expectations config goes here. You can use an alternate
|
|
21
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
|
22
|
+
# assertions if you prefer.
|
|
23
|
+
config.expect_with :rspec do |expectations|
|
|
24
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
|
25
|
+
# and `failure_message` of custom matchers include text for helper methods
|
|
26
|
+
# defined using `chain`, e.g.:
|
|
27
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
|
28
|
+
# # => "be bigger than 2 and smaller than 4"
|
|
29
|
+
# ...rather than:
|
|
30
|
+
# # => "be bigger than 2"
|
|
31
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
|
35
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
|
36
|
+
config.mock_with :rspec do |mocks|
|
|
37
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
|
38
|
+
# a real object. This is generally recommended, and will default to
|
|
39
|
+
# `true` in RSpec 4.
|
|
40
|
+
mocks.verify_partial_doubles = true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The settings below are suggested to provide a good initial experience
|
|
44
|
+
# with RSpec, but feel free to customize to your heart's content.
|
|
45
|
+
=begin
|
|
46
|
+
# These two settings work together to allow you to limit a spec run
|
|
47
|
+
# to individual examples or groups you care about by tagging them with
|
|
48
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
|
49
|
+
# get run.
|
|
50
|
+
config.filter_run :focus
|
|
51
|
+
config.run_all_when_everything_filtered = true
|
|
52
|
+
|
|
53
|
+
# Allows RSpec to persist some state between runs in order to support
|
|
54
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
|
55
|
+
# you configure your source control system to ignore this file.
|
|
56
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
|
57
|
+
|
|
58
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
|
59
|
+
# recommended. For more details, see:
|
|
60
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
|
61
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
62
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
|
63
|
+
config.disable_monkey_patching!
|
|
64
|
+
|
|
65
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
|
66
|
+
# be too noisy due to issues in dependencies.
|
|
67
|
+
config.warnings = true
|
|
68
|
+
|
|
69
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
|
70
|
+
# file, and it's useful to allow more verbose output when running an
|
|
71
|
+
# individual spec file.
|
|
72
|
+
if config.files_to_run.one?
|
|
73
|
+
# Use the documentation formatter for detailed output,
|
|
74
|
+
# unless a formatter has already been configured
|
|
75
|
+
# (e.g. via a command-line flag).
|
|
76
|
+
config.default_formatter = 'doc'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Print the 10 slowest examples and example groups at the
|
|
80
|
+
# end of the spec run, to help surface which specs are running
|
|
81
|
+
# particularly slow.
|
|
82
|
+
config.profile_examples = 10
|
|
83
|
+
|
|
84
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
85
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
86
|
+
# the seed, which is printed after each run.
|
|
87
|
+
# --seed 1234
|
|
88
|
+
config.order = :random
|
|
89
|
+
|
|
90
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
|
91
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
|
92
|
+
# test failures related to randomization by passing the same `--seed` value
|
|
93
|
+
# as the one that triggered the failure.
|
|
94
|
+
Kernel.srand config.seed
|
|
95
|
+
=end
|
|
96
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'v8eval'
|
|
2
|
+
|
|
3
|
+
RSpec.describe V8Eval, '#eval' do
|
|
4
|
+
context 'with vaild source code' do
|
|
5
|
+
it 'should evaluate the source code' do
|
|
6
|
+
v8 = V8Eval::V8.new
|
|
7
|
+
expect(v8.eval('1+2')).to eq 3
|
|
8
|
+
expect(v8.eval('var p = { x: 1.1, y: 2.2 }; p')).to eq('x' => 1.1,
|
|
9
|
+
'y' => 2.2)
|
|
10
|
+
expect(v8.eval('')).to eq nil
|
|
11
|
+
|
|
12
|
+
expect { v8.eval(nil) }.to raise_exception(TypeError)
|
|
13
|
+
expect { v8.eval('foo') }.to raise_exception(RuntimeError)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
RSpec.describe V8Eval, '#call' do
|
|
19
|
+
context 'with valid function and arguments' do
|
|
20
|
+
it 'should evaluate the given function' do
|
|
21
|
+
v8 = V8Eval::V8.new
|
|
22
|
+
v8.eval('function inc(x) { return x + 1; }')
|
|
23
|
+
expect(v8.call('inc', [7])).to eq 8
|
|
24
|
+
|
|
25
|
+
expect { v8.call(nil, [7]) }.to raise_exception(TypeError)
|
|
26
|
+
expect { v8.call('inc', nil) }.to raise_exception(TypeError)
|
|
27
|
+
expect { v8.call('i', [7]) }.to raise_exception(RuntimeError)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
RSpec.describe V8Eval, '#multithreading' do
|
|
33
|
+
context 'with multithread execution' do
|
|
34
|
+
it 'should execute concurrently' do
|
|
35
|
+
def v8_thread(num)
|
|
36
|
+
num_repeat = num
|
|
37
|
+
v8 = V8Eval::V8.new
|
|
38
|
+
counter = 0
|
|
39
|
+
thread = Thread.new do
|
|
40
|
+
v8.eval('function inc(x) { return x + 1; }')
|
|
41
|
+
num_repeat.times do
|
|
42
|
+
counter = v8.call('inc', [counter])
|
|
43
|
+
end
|
|
44
|
+
expect(counter).to eq(num_repeat)
|
|
45
|
+
end
|
|
46
|
+
thread
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
num_repeat = 10_000
|
|
50
|
+
|
|
51
|
+
thread1 = v8_thread(num_repeat)
|
|
52
|
+
thread2 = v8_thread(num_repeat)
|
|
53
|
+
|
|
54
|
+
thread1.join
|
|
55
|
+
thread2.join
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/src/v8eval.cxx
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#include "v8eval.h"
|
|
2
|
+
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#include "libplatform/libplatform.h"
|
|
7
|
+
|
|
8
|
+
namespace v8eval {
|
|
9
|
+
|
|
10
|
+
static v8::Platform* platform = nullptr;
|
|
11
|
+
|
|
12
|
+
bool initialize() {
|
|
13
|
+
if (platform) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!v8::V8::InitializeICU()) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
platform = v8::platform::CreateDefaultPlatform();
|
|
22
|
+
v8::V8::InitializePlatform(platform);
|
|
23
|
+
|
|
24
|
+
return v8::V8::Initialize();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
bool dispose() {
|
|
28
|
+
if (!platform) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
v8::V8::Dispose();
|
|
33
|
+
|
|
34
|
+
v8::V8::ShutdownPlatform();
|
|
35
|
+
delete platform;
|
|
36
|
+
platform = nullptr;
|
|
37
|
+
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
|
42
|
+
public:
|
|
43
|
+
virtual void* Allocate(size_t length) {
|
|
44
|
+
void* data = AllocateUninitialized(length);
|
|
45
|
+
return data == NULL ? data : memset(data, 0, length);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
virtual void* AllocateUninitialized(size_t length) {
|
|
49
|
+
return malloc(length);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
virtual void Free(void* data, size_t) {
|
|
53
|
+
free(data);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
static ArrayBufferAllocator allocator;
|
|
58
|
+
|
|
59
|
+
_V8::_V8() {
|
|
60
|
+
v8::Isolate::CreateParams create_params;
|
|
61
|
+
create_params.array_buffer_allocator = &allocator;
|
|
62
|
+
isolate_ = v8::Isolate::New(create_params);
|
|
63
|
+
|
|
64
|
+
v8::Locker locker(isolate_);
|
|
65
|
+
|
|
66
|
+
v8::Isolate::Scope isolate_scope(isolate_);
|
|
67
|
+
v8::HandleScope handle_scope(isolate_);
|
|
68
|
+
context_.Reset(isolate_, new_context());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_V8::~_V8() {
|
|
72
|
+
context_.Reset();
|
|
73
|
+
|
|
74
|
+
isolate_->Dispose();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
v8::Local<v8::Context> _V8::new_context() {
|
|
78
|
+
if (context_.IsEmpty()) {
|
|
79
|
+
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
|
|
80
|
+
return v8::Context::New(isolate_, nullptr, global);
|
|
81
|
+
} else {
|
|
82
|
+
return v8::Local<v8::Context>::New(isolate_, context_);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
v8::Local<v8::String> _V8::new_string(const char* str) {
|
|
87
|
+
return v8::String::NewFromUtf8(isolate_, str ? str : "", v8::NewStringType::kNormal).ToLocalChecked();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static std::string to_std_string(v8::Local<v8::Value> value) {
|
|
91
|
+
v8::String::Utf8Value str(value);
|
|
92
|
+
return *str ? *str : "Error: Cannot convert to string";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
v8::Local<v8::Value> _V8::json_parse(v8::Local<v8::Context> context, v8::Local<v8::String> str) {
|
|
96
|
+
v8::Local<v8::Object> global = context->Global();
|
|
97
|
+
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject();
|
|
98
|
+
v8::Local<v8::Function> parse = v8::Local<v8::Function>::Cast(json->Get(context, new_string("parse")).ToLocalChecked());
|
|
99
|
+
|
|
100
|
+
v8::Local<v8::Value> result;
|
|
101
|
+
v8::Local<v8::Value> value = str;
|
|
102
|
+
if (!parse->Call(context, json, 1, &value).ToLocal(&result)) {
|
|
103
|
+
return v8::Local<v8::Value>(); // empty
|
|
104
|
+
} else {
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
v8::Local<v8::String> _V8::json_stringify(v8::Local<v8::Context> context, v8::Local<v8::Value> value) {
|
|
110
|
+
v8::Local<v8::Object> global = context->Global();
|
|
111
|
+
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject();
|
|
112
|
+
v8::Local<v8::Function> stringify = v8::Local<v8::Function>::Cast(json->Get(context, new_string("stringify")).ToLocalChecked());
|
|
113
|
+
|
|
114
|
+
v8::Local<v8::Value> result;
|
|
115
|
+
if (!stringify->Call(context, json, 1, &value).ToLocal(&result)) {
|
|
116
|
+
return new_string("");
|
|
117
|
+
} else {
|
|
118
|
+
return result->ToString();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
std::string _V8::eval(const std::string& src) {
|
|
123
|
+
v8::Locker locker(isolate_);
|
|
124
|
+
|
|
125
|
+
v8::Isolate::Scope isolate_scope(isolate_);
|
|
126
|
+
v8::HandleScope handle_scope(isolate_);
|
|
127
|
+
|
|
128
|
+
v8::Local<v8::Context> context = new_context();
|
|
129
|
+
v8::Context::Scope context_scope(context);
|
|
130
|
+
|
|
131
|
+
v8::TryCatch try_catch(isolate_);
|
|
132
|
+
|
|
133
|
+
v8::Local<v8::String> source = new_string(src.c_str());
|
|
134
|
+
|
|
135
|
+
v8::Local<v8::String> name = new_string("v8eval");
|
|
136
|
+
v8::ScriptOrigin origin(name);
|
|
137
|
+
|
|
138
|
+
v8::Local<v8::Script> script;
|
|
139
|
+
if (!v8::Script::Compile(context, source, &origin).ToLocal(&script)) {
|
|
140
|
+
return to_std_string(try_catch.Exception());
|
|
141
|
+
} else {
|
|
142
|
+
v8::Local<v8::Value> result;
|
|
143
|
+
if (!script->Run(context).ToLocal(&result)) {
|
|
144
|
+
return to_std_string(try_catch.Exception());
|
|
145
|
+
} else {
|
|
146
|
+
return to_std_string(json_stringify(context, result));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
std::string _V8::call(const std::string& func, const std::string& args) {
|
|
152
|
+
v8::Locker locker(isolate_);
|
|
153
|
+
|
|
154
|
+
v8::Isolate::Scope isolate_scope(isolate_);
|
|
155
|
+
v8::HandleScope handle_scope(isolate_);
|
|
156
|
+
|
|
157
|
+
v8::Local<v8::Context> context = new_context();
|
|
158
|
+
v8::Context::Scope context_scope(context);
|
|
159
|
+
|
|
160
|
+
v8::TryCatch try_catch(isolate_);
|
|
161
|
+
|
|
162
|
+
v8::Local<v8::Object> global = context->Global();
|
|
163
|
+
v8::Local<v8::Value> result;
|
|
164
|
+
if (!global->Get(context, new_string(func.c_str())).ToLocal(&result)) {
|
|
165
|
+
return to_std_string(try_catch.Exception());
|
|
166
|
+
} else if (!result->IsFunction()) {
|
|
167
|
+
return "TypeError: '" + func + "' is not a function";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
v8::Local<v8::Function> function = v8::Handle<v8::Function>::Cast(result);
|
|
171
|
+
v8::Local<v8::Function> apply = v8::Handle<v8::Function>::Cast(function->Get(context, new_string("apply")).ToLocalChecked());
|
|
172
|
+
v8::Local<v8::Value> arguments = json_parse(context, new_string(args.c_str()));
|
|
173
|
+
if (arguments.IsEmpty() || !arguments->IsArray()) {
|
|
174
|
+
return "TypeError: '" + args + "' is not an array";
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
v8::Local<v8::Value> values[] = { function, arguments };
|
|
178
|
+
if (!apply->Call(context, function, 2, values).ToLocal(&result)) {
|
|
179
|
+
return to_std_string(try_catch.Exception());
|
|
180
|
+
} else {
|
|
181
|
+
return to_std_string(json_stringify(context, result));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
} // namespace v8eval
|
data/src/v8eval.h
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#ifndef V8EVAL_H_
|
|
2
|
+
#define V8EVAL_H_
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
|
|
6
|
+
#include "v8.h"
|
|
7
|
+
|
|
8
|
+
/// \file
|
|
9
|
+
namespace v8eval {
|
|
10
|
+
|
|
11
|
+
/// \brief Initialize the V8 runtime environment
|
|
12
|
+
/// \return success or not as boolean
|
|
13
|
+
///
|
|
14
|
+
/// This method initializes the V8 runtime environment. It must be called before creating any V8 instance.
|
|
15
|
+
bool initialize();
|
|
16
|
+
|
|
17
|
+
/// \brief Dispose the V8 runtime environment
|
|
18
|
+
/// \return success or not as boolean
|
|
19
|
+
///
|
|
20
|
+
/// This method disposes the V8 runtime environment.
|
|
21
|
+
bool dispose();
|
|
22
|
+
|
|
23
|
+
/// \class _V8
|
|
24
|
+
///
|
|
25
|
+
/// _V8 instances can be used in multiple threads.
|
|
26
|
+
/// But each _V8 instance can be used in only one thread at a time.
|
|
27
|
+
class _V8 {
|
|
28
|
+
public:
|
|
29
|
+
_V8();
|
|
30
|
+
virtual ~_V8();
|
|
31
|
+
|
|
32
|
+
/// \brief Evaluate JavaScript code
|
|
33
|
+
/// \param src JavaScript code
|
|
34
|
+
/// \return JSON-encoded result or exception message
|
|
35
|
+
///
|
|
36
|
+
/// This method evaluates the given JavaScript code 'src' and returns the result in JSON.
|
|
37
|
+
/// If some JavaScript exception happens in runtime, the exception message is returned.
|
|
38
|
+
std::string eval(const std::string& src);
|
|
39
|
+
|
|
40
|
+
/// \brief Call a JavaScript function
|
|
41
|
+
/// \param func Name of a JavaScript function
|
|
42
|
+
/// \param args JSON-encoded argument array
|
|
43
|
+
/// \return JSON-encoded result or exception message
|
|
44
|
+
///
|
|
45
|
+
/// This method calls the JavaScript function specified by 'func'
|
|
46
|
+
/// with the JSON-encoded argument array 'args'
|
|
47
|
+
/// and returns the result in JSON.
|
|
48
|
+
/// If some JavaScript exception happens in runtime, the exception message is returned.
|
|
49
|
+
std::string call(const std::string& func, const std::string& args);
|
|
50
|
+
|
|
51
|
+
private:
|
|
52
|
+
v8::Local<v8::Context> new_context();
|
|
53
|
+
v8::Local<v8::String> new_string(const char* str);
|
|
54
|
+
v8::Local<v8::Value> json_parse(v8::Local<v8::Context> context, v8::Local<v8::String> str);
|
|
55
|
+
v8::Local<v8::String> json_stringify(v8::Local<v8::Context> context, v8::Local<v8::Value> value);
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
v8::Isolate* isolate_;
|
|
59
|
+
v8::Persistent<v8::Context> context_;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace v8eval
|
|
63
|
+
|
|
64
|
+
#endif // V8EVAL_H_
|
data/src/v8eval.i
ADDED
data/v8eval.gemspec
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new 'v8eval', '1.0' do |s|
|
|
4
|
+
s.name = 'v8eval'
|
|
5
|
+
s.version = '0.1.3'
|
|
6
|
+
s.licenses = ['MIT']
|
|
7
|
+
s.description = 'Run JavaScript engine V8 in Ruby'
|
|
8
|
+
s.summary = 'v8eval gem is ruby binding to the latest V8 4.7 and
|
|
9
|
+
supports Linux and Mac OS X.'
|
|
10
|
+
s.authors = ['Prateek Papriwal']
|
|
11
|
+
s.email = 'papriwalprateek@gmail.com'
|
|
12
|
+
s.homepage = 'https://github.com/sony/v8eval'
|
|
13
|
+
s.extra_rdoc_files = ['README.md']
|
|
14
|
+
|
|
15
|
+
s.files = Dir['ruby/**/*'] + Dir['src/**/*'] + Dir['build.sh']
|
|
16
|
+
s.files += Dir['LICENSE'] + Dir['README.md'] + Dir['CMakeLists.txt'] + Dir['v8eval.gemspec']
|
|
17
|
+
s.platform = Gem::Platform::RUBY
|
|
18
|
+
s.require_paths = ['ruby/lib', 'ruby/ext']
|
|
19
|
+
s.extensions = Dir['ruby/ext/**/extconf.rb']
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
|
|
22
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
|
23
|
+
s.add_development_dependency 'yard', '0.8.7.6'
|
|
24
|
+
|
|
25
|
+
s.required_ruby_version = '>= 2.0.0'
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: v8eval
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Prateek Papriwal
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-10-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '10.4'
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 10.4.2
|
|
23
|
+
type: :development
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - "~>"
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '10.4'
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: 10.4.2
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: rspec
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.0'
|
|
40
|
+
type: :development
|
|
41
|
+
prerelease: false
|
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '3.0'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: yard
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - '='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 0.8.7.6
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - '='
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 0.8.7.6
|
|
61
|
+
description: Run JavaScript engine V8 in Ruby
|
|
62
|
+
email: papriwalprateek@gmail.com
|
|
63
|
+
executables: []
|
|
64
|
+
extensions:
|
|
65
|
+
- ruby/ext/v8eval/extconf.rb
|
|
66
|
+
extra_rdoc_files:
|
|
67
|
+
- README.md
|
|
68
|
+
files:
|
|
69
|
+
- CMakeLists.txt
|
|
70
|
+
- LICENSE
|
|
71
|
+
- README.md
|
|
72
|
+
- build.sh
|
|
73
|
+
- ruby/Gemfile
|
|
74
|
+
- ruby/Rakefile
|
|
75
|
+
- ruby/build.sh
|
|
76
|
+
- ruby/example/js_add.rb
|
|
77
|
+
- ruby/ext/v8eval/extconf.rb
|
|
78
|
+
- ruby/lib/setup/extension_builder.rb
|
|
79
|
+
- ruby/lib/v8eval.rb
|
|
80
|
+
- ruby/spec/spec_helper.rb
|
|
81
|
+
- ruby/spec/v8eval_spec.rb
|
|
82
|
+
- src/v8eval.cxx
|
|
83
|
+
- src/v8eval.h
|
|
84
|
+
- src/v8eval.i
|
|
85
|
+
- v8eval.gemspec
|
|
86
|
+
homepage: https://github.com/sony/v8eval
|
|
87
|
+
licenses:
|
|
88
|
+
- MIT
|
|
89
|
+
metadata: {}
|
|
90
|
+
post_install_message:
|
|
91
|
+
rdoc_options: []
|
|
92
|
+
require_paths:
|
|
93
|
+
- ruby/lib
|
|
94
|
+
- ruby/ext
|
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: 2.0.0
|
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
requirements: []
|
|
106
|
+
rubyforge_project:
|
|
107
|
+
rubygems_version: 2.4.6
|
|
108
|
+
signing_key:
|
|
109
|
+
specification_version: 4
|
|
110
|
+
summary: v8eval gem is ruby binding to the latest V8 4.7 and supports Linux and Mac
|
|
111
|
+
OS X.
|
|
112
|
+
test_files: []
|
|
113
|
+
has_rdoc:
|