mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
support for indexed property access
This commit is contained in:
parent
8191e68c2e
commit
626b36cf5c
3 changed files with 66 additions and 17 deletions
|
@ -114,10 +114,14 @@ namespace {
|
||||||
Handle<Value> RubyIndexedPropertyGetter(uint32_t index, const AccessorInfo& info) {
|
Handle<Value> RubyIndexedPropertyGetter(uint32_t index, const AccessorInfo& info) {
|
||||||
VALUE code = (VALUE)External::Unwrap(info.Data());
|
VALUE code = (VALUE)External::Unwrap(info.Data());
|
||||||
VALUE getter = rb_hash_lookup(code, "getter");
|
VALUE getter = rb_hash_lookup(code, "getter");
|
||||||
VALUE result = rb_funcall(getter, rb_intern("call"), 1, UINT2NUM(index));
|
VALUE result = rb_funcall(getter, rb_intern("call"), 2, UINT2NUM(index), rr_v82rb(info));
|
||||||
return rr_rb2v8(result);
|
return rr_rb2v8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value if the setter intercepts the request.
|
||||||
|
* Otherwise, returns an empty handle.
|
||||||
|
*/
|
||||||
Handle<Value> RubyIndexedPropertySetter(uint32_t index, Local<Value> value, const AccessorInfo& info) {
|
Handle<Value> RubyIndexedPropertySetter(uint32_t index, Local<Value> value, const AccessorInfo& info) {
|
||||||
VALUE code = (VALUE)External::Unwrap(info.Data());
|
VALUE code = (VALUE)External::Unwrap(info.Data());
|
||||||
VALUE setter = rb_hash_lookup(code, "setter");
|
VALUE setter = rb_hash_lookup(code, "setter");
|
||||||
|
@ -302,6 +306,7 @@ void rr_init_template() {
|
||||||
rr_define_singleton_method(ObjectTemplateClass, "New", Obj::New, 0);
|
rr_define_singleton_method(ObjectTemplateClass, "New", Obj::New, 0);
|
||||||
rr_define_method(ObjectTemplateClass, "NewInstance", Obj::NewInstance, 0);
|
rr_define_method(ObjectTemplateClass, "NewInstance", Obj::NewInstance, 0);
|
||||||
rr_define_method(ObjectTemplateClass, "SetNamedPropertyHandler", Obj::SetNamedPropertyHandler, 5);
|
rr_define_method(ObjectTemplateClass, "SetNamedPropertyHandler", Obj::SetNamedPropertyHandler, 5);
|
||||||
|
rr_define_method(ObjectTemplateClass, "SetIndexedPropertyHandler", Obj::SetIndexedPropertyHandler, 5);
|
||||||
|
|
||||||
FunctionTemplateClass = rr_define_class("FunctionTemplate", Template);
|
FunctionTemplateClass = rr_define_class("FunctionTemplate", Template);
|
||||||
rr_define_singleton_method(FunctionTemplateClass, "New", Func::New, 0);
|
rr_define_singleton_method(FunctionTemplateClass, "New", Func::New, 0);
|
||||||
|
|
|
@ -25,13 +25,7 @@ module V8
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
template(cls).tap do |t|
|
template(cls).tap do |t|
|
||||||
t.InstanceTemplate().SetNamedPropertyHandler(
|
Access.setuptemplate(t.InstanceTemplate())
|
||||||
NamedPropertyGetter,
|
|
||||||
NamedPropertySetter,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
NamedPropertyEnumerator
|
|
||||||
)
|
|
||||||
if cls.name && cls.name =~ /(::)?(\w+?)$/
|
if cls.name && cls.name =~ /(::)?(\w+?)$/
|
||||||
t.SetClassName(C::String::NewSymbol("rb::" + $2))
|
t.SetClassName(C::String::NewSymbol("rb::" + $2))
|
||||||
else
|
else
|
||||||
|
@ -56,6 +50,11 @@ module V8
|
||||||
|
|
||||||
def self.rubyobject
|
def self.rubyobject
|
||||||
@rubyobject ||= C::ObjectTemplate::New().tap do |t|
|
@rubyobject ||= C::ObjectTemplate::New().tap do |t|
|
||||||
|
setuptemplate(t)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.setuptemplate(t)
|
||||||
t.SetNamedPropertyHandler(
|
t.SetNamedPropertyHandler(
|
||||||
NamedPropertyGetter,
|
NamedPropertyGetter,
|
||||||
NamedPropertySetter,
|
NamedPropertySetter,
|
||||||
|
@ -63,7 +62,13 @@ module V8
|
||||||
nil,
|
nil,
|
||||||
NamedPropertyEnumerator
|
NamedPropertyEnumerator
|
||||||
)
|
)
|
||||||
end
|
t.SetIndexedPropertyHandler(
|
||||||
|
IndexedPropertyGetter,
|
||||||
|
IndexedPropertySetter,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
IndexedPropertyEnumerator
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -134,6 +139,45 @@ module V8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class IndexedPropertyGetter
|
||||||
|
def self.call(index, info)
|
||||||
|
obj = To.rb(info.This())
|
||||||
|
if obj.respond_to?(:[])
|
||||||
|
obj[index]
|
||||||
|
else
|
||||||
|
C::Empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class IndexedPropertySetter
|
||||||
|
def self.call(index, value, info)
|
||||||
|
obj = To.rb(info.This())
|
||||||
|
if obj.respond_to?(:[]=)
|
||||||
|
obj[index] = To.rb(value)
|
||||||
|
value
|
||||||
|
else
|
||||||
|
C::Empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class IndexedPropertyEnumerator
|
||||||
|
def self.call(info)
|
||||||
|
obj = To.rb(info.This())
|
||||||
|
if obj.respond_to?(:length)
|
||||||
|
C::Array::New(obj.length).tap do |indices|
|
||||||
|
for index in 0..obj.length - 1
|
||||||
|
rputs "index: #{index}"
|
||||||
|
indices.Set(index,index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
C::Array::New()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
# evil - but access will be plugggable
|
# evil - but access will be plugggable
|
||||||
def accessible_methods(obj)
|
def accessible_methods(obj)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7a555f5400d0b97cc65862f06949f4ec42946d40
|
Subproject commit 7587bc34da1f2944393e312bf4f1911218375b4a
|
Loading…
Add table
Reference in a new issue