v8eval 0.2.4 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CMakeLists.txt +27 -17
- data/README.md +12 -4
- data/build.sh +71 -57
- data/ruby/Gemfile +2 -2
- data/ruby/build.sh +9 -9
- data/ruby/ext/v8eval/extconf.rb +24 -13
- data/ruby/lib/v8eval.rb +0 -16
- data/ruby/spec/v8eval_spec.rb +0 -17
- data/src/v8eval.cxx +49 -128
- data/src/v8eval.h +11 -35
- data/src/v8eval_go.cxx +3 -1
- data/v8eval.gemspec +6 -6
- metadata +13 -22
- data/src/dbgsrv.cxx +0 -211
- data/src/dbgsrv.h +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a5dc6e83198eff2e218f3aa5b2f747cc7d96a41d7c181d7b2e64014faec6730
|
4
|
+
data.tar.gz: 3e41fc88040ec1638af5df47c8fcb191c8a0075d0fb184a3233650e6ee478343
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f54f5361f29e213ed5ec563b6db662435c390d64687db3489bd8807f30a76a435885dc33d14e46cf8d25396939fd248bd611588a38e66fdb1235b24ef699b8d
|
7
|
+
data.tar.gz: 33266b6f1ee5ca2cd77285536f445e4bd0f9526f5a5d8ff096051bc0dffdf6c25325a32609dbe24621b4372bbaf806e11f6c8ed898c6da328d743ab30de194a2
|
data/CMakeLists.txt
CHANGED
@@ -11,33 +11,29 @@ endif(COMMAND cmake_policy)
|
|
11
11
|
include_directories(
|
12
12
|
v8
|
13
13
|
v8/include
|
14
|
-
v8/third_party/icu/source/i18n
|
15
|
-
v8/third_party/icu/source/common
|
16
|
-
uv/include
|
17
14
|
src
|
18
|
-
|
15
|
+
v8/third_party/googletest/src/googletest/include
|
19
16
|
)
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
endif(APPLE)
|
18
|
+
set(v8eval-linkdirs
|
19
|
+
v8/out.gn/x64.release/obj
|
20
|
+
v8/out.gn/x64.release/obj/third_party/googletest
|
21
|
+
)
|
26
22
|
|
27
23
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
28
|
-
|
29
|
-
|
30
|
-
v8/out/x64.release/obj
|
24
|
+
set(v8eval-linkdirs
|
25
|
+
${v8eval-linkdirs}
|
26
|
+
v8/out.gn/x64.release/obj/buildtools/third_party/libc++
|
27
|
+
v8/out.gn/x64.release/obj/buildtools/third_party/libc++abi
|
31
28
|
)
|
32
29
|
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
33
30
|
|
34
31
|
link_directories(
|
35
|
-
|
32
|
+
${v8eval-linkdirs}
|
36
33
|
)
|
37
34
|
|
38
35
|
add_library(v8eval STATIC
|
39
36
|
src/v8eval.cxx
|
40
|
-
src/dbgsrv.cxx
|
41
37
|
)
|
42
38
|
|
43
39
|
add_library(v8eval_go STATIC
|
@@ -54,7 +50,6 @@ add_library(v8eval_ruby STATIC
|
|
54
50
|
|
55
51
|
set(v8eval-cflags
|
56
52
|
-Wall
|
57
|
-
-Wendif-labels
|
58
53
|
-Werror
|
59
54
|
-Wno-missing-field-initializers
|
60
55
|
-Wno-unused-parameter
|
@@ -64,13 +59,28 @@ set(v8eval-cflags
|
|
64
59
|
-fno-rtti
|
65
60
|
-fno-strict-aliasing
|
66
61
|
-fno-threadsafe-statics
|
67
|
-
-fstrict-aliasing
|
68
62
|
-fvisibility=hidden
|
69
63
|
-fvisibility-inlines-hidden
|
70
64
|
-gdwarf-2
|
71
|
-
-std=c++
|
65
|
+
-std=c++14
|
72
66
|
)
|
73
67
|
|
68
|
+
if(APPLE)
|
69
|
+
set(v8eval-cflags
|
70
|
+
${v8eval-cflags}
|
71
|
+
-stdlib=libc++
|
72
|
+
)
|
73
|
+
endif(APPLE)
|
74
|
+
|
75
|
+
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
76
|
+
set(v8eval-cflags
|
77
|
+
${v8eval-cflags}
|
78
|
+
-nostdinc++
|
79
|
+
-isystem ${CMAKE_CURRENT_SOURCE_DIR}/v8/buildtools/third_party/libc++/trunk/include
|
80
|
+
-isystem ${CMAKE_CURRENT_SOURCE_DIR}/v8/buildtools/third_party/libc++abi/trunk/include
|
81
|
+
)
|
82
|
+
endif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
83
|
+
|
74
84
|
string(REPLACE ";" " " v8eval-cflags "${v8eval-cflags}")
|
75
85
|
|
76
86
|
set_target_properties(v8eval PROPERTIES
|
data/README.md
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
[![PyPI version](https://badge.fury.io/py/v8eval.svg)](http://badge.fury.io/py/v8eval)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/v8eval.svg)](https://badge.fury.io/rb/v8eval)
|
5
|
-
[![GoDoc](https://godoc.org/github.com/sony/v8eval/go/v8eval?status.
|
5
|
+
[![GoDoc](https://godoc.org/github.com/sony/v8eval/go/v8eval?status.svg)](http://godoc.org/github.com/sony/v8eval/go/v8eval)
|
6
6
|
|
7
7
|
Multi-language bindings to JavaScript engine V8.
|
8
8
|
|
9
|
-
Currently v8eval provides Go, Python and Ruby bindings to the latest V8
|
9
|
+
Currently v8eval provides Go, Python and Ruby bindings to the latest V8 7.1 and supports Linux and Mac OS X.
|
10
10
|
v8eval uses SWIG and can be extended easily for other languages.
|
11
11
|
|
12
12
|
## Pre-installation
|
@@ -25,9 +25,17 @@ The installation takes several tens of minutes due to V8 build.
|
|
25
25
|
|
26
26
|
#### Go
|
27
27
|
|
28
|
+
v8eval requires Go 1.10 or later.
|
29
|
+
|
30
|
+
```
|
31
|
+
git clone https://github.com/sony/v8eval.git ${GOPATH}/src/github.com/sony/v8eval
|
32
|
+
${GOPATH}/src/github.com/sony/v8eval/go/build.sh install
|
33
|
+
```
|
34
|
+
|
35
|
+
In the case of Linux, you need to build your Go program with `build.sh`:
|
36
|
+
|
28
37
|
```
|
29
|
-
|
30
|
-
$GOPATH/src/github.com/sony/v8eval/go/build.sh install
|
38
|
+
${GOPATH}/src/github.com/sony/v8eval/go/build.sh go build
|
31
39
|
```
|
32
40
|
|
33
41
|
#### Python
|
data/build.sh
CHANGED
@@ -1,109 +1,123 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
V8EVAL_ROOT=`cd $(dirname $0) && pwd`
|
3
|
+
V8EVAL_ROOT=`cd $(dirname ${0}) && pwd`
|
4
4
|
|
5
5
|
PLATFORM=`uname`
|
6
|
-
if [ $PLATFORM = "Linux" ]
|
7
|
-
NUM_CPU_CORES=`cat /proc/cpuinfo | grep cores | grep -o '[0-9]\+' | awk '{total=total+$1}; END{print total}'`
|
8
|
-
|
9
|
-
export CC=$V8EVAL_ROOT/v8/third_party/llvm-build/Release+Asserts/bin/clang
|
10
|
-
export CXX=$V8EVAL_ROOT/v8/third_party/llvm-build/Release+Asserts/bin/clang++
|
11
|
-
elif [ $PLATFORM = "Darwin" ]; then
|
12
|
-
NUM_CPU_CORES=`sysctl -n hw.ncpu`
|
13
|
-
|
14
|
-
export CC=`which clang`
|
15
|
-
export CXX=`which clang++`
|
16
|
-
export CPP="`which clang` -E"
|
17
|
-
export LINK="`which clang++`"
|
18
|
-
export CC_host=`which clang`
|
19
|
-
export CXX_host=`which clang++`
|
20
|
-
export CPP_host="`which clang` -E"
|
21
|
-
export LINK_host=`which clang++`
|
22
|
-
export GYP_DEFINES="clang=1 mac_deployment_target=10.10"
|
23
|
-
else
|
6
|
+
if [ ! ${PLATFORM} = "Linux" -a ! ${PLATFORM} = "Darwin" ]; then
|
24
7
|
echo "unsupported platform: ${PLATFORM}"
|
25
8
|
exit 1
|
26
9
|
fi
|
27
10
|
|
28
|
-
|
29
|
-
|
30
|
-
if [ -d $V8EVAL_ROOT/depot_tools ]; then
|
31
|
-
return 0
|
32
|
-
fi
|
11
|
+
export CC=${V8EVAL_ROOT}/v8/third_party/llvm-build/Release+Asserts/bin/clang
|
12
|
+
export CXX=${V8EVAL_ROOT}/v8/third_party/llvm-build/Release+Asserts/bin/clang++
|
33
13
|
|
34
|
-
|
35
|
-
|
36
|
-
|
14
|
+
if [ ${PLATFORM} = "Linux" ]; then
|
15
|
+
export PATH=${V8EVAL_ROOT}/v8/third_party/binutils/Linux_x64/Release/bin:${PATH}
|
16
|
+
fi
|
37
17
|
|
38
|
-
|
39
|
-
|
18
|
+
install_depot_tools() {
|
19
|
+
export PATH=${V8EVAL_ROOT}/depot_tools:${PATH}
|
20
|
+
if [ -d ${V8EVAL_ROOT}/depot_tools ]; then
|
40
21
|
return 0
|
41
22
|
fi
|
42
23
|
|
43
|
-
cd $V8EVAL_ROOT
|
44
|
-
git clone https://
|
45
|
-
git checkout release-1.7.0
|
24
|
+
cd ${V8EVAL_ROOT}
|
25
|
+
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
46
26
|
}
|
47
27
|
|
48
28
|
install_v8() {
|
49
|
-
if [ -d $V8EVAL_ROOT/v8 ]; then
|
29
|
+
if [ -d ${V8EVAL_ROOT}/v8 ]; then
|
50
30
|
return 0
|
51
31
|
fi
|
52
32
|
|
53
|
-
cd $V8EVAL_ROOT
|
33
|
+
cd ${V8EVAL_ROOT}
|
54
34
|
fetch v8
|
55
35
|
cd v8
|
56
|
-
git checkout
|
57
|
-
|
36
|
+
git checkout 7.1.177
|
37
|
+
gclient sync
|
38
|
+
if [ ${PLATFORM} = "Linux" ]; then
|
39
|
+
./build/install-build-deps.sh
|
40
|
+
fi
|
41
|
+
tools/dev/v8gen.py x64.release -- v8_use_snapshot=false v8_enable_i18n_support=false
|
42
|
+
ninja -v -C out.gn/x64.release
|
58
43
|
}
|
59
44
|
|
60
|
-
|
61
|
-
if [ -
|
45
|
+
archive_lib() {
|
46
|
+
if [ -f ${1}/lib${2}.a ]; then
|
62
47
|
return 0
|
63
48
|
fi
|
64
49
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
50
|
+
if [ `echo ${2} | cut -c 1-3` = "lib" ]; then
|
51
|
+
ar cr ${1}/${2}.a ${1}/${2}/*.o
|
52
|
+
else
|
53
|
+
ar cr ${1}/lib${2}.a ${1}/${2}/*.o
|
54
|
+
fi
|
55
|
+
}
|
56
|
+
|
57
|
+
V8_OUT=${V8EVAL_ROOT}/v8/out.gn/x64.release/obj
|
58
|
+
|
59
|
+
archive_v8() {
|
60
|
+
archive_lib ${V8_OUT} v8_base
|
61
|
+
archive_lib ${V8_OUT} v8_libsampler
|
62
|
+
archive_lib ${V8_OUT} v8_init
|
63
|
+
archive_lib ${V8_OUT} v8_initializers
|
64
|
+
archive_lib ${V8_OUT} v8_nosnapshot
|
65
|
+
archive_lib ${V8_OUT} torque_generated_initializers
|
66
|
+
}
|
67
|
+
|
68
|
+
archive_libcxx() {
|
69
|
+
archive_lib ${V8_OUT}/buildtools/third_party/libc++ libc++
|
70
|
+
}
|
71
|
+
|
72
|
+
archive_libcxxabi() {
|
73
|
+
archive_lib ${V8_OUT}/buildtools/third_party/libc++abi libc++abi
|
74
|
+
}
|
75
|
+
|
76
|
+
archive_googletest() {
|
77
|
+
archive_lib ${V8_OUT}/third_party/googletest gtest
|
78
|
+
archive_lib ${V8_OUT}/third_party/googletest gtest_main
|
72
79
|
}
|
73
80
|
|
74
81
|
build() {
|
75
82
|
install_depot_tools
|
76
83
|
install_v8
|
77
|
-
|
84
|
+
archive_v8
|
85
|
+
if [ ${PLATFORM} = "Linux" ]; then
|
86
|
+
archive_libcxx
|
87
|
+
archive_libcxxabi
|
88
|
+
fi
|
78
89
|
|
79
|
-
cd $V8EVAL_ROOT
|
90
|
+
cd ${V8EVAL_ROOT}
|
80
91
|
mkdir -p build
|
81
92
|
cd build
|
82
93
|
cmake -DCMAKE_BUILD_TYPE=Release -DV8EVAL_TEST=OFF ..
|
83
94
|
make VERBOSE=1
|
95
|
+
|
96
|
+
cd ${V8EVAL_ROOT}
|
97
|
+
rm -rf old_v8_tools_luci-go.git
|
84
98
|
}
|
85
99
|
|
86
100
|
docs() {
|
87
|
-
cd $V8EVAL_ROOT/docs
|
101
|
+
cd ${V8EVAL_ROOT}/docs
|
88
102
|
rm -rf ./html
|
89
103
|
doxygen
|
90
104
|
}
|
91
105
|
|
92
106
|
test() {
|
93
107
|
build
|
94
|
-
|
108
|
+
archive_googletest
|
95
109
|
|
96
|
-
cd $V8EVAL_ROOT/build
|
110
|
+
cd ${V8EVAL_ROOT}/build
|
97
111
|
cmake -DCMAKE_BUILD_TYPE=Release -DV8EVAL_TEST=ON ..
|
98
112
|
make VERBOSE=1
|
99
113
|
./test/v8eval-test
|
100
114
|
}
|
101
115
|
|
102
|
-
# dispatch
|
103
|
-
SUBCOMMAND
|
104
|
-
case
|
105
|
-
""
|
106
|
-
"docs"
|
107
|
-
"test"
|
108
|
-
*
|
116
|
+
# dispatch subcommands
|
117
|
+
SUBCOMMAND=${1}
|
118
|
+
case ${SUBCOMMAND} in
|
119
|
+
"" ) build ;;
|
120
|
+
"docs" ) docs ;;
|
121
|
+
"test" ) test ;;
|
122
|
+
* ) echo "unknown subcommand: ${SUBCOMMAND}"; exit 1 ;;
|
109
123
|
esac
|
data/ruby/Gemfile
CHANGED
data/ruby/build.sh
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
V8EVAL_ROOT=`cd $(dirname $0)/.. && pwd`
|
3
|
+
V8EVAL_ROOT=`cd $(dirname ${0})/.. && pwd`
|
4
4
|
|
5
5
|
build() {
|
6
|
-
cd $V8EVAL_ROOT/ruby
|
6
|
+
cd ${V8EVAL_ROOT}/ruby
|
7
7
|
rake prepare_build
|
8
8
|
rake build_ext
|
9
9
|
}
|
10
10
|
|
11
11
|
install() {
|
12
|
-
cd $V8EVAL_ROOT
|
12
|
+
cd ${V8EVAL_ROOT}
|
13
13
|
gem build v8eval.gemspec
|
14
14
|
gem install v8eval-*.gem
|
15
15
|
}
|
16
16
|
|
17
17
|
docs() {
|
18
|
-
cd $V8EVAL_ROOT/ruby
|
18
|
+
cd ${V8EVAL_ROOT}/ruby
|
19
19
|
rm -rf ./doc
|
20
20
|
mkdir ./doc
|
21
21
|
yardoc --main ../README.md lib/v8eval.rb
|
@@ -24,16 +24,16 @@ docs() {
|
|
24
24
|
test() {
|
25
25
|
build
|
26
26
|
|
27
|
-
gem install
|
28
|
-
cd $V8EVAL_ROOT/ruby
|
27
|
+
gem install bundler -v 1.14.5
|
28
|
+
cd ${V8EVAL_ROOT}/ruby
|
29
29
|
bundle install
|
30
30
|
|
31
|
-
rspec --init
|
32
|
-
rspec
|
31
|
+
bundle exec rspec --init
|
32
|
+
bundle exec rspec
|
33
33
|
}
|
34
34
|
|
35
35
|
# dispatch subcommand
|
36
|
-
SUBCOMMAND="$1";
|
36
|
+
SUBCOMMAND="${1}";
|
37
37
|
case "${SUBCOMMAND}" in
|
38
38
|
"" ) build ;;
|
39
39
|
"install" ) install ;;
|
data/ruby/ext/v8eval/extconf.rb
CHANGED
@@ -6,7 +6,6 @@ require_relative '../../lib/setup/extension_builder'
|
|
6
6
|
# set path variables
|
7
7
|
v8eval_root = File.expand_path('../../..', Dir.pwd)
|
8
8
|
v8_dir = v8eval_root + '/v8'
|
9
|
-
uv_dir = v8eval_root + '/uv'
|
10
9
|
|
11
10
|
# make instance of BuildTool class
|
12
11
|
tool = BuildTool.new(v8eval_root)
|
@@ -23,33 +22,45 @@ INCLUDEDIR = RbConfig::CONFIG['includedir']
|
|
23
22
|
header_dirs = [
|
24
23
|
v8_dir,
|
25
24
|
v8_dir + '/include',
|
26
|
-
uv_dir + '/include',
|
27
25
|
INCLUDEDIR
|
28
26
|
]
|
29
27
|
|
30
28
|
lib_dirs = [
|
31
29
|
v8eval_root + '/build',
|
32
|
-
|
30
|
+
v8_dir + '/out.gn/x64.release/obj',
|
33
31
|
LIBDIR
|
34
32
|
]
|
35
33
|
|
36
|
-
if RUBY_PLATFORM =~ /
|
34
|
+
if RUBY_PLATFORM =~ /linux/
|
37
35
|
lib_dirs += [
|
38
|
-
v8_dir + '/out/x64.release'
|
39
|
-
|
40
|
-
elsif RUBY_PLATFORM =~ /linux/
|
41
|
-
lib_dirs += [
|
42
|
-
v8_dir + '/out/x64.release/obj.target/src',
|
43
|
-
v8_dir + '/out/x64.release/obj.target/third_party/icu'
|
36
|
+
v8_dir + '/out.gn/x64.release/obj/buildtools/third_party/libc++',
|
37
|
+
v8_dir + '/out.gn/x64.release/obj/buildtools/third_party/libc++abi'
|
44
38
|
]
|
39
|
+
end
|
45
40
|
|
41
|
+
dir_config('', header_dirs, lib_dirs)
|
42
|
+
|
43
|
+
if RUBY_PLATFORM =~ /linux/
|
46
44
|
RbConfig::MAKEFILE_CONFIG['CC'] = v8_dir + '/third_party/llvm-build/Release+Asserts/bin/clang'
|
47
45
|
RbConfig::MAKEFILE_CONFIG['CXX'] = v8_dir + '/third_party/llvm-build/Release+Asserts/bin/clang++'
|
48
46
|
end
|
49
47
|
|
50
|
-
|
48
|
+
$LDFLAGS << ' -lv8eval' +
|
49
|
+
' -lv8eval_ruby' +
|
50
|
+
' -lv8_libplatform' +
|
51
|
+
' -lv8_base' +
|
52
|
+
' -lv8_libbase' +
|
53
|
+
' -lv8_libsampler' +
|
54
|
+
' -lv8_init' +
|
55
|
+
' -lv8_initializers' +
|
56
|
+
' -lv8_nosnapshot' +
|
57
|
+
' -ltorque_generated_initializers'
|
58
|
+
$CPPFLAGS << ' -O3 -std=c++14 -stdlib=libc++'
|
51
59
|
|
52
|
-
|
53
|
-
$
|
60
|
+
if RUBY_PLATFORM =~ /linux/
|
61
|
+
$LDFLAGS << ' -lrt -lc++ -lc++abi'
|
62
|
+
$CPPFLAGS << ' -isystem' + v8_dir + '/buildtools/third_party/libc++/trunk/include' +
|
63
|
+
' -isystem' + v8_dir + '/buildtools/third_party/libc++abi/trunk/include'
|
64
|
+
end
|
54
65
|
|
55
66
|
create_makefile('v8eval/v8eval')
|
data/ruby/lib/v8eval.rb
CHANGED
@@ -58,22 +58,6 @@ module V8Eval
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
62
|
-
# Starts a debug server associated with the V8 instance.
|
63
|
-
# @param [Integer] port TCP/IP port the server will listen, at localhost.
|
64
|
-
# @return nil.
|
65
|
-
# @raise [TypeError] If port is not an int.
|
66
|
-
# @raise [V8Error] If failing to start the debug server.
|
67
|
-
def enable_debugger(port)
|
68
|
-
fail TypeError, 'port not integer' unless port.is_a?(Integer)
|
69
|
-
fail V8Error, 'failed to start debug server' unless @v8.enable_debugger(port)
|
70
|
-
end
|
71
|
-
|
72
|
-
# Stops the debug server, if running.
|
73
|
-
# @return nil.
|
74
|
-
def disable_debugger
|
75
|
-
@v8.disable_debugger
|
76
|
-
end
|
77
61
|
end
|
78
62
|
end
|
79
63
|
|
data/ruby/spec/v8eval_spec.rb
CHANGED
@@ -55,20 +55,3 @@ RSpec.describe V8Eval, '#multithreading' do
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
59
|
-
RSpec.describe V8Eval, '#test_debugger' do
|
60
|
-
context 'with debugging functionality' do
|
61
|
-
it 'should enable and disable debugger properly' do
|
62
|
-
v8 = V8Eval::V8.new
|
63
|
-
expect { v8.enable_debugger(0.1) }.to raise_exception(TypeError)
|
64
|
-
expect { v8.enable_debugger(-1) }.to raise_exception(V8Eval::V8Error)
|
65
|
-
|
66
|
-
port = 12_345
|
67
|
-
expect(v8.enable_debugger(port)).to be nil
|
68
|
-
expect { v8.enable_debugger(port) }.to raise_exception(V8Eval::V8Error)
|
69
|
-
expect(v8.disable_debugger).to be nil
|
70
|
-
expect(v8.enable_debugger(port)).to be nil
|
71
|
-
expect(v8.disable_debugger).to be nil
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/src/v8eval.cxx
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#include "v8eval.h"
|
2
|
-
#include "dbgsrv.h"
|
3
2
|
|
4
|
-
#include <
|
5
|
-
#include <
|
3
|
+
#include <cassert>
|
4
|
+
#include <cstdlib>
|
5
|
+
#include <cstring>
|
6
6
|
|
7
7
|
#include "libplatform/libplatform.h"
|
8
8
|
|
@@ -10,15 +10,15 @@ namespace v8eval {
|
|
10
10
|
|
11
11
|
static v8::Platform* platform = nullptr;
|
12
12
|
|
13
|
+
void set_flags(const std::string& flags) {
|
14
|
+
v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.length()));
|
15
|
+
}
|
16
|
+
|
13
17
|
bool initialize() {
|
14
18
|
if (platform) {
|
15
19
|
return false;
|
16
20
|
}
|
17
21
|
|
18
|
-
if (!v8::V8::InitializeICU()) {
|
19
|
-
return false;
|
20
|
-
}
|
21
|
-
|
22
22
|
platform = v8::platform::CreateDefaultPlatform();
|
23
23
|
v8::V8::InitializePlatform(platform);
|
24
24
|
|
@@ -39,39 +39,12 @@ bool dispose() {
|
|
39
39
|
return true;
|
40
40
|
}
|
41
41
|
|
42
|
-
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
43
|
-
public:
|
44
|
-
virtual void* Allocate(size_t length) {
|
45
|
-
void* data = AllocateUninitialized(length);
|
46
|
-
return data == NULL ? data : memset(data, 0, length);
|
47
|
-
}
|
48
|
-
|
49
|
-
virtual void* AllocateUninitialized(size_t length) {
|
50
|
-
return malloc(length);
|
51
|
-
}
|
52
|
-
|
53
|
-
virtual void Free(void* data, size_t) {
|
54
|
-
free(data);
|
55
|
-
}
|
56
|
-
};
|
57
|
-
|
58
|
-
static ArrayBufferAllocator allocator;
|
59
|
-
|
60
42
|
_V8::_V8() {
|
61
43
|
v8::Isolate::CreateParams create_params;
|
62
|
-
create_params.array_buffer_allocator =
|
44
|
+
create_params.array_buffer_allocator =
|
45
|
+
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
63
46
|
isolate_ = v8::Isolate::New(create_params);
|
64
47
|
|
65
|
-
dbg_server_ = nullptr;
|
66
|
-
dbg_isolate_ = nullptr;
|
67
|
-
callback_ = nullptr;
|
68
|
-
callback_opq_ = nullptr;
|
69
|
-
|
70
|
-
// Use Isolate's local storage to store a pointer to the associated
|
71
|
-
// V8 instance. This is retrieved in the V8 debugger's callback, as
|
72
|
-
// the instance pointer is the only context we get from the caller.
|
73
|
-
isolate_->SetData(0, this);
|
74
|
-
|
75
48
|
v8::Locker locker(isolate_);
|
76
49
|
|
77
50
|
v8::Isolate::Scope isolate_scope(isolate_);
|
@@ -80,20 +53,20 @@ _V8::_V8() {
|
|
80
53
|
}
|
81
54
|
|
82
55
|
_V8::~_V8() {
|
83
|
-
if (dbg_server_) {
|
84
|
-
delete dbg_server_;
|
85
|
-
}
|
86
|
-
|
87
|
-
context_.Reset();
|
88
56
|
isolate_->Dispose();
|
89
57
|
}
|
90
58
|
|
91
|
-
v8::Local<v8::Context> _V8::
|
92
|
-
|
59
|
+
v8::Local<v8::Context> _V8::context() {
|
60
|
+
assert(context_.IsEmpty());
|
61
|
+
return v8::Local<v8::Context>::New(isolate_, context_);
|
62
|
+
}
|
63
|
+
|
64
|
+
v8::Local<v8::Context> _V8::new_context(v8::Local<v8::ObjectTemplate> global_tmpl, v8::Local<v8::Value> global_obj) {
|
65
|
+
if (global_tmpl.IsEmpty() && global_obj.IsEmpty()) {
|
93
66
|
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
|
94
67
|
return v8::Context::New(isolate_, nullptr, global);
|
95
68
|
} else {
|
96
|
-
return v8::
|
69
|
+
return v8::Context::New(isolate_, nullptr, global_tmpl, global_obj);
|
97
70
|
}
|
98
71
|
}
|
99
72
|
|
@@ -101,14 +74,14 @@ v8::Local<v8::String> _V8::new_string(const char* str) {
|
|
101
74
|
return v8::String::NewFromUtf8(isolate_, str ? str : "", v8::NewStringType::kNormal).ToLocalChecked();
|
102
75
|
}
|
103
76
|
|
104
|
-
|
105
|
-
v8::String::Utf8Value str(value);
|
77
|
+
std::string _V8::to_std_string(v8::Local<v8::Value> value) {
|
78
|
+
v8::String::Utf8Value str(isolate_, value);
|
106
79
|
return *str ? *str : "Error: Cannot convert to string";
|
107
80
|
}
|
108
81
|
|
109
82
|
v8::Local<v8::Value> _V8::json_parse(v8::Local<v8::Context> context, v8::Local<v8::String> str) {
|
110
83
|
v8::Local<v8::Object> global = context->Global();
|
111
|
-
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject();
|
84
|
+
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject(isolate_);
|
112
85
|
v8::Local<v8::Function> parse = v8::Local<v8::Function>::Cast(json->Get(context, new_string("parse")).ToLocalChecked());
|
113
86
|
|
114
87
|
v8::Local<v8::Value> result;
|
@@ -122,14 +95,14 @@ v8::Local<v8::Value> _V8::json_parse(v8::Local<v8::Context> context, v8::Local<v
|
|
122
95
|
|
123
96
|
v8::Local<v8::String> _V8::json_stringify(v8::Local<v8::Context> context, v8::Local<v8::Value> value) {
|
124
97
|
v8::Local<v8::Object> global = context->Global();
|
125
|
-
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject();
|
98
|
+
v8::Local<v8::Object> json = global->Get(context, new_string("JSON")).ToLocalChecked()->ToObject(isolate_);
|
126
99
|
v8::Local<v8::Function> stringify = v8::Local<v8::Function>::Cast(json->Get(context, new_string("stringify")).ToLocalChecked());
|
127
100
|
|
128
101
|
v8::Local<v8::Value> result;
|
129
102
|
if (!stringify->Call(context, json, 1, &value).ToLocal(&result)) {
|
130
103
|
return new_string("");
|
131
104
|
} else {
|
132
|
-
return result->ToString();
|
105
|
+
return result->ToString(isolate_);
|
133
106
|
}
|
134
107
|
}
|
135
108
|
|
@@ -139,7 +112,7 @@ std::string _V8::eval(const std::string& src) {
|
|
139
112
|
v8::Isolate::Scope isolate_scope(isolate_);
|
140
113
|
v8::HandleScope handle_scope(isolate_);
|
141
114
|
|
142
|
-
v8::Local<v8::Context> context =
|
115
|
+
v8::Local<v8::Context> context = this->context();
|
143
116
|
v8::Context::Scope context_scope(context);
|
144
117
|
|
145
118
|
v8::TryCatch try_catch(isolate_);
|
@@ -155,7 +128,12 @@ std::string _V8::eval(const std::string& src) {
|
|
155
128
|
} else {
|
156
129
|
v8::Local<v8::Value> result;
|
157
130
|
if (!script->Run(context).ToLocal(&result)) {
|
158
|
-
|
131
|
+
v8::Local<v8::Value> stack;
|
132
|
+
if (!try_catch.StackTrace(context).ToLocal(&stack)) {
|
133
|
+
return to_std_string(try_catch.Exception());
|
134
|
+
} else {
|
135
|
+
return to_std_string(stack);
|
136
|
+
}
|
159
137
|
} else {
|
160
138
|
return to_std_string(json_stringify(context, result));
|
161
139
|
}
|
@@ -168,7 +146,7 @@ std::string _V8::call(const std::string& func, const std::string& args) {
|
|
168
146
|
v8::Isolate::Scope isolate_scope(isolate_);
|
169
147
|
v8::HandleScope handle_scope(isolate_);
|
170
148
|
|
171
|
-
v8::Local<v8::Context> context =
|
149
|
+
v8::Local<v8::Context> context = this->context();
|
172
150
|
v8::Context::Scope context_scope(context);
|
173
151
|
|
174
152
|
v8::TryCatch try_catch(isolate_);
|
@@ -196,93 +174,36 @@ std::string _V8::call(const std::string& func, const std::string& args) {
|
|
196
174
|
}
|
197
175
|
}
|
198
176
|
|
199
|
-
|
200
|
-
|
201
|
-
return false;
|
202
|
-
}
|
177
|
+
void Heap(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
178
|
+
v8::Isolate* isolate = args.GetIsolate();
|
203
179
|
|
204
|
-
|
205
|
-
|
206
|
-
delete dbg_server_;
|
207
|
-
dbg_server_ = nullptr;
|
208
|
-
return false;
|
209
|
-
}
|
210
|
-
|
211
|
-
return true;
|
212
|
-
}
|
213
|
-
|
214
|
-
void _V8::disable_debugger() {
|
215
|
-
if (dbg_server_) {
|
216
|
-
delete dbg_server_;
|
217
|
-
dbg_server_ = nullptr;
|
218
|
-
}
|
219
|
-
}
|
180
|
+
v8::HeapStatistics s;
|
181
|
+
isolate->GetHeapStatistics(&s);
|
220
182
|
|
221
|
-
|
222
|
-
v8::
|
223
|
-
|
224
|
-
|
183
|
+
v8::Local<v8::Object> obj = v8::Object::New(isolate);
|
184
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "totalHeapSize"), v8::Number::New(isolate, s.total_heap_size()));
|
185
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "totalHeapSizeExecutable"), v8::Number::New(isolate, s.total_heap_size_executable()));
|
186
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "totalPhysicalSize"), v8::Number::New(isolate, s.total_physical_size()));
|
187
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "totalAvailableSize"), v8::Number::New(isolate, s.total_available_size()));
|
188
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "usedHeapSize"), v8::Number::New(isolate, s.used_heap_size()));
|
189
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "heapSizeLimit"), v8::Number::New(isolate, s.heap_size_limit()));
|
190
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "mallocedMemory"), v8::Number::New(isolate, s.malloced_memory()));
|
191
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "peakMallocedMemory"), v8::Number::New(isolate, s.peak_malloced_memory()));
|
192
|
+
obj->Set(v8::String::NewFromUtf8(isolate, "doesZapGarbage"), v8::Number::New(isolate, s.does_zap_garbage()));
|
225
193
|
|
226
|
-
|
227
|
-
_v8->callback_(string, _v8->callback_opq_);
|
228
|
-
}
|
194
|
+
args.GetReturnValue().Set(obj);
|
229
195
|
}
|
230
196
|
|
231
|
-
|
232
|
-
v8::Isolate::CreateParams create_params;
|
233
|
-
create_params.array_buffer_allocator = &allocator;
|
234
|
-
dbg_isolate_ = v8::Isolate::New(create_params);
|
235
|
-
|
236
|
-
if (callback_) {
|
237
|
-
return false;
|
238
|
-
}
|
239
|
-
|
240
|
-
callback_ = cb;
|
241
|
-
callback_opq_ = cbopq;
|
242
|
-
|
243
|
-
// Set Debuger callback.
|
197
|
+
void _V8::enable_heap_report() {
|
244
198
|
v8::Locker locker(isolate_);
|
245
|
-
v8::Isolate::Scope isolate_scope(isolate_);
|
246
|
-
v8::HandleScope handle_scope(isolate_);
|
247
|
-
v8::Debug::SetMessageHandler(debugger_message_handler);
|
248
199
|
|
249
|
-
return true;
|
250
|
-
}
|
251
|
-
|
252
|
-
void _V8::debugger_process() {
|
253
|
-
// Process debug messages on behalf of the V8 instance.
|
254
|
-
v8::Locker locker(isolate_);
|
255
200
|
v8::Isolate::Scope isolate_scope(isolate_);
|
256
201
|
v8::HandleScope handle_scope(isolate_);
|
257
202
|
|
258
|
-
v8::
|
259
|
-
|
260
|
-
|
261
|
-
bool _V8::debugger_send(const std::string& cmd) {
|
262
|
-
v8::Locker locker(dbg_isolate_);
|
263
|
-
v8::Isolate::Scope isolate_scope(dbg_isolate_);
|
264
|
-
v8::HandleScope handle_scope(dbg_isolate_);
|
265
|
-
|
266
|
-
if (!callback_) {
|
267
|
-
return false;
|
268
|
-
}
|
269
|
-
|
270
|
-
v8::Local<v8::String> vstr = v8::String::NewFromUtf8(dbg_isolate_, cmd.c_str(), v8::NewStringType::kNormal).ToLocalChecked();
|
271
|
-
v8::String::Value v(vstr);
|
272
|
-
v8::Debug::SendCommand(isolate_, *v, v.length());
|
273
|
-
return true;
|
274
|
-
}
|
275
|
-
|
276
|
-
void _V8::debugger_stop() {
|
277
|
-
v8::Locker locker(isolate_);
|
278
|
-
v8::Isolate::Scope isolate_scope(isolate_);
|
279
|
-
v8::HandleScope handle_scope(isolate_);
|
280
|
-
v8::Debug::SetMessageHandler(nullptr);
|
203
|
+
v8::Local<v8::Context> context = this->context();
|
204
|
+
v8::Context::Scope context_scope(context);
|
281
205
|
|
282
|
-
|
283
|
-
callback_opq_ = nullptr;
|
284
|
-
dbg_isolate_->Dispose();
|
285
|
-
dbg_isolate_ = nullptr;
|
206
|
+
context->Global()->Set(new_string("heap"), v8::FunctionTemplate::New(isolate_, Heap)->GetFunction());
|
286
207
|
}
|
287
208
|
|
288
209
|
} // namespace v8eval
|
data/src/v8eval.h
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
#include <string>
|
5
5
|
|
6
6
|
#include "v8.h"
|
7
|
-
#include "v8-debug.h"
|
8
7
|
|
9
8
|
/// \file
|
10
9
|
namespace v8eval {
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
/// \brief Set the given V8 flags
|
12
|
+
///
|
13
|
+
/// This method sets the given V8 flags.
|
14
|
+
void set_flags(const std::string& flags);
|
15
15
|
|
16
16
|
/// \brief Initialize the V8 runtime environment
|
17
17
|
/// \return success or not as boolean
|
@@ -53,45 +53,21 @@ class _V8 {
|
|
53
53
|
/// If some JavaScript exception happens in runtime, the exception message is returned.
|
54
54
|
std::string call(const std::string& func, const std::string& args);
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
/// \return success or not as boolean
|
59
|
-
///
|
60
|
-
/// After the debugger is successfully started, it will be possible to
|
61
|
-
/// send commands and receive events at the specified port. When the
|
62
|
-
/// debugger is started, the Javascript's "debugger" statement will
|
63
|
-
/// cause the V8 instance to halt and wait for instructions through
|
64
|
-
/// the debugger port.
|
65
|
-
bool enable_debugger(int port);
|
66
|
-
|
67
|
-
/// \brief Stop the debug server, if running.
|
68
|
-
///
|
69
|
-
/// The debug server, if currently running, will be stopped, causing
|
70
|
-
/// connections to remote debuggers to be dropped.
|
71
|
-
void disable_debugger();
|
56
|
+
protected:
|
57
|
+
void enable_heap_report();
|
72
58
|
|
73
|
-
|
74
|
-
|
75
|
-
|
59
|
+
v8::Local<v8::Context> context();
|
60
|
+
v8::Local<v8::Context> new_context(
|
61
|
+
v8::Local<v8::ObjectTemplate> global_tmpl = v8::Local<v8::ObjectTemplate>(),
|
62
|
+
v8::Local<v8::Value> global_obj = v8::Local<v8::Value>());
|
76
63
|
v8::Local<v8::String> new_string(const char* str);
|
77
64
|
v8::Local<v8::Value> json_parse(v8::Local<v8::Context> context, v8::Local<v8::String> str);
|
78
65
|
v8::Local<v8::String> json_stringify(v8::Local<v8::Context> context, v8::Local<v8::Value> value);
|
79
|
-
|
80
|
-
bool debugger_init(debugger_cb cb, void *cbopq);
|
81
|
-
bool debugger_send(const std::string& cmd);
|
82
|
-
void debugger_process();
|
83
|
-
void debugger_stop();
|
66
|
+
std::string to_std_string(v8::Local<v8::Value> value);
|
84
67
|
|
85
68
|
private:
|
86
69
|
v8::Isolate* isolate_;
|
87
70
|
v8::Persistent<v8::Context> context_;
|
88
|
-
|
89
|
-
DbgSrv* dbg_server_;
|
90
|
-
v8::Isolate* dbg_isolate_;
|
91
|
-
debugger_cb callback_;
|
92
|
-
void* callback_opq_;
|
93
|
-
|
94
|
-
friend class DbgSrv;
|
95
71
|
};
|
96
72
|
|
97
73
|
} // namespace v8eval
|
data/src/v8eval_go.cxx
CHANGED
data/v8eval.gemspec
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
Gem::Specification.new 'v8eval', '1.0' do |s|
|
2
2
|
s.name = 'v8eval'
|
3
|
-
s.version = '0.2
|
3
|
+
s.version = '0.3.2'
|
4
4
|
s.licenses = ['MIT']
|
5
5
|
s.description = 'Run JavaScript engine V8 in Ruby'
|
6
|
-
s.summary = 'v8eval gem is ruby binding to the latest V8
|
6
|
+
s.summary = 'v8eval gem is ruby binding to the latest V8 and supports
|
7
7
|
Linux and Mac OS X.'
|
8
|
-
s.authors = ['Prateek Papriwal']
|
9
|
-
s.email = '
|
8
|
+
s.authors = ['Prateek Papriwal', 'Yoshiyuki Mineo']
|
9
|
+
s.email = 'Yoshiyuki.Mineo@sony.com'
|
10
10
|
s.homepage = 'https://github.com/sony/v8eval'
|
11
11
|
s.extra_rdoc_files = ['README.md']
|
12
12
|
|
@@ -17,9 +17,9 @@ Gem::Specification.new 'v8eval', '1.0' do |s|
|
|
17
17
|
s.require_paths = ['ruby/lib', 'ruby/ext']
|
18
18
|
s.extensions = Dir['ruby/ext/**/extconf.rb']
|
19
19
|
|
20
|
-
s.add_development_dependency 'rake', '
|
20
|
+
s.add_development_dependency 'rake', '>= 12.3.3'
|
21
21
|
s.add_development_dependency 'rspec', '~> 3.0'
|
22
|
-
s.add_development_dependency 'yard', '0.
|
22
|
+
s.add_development_dependency 'yard', '>= 0.9.11'
|
23
23
|
|
24
24
|
s.required_ruby_version = '>= 2.0.0'
|
25
25
|
end
|
metadata
CHANGED
@@ -1,35 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: v8eval
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Prateek Papriwal
|
8
|
+
- Yoshiyuki Mineo
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2020-12-29 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rake
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '10.4'
|
20
18
|
- - ">="
|
21
19
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
20
|
+
version: 12.3.3
|
23
21
|
type: :development
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
24
|
requirements:
|
27
|
-
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '10.4'
|
30
25
|
- - ">="
|
31
26
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
27
|
+
version: 12.3.3
|
33
28
|
- !ruby/object:Gem::Dependency
|
34
29
|
name: rspec
|
35
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -48,18 +43,18 @@ dependencies:
|
|
48
43
|
name: yard
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
45
|
requirements:
|
51
|
-
- -
|
46
|
+
- - ">="
|
52
47
|
- !ruby/object:Gem::Version
|
53
|
-
version: 0.
|
48
|
+
version: 0.9.11
|
54
49
|
type: :development
|
55
50
|
prerelease: false
|
56
51
|
version_requirements: !ruby/object:Gem::Requirement
|
57
52
|
requirements:
|
58
|
-
- -
|
53
|
+
- - ">="
|
59
54
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.
|
55
|
+
version: 0.9.11
|
61
56
|
description: Run JavaScript engine V8 in Ruby
|
62
|
-
email:
|
57
|
+
email: Yoshiyuki.Mineo@sony.com
|
63
58
|
executables: []
|
64
59
|
extensions:
|
65
60
|
- ruby/ext/v8eval/extconf.rb
|
@@ -79,8 +74,6 @@ files:
|
|
79
74
|
- ruby/lib/setup/extension_builder.rb
|
80
75
|
- ruby/lib/v8eval.rb
|
81
76
|
- ruby/spec/v8eval_spec.rb
|
82
|
-
- src/dbgsrv.cxx
|
83
|
-
- src/dbgsrv.h
|
84
77
|
- src/v8eval.cxx
|
85
78
|
- src/v8eval.h
|
86
79
|
- src/v8eval_go.cxx
|
@@ -110,11 +103,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
103
|
- !ruby/object:Gem::Version
|
111
104
|
version: '0'
|
112
105
|
requirements: []
|
113
|
-
|
114
|
-
rubygems_version: 2.4.6
|
106
|
+
rubygems_version: 3.1.4
|
115
107
|
signing_key:
|
116
108
|
specification_version: 4
|
117
|
-
summary: v8eval gem is ruby binding to the latest V8
|
118
|
-
|
109
|
+
summary: v8eval gem is ruby binding to the latest V8 and supports Linux and Mac OS
|
110
|
+
X.
|
119
111
|
test_files: []
|
120
|
-
has_rdoc:
|
data/src/dbgsrv.cxx
DELETED
@@ -1,211 +0,0 @@
|
|
1
|
-
#include "dbgsrv.h"
|
2
|
-
#include "v8eval.h"
|
3
|
-
|
4
|
-
namespace v8eval {
|
5
|
-
|
6
|
-
//
|
7
|
-
// DbgSrv
|
8
|
-
//
|
9
|
-
|
10
|
-
// container_of helper function
|
11
|
-
//
|
12
|
-
// libuv does not accept opaque values in its callbacks, so we have to
|
13
|
-
// recover the instance of the debug server (and associated v8 vm)
|
14
|
-
// through a C++ version of offsetof().
|
15
|
-
template<class A, class B, class C>
|
16
|
-
A* container_of(B* ptr, const C A::* member) {
|
17
|
-
size_t offset = (size_t) &(reinterpret_cast<A*>(0)->*member);
|
18
|
-
return (A*)((char *)ptr - offset);
|
19
|
-
}
|
20
|
-
|
21
|
-
DbgSrv::DbgSrv(_V8& v8) : v8_(v8) {
|
22
|
-
dbgsrv_port_ = 0;
|
23
|
-
uv_loop_init(&dbgsrv_loop_);
|
24
|
-
|
25
|
-
// Start up the Debugger Processing Loop
|
26
|
-
uv_loop_init(&dbgproc_loop_);
|
27
|
-
uv_async_init(&dbgproc_loop_, &dbgproc_proc_, dbgproc_do_proc);
|
28
|
-
uv_async_init(&dbgproc_loop_, &dbgproc_stop_, dbgproc_do_stop);
|
29
|
-
uv_thread_create(&dbgproc_thread_, dbgproc, this);
|
30
|
-
|
31
|
-
status_ = dbgsrv_offline;
|
32
|
-
}
|
33
|
-
|
34
|
-
DbgSrv::~DbgSrv() {
|
35
|
-
if (status_ != dbgsrv_offline) {
|
36
|
-
v8_.debugger_stop();
|
37
|
-
uv_async_send(&dbgsrv_stop_);
|
38
|
-
uv_thread_join(&dbgsrv_thread_);
|
39
|
-
}
|
40
|
-
uv_loop_close(&dbgsrv_loop_);
|
41
|
-
|
42
|
-
uv_async_send(&dbgproc_stop_);
|
43
|
-
uv_thread_join(&dbgproc_thread_);
|
44
|
-
uv_loop_close(&dbgproc_loop_);
|
45
|
-
}
|
46
|
-
|
47
|
-
static void end_write(uv_write_t *req, int status) {
|
48
|
-
if (status) {
|
49
|
-
fprintf(stderr, "write: %s\n", uv_strerror(status));
|
50
|
-
}
|
51
|
-
free(req);
|
52
|
-
}
|
53
|
-
|
54
|
-
void DbgSrv::dbgsrv_do_send(uv_async_t *async) {
|
55
|
-
DbgSrv *db = container_of(async, &DbgSrv::dbgsrv_send_);
|
56
|
-
uv_buf_t buf;
|
57
|
-
uv_write_t *wreq;
|
58
|
-
|
59
|
-
while (!db->msg_queue_.empty()) {
|
60
|
-
std::string& str = db->msg_queue_.back();
|
61
|
-
|
62
|
-
buf = uv_buf_init((char *)str.c_str(), (unsigned int)str.size());
|
63
|
-
wreq = (uv_write_t *)malloc(sizeof(*wreq));
|
64
|
-
uv_write(wreq, (uv_stream_t *)&db->dbgsrv_clnt_, &buf, 1, end_write);
|
65
|
-
db->msg_queue_.pop_back();
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
void DbgSrv::dbgsrv_do_clnt(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
|
70
|
-
DbgSrv *db = container_of(client, &DbgSrv::dbgsrv_clnt_);
|
71
|
-
|
72
|
-
if (nread == 0) return;
|
73
|
-
|
74
|
-
if (nread < 0) {
|
75
|
-
// Close the client
|
76
|
-
uv_close((uv_handle_t *)&db->dbgsrv_send_, NULL);
|
77
|
-
uv_close((uv_handle_t *)&db->dbgsrv_clnt_, NULL);
|
78
|
-
db->status_ = dbgsrv_started;
|
79
|
-
return;
|
80
|
-
}
|
81
|
-
|
82
|
-
const std::string string(buf->base, nread);
|
83
|
-
db->v8_.debugger_send(string);
|
84
|
-
free(buf->base);
|
85
|
-
|
86
|
-
uv_async_send(&db->dbgproc_proc_);
|
87
|
-
}
|
88
|
-
|
89
|
-
static void alloc_buffer(uv_handle_t *handle, size_t size, uv_buf_t *buf) {
|
90
|
-
buf->len = size;
|
91
|
-
buf->base = (char*) malloc(size);
|
92
|
-
}
|
93
|
-
|
94
|
-
void DbgSrv::dbgsrv_do_serv(uv_stream_t *server, int status) {
|
95
|
-
DbgSrv *db = container_of(server, &DbgSrv::dbgsrv_serv_);
|
96
|
-
|
97
|
-
if (status < 0) {
|
98
|
-
return;
|
99
|
-
}
|
100
|
-
|
101
|
-
// Connect with the client.
|
102
|
-
uv_tcp_init(&db->dbgsrv_loop_, &db->dbgsrv_clnt_);
|
103
|
-
if (uv_accept(server, (uv_stream_t *)&db->dbgsrv_clnt_)) {
|
104
|
-
uv_close((uv_handle_t *)&db->dbgsrv_clnt_, NULL);
|
105
|
-
return;
|
106
|
-
}
|
107
|
-
|
108
|
-
// Setup async R/W callbacks.
|
109
|
-
uv_async_init(&db->dbgsrv_loop_, &db->dbgsrv_send_, dbgsrv_do_send);
|
110
|
-
uv_read_start((uv_stream_t *)&db->dbgsrv_clnt_, alloc_buffer, dbgsrv_do_clnt);
|
111
|
-
|
112
|
-
db->status_ = dbgsrv_connected;
|
113
|
-
}
|
114
|
-
|
115
|
-
void DbgSrv::dbgsrv_do_stop(uv_async_t *async) {
|
116
|
-
DbgSrv *db = container_of(async, &DbgSrv::dbgsrv_stop_);
|
117
|
-
|
118
|
-
// Stop Server Loop
|
119
|
-
if (db->status_ == dbgsrv_connected) {
|
120
|
-
uv_close((uv_handle_t *)&db->dbgsrv_send_, NULL);
|
121
|
-
uv_close((uv_handle_t *)&db->dbgsrv_clnt_, NULL);
|
122
|
-
db->status_ = dbgsrv_started;
|
123
|
-
}
|
124
|
-
if (db->status_ == dbgsrv_started) {
|
125
|
-
uv_close((uv_handle_t *)&db->dbgsrv_serv_, NULL);
|
126
|
-
uv_close((uv_handle_t *)&db->dbgsrv_stop_, NULL);
|
127
|
-
}
|
128
|
-
}
|
129
|
-
|
130
|
-
void DbgSrv::dbgsrv(void *ptr) {
|
131
|
-
DbgSrv *db = (DbgSrv*)ptr;
|
132
|
-
|
133
|
-
uv_run(&db->dbgsrv_loop_, UV_RUN_DEFAULT);
|
134
|
-
}
|
135
|
-
|
136
|
-
void DbgSrv::dbgproc_do_stop(uv_async_t *async) {
|
137
|
-
DbgSrv *db = container_of(async, &DbgSrv::dbgproc_stop_);
|
138
|
-
|
139
|
-
uv_close((uv_handle_t *)&db->dbgproc_proc_, NULL);
|
140
|
-
uv_close((uv_handle_t *)&db->dbgproc_stop_, NULL);
|
141
|
-
}
|
142
|
-
|
143
|
-
void DbgSrv::dbgproc_do_proc(uv_async_t *async) {
|
144
|
-
DbgSrv *db = container_of(async, &DbgSrv::dbgproc_proc_);
|
145
|
-
|
146
|
-
db->v8_.debugger_process();
|
147
|
-
}
|
148
|
-
|
149
|
-
void DbgSrv::dbgproc(void *ptr) {
|
150
|
-
DbgSrv *db = (DbgSrv*)ptr;
|
151
|
-
|
152
|
-
uv_run(&db->dbgproc_loop_, UV_RUN_DEFAULT);
|
153
|
-
}
|
154
|
-
|
155
|
-
void DbgSrv::recv_from_debugger(std::string& string, void *opq) {
|
156
|
-
DbgSrv *db = (DbgSrv *)opq;
|
157
|
-
|
158
|
-
db->msg_queue_.push_front(string);
|
159
|
-
uv_async_send(&db->dbgsrv_send_);
|
160
|
-
}
|
161
|
-
|
162
|
-
bool DbgSrv::start(int port) {
|
163
|
-
struct sockaddr_in addr;
|
164
|
-
|
165
|
-
if (status_ != dbgsrv_offline) {
|
166
|
-
return false;
|
167
|
-
}
|
168
|
-
|
169
|
-
if (port != (uint16_t)port) {
|
170
|
-
return false;
|
171
|
-
}
|
172
|
-
|
173
|
-
// Set up the TCP Connection.
|
174
|
-
uv_tcp_init(&dbgsrv_loop_, &dbgsrv_serv_);
|
175
|
-
uv_ip4_addr("127.0.0.1", port, &addr);
|
176
|
-
if (uv_tcp_bind(&dbgsrv_serv_, (const struct sockaddr*)&addr, 0)) {
|
177
|
-
uv_close((uv_handle_t *)&dbgsrv_serv_, NULL);
|
178
|
-
perror("bind");
|
179
|
-
return false;
|
180
|
-
}
|
181
|
-
|
182
|
-
if (port == 0) {
|
183
|
-
int addrlen = sizeof(addr);
|
184
|
-
if (uv_tcp_getsockname(&dbgsrv_serv_, (struct sockaddr*)&addr, &addrlen)) {
|
185
|
-
uv_close((uv_handle_t *)&dbgsrv_serv_, NULL);
|
186
|
-
perror("getsockname");
|
187
|
-
return false;
|
188
|
-
}
|
189
|
-
dbgsrv_port_ = ntohs(addr.sin_port);
|
190
|
-
} else {
|
191
|
-
dbgsrv_port_ = port;
|
192
|
-
}
|
193
|
-
|
194
|
-
if (uv_listen((uv_stream_t *)&dbgsrv_serv_, 0, dbgsrv_do_serv)) {
|
195
|
-
uv_close((uv_handle_t *)&dbgsrv_serv_, NULL);
|
196
|
-
perror("listen");
|
197
|
-
return false;
|
198
|
-
}
|
199
|
-
|
200
|
-
// Start V8 debugger
|
201
|
-
v8_.debugger_init(recv_from_debugger, this);
|
202
|
-
|
203
|
-
// Start the Debug Server Loop
|
204
|
-
uv_async_init(&dbgsrv_loop_, &dbgsrv_stop_, dbgsrv_do_stop);
|
205
|
-
uv_thread_create(&dbgsrv_thread_, dbgsrv, this);
|
206
|
-
|
207
|
-
status_ = dbgsrv_started;
|
208
|
-
return true;
|
209
|
-
}
|
210
|
-
|
211
|
-
} // namespace v8eval
|
data/src/dbgsrv.h
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
#ifndef DBGSRV_H_
|
2
|
-
#define DBGSRV_H_
|
3
|
-
|
4
|
-
#include "uv.h"
|
5
|
-
#include <string>
|
6
|
-
#include <list>
|
7
|
-
|
8
|
-
namespace v8eval {
|
9
|
-
|
10
|
-
class _V8;
|
11
|
-
|
12
|
-
/// \class DbgSrv
|
13
|
-
///
|
14
|
-
/// A debugger server is associated to a _V8 instance and accepts
|
15
|
-
/// TCP/IP connections to exchange messages in the V8 debugger
|
16
|
-
/// protocol.
|
17
|
-
class DbgSrv {
|
18
|
-
public:
|
19
|
-
DbgSrv(_V8& v8);
|
20
|
-
~DbgSrv();
|
21
|
-
|
22
|
-
/// \brief Starts a debugger server
|
23
|
-
/// \param port TCP/IP port the server will listen
|
24
|
-
/// \return success or not as boolean
|
25
|
-
///
|
26
|
-
/// The port can be set to 0 to have a port automatically assigned.
|
27
|
-
bool start(int port);
|
28
|
-
|
29
|
-
/// \brief Get the TCP/IP port the system is currently listening from
|
30
|
-
/// \return A TCP/IP port or 0 if not currently set.
|
31
|
-
inline int get_port() { return dbgsrv_port_; }
|
32
|
-
|
33
|
-
private:
|
34
|
-
static void recv_from_debugger(std::string& string, void *opq);
|
35
|
-
|
36
|
-
static void dbgsrv_do_clnt(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf);
|
37
|
-
static void dbgsrv_do_send(uv_async_t *async);
|
38
|
-
static void dbgsrv_do_serv(uv_stream_t *server, int status);
|
39
|
-
static void dbgsrv_do_stop(uv_async_t *async);
|
40
|
-
static void dbgsrv(void *);
|
41
|
-
|
42
|
-
static void dbgproc_do_proc(uv_async_t *);
|
43
|
-
static void dbgproc_do_stop(uv_async_t *);
|
44
|
-
static void dbgproc(void *);
|
45
|
-
|
46
|
-
private:
|
47
|
-
_V8& v8_;
|
48
|
-
|
49
|
-
enum {
|
50
|
-
dbgsrv_offline,
|
51
|
-
dbgsrv_started,
|
52
|
-
dbgsrv_connected
|
53
|
-
} status_;
|
54
|
-
std::list<std::string> msg_queue_;
|
55
|
-
|
56
|
-
int dbgsrv_port_;
|
57
|
-
uv_tcp_t dbgsrv_serv_;
|
58
|
-
uv_tcp_t dbgsrv_clnt_;
|
59
|
-
uv_async_t dbgsrv_send_;
|
60
|
-
uv_async_t dbgsrv_stop_;
|
61
|
-
uv_thread_t dbgsrv_thread_;
|
62
|
-
uv_loop_t dbgsrv_loop_;
|
63
|
-
|
64
|
-
uv_async_t dbgproc_proc_;
|
65
|
-
uv_async_t dbgproc_stop_;
|
66
|
-
uv_thread_t dbgproc_thread_;
|
67
|
-
uv_loop_t dbgproc_loop_;
|
68
|
-
};
|
69
|
-
|
70
|
-
} // namespace v8eval
|
71
|
-
|
72
|
-
#endif // DBGSRV_H_
|