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/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/context'
|
||||
require 'v8/object'
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
class V8::Array < V8::Object
|
||||
|
||||
def initialize(native_or_length = nil)
|
||||
if native_or_length.is_a?(Numeric)
|
||||
super V8::C::Array::New(native.to_i)
|
||||
native = if native_or_length.is_a?(Numeric)
|
||||
V8::C::Array::New(native_or_length)
|
||||
elsif native_or_length.is_a?(V8::C::Array)
|
||||
super native_or_length
|
||||
native_or_length
|
||||
else
|
||||
super V8::C::Array::New()
|
||||
V8::C::Array::New()
|
||||
end
|
||||
super native
|
||||
end
|
||||
|
||||
def each
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
module V8
|
||||
class Context
|
||||
include Conversion
|
||||
|
||||
attr_reader :native
|
||||
|
||||
def initialize
|
||||
@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
|
||||
|
||||
def enter(&block)
|
||||
|
@ -46,10 +54,22 @@ module V8
|
|||
|
||||
def eval(source, filename = '<eval>', line = 1)
|
||||
enter do
|
||||
source = V8::C::String::New(source.to_s)
|
||||
filename = V8::C::String::New(filename.to_s)
|
||||
script = V8::C::Script::New(source, filename)
|
||||
to_ruby script.Run()
|
||||
V8::C::TryCatch() do |trycatch|
|
||||
source = V8::C::String::New(source.to_s)
|
||||
filename = V8::C::String::New(filename.to_s)
|
||||
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
|
||||
|
||||
|
|
|
@ -1,109 +1,68 @@
|
|||
module V8::Conversion
|
||||
|
||||
class V8::Conversion
|
||||
include Fundamental
|
||||
include Identity
|
||||
|
||||
def to_ruby(v8_object)
|
||||
v8_cache.get(v8_object) do
|
||||
v8_object.respond_to?(:to_ruby) ? v8_object.to_ruby : v8_object
|
||||
end
|
||||
super v8_object
|
||||
end
|
||||
|
||||
def to_v8(ruby_object)
|
||||
ruby_object.respond_to?(:to_v8) ? ruby_object.to_v8 : V8::C::Object::New()
|
||||
super ruby_object
|
||||
end
|
||||
end
|
||||
|
||||
def v8_cache
|
||||
@v8_cache ||= Cache.new
|
||||
end
|
||||
|
||||
|
||||
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
|
||||
for type in [Numeric, Object, Array, Hash, String, Symbol, Time, Proc] do
|
||||
type.class_eval do
|
||||
include V8::Conversion.const_get(name)
|
||||
end
|
||||
end
|
||||
|
||||
class Numeric
|
||||
def to_v8
|
||||
self
|
||||
end
|
||||
include V8::Conversion::Numeric
|
||||
end
|
||||
|
||||
class V8::C::String
|
||||
def to_ruby
|
||||
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
|
||||
class Object
|
||||
include V8::Conversion::Object
|
||||
end
|
||||
|
||||
class Array
|
||||
def to_v8
|
||||
array = V8::Array.new(length)
|
||||
each_with_index do |item, i|
|
||||
array[i] = item
|
||||
end
|
||||
return array.to_v8
|
||||
end
|
||||
include V8::Conversion::Array
|
||||
end
|
||||
|
||||
class Hash
|
||||
def to_v8
|
||||
object = V8::Object.new
|
||||
each do |key, value|
|
||||
object[key] = value
|
||||
end
|
||||
return object.to_v8
|
||||
end
|
||||
end
|
||||
include V8::Conversion::Hash
|
||||
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
|
||||
include Enumerable
|
||||
attr_reader :native
|
||||
alias_method :to_v8, :native
|
||||
|
||||
def initialize(native = nil)
|
||||
@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
|
||||
@context.enter do
|
||||
names = @native.GetPropertyNames()
|
||||
0.upto(@native.Length() - 1) do |i|
|
||||
0.upto(names.Length() - 1) do |i|
|
||||
name = names.Get(i)
|
||||
yield @context.to_ruby(name), @context.to_ruby(@native.Get(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
@context.enter do
|
||||
"#{self.class}#{@native.ToString().Utf8Value()}"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue