h8 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/h8/extconf.rb +1 -1
- data/ext/h8/h8.cpp +18 -14
- data/ext/h8/h8.h +16 -11
- data/ext/h8/js_gate.h +2 -2
- data/lib/h8/version.rb +1 -1
- data/spec/context_spec.rb +26 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f57dd0c74b95006a890c9cf0369c125cef269f5
|
4
|
+
data.tar.gz: f3d4718d58ff97858d8b6eba3d24153b1cda7c92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c27679efadcb3972abbfee520b177455387b21263e7541e32d6e16ecf98bff1d701c2670f5590843936a1afed0f131bc4d8210ed9eb7bf65321a0d941726df7a
|
7
|
+
data.tar.gz: 0a4f4b5733f65efd133b7e5323c4c172685879cd44b84690c1ec80ff1978bd4d86d66c91df59a76ecbe4b16248f385472fde76adb5655beb128c605c11411edc
|
data/ext/h8/extconf.rb
CHANGED
@@ -37,7 +37,7 @@ begin
|
|
37
37
|
v8_path = ENV['V8_3_31_ROOT'] or raise "Please give me export V8_3_31_ROOT=..."
|
38
38
|
# dir_config('v8', '/Users/sergeych/dev/v8', '/Users/sergeych/dev/v8/out/native')
|
39
39
|
dir_config('v8', v8_path, v8_path+'/out/native')
|
40
|
-
CONFIG['CXXFLAGS'] += ' --std=c++11'
|
40
|
+
CONFIG['CXXFLAGS'] += ' --std=c++11 -O6'
|
41
41
|
else
|
42
42
|
# example linux package https://github.com/porzione/v8-git-debian
|
43
43
|
dir_config('v8', '/usr/include/libv8-3.31', '/usr/lib/libv8-3.31')
|
data/ext/h8/h8.cpp
CHANGED
@@ -27,7 +27,8 @@ void h8::JsError::raise() {
|
|
27
27
|
ruby_exception = ruby_exception = rb_exc_new2(js_exception,
|
28
28
|
*res ? *res : "unknown javascript exception");
|
29
29
|
rb_iv_set(ruby_exception, "@message", h8->to_ruby(s));
|
30
|
-
rb_iv_set(ruby_exception, "@javascript_error",
|
30
|
+
rb_iv_set(ruby_exception, "@javascript_error",
|
31
|
+
h8->to_ruby(jsx));
|
31
32
|
}
|
32
33
|
}
|
33
34
|
rb_exc_raise(ruby_exception);
|
@@ -60,7 +61,7 @@ void h8::H8::ruby_mark_gc() const {
|
|
60
61
|
((AllocatedResource*) x)->rb_mark_gc();
|
61
62
|
}
|
62
63
|
|
63
|
-
v8::Handle<v8::Value> h8::H8::eval(const char* script_utf,unsigned max_ms) {
|
64
|
+
v8::Handle<v8::Value> h8::H8::eval(const char* script_utf, unsigned max_ms) {
|
64
65
|
v8::EscapableHandleScope escape(isolate);
|
65
66
|
Local<Value> result;
|
66
67
|
|
@@ -76,20 +77,20 @@ v8::Handle<v8::Value> h8::H8::eval(const char* script_utf,unsigned max_ms) {
|
|
76
77
|
result = Undefined(isolate);
|
77
78
|
} else {
|
78
79
|
result = Undefined(isolate);
|
79
|
-
if(
|
80
|
+
if (max_ms > 0) {
|
80
81
|
std::mutex m;
|
81
82
|
std::condition_variable cv;
|
82
|
-
std::thread thr(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
std::thread thr(
|
84
|
+
[&] {
|
85
|
+
std::unique_lock<std::mutex> lock(m);
|
86
|
+
if( std::cv_status::timeout == cv.wait_for(lock, std::chrono::milliseconds(max_ms) ) ) {
|
87
|
+
isolate->TerminateExecution();
|
88
|
+
}
|
89
|
+
});
|
88
90
|
script->Run();
|
89
91
|
cv.notify_all();
|
90
92
|
thr.join();
|
91
|
-
}
|
92
|
-
else {
|
93
|
+
} else {
|
93
94
|
result = script->Run();
|
94
95
|
}
|
95
96
|
try_catch.throwIfCaught();
|
@@ -98,9 +99,12 @@ v8::Handle<v8::Value> h8::H8::eval(const char* script_utf,unsigned max_ms) {
|
|
98
99
|
}
|
99
100
|
|
100
101
|
h8::H8::~H8() {
|
101
|
-
|
102
|
-
|
103
|
-
resources.
|
102
|
+
{
|
103
|
+
Scope s(this);
|
104
|
+
while (!resources.is_empty()) {
|
105
|
+
// this should also remove it from the list:
|
106
|
+
resources.peek_first<AllocatedResource>()->free();
|
107
|
+
}
|
104
108
|
}
|
105
109
|
|
106
110
|
persistent_context.Reset();
|
data/ext/h8/h8.h
CHANGED
@@ -81,16 +81,22 @@ public:
|
|
81
81
|
class H8 {
|
82
82
|
public:
|
83
83
|
|
84
|
-
class Scope
|
85
|
-
|
86
|
-
|
84
|
+
class Scope {
|
85
|
+
Locker locker;
|
86
|
+
Isolate::Scope isolate_scope;
|
87
|
+
HandleScope handle_scope;
|
88
|
+
Context::Scope context_scope;
|
89
|
+
|
87
90
|
H8* rcontext;
|
88
91
|
|
89
92
|
public:
|
90
93
|
Scope(H8* cxt) :
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
+
locker(cxt->getIsolate()),
|
95
|
+
handle_scope(cxt->getIsolate()),
|
96
|
+
isolate_scope(cxt->getIsolate()),
|
97
|
+
context_scope(cxt->getContext()),
|
98
|
+
rcontext(cxt)
|
99
|
+
{
|
94
100
|
}
|
95
101
|
};
|
96
102
|
|
@@ -99,6 +105,7 @@ public:
|
|
99
105
|
H8() :
|
100
106
|
self(Qnil) {
|
101
107
|
isolate = Isolate::New();
|
108
|
+
Locker l(isolate);
|
102
109
|
Isolate::Scope isolate_scope(isolate);
|
103
110
|
HandleScope handle_scope(isolate);
|
104
111
|
isolate->SetCaptureStackTraceForUncaughtExceptions(true);
|
@@ -217,11 +224,9 @@ inline VALUE h8::H8::to_ruby(Handle<Value> value) {
|
|
217
224
|
|
218
225
|
inline h8::JsError::JsError(H8* h8, Local<Message> message,
|
219
226
|
Local<Value> exception) :
|
220
|
-
h8(h8),
|
221
|
-
|
222
|
-
|
223
|
-
has_js_exception(true),
|
224
|
-
reason(NULL) {
|
227
|
+
h8(h8), _message(h8->getIsolate(), message), _exception(
|
228
|
+
h8->getIsolate(), exception), has_js_exception(true), reason(
|
229
|
+
NULL) {
|
225
230
|
}
|
226
231
|
|
227
232
|
inline Local<Message> h8::JsError::message() const {
|
data/ext/h8/js_gate.h
CHANGED
@@ -162,12 +162,12 @@ public:
|
|
162
162
|
* Call this as function over global context
|
163
163
|
*/
|
164
164
|
VALUE call(VALUE args) const {
|
165
|
-
|
165
|
+
H8::Scope scope(h8);
|
166
166
|
return apply(h8->getContext()->Global(), args);
|
167
167
|
}
|
168
168
|
|
169
169
|
VALUE apply(VALUE self, VALUE args) const {
|
170
|
-
|
170
|
+
H8::Scope scope(h8);
|
171
171
|
return apply(h8->gateObject(self), args);
|
172
172
|
}
|
173
173
|
|
data/lib/h8/version.rb
CHANGED
data/spec/context_spec.rb
CHANGED
@@ -74,4 +74,30 @@ describe 'context' do
|
|
74
74
|
cxt.eval('(last-start)/1000').should < 250
|
75
75
|
end
|
76
76
|
|
77
|
+
it 'should work in many threads' do
|
78
|
+
sum = 0
|
79
|
+
valid = 0
|
80
|
+
n = 10
|
81
|
+
contexts = []
|
82
|
+
tt = n.times.map { |n|
|
83
|
+
valid += (n+1)*100 + 10
|
84
|
+
Thread.start {
|
85
|
+
cxt = H8::Context.new
|
86
|
+
contexts << cxt
|
87
|
+
cxt[:array] = 100024.times.map { |x| x*(n+1) }
|
88
|
+
cxt[:n] = n+1
|
89
|
+
sum += cxt.eval('result = array[100] + 10')
|
90
|
+
}
|
91
|
+
}
|
92
|
+
tt.each &:join
|
93
|
+
sum.should == valid
|
94
|
+
GC.start
|
95
|
+
# Cross-thread access
|
96
|
+
contexts.each { |cxt|
|
97
|
+
s, n = cxt.eval('data = [result,n]')
|
98
|
+
s.should == 100*n + 10
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
|
77
103
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: h8
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sergeych
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
134
|
version: '0'
|
135
135
|
requirements: []
|
136
136
|
rubyforge_project:
|
137
|
-
rubygems_version: 2.
|
137
|
+
rubygems_version: 2.4.5
|
138
138
|
signing_key:
|
139
139
|
specification_version: 4
|
140
140
|
summary: Minimalistic and fast Ruby <--> V8 integration
|