v8eval 0.2.4 → 0.3.2
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 +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
|
[](http://badge.fury.io/py/v8eval)
|
4
4
|
[](https://badge.fury.io/rb/v8eval)
|
5
|
-
[](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_
|