v8eval 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/sony/v8eval.svg)](https://travis-ci.org/sony/v8eval)
|
4
|
+
[![PyPI version](https://badge.fury.io/py/v8eval.svg)](http://badge.fury.io/py/v8eval)
|
5
|
+
[![GoDoc](https://godoc.org/github.com/sony/v8eval/go/v8eval?status.png)](http://godoc.org/github.com/sony/v8eval/go/v8eval)
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/v8eval.svg)](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:
|