| Index: gin/object_template_builder.cc
|
| diff --git a/gin/object_template_builder.cc b/gin/object_template_builder.cc
|
| index 8bc271450ad47a9c17bae91bc614c71b21064334..603166cfabff1edb2a964bbdce3fa2d79edc2b53 100644
|
| --- a/gin/object_template_builder.cc
|
| +++ b/gin/object_template_builder.cc
|
| @@ -3,10 +3,133 @@
|
| // found in the LICENSE file.
|
|
|
| #include "gin/object_template_builder.h"
|
| +
|
| +#include "gin/interceptor.h"
|
| +#include "gin/per_isolate_data.h"
|
| #include "gin/public/wrapper_info.h"
|
|
|
| namespace gin {
|
|
|
| +namespace {
|
| +
|
| +WrappableBase* WrappableFromV8(v8::Isolate* isolate,
|
| + v8::Handle<v8::Value> val) {
|
| + if (!val->IsObject())
|
| + return NULL;
|
| + v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val);
|
| + WrapperInfo* info = WrapperInfo::From(obj);
|
| +
|
| + // If this fails, the object is not managed by Gin.
|
| + if (!info)
|
| + return NULL;
|
| +
|
| + // We don't further validate the type of the object, but assume it's derived
|
| + // from WrappableBase. We look up the pointer in a global registry, to make
|
| + // sure it's actually pointed to a valid life object.
|
| + return static_cast<WrappableBase*>(
|
| + obj->GetAlignedPointerFromInternalField(kEncodedValueIndex));
|
| +}
|
| +
|
| +NamedPropertyInterceptor* NamedInterceptorFromV8(v8::Isolate* isolate,
|
| + v8::Handle<v8::Value> val) {
|
| + WrappableBase* base = WrappableFromV8(isolate, val);
|
| + if (!base)
|
| + return NULL;
|
| + return PerIsolateData::From(isolate)->GetNamedPropertyInterceptor(base);
|
| +}
|
| +
|
| +IndexedPropertyInterceptor* IndexedInterceptorFromV8(
|
| + v8::Isolate* isolate,
|
| + v8::Handle<v8::Value> val) {
|
| + WrappableBase* base = WrappableFromV8(isolate, val);
|
| + if (!base)
|
| + return NULL;
|
| + return PerIsolateData::From(isolate)->GetIndexedPropertyInterceptor(base);
|
| +}
|
| +
|
| +void NamedPropertyGetter(v8::Local<v8::String> property,
|
| + const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + NamedPropertyInterceptor* interceptor =
|
| + NamedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + std::string name;
|
| + ConvertFromV8(isolate, property, &name);
|
| + info.GetReturnValue().Set(interceptor->GetNamedProperty(isolate, name));
|
| +}
|
| +
|
| +void NamedPropertySetter(v8::Local<v8::String> property,
|
| + v8::Local<v8::Value> value,
|
| + const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + NamedPropertyInterceptor* interceptor =
|
| + NamedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + std::string name;
|
| + ConvertFromV8(isolate, property, &name);
|
| + interceptor->SetNamedProperty(isolate, name, value);
|
| +}
|
| +
|
| +void NamedPropertyQuery(v8::Local<v8::String> property,
|
| + const v8::PropertyCallbackInfo<v8::Integer>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + NamedPropertyInterceptor* interceptor =
|
| + NamedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + std::string name;
|
| + ConvertFromV8(isolate, property, &name);
|
| + if (interceptor->GetNamedProperty(isolate, name).IsEmpty())
|
| + return;
|
| + info.GetReturnValue().Set(0);
|
| +}
|
| +
|
| +void NamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + NamedPropertyInterceptor* interceptor =
|
| + NamedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + info.GetReturnValue().Set(v8::Handle<v8::Array>::Cast(
|
| + ConvertToV8(isolate, interceptor->EnumerateNamedProperties(isolate))));
|
| +}
|
| +
|
| +void IndexedPropertyGetter(uint32_t index,
|
| + const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + IndexedPropertyInterceptor* interceptor =
|
| + IndexedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + info.GetReturnValue().Set(interceptor->GetIndexedProperty(isolate, index));
|
| +}
|
| +
|
| +void IndexedPropertySetter(uint32_t index,
|
| + v8::Local<v8::Value> value,
|
| + const v8::PropertyCallbackInfo<v8::Value>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + IndexedPropertyInterceptor* interceptor =
|
| + IndexedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + interceptor->SetIndexedProperty(isolate, index, value);
|
| +}
|
| +
|
| +void IndexedPropertyEnumerator(
|
| + const v8::PropertyCallbackInfo<v8::Array>& info) {
|
| + v8::Isolate* isolate = info.GetIsolate();
|
| + IndexedPropertyInterceptor* interceptor =
|
| + IndexedInterceptorFromV8(isolate, info.Holder());
|
| + if (!interceptor)
|
| + return;
|
| + info.GetReturnValue().Set(v8::Handle<v8::Array>::Cast(
|
| + ConvertToV8(isolate, interceptor->EnumerateIndexedProperties(isolate))));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
|
| : isolate_(isolate), template_(v8::ObjectTemplate::New(isolate)) {
|
| template_->SetInternalFieldCount(kNumberOfInternalFields);
|
| @@ -15,6 +138,24 @@ ObjectTemplateBuilder::ObjectTemplateBuilder(v8::Isolate* isolate)
|
| ObjectTemplateBuilder::~ObjectTemplateBuilder() {
|
| }
|
|
|
| +ObjectTemplateBuilder& ObjectTemplateBuilder::AddNamedPropertyInterceptor() {
|
| + template_->SetNamedPropertyHandler(&NamedPropertyGetter,
|
| + &NamedPropertySetter,
|
| + &NamedPropertyQuery,
|
| + NULL,
|
| + &NamedPropertyEnumerator);
|
| + return *this;
|
| +}
|
| +
|
| +ObjectTemplateBuilder& ObjectTemplateBuilder::AddIndexedPropertyInterceptor() {
|
| + template_->SetIndexedPropertyHandler(&IndexedPropertyGetter,
|
| + &IndexedPropertySetter,
|
| + NULL,
|
| + NULL,
|
| + &IndexedPropertyEnumerator);
|
| + return *this;
|
| +}
|
| +
|
| ObjectTemplateBuilder& ObjectTemplateBuilder::SetImpl(
|
| const base::StringPiece& name, v8::Handle<v8::Data> val) {
|
| template_->Set(StringToSymbol(isolate_, name), val);
|
|
|