1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00
therubyracer/lib/v8/to.rb

133 lines
3.9 KiB
Ruby
Raw Normal View History

2010-06-08 05:47:20 -04:00
require 'weakref'
2009-12-18 02:48:06 -05:00
module V8
module To
class << self
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()
when V8::C::Date then Time.at(value.NumberValue())
2009-12-18 02:48:06 -05:00
else
value
end
end
2009-12-18 02:48:06 -05:00
def v8(value)
case value
when V8::Object
value.instance_eval {@native}
when String, Symbol
C::String::New(value.to_s)
when Proc,Method
template = C::FunctionTemplate::New() do |arguments|
rbargs = []
for i in 0..arguments.Length() - 1
rbargs << To.rb(arguments[i])
end
V8::Function.rubycall(value, *rbargs)
end
return template.GetFunction()
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
when ::Hash
C::Object::New().tap do |o|
value.each do |key, value|
o.Set(To.v8(key), To.v8(value))
end
end
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
when nil,Numeric,TrueClass,FalseClass, C::Value
2009-12-18 02:48:06 -05:00
value
else
2010-06-08 05:47:20 -04:00
args = C::Array::New(1)
args.Set(0, C::External::New(value))
2010-06-08 05:47:20 -04:00
obj = To.class_template(value.class).GetFunction().NewInstance(args)
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
def template
@rubyobject ||= C::ObjectTemplate::New().tap do |t|
t.SetNamedPropertyHandler(
NamedPropertyGetter,
NamedPropertySetter,
nil,
nil,
NamedPropertyEnumerator
)
end
end
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)
wrapper = C::External::New(instance)
2010-06-08 05:47:20 -04:00
end
arguments.This().tap do |this|
2010-06-08 12:51:09 -04:00
this.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyObject"), wrapper)
end
2010-06-08 05:47:20 -04:00
end
class_template.InstanceTemplate().SetNamedPropertyHandler(
2010-06-08 05:47:20 -04:00
NamedPropertyGetter,
NamedPropertySetter,
nil,
nil,
NamedPropertyEnumerator
)
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
def camel_case(str)
str.to_s.gsub(/_(\w)/) {$1.upcase}
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