1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

Automatically lock v8 whenever performing any JavaScript operation.

This commit is contained in:
Charles Lowell 2011-07-02 22:23:08 -05:00
parent 12b58f3289
commit 0d3bf45af4
7 changed files with 65 additions and 44 deletions

View file

@ -25,6 +25,7 @@ extern "C" {
extern "C" { extern "C" {
void Init_v8() { void Init_v8() {
v8::Locker locker;
rr_init_handle(); rr_init_handle();
rr_init_context(); rr_init_context();
rr_init_value(); rr_init_value();

View file

@ -7,24 +7,26 @@ module V8
def initialize(opts = {}) def initialize(opts = {})
@access = Access.new @access = Access.new
@to = Portal.new(self, @access) @to = Portal.new(self, @access)
with = opts[:with] @to.lock do
constructor = nil with = opts[:with]
template = if with constructor = nil
constructor = @to.templates.to_constructor(with.class) template = if with
constructor.disable() constructor = @to.templates.to_constructor(with.class)
constructor.template.InstanceTemplate() constructor.disable()
else constructor.template.InstanceTemplate()
C::ObjectTemplate::New() else
C::ObjectTemplate::New()
end
@native = opts[:with] ? C::Context::New(template) : C::Context::New()
@native.enter do
@global = @native.Global()
@to.proxies.register_javascript_proxy @global, :for => with if with
constructor.enable() if constructor
@scope = @to.rb(@global)
@global.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext"), C::External::New(self))
end
yield(self) if block_given?
end end
@native = opts[:with] ? C::Context::New(template) : C::Context::New()
@native.enter do
@global = @native.Global()
@to.proxies.register_javascript_proxy @global, :for => with if with
constructor.enable() if constructor
@scope = @to.rb(@global)
@global.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext"), C::External::New(self))
end
yield(self) if block_given?
end end
def eval(javascript, filename = "<eval>", line = 1) def eval(javascript, filename = "<eval>", line = 1)
@ -33,17 +35,19 @@ module V8
end end
err = nil err = nil
value = nil value = nil
C::TryCatch.try do |try| @to.lock do
@native.enter do C::TryCatch.try do |try|
script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s)) @native.enter do
if try.HasCaught() script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
err = JSError.new(try, @to)
else
result = script.Run()
if try.HasCaught() if try.HasCaught()
err = JSError.new(try, @to) err = JSError.new(try, @to)
else else
value = @to.rb(result) result = script.Run()
if try.HasCaught()
err = JSError.new(try, @to)
else
value = @to.rb(result)
end
end end
end end
end end

View file

@ -1,11 +1,11 @@
module V8 module V8
class Function < V8::Object class Function < V8::Object
def methodcall(thisObject, *args) def methodcall(thisObject, *args)
err = nil err = nil
return_value = nil return_value = nil
C::TryCatch.try do |try| @portal.open do |to|
@portal.open do |to| C::TryCatch.try do |try|
this = to.v8(thisObject) this = to.v8(thisObject)
return_value = to.rb(@native.Call(this, to.v8(args))) return_value = to.rb(@native.Call(this, to.v8(args)))
err = JSError.new(try, to) if try.HasCaught() err = JSError.new(try, to) if try.HasCaught()
@ -14,11 +14,13 @@ module V8
raise err if err raise err if err
return return_value return return_value
end end
def call(*args) def call(*args)
self.methodcall(@portal.context.native.Global(), *args) @portal.open do
self.methodcall(@portal.context.native.Global(), *args)
end
end end
def new(*args) def new(*args)
@portal.open do |to| @portal.open do |to|
to.rb(@native.NewInstance(to.v8(args))) to.rb(@native.NewInstance(to.v8(args)))

View file

@ -11,10 +11,19 @@ module V8
@caller = Caller.new(self) @caller = Caller.new(self)
end end
def lock
lock = V8::C::Locker.new
yield
ensure
lock.delete
end
def open def open
@context.native.enter do lock do
yield(self) @context.native.enter do
end if block_given? yield(self)
end if block_given?
end
end end
def rb(value) def rb(value)

View file

@ -3,7 +3,10 @@ require "#{File.dirname(__FILE__)}/../spec_helper.rb"
include V8 include V8
describe C::Context do describe C::Context do
before {@lock = C::Locker.new}
after {@lock.delete}
it "should not have a current context if no context is open" do it "should not have a current context if no context is open" do
C::Context::GetEntered().should be_nil C::Context::GetEntered().should be_nil
@ -26,11 +29,11 @@ describe C::Context do
function one() { function one() {
return two(); return two();
} }
function two() { function two() {
return three(); return three();
} }
function three() { function three() {
return getTrace() return getTrace()
} }

View file

@ -4,12 +4,14 @@ module V8::ExtSpec
def self.included(object) def self.included(object)
object.class_eval do object.class_eval do
before do before do
@lock = c::Locker.new
@cxt = c::Context::New() @cxt = c::Context::New()
@cxt.Enter() @cxt.Enter()
end end
after do after do
@cxt.Exit() @cxt.Exit()
@cxt.Dispose() @cxt.Dispose()
@lock.delete
end end
end end
end end

View file

@ -4,25 +4,25 @@ include V8
describe C::TryCatch do describe C::TryCatch do
before {@cxt = C::Context::New()} before {@lock = C::Locker.new;@cxt = C::Context::New();}
after {@cxt.Dispose()} after {@cxt.Dispose(); @lock.delete}
it "does not allow instance creation by default" do it "does not allow instance creation by default" do
lambda { lambda {
C::TryCatch.new C::TryCatch.new
}.should raise_error }.should raise_error
end end
it "will do nothing if not passed a block" do it "will do nothing if not passed a block" do
C::TryCatch.try.should == nil C::TryCatch.try.should == nil
end end
it "executes a block in the context of a C++ stack frame" do it "executes a block in the context of a C++ stack frame" do
C::TryCatch.try do |catch| C::TryCatch.try do |catch|
catch.HasCaught().should be(false) catch.HasCaught().should be(false)
end end
end end
it "raises an erro if you try to access it outside of its scope" do it "raises an erro if you try to access it outside of its scope" do
tc = C::TryCatch.try do |catch| tc = C::TryCatch.try do |catch|
catch.tap {} catch.tap {}