1
0
Fork 0
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:
Charles Lowell 2012-06-11 01:58:12 -05:00
parent 3590c0dadb
commit 32028f31fc
15 changed files with 231 additions and 102 deletions

View file

@ -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'

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View 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
View 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

View 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

View file

@ -0,0 +1,7 @@
class V8::Conversion
module Numeric
def to_v8
self
end
end
end

View 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

View file

@ -0,0 +1,7 @@
class V8::Conversion
module Proc
def to_v8
end
end
end

View 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

View 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
View 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

View file

@ -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