2010-06-08 05:47:20 -04:00
|
|
|
require 'weakref'
|
2009-12-18 02:48:06 -05:00
|
|
|
|
|
|
|
module V8
|
|
|
|
module To
|
|
|
|
class << self
|
2010-06-07 03:59:41 -04:00
|
|
|
def rb(value)
|
2009-12-18 02:48:06 -05:00
|
|
|
case value
|
2010-06-08 12:51:09 -04:00
|
|
|
when V8::C::Function then peer(value) {V8::Function}
|
|
|
|
when V8::C::Array then peer(value) {V8::Array}
|
|
|
|
when V8::C::Object then peer(value) {V8::Object}
|
2010-05-17 07:39:29 -04:00
|
|
|
when V8::C::String then value.Utf8Value()
|
2010-05-25 02:40:33 -04:00
|
|
|
when V8::C::Date then Time.at(value.NumberValue())
|
2009-12-18 02:48:06 -05:00
|
|
|
else
|
|
|
|
value
|
|
|
|
end
|
|
|
|
end
|
2010-05-22 02:23:22 -04:00
|
|
|
|
2009-12-18 02:48:06 -05:00
|
|
|
def v8(value)
|
|
|
|
case value
|
2010-05-22 02:23:22 -04:00
|
|
|
when V8::Object
|
|
|
|
value.instance_eval {@native}
|
|
|
|
when String, Symbol
|
|
|
|
C::String::New(value.to_s)
|
2010-05-19 08:55:11 -04:00
|
|
|
when Proc,Method
|
2010-05-22 02:23:22 -04:00
|
|
|
template = C::FunctionTemplate::New() do |arguments|
|
2010-05-19 08:55:11 -04:00
|
|
|
rbargs = []
|
|
|
|
for i in 0..arguments.Length() - 1
|
2010-06-07 03:59:41 -04:00
|
|
|
rbargs << To.rb(arguments[i])
|
2010-05-19 08:55:11 -04:00
|
|
|
end
|
2010-05-27 11:30:19 -04:00
|
|
|
V8::Function.rubycall(value, *rbargs)
|
2010-05-22 02:23:22 -04:00
|
|
|
end
|
|
|
|
return template.GetFunction()
|
2010-05-22 22:31:36 -04:00
|
|
|
when ::Array
|
|
|
|
C::Array::New(value.length).tap do |a|
|
|
|
|
value.each_with_index do |item, i|
|
|
|
|
a.Set(i, To.v8(item))
|
|
|
|
end
|
|
|
|
end
|
2010-05-22 22:38:31 -04:00
|
|
|
when ::Hash
|
|
|
|
C::Object::New().tap do |o|
|
|
|
|
value.each do |key, value|
|
|
|
|
o.Set(To.v8(key), To.v8(value))
|
|
|
|
end
|
|
|
|
end
|
2010-05-25 02:40:33 -04:00
|
|
|
when ::Time
|
|
|
|
C::Date::New(value)
|
2010-06-08 12:51:09 -04:00
|
|
|
when ::Class
|
|
|
|
To.class_template(value).GetFunction().tap do |f|
|
|
|
|
f.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyObject"), C::External::New(value))
|
|
|
|
end
|
2010-06-03 05:51:06 -04:00
|
|
|
when nil,Numeric,TrueClass,FalseClass, C::Value
|
2009-12-18 02:48:06 -05:00
|
|
|
value
|
2010-05-22 02:23:22 -04:00
|
|
|
else
|
2010-06-08 05:47:20 -04:00
|
|
|
args = C::Array::New(1)
|
2010-06-08 07:37:28 -04:00
|
|
|
args.Set(0, C::External::New(value))
|
2010-06-08 05:47:20 -04:00
|
|
|
obj = To.class_template(value.class).GetFunction().NewInstance(args)
|
2010-05-22 02:23:22 -04:00
|
|
|
return obj
|
|
|
|
end
|
|
|
|
end
|
2010-06-08 12:51:09 -04:00
|
|
|
|
|
|
|
def peer(value)
|
|
|
|
external = value.GetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyObject"))
|
|
|
|
if external && !external.IsEmpty()
|
|
|
|
external.Value()
|
|
|
|
else
|
|
|
|
yield.new(value)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-06-06 06:18:15 -04:00
|
|
|
def template
|
|
|
|
@rubyobject ||= C::ObjectTemplate::New().tap do |t|
|
|
|
|
t.SetNamedPropertyHandler(
|
|
|
|
NamedPropertyGetter,
|
|
|
|
NamedPropertySetter,
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
NamedPropertyEnumerator
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2010-05-22 02:23:22 -04:00
|
|
|
|
2010-06-08 05:47:20 -04:00
|
|
|
def class_template(cls)
|
|
|
|
@classes ||= {}
|
|
|
|
if ref = @classes[cls.object_id]
|
|
|
|
if ref.weakref_alive?
|
|
|
|
ref.__getobj__
|
|
|
|
else
|
|
|
|
@classes.delete(cls.object_id)
|
|
|
|
self.class_template(cls)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
class_template = C::FunctionTemplate::New() do |arguments|
|
2010-06-08 12:51:09 -04:00
|
|
|
if arguments.Length() > 0 && arguments[0].kind_of?(C::External)
|
2010-06-08 05:47:20 -04:00
|
|
|
wrapper = arguments[0]
|
|
|
|
else
|
|
|
|
rbargs = []
|
|
|
|
for i in 0..arguments.Length() - 1
|
|
|
|
rbargs << To.rb(arguments[i])
|
|
|
|
end
|
|
|
|
instance = V8::Function.rubycall(cls.method(:new), *rbargs)
|
2010-06-08 07:37:28 -04:00
|
|
|
wrapper = C::External::New(instance)
|
2010-06-08 05:47:20 -04:00
|
|
|
end
|
2010-06-08 07:33:54 -04:00
|
|
|
arguments.This().tap do |this|
|
2010-06-08 12:51:09 -04:00
|
|
|
this.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyObject"), wrapper)
|
2010-06-08 07:33:54 -04:00
|
|
|
end
|
2010-06-08 05:47:20 -04:00
|
|
|
end
|
2010-06-08 07:33:54 -04:00
|
|
|
class_template.InstanceTemplate().SetNamedPropertyHandler(
|
2010-06-08 05:47:20 -04:00
|
|
|
NamedPropertyGetter,
|
|
|
|
NamedPropertySetter,
|
|
|
|
nil,
|
|
|
|
nil,
|
|
|
|
NamedPropertyEnumerator
|
|
|
|
)
|
2010-06-08 07:33:54 -04:00
|
|
|
if cls.name && cls.name =~ /(::)?(\w+?)$/
|
|
|
|
class_template.SetClassName(C::String::NewSymbol($2))
|
2010-06-08 05:47:20 -04:00
|
|
|
else
|
|
|
|
class_template.SetClassName("Ruby")
|
|
|
|
end
|
|
|
|
@classes[cls.object_id] = WeakRef.new(class_template)
|
|
|
|
class_template
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2010-01-17 18:12:23 -05:00
|
|
|
def camel_case(str)
|
2010-01-10 04:37:51 -05:00
|
|
|
str.to_s.gsub(/_(\w)/) {$1.upcase}
|
2010-01-17 17:25:40 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def perl_case(str)
|
|
|
|
str.gsub(/([A-Z])([a-z])/) {"_#{$1.downcase}#{$2}"}.downcase
|
|
|
|
end
|
2009-12-18 02:48:06 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|