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.

@@ -25,6 +25,7 @@ extern "C" {
25
25
 
26
26
  extern "C" {
27
27
  void Init_v8() {
28
+ v8::Locker locker;
28
29
  rr_init_handle();
29
30
  rr_init_context();
30
31
  rr_init_value();
@@ -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) {
@@ -7,7 +7,6 @@
7
7
  /**
8
8
  * Holds a reference to a V8 heap object. This serves as the base
9
9
  * class for all of the low-level proxies that reference into V8.
10
- *
11
10
  */
12
11
  struct v8_handle {
13
12
 
@@ -7,24 +7,26 @@ module V8
7
7
  def initialize(opts = {})
8
8
  @access = Access.new
9
9
  @to = Portal.new(self, @access)
10
- with = opts[:with]
11
- constructor = nil
12
- template = if with
13
- constructor = @to.templates.to_constructor(with.class)
14
- constructor.disable()
15
- constructor.template.InstanceTemplate()
16
- else
17
- C::ObjectTemplate::New()
18
- end
19
- @native = opts[:with] ? C::Context::New(template) : C::Context::New()
20
- @native.enter do
21
- @global = @native.Global()
22
- @to.proxies.register_javascript_proxy @global, :for => with if with
23
- constructor.enable() if constructor
24
- @scope = @to.rb(@global)
25
- @global.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext"), C::External::New(self))
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
- C::TryCatch.try do |try|
37
- @native.enter do
38
- script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
39
- if try.HasCaught()
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
- value = @to.rb(result)
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
- @scope[key]
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
- @scope[key] = value
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)
@@ -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
- C::TryCatch.try do |try|
8
- @portal.open do |to|
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
- self.methodcall(@portal.context.native.Global(), *args)
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)))
@@ -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
- @context.native.enter do
16
- yield(self)
17
- end if block_given?
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)
@@ -1,3 +1,3 @@
1
1
  module V8
2
- VERSION = "0.9.2"
2
+ VERSION = "0.9.3beta1"
3
3
  end
@@ -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
  }
@@ -4,12 +4,14 @@ module V8::ExtSpec
4
4
  def self.included(object)
5
5
  object.class_eval do
6
6
  before do
7
+ @lock = c::Locker.new
7
8
  @cxt = c::Context::New()
8
9
  @cxt.Enter()
9
10
  end
10
11
  after do
11
12
  @cxt.Exit()
12
13
  @cxt.Dispose()
14
+ @lock.delete
13
15
  end
14
16
  end
15
17
  end
@@ -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.2
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-06-23 00:00:00 -05:00
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: -3220606308753649861
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
- hash: -3220606308753649861
187
- segments:
188
- - 0
189
- version: "0"
186
+ version: 1.3.1
190
187
  requirements: []
191
188
 
192
189
  rubyforge_project: therubyracer