therubyracer 0.9.2 → 0.9.3beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of therubyracer might be problematic. Click here for more details.
- data/ext/v8/v8.cpp +1 -0
- data/ext/v8/v8_handle.cpp +12 -2
- data/ext/v8/v8_handle.h +0 -1
- data/lib/v8/context.rb +36 -27
- data/lib/v8/function.rb +8 -6
- data/lib/v8/portal.rb +12 -3
- data/lib/v8/version.rb +1 -1
- data/spec/ext/cxt_spec.rb +13 -3
- data/spec/ext/ext_spec_helper.rb +2 -0
- data/spec/ext/try_catch_spec.rb +7 -7
- metadata +6 -9
data/ext/v8/v8.cpp
CHANGED
data/ext/v8/v8_handle.cpp
CHANGED
@@ -6,7 +6,9 @@ using namespace v8;
|
|
6
6
|
|
7
7
|
/**
|
8
8
|
* Creates a new Persistent storage cell for `handle`
|
9
|
-
* so that we can reference it from Ruby.
|
9
|
+
* so that we can reference it from Ruby. Ruby metadat
|
10
|
+
* is contained on the handle object, and then the actual
|
11
|
+
* v8 references are contain in an instance of `Payload`
|
10
12
|
*/
|
11
13
|
v8_handle::v8_handle(Handle<void> object) {
|
12
14
|
this->weakref_callback = Qnil;
|
@@ -17,6 +19,14 @@ v8_handle::v8_handle(Handle<void> object) {
|
|
17
19
|
|
18
20
|
v8_handle::~v8_handle() {}
|
19
21
|
|
22
|
+
/**
|
23
|
+
* Construct a new handle payload.
|
24
|
+
*
|
25
|
+
* Each payload contains a Ruby object wrapper so that it
|
26
|
+
* can be enqueued for V8 GC (the GC queue is a ruby Array)
|
27
|
+
* the wrapper is pre-allocated at payload creation time
|
28
|
+
* so that no Ruby objects are allocated during Ruby GC.
|
29
|
+
*/
|
20
30
|
v8_handle::Payload::Payload(Handle<void> object) {
|
21
31
|
rb_gc_register_address(&wrapper);
|
22
32
|
handle = Persistent<void>::New(object);
|
@@ -56,7 +66,7 @@ namespace {
|
|
56
66
|
/**
|
57
67
|
* Whenver a V8::C::Handle becomes garbage collected, we do not free it immediately.
|
58
68
|
* instead, we put them into a "zombie" queue, where its corresponding V8 storage cell
|
59
|
-
* can be released safely while the V8 engine is running. A zombie Ruby object is
|
69
|
+
* can be released safely while the V8 engine is running. A zombie Ruby object is
|
60
70
|
* created to wrap it so that it can be stored in the queue.
|
61
71
|
*/
|
62
72
|
void v8_handle_enqueue(v8_handle* handle) {
|
data/ext/v8/v8_handle.h
CHANGED
data/lib/v8/context.rb
CHANGED
@@ -7,24 +7,26 @@ module V8
|
|
7
7
|
def initialize(opts = {})
|
8
8
|
@access = Access.new
|
9
9
|
@to = Portal.new(self, @access)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
10
|
+
@to.lock do
|
11
|
+
with = opts[:with]
|
12
|
+
constructor = nil
|
13
|
+
template = if with
|
14
|
+
constructor = @to.templates.to_constructor(with.class)
|
15
|
+
constructor.disable()
|
16
|
+
constructor.template.InstanceTemplate()
|
17
|
+
else
|
18
|
+
C::ObjectTemplate::New()
|
19
|
+
end
|
20
|
+
@native = opts[:with] ? C::Context::New(template) : C::Context::New()
|
21
|
+
@native.enter do
|
22
|
+
@global = @native.Global()
|
23
|
+
@to.proxies.register_javascript_proxy @global, :for => with if with
|
24
|
+
constructor.enable() if constructor
|
25
|
+
@scope = @to.rb(@global)
|
26
|
+
@global.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext"), C::External::New(self))
|
27
|
+
end
|
28
|
+
yield(self) if block_given?
|
26
29
|
end
|
27
|
-
yield(self) if block_given?
|
28
30
|
end
|
29
31
|
|
30
32
|
def eval(javascript, filename = "<eval>", line = 1)
|
@@ -33,17 +35,19 @@ module V8
|
|
33
35
|
end
|
34
36
|
err = nil
|
35
37
|
value = nil
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
err = JSError.new(try, @to)
|
41
|
-
else
|
42
|
-
result = script.Run()
|
38
|
+
@to.lock do
|
39
|
+
C::TryCatch.try do |try|
|
40
|
+
@native.enter do
|
41
|
+
script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
|
43
42
|
if try.HasCaught()
|
44
43
|
err = JSError.new(try, @to)
|
45
44
|
else
|
46
|
-
|
45
|
+
result = script.Run()
|
46
|
+
if try.HasCaught()
|
47
|
+
err = JSError.new(try, @to)
|
48
|
+
else
|
49
|
+
value = @to.rb(result)
|
50
|
+
end
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -59,11 +63,16 @@ module V8
|
|
59
63
|
end
|
60
64
|
|
61
65
|
def [](key)
|
62
|
-
@
|
66
|
+
@to.open do
|
67
|
+
@to.rb @global.Get(@to.v8(key))
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
def []=(key, value)
|
66
|
-
@
|
72
|
+
@to.open do
|
73
|
+
@global.Set(@to.v8(key), @to.v8(value))
|
74
|
+
end
|
75
|
+
return value
|
67
76
|
end
|
68
77
|
|
69
78
|
def self.stack(limit = 99)
|
data/lib/v8/function.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module V8
|
2
2
|
class Function < V8::Object
|
3
|
-
|
3
|
+
|
4
4
|
def methodcall(thisObject, *args)
|
5
5
|
err = nil
|
6
6
|
return_value = nil
|
7
|
-
|
8
|
-
|
7
|
+
@portal.open do |to|
|
8
|
+
C::TryCatch.try do |try|
|
9
9
|
this = to.v8(thisObject)
|
10
10
|
return_value = to.rb(@native.Call(this, to.v8(args)))
|
11
11
|
err = JSError.new(try, to) if try.HasCaught()
|
@@ -14,11 +14,13 @@ module V8
|
|
14
14
|
raise err if err
|
15
15
|
return return_value
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def call(*args)
|
19
|
-
|
19
|
+
@portal.open do
|
20
|
+
self.methodcall(@portal.context.native.Global(), *args)
|
21
|
+
end
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
def new(*args)
|
23
25
|
@portal.open do |to|
|
24
26
|
to.rb(@native.NewInstance(to.v8(args)))
|
data/lib/v8/portal.rb
CHANGED
@@ -11,10 +11,19 @@ module V8
|
|
11
11
|
@caller = Caller.new(self)
|
12
12
|
end
|
13
13
|
|
14
|
+
def lock
|
15
|
+
lock = V8::C::Locker.new
|
16
|
+
yield
|
17
|
+
ensure
|
18
|
+
lock.delete
|
19
|
+
end
|
20
|
+
|
14
21
|
def open
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
lock do
|
23
|
+
@context.native.enter do
|
24
|
+
yield(self)
|
25
|
+
end if block_given?
|
26
|
+
end
|
18
27
|
end
|
19
28
|
|
20
29
|
def rb(value)
|
data/lib/v8/version.rb
CHANGED
data/spec/ext/cxt_spec.rb
CHANGED
@@ -3,12 +3,22 @@ require "#{File.dirname(__FILE__)}/../spec_helper.rb"
|
|
3
3
|
|
4
4
|
include V8
|
5
5
|
|
6
|
-
describe C::Context do
|
6
|
+
describe C::Context do
|
7
|
+
|
8
|
+
before {@lock = C::Locker.new}
|
9
|
+
after {@lock.delete}
|
7
10
|
|
8
11
|
it "should not have a current context if no context is open" do
|
9
12
|
C::Context::GetEntered().should be_nil
|
10
13
|
end
|
11
14
|
|
15
|
+
it "can javascript properties on the global scope via ruby when the default scope is a ruby object" do
|
16
|
+
V8::Context.new(:with => Object.new) do |cxt|
|
17
|
+
cxt['foo'] = 'bar'
|
18
|
+
cxt.eval('foo').should eql('bar')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
12
22
|
it "can get the current javascript execution stack" do
|
13
23
|
V8::Context.new do |cxt|
|
14
24
|
trace = nil
|
@@ -19,11 +29,11 @@ describe C::Context do
|
|
19
29
|
function one() {
|
20
30
|
return two();
|
21
31
|
}
|
22
|
-
|
32
|
+
|
23
33
|
function two() {
|
24
34
|
return three();
|
25
35
|
}
|
26
|
-
|
36
|
+
|
27
37
|
function three() {
|
28
38
|
return getTrace()
|
29
39
|
}
|
data/spec/ext/ext_spec_helper.rb
CHANGED
data/spec/ext/try_catch_spec.rb
CHANGED
@@ -4,25 +4,25 @@ include V8
|
|
4
4
|
|
5
5
|
describe C::TryCatch do
|
6
6
|
|
7
|
-
before {@cxt = C::Context::New()}
|
8
|
-
after {@cxt.Dispose()}
|
7
|
+
before {@lock = C::Locker.new;@cxt = C::Context::New();}
|
8
|
+
after {@cxt.Dispose(); @lock.delete}
|
9
9
|
|
10
10
|
it "does not allow instance creation by default" do
|
11
11
|
lambda {
|
12
|
-
C::TryCatch.new
|
12
|
+
C::TryCatch.new
|
13
13
|
}.should raise_error
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "will do nothing if not passed a block" do
|
17
17
|
C::TryCatch.try.should == nil
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "executes a block in the context of a C++ stack frame" do
|
21
21
|
C::TryCatch.try do |catch|
|
22
|
-
catch.HasCaught().should be(false)
|
22
|
+
catch.HasCaught().should be(false)
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
it "raises an erro if you try to access it outside of its scope" do
|
27
27
|
tc = C::TryCatch.try do |catch|
|
28
28
|
catch.tap {}
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: therubyracer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 0.9.
|
4
|
+
prerelease: 5
|
5
|
+
version: 0.9.3beta1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Charles Lowell
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2011-
|
14
|
+
date: 2011-07-05 00:00:00 -05:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -174,19 +174,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
174
174
|
requirements:
|
175
175
|
- - ">="
|
176
176
|
- !ruby/object:Gem::Version
|
177
|
-
hash:
|
177
|
+
hash: 2112963294827499619
|
178
178
|
segments:
|
179
179
|
- 0
|
180
180
|
version: "0"
|
181
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
182
182
|
none: false
|
183
183
|
requirements:
|
184
|
-
- - "
|
184
|
+
- - ">"
|
185
185
|
- !ruby/object:Gem::Version
|
186
|
-
|
187
|
-
segments:
|
188
|
-
- 0
|
189
|
-
version: "0"
|
186
|
+
version: 1.3.1
|
190
187
|
requirements: []
|
191
188
|
|
192
189
|
rubyforge_project: therubyracer
|