Class: V8::Context
Overview
All JavaScript must be executed in a context. This context consists of a global scope containing the standard JavaScript objects¨and functions like Object, String, Array, as well as any objects or functions from Ruby which have been embedded into it from the containing enviroment. E.g.
V8::Context.new do |cxt|
cxt['num'] = 5
cxt.eval('num + 5') #=> 10
end
The same object may appear in any number of contexts, but only one context may be executing JavaScript code in any given thread. If a new context is opened in a thread in which a context is already opened, the second context will “mask” the old context e.g.
six = 6
Context.new do |cxt|
cxt['num'] = 5
cxt.eval('num') # => 5
Context.new do |cxt|
cxt['num'] = 10
cxt.eval('num') # => 10
cxt.eval('++num') # => 11
end
cxt.eval('num') # => 5
end
Instance Attribute Summary collapse
-
#access ⇒ Object
readonly
Returns the value of attribute access.
-
#conversion ⇒ Object
readonly
Returns the value of attribute conversion.
-
#native ⇒ Object
readonly
Returns the value of attribute native.
-
#timeout ⇒ Object
readonly
Returns the value of attribute timeout.
Class Method Summary collapse
-
.current ⇒ V8::Context
Get the currently entered context.
- .enter ⇒ Object
-
.link(ruby_object, v8_object) ⇒ Object
Links ‘ruby_object` and `v8_object` inside the currently entered context.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Read a value from the global scope of this context.
-
#[]=(key, value) ⇒ Object
Binds ‘value` to the name `key` in the global scope of this context.
-
#dispose ⇒ Object
Destroy this context and release any internal references it may contain to embedded Ruby objects.
-
#enter(&block) ⇒ Object
Run some Ruby code in the context of this context.
-
#entered? ⇒ Boolean
Indicates if this context is the currently entered context.
-
#eval(source, filename = '<eval>', line = 1) ⇒ Object
Compile and execute a string of JavaScript source.
-
#initialize(options = {}) {|V8::Context| ... } ⇒ Context
constructor
Creates a new context.
-
#link(ruby_object, v8_object) ⇒ Object
Marks a Ruby object and a v8 C++ Object as being the same.
-
#load(filename) ⇒ Object
Compile and execute the contents of the file with path ‘filename` as JavaScript code.
-
#scope ⇒ Object
Returns this context’s global object.
-
#to_ruby(v8_object) ⇒ Object
Converts a v8 C++ object into its ruby counterpart.
-
#to_v8(ruby_object) ⇒ V8::C::Object
Converts a Ruby object into a native v8 C++ object.
Methods included from Error::Try
Constructor Details
#initialize(options = {}) {|V8::Context| ... } ⇒ Context
Creates a new context.
If passed the ‘:with` option, that object will be used as the global scope of the newly creating context. e.g.
scope = Object.new
def scope.hello; "Hi"; end
V8::Context.new(:with => scope) do |cxt|
cxt['hello'] #=> 'Hi'
end
If passed the ‘:timeout` option, every eval will timeout once
N milliseconds elapse
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/v8/context.rb', line 64 def initialize( = {}) @conversion = Conversion.new @access = Access.new @timeout = [:timeout] if global = [:with] Context.new.enter do global_template = global.class.to_template.InstanceTemplate() @native = V8::C::Context::New(nil, global_template) end enter {link global, @native.Global()} else V8::C::Locker() do @native = V8::C::Context::New() end end yield self if block_given? end |
Instance Attribute Details
#access ⇒ Object (readonly)
Returns the value of attribute access.
37 38 39 |
# File 'lib/v8/context.rb', line 37 def access @access end |
#conversion ⇒ Object (readonly)
Returns the value of attribute conversion.
33 34 35 |
# File 'lib/v8/context.rb', line 33 def conversion @conversion end |
#native ⇒ Object (readonly)
Returns the value of attribute native.
41 42 43 |
# File 'lib/v8/context.rb', line 41 def native @native end |
#timeout ⇒ Object (readonly)
Returns the value of attribute timeout.
45 46 47 |
# File 'lib/v8/context.rb', line 45 def timeout @timeout end |
Class Method Details
.current ⇒ V8::Context
Get the currently entered context.
220 221 222 |
# File 'lib/v8/context.rb', line 220 def self.current Thread.current[:v8_context] end |
.enter ⇒ Object
135 136 137 |
# File 'lib/v8/context.rb', line 135 def self.enter fail "cannot enter a context which has already been disposed" end |
.link(ruby_object, v8_object) ⇒ Object
Links ‘ruby_object` and `v8_object` inside the currently entered context. This is an error if no context has been entered.
190 191 192 |
# File 'lib/v8/context.rb', line 190 def self.link(ruby_object, v8_object) current.link ruby_object, v8_object end |
Instance Method Details
#[](key) ⇒ Object
Read a value from the global scope of this context
108 109 110 111 112 |
# File 'lib/v8/context.rb', line 108 def [](key) enter do to_ruby(@native.Global().Get(to_v8(key))) end end |
#[]=(key, value) ⇒ Object
Binds ‘value` to the name `key` in the global scope of this context.
118 119 120 121 122 123 |
# File 'lib/v8/context.rb', line 118 def []=(key, value) enter do @native.Global().Set(to_v8(key), to_v8(value)) end return value end |
#dispose ⇒ Object
Destroy this context and release any internal references it may contain to embedded Ruby objects.
A disposed context may never again be used for anything, and all objects created with it will become unusable.
130 131 132 133 134 135 136 137 138 |
# File 'lib/v8/context.rb', line 130 def dispose return unless @native @native.Dispose() @native = nil V8::C::V8::ContextDisposedNotification() def self.enter fail "cannot enter a context which has already been disposed" end end |
#enter(&block) ⇒ Object
Run some Ruby code in the context of this context.
This will acquire the V8 interpreter lock (possibly blocking until it is available), and prepare V8 for JavaScript execution.
Only one context may be running at a time per thread.
202 203 204 205 206 207 208 |
# File 'lib/v8/context.rb', line 202 def enter(&block) if !entered? lock_scope_and_enter(&block) else yield end end |
#entered? ⇒ Boolean
Indicates if this context is the currently entered context
213 214 215 |
# File 'lib/v8/context.rb', line 213 def entered? Context.current == self end |
#eval(source, filename = '<eval>', line = 1) ⇒ Object
Compile and execute a string of JavaScript source.
If ‘source` is an IO object it will be read fully before being evaluated
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/v8/context.rb', line 90 def eval(source, filename = '<eval>', line = 1) if IO === source || StringIO === source source = source.read end enter do script = try { V8::C::Script::New(source.to_s, filename.to_s) } if @timeout to_ruby try {script.RunWithTimeout(@timeout)} else to_ruby try {script.Run()} end end end |
#link(ruby_object, v8_object) ⇒ Object
Marks a Ruby object and a v8 C++ Object as being the same. In other words whenever ‘ruby_object` is passed to v8, the result of the conversion should be `v8_object`. Conversely, whenever `v8_object` is passed to Ruby, the result of the conversion should be `ruby_object`. The Ruby Racer uses this mechanism to maintain referential integrity between Ruby and JavaScript peers
181 182 183 |
# File 'lib/v8/context.rb', line 181 def link(ruby_object, v8_object) @conversion.equate ruby_object, v8_object end |
#load(filename) ⇒ Object
Compile and execute the contents of the file with path ‘filename` as JavaScript code.
229 230 231 232 233 |
# File 'lib/v8/context.rb', line 229 def load(filename) File.open(filename) do |file| self.eval file, filename end end |
#scope ⇒ Object
Returns this context’s global object. This will be a ‘V8::Object` if no scope was provided or just an `Object` if a Ruby object is serving as the global scope.
145 146 147 |
# File 'lib/v8/context.rb', line 145 def scope enter { to_ruby @native.Global() } end |
#to_ruby(v8_object) ⇒ Object
Converts a v8 C++ object into its ruby counterpart. This is method is used to translate all values passed to Ruby from JavaScript, either as return values or as callback parameters.
156 157 158 |
# File 'lib/v8/context.rb', line 156 def to_ruby(v8_object) @conversion.to_ruby(v8_object) end |
#to_v8(ruby_object) ⇒ V8::C::Object
Converts a Ruby object into a native v8 C++ object. This method is used to translate all values passed to JavaScript from Ruby, either as return value or as callback parameters.
167 168 169 |
# File 'lib/v8/context.rb', line 167 def to_v8(ruby_object) @conversion.to_v8(ruby_object) end |