mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
factor out v8 conversions into separate modules
This commit is contained in:
parent
3590c0dadb
commit
32028f31fc
15 changed files with 231 additions and 102 deletions
10
lib/v8.rb
10
lib/v8.rb
|
@ -1,6 +1,16 @@
|
||||||
require "v8/version"
|
require "v8/version"
|
||||||
|
|
||||||
require 'v8/init'
|
require 'v8/init'
|
||||||
|
require 'v8/conversion/fundamental'
|
||||||
|
require 'v8/conversion/indentity'
|
||||||
|
require 'v8/conversion/numeric'
|
||||||
|
require 'v8/conversion/object'
|
||||||
|
require 'v8/conversion/time'
|
||||||
|
require 'v8/conversion/hash'
|
||||||
|
require 'v8/conversion/array'
|
||||||
|
require 'v8/conversion/proc'
|
||||||
|
require 'v8/conversion/symbol'
|
||||||
|
require 'v8/conversion/string'
|
||||||
require 'v8/conversion'
|
require 'v8/conversion'
|
||||||
require 'v8/context'
|
require 'v8/context'
|
||||||
require 'v8/object'
|
require 'v8/object'
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
class V8::Array < V8::Object
|
class V8::Array < V8::Object
|
||||||
|
|
||||||
def initialize(native_or_length = nil)
|
def initialize(native_or_length = nil)
|
||||||
if native_or_length.is_a?(Numeric)
|
native = if native_or_length.is_a?(Numeric)
|
||||||
super V8::C::Array::New(native.to_i)
|
V8::C::Array::New(native_or_length)
|
||||||
elsif native_or_length.is_a?(V8::C::Array)
|
elsif native_or_length.is_a?(V8::C::Array)
|
||||||
super native_or_length
|
native_or_length
|
||||||
else
|
else
|
||||||
super V8::C::Array::New()
|
V8::C::Array::New()
|
||||||
end
|
end
|
||||||
|
super native
|
||||||
end
|
end
|
||||||
|
|
||||||
def each
|
def each
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
module V8
|
module V8
|
||||||
class Context
|
class Context
|
||||||
include Conversion
|
|
||||||
|
|
||||||
attr_reader :native
|
attr_reader :native
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@native = V8::C::Context::New()
|
@native = V8::C::Context::New()
|
||||||
|
@conversion = Conversion.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_ruby(v8_object)
|
||||||
|
@conversion.to_ruby(v8_object)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_v8(ruby_object)
|
||||||
|
@conversion.to_v8(ruby_object)
|
||||||
end
|
end
|
||||||
|
|
||||||
def enter(&block)
|
def enter(&block)
|
||||||
|
@ -46,10 +54,22 @@ module V8
|
||||||
|
|
||||||
def eval(source, filename = '<eval>', line = 1)
|
def eval(source, filename = '<eval>', line = 1)
|
||||||
enter do
|
enter do
|
||||||
source = V8::C::String::New(source.to_s)
|
V8::C::TryCatch() do |trycatch|
|
||||||
filename = V8::C::String::New(filename.to_s)
|
source = V8::C::String::New(source.to_s)
|
||||||
script = V8::C::Script::New(source, filename)
|
filename = V8::C::String::New(filename.to_s)
|
||||||
to_ruby script.Run()
|
script = V8::C::Script::New(source, filename)
|
||||||
|
result = script.Run()
|
||||||
|
if trycatch.HasCaught()
|
||||||
|
exception = trycatch.Exception()
|
||||||
|
if exception.IsNativeError()
|
||||||
|
raise to_ruby exception.Get("message")
|
||||||
|
else
|
||||||
|
raise to_ruby exception.ToString()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
to_ruby result
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,109 +1,68 @@
|
||||||
module V8::Conversion
|
|
||||||
|
class V8::Conversion
|
||||||
|
include Fundamental
|
||||||
|
include Identity
|
||||||
|
|
||||||
def to_ruby(v8_object)
|
def to_ruby(v8_object)
|
||||||
v8_cache.get(v8_object) do
|
super v8_object
|
||||||
v8_object.respond_to?(:to_ruby) ? v8_object.to_ruby : v8_object
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_v8(ruby_object)
|
def to_v8(ruby_object)
|
||||||
ruby_object.respond_to?(:to_v8) ? ruby_object.to_v8 : V8::C::Object::New()
|
super ruby_object
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def v8_cache
|
for type in [Numeric, Object, Array, Hash, String, Symbol, Time, Proc] do
|
||||||
@v8_cache ||= Cache.new
|
type.class_eval do
|
||||||
end
|
include V8::Conversion.const_get(name)
|
||||||
|
|
||||||
|
|
||||||
class Cache
|
|
||||||
def initialize
|
|
||||||
@storage = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(v8_object)
|
|
||||||
if v8_object.is_a?(V8::C::Object)
|
|
||||||
weakref = @storage[v8_object.GetIdentityHash()]
|
|
||||||
if weakref && weakref.weakref_alive?
|
|
||||||
weakref.__getobj__
|
|
||||||
else
|
|
||||||
@storage[v8_object.GetIdentityHash()] = WeakRef.new(yield)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
yield
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Numeric
|
class Numeric
|
||||||
def to_v8
|
include V8::Conversion::Numeric
|
||||||
self
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class V8::C::String
|
class Object
|
||||||
def to_ruby
|
include V8::Conversion::Object
|
||||||
self.Utf8Value()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class String
|
|
||||||
def to_v8
|
|
||||||
V8::C::String::New(self)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Symbol
|
|
||||||
def to_v8
|
|
||||||
V8::C::String::NewSymbol(to_s)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class V8::C::Date
|
|
||||||
def to_ruby
|
|
||||||
Time.at(self.NumberValue() / 1000)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Time
|
|
||||||
def to_v8
|
|
||||||
V8::C::Date::New(to_f * 1000)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class V8::C::Object
|
|
||||||
def to_ruby
|
|
||||||
V8::Object.new(self)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class V8::Object
|
|
||||||
def to_v8
|
|
||||||
self.native
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class V8::C::Array
|
|
||||||
def to_ruby
|
|
||||||
V8::Array.new(self)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Array
|
class Array
|
||||||
def to_v8
|
include V8::Conversion::Array
|
||||||
array = V8::Array.new(length)
|
|
||||||
each_with_index do |item, i|
|
|
||||||
array[i] = item
|
|
||||||
end
|
|
||||||
return array.to_v8
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Hash
|
class Hash
|
||||||
def to_v8
|
include V8::Conversion::Hash
|
||||||
object = V8::Object.new
|
|
||||||
each do |key, value|
|
|
||||||
object[key] = value
|
|
||||||
end
|
|
||||||
return object.to_v8
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class String
|
||||||
|
include V8::Conversion::String
|
||||||
|
end
|
||||||
|
|
||||||
|
class Symbol
|
||||||
|
include V8::Conversion::Symbol
|
||||||
|
end
|
||||||
|
|
||||||
|
class Time
|
||||||
|
include V8::Conversion::Time
|
||||||
|
end
|
||||||
|
|
||||||
|
class Proc
|
||||||
|
include V8::Conversion::Proc
|
||||||
|
end
|
||||||
|
|
||||||
|
class V8::C::Object
|
||||||
|
include V8::Conversion::NativeObject
|
||||||
|
end
|
||||||
|
|
||||||
|
class V8::C::Array
|
||||||
|
include V8::Conversion::NativeArray
|
||||||
|
end
|
||||||
|
|
||||||
|
class V8::C::String
|
||||||
|
include V8::Conversion::NativeString
|
||||||
|
end
|
||||||
|
|
||||||
|
class V8::C::Date
|
||||||
|
include V8::Conversion::NativeDate
|
||||||
|
end
|
||||||
|
|
||||||
|
|
17
lib/v8/conversion/array.rb
Normal file
17
lib/v8/conversion/array.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Array
|
||||||
|
def to_v8
|
||||||
|
array = V8::Array.new(length)
|
||||||
|
each_with_index do |item, i|
|
||||||
|
array[i] = item
|
||||||
|
end
|
||||||
|
return array.to_v8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NativeArray
|
||||||
|
def to_ruby
|
||||||
|
V8::Array.new(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/v8/conversion/fundamental.rb
Normal file
11
lib/v8/conversion/fundamental.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Fundamental
|
||||||
|
def to_ruby(v8_object)
|
||||||
|
v8_object.to_ruby
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_v8(ruby_object)
|
||||||
|
ruby_object.to_v8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/v8/conversion/hash.rb
Normal file
11
lib/v8/conversion/hash.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Hash
|
||||||
|
def to_v8
|
||||||
|
object = V8::Object.new
|
||||||
|
each do |key, value|
|
||||||
|
object[key] = value
|
||||||
|
end
|
||||||
|
return object.to_v8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
lib/v8/conversion/indentity.rb
Normal file
30
lib/v8/conversion/indentity.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Identity
|
||||||
|
def to_ruby(v8_object)
|
||||||
|
v8_idmap.lookup(v8_object) {super}
|
||||||
|
end
|
||||||
|
|
||||||
|
def v8_idmap
|
||||||
|
@v8_idmap ||= V8IDMap.new
|
||||||
|
end
|
||||||
|
|
||||||
|
class V8IDMap
|
||||||
|
def initialize
|
||||||
|
@storage = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def lookup(v8_object)
|
||||||
|
if v8_object.is_a?(V8::C::Object)
|
||||||
|
weakref = @storage[v8_object.GetIdentityHash()]
|
||||||
|
if weakref && weakref.weakref_alive?
|
||||||
|
weakref.__getobj__
|
||||||
|
else
|
||||||
|
@storage[v8_object.GetIdentityHash()] = WeakRef.new(yield)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
lib/v8/conversion/numeric.rb
Normal file
7
lib/v8/conversion/numeric.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Numeric
|
||||||
|
def to_v8
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
lib/v8/conversion/object.rb
Normal file
17
lib/v8/conversion/object.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Object
|
||||||
|
def to_v8
|
||||||
|
V8::C::Object::New()
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_ruby
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NativeObject
|
||||||
|
def to_ruby
|
||||||
|
::V8::Object.new(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
lib/v8/conversion/proc.rb
Normal file
7
lib/v8/conversion/proc.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Proc
|
||||||
|
def to_v8
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/v8/conversion/string.rb
Normal file
12
lib/v8/conversion/string.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module String
|
||||||
|
def to_v8
|
||||||
|
V8::C::String::New(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
module NativeString
|
||||||
|
def to_ruby
|
||||||
|
self.Utf8Value()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
lib/v8/conversion/symbol.rb
Normal file
7
lib/v8/conversion/symbol.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Symbol
|
||||||
|
def to_v8
|
||||||
|
V8::C::String::NewSymbol(to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
13
lib/v8/conversion/time.rb
Normal file
13
lib/v8/conversion/time.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
class V8::Conversion
|
||||||
|
module Time
|
||||||
|
def to_v8
|
||||||
|
V8::C::Date::New(to_f * 1000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NativeDate
|
||||||
|
def to_ruby
|
||||||
|
::Time.at(self.NumberValue() / 1000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
class V8::Object
|
class V8::Object
|
||||||
include Enumerable
|
include Enumerable
|
||||||
attr_reader :native
|
attr_reader :native
|
||||||
|
alias_method :to_v8, :native
|
||||||
|
|
||||||
def initialize(native = nil)
|
def initialize(native = nil)
|
||||||
@context = V8::Context.current or fail "tried to initialize a #{self.class} without being in an entered V8::Context"
|
@context = V8::Context.current or fail "tried to initialize a #{self.class} without being in an entered V8::Context"
|
||||||
|
@ -23,10 +24,16 @@ class V8::Object
|
||||||
def each
|
def each
|
||||||
@context.enter do
|
@context.enter do
|
||||||
names = @native.GetPropertyNames()
|
names = @native.GetPropertyNames()
|
||||||
0.upto(@native.Length() - 1) do |i|
|
0.upto(names.Length() - 1) do |i|
|
||||||
name = names.Get(i)
|
name = names.Get(i)
|
||||||
yield @context.to_ruby(name), @context.to_ruby(@native.Get(name))
|
yield @context.to_ruby(name), @context.to_ruby(@native.Get(name))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
@context.enter do
|
||||||
|
"#{self.class}#{@native.ToString().Utf8Value()}"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Add table
Reference in a new issue