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" {
void Init_v8() {
v8::Locker locker;
rr_init_handle();
rr_init_context();
rr_init_value();

View file

@ -7,24 +7,26 @@ module V8
def initialize(opts = {})
@access = Access.new
@to = Portal.new(self, @access)
with = opts[:with]
constructor = nil
template = if with
constructor = @to.templates.to_constructor(with.class)
constructor.disable()
constructor.template.InstanceTemplate()
else
C::ObjectTemplate::New()
@to.lock do
with = opts[:with]
constructor = nil
template = if with
constructor = @to.templates.to_constructor(with.class)
constructor.disable()
constructor.template.InstanceTemplate()
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
@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
def eval(javascript, filename = "<eval>", line = 1)
@ -33,17 +35,19 @@ module V8
end
err = nil
value = nil
C::TryCatch.try do |try|
@native.enter do
script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
if try.HasCaught()
err = JSError.new(try, @to)
else
result = script.Run()
@to.lock do
C::TryCatch.try do |try|
@native.enter do
script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
if try.HasCaught()
err = JSError.new(try, @to)
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

View file

@ -4,8 +4,8 @@ module V8
def methodcall(thisObject, *args)
err = 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)
return_value = to.rb(@native.Call(this, to.v8(args)))
err = JSError.new(try, to) if try.HasCaught()
@ -16,7 +16,9 @@ module V8
end
def call(*args)
self.methodcall(@portal.context.native.Global(), *args)
@portal.open do
self.methodcall(@portal.context.native.Global(), *args)
end
end
def new(*args)

View file

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

View file

@ -5,6 +5,9 @@ include V8
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
C::Context::GetEntered().should be_nil
end

View file

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

View file

@ -4,8 +4,8 @@ include V8
describe C::TryCatch do
before {@cxt = C::Context::New()}
after {@cxt.Dispose()}
before {@lock = C::Locker.new;@cxt = C::Context::New();}
after {@cxt.Dispose(); @lock.delete}
it "does not allow instance creation by default" do
lambda {