aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch')
-rw-r--r--src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch364
1 files changed, 364 insertions, 0 deletions
diff --git a/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
new file mode 100644
index 0000000000..daa2250a25
--- /dev/null
+++ b/src/declarative/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
@@ -0,0 +1,364 @@
+From ae8688b53d67044f2c9b0cce25fc282b078610c1 Mon Sep 17 00:00:00 2001
+From: Aaron Kennedy <aaron.kennedy@nokia.com>
+Date: Mon, 23 May 2011 16:21:02 +1000
+Subject: [PATCH 3/8] Add a "fallback" mode for named property interceptors
+
+By default interceptors are called before the normal property
+resolution on objects. When an interceptor is installed as a
+"fallback" interceptor, it is only called if the object doesn't
+already have the property.
+
+In the case of a global object having an fallback interceptor,
+the interceptor is not invoked at all for var or function
+declarations.
+---
+ include/v8.h | 8 ++++++++
+ src/api.cc | 29 +++++++++++++++++++++++++++++
+ src/factory.cc | 4 ++++
+ src/handles.cc | 6 ++++--
+ src/handles.h | 3 ++-
+ src/objects-inl.h | 16 ++++++++++++++++
+ src/objects.cc | 22 ++++++++++++++++------
+ src/objects.h | 18 ++++++++++++++----
+ src/runtime.cc | 11 ++++++-----
+ 9 files changed, 99 insertions(+), 18 deletions(-)
+
+diff --git a/include/v8.h b/include/v8.h
+index bbd29e9..85452aa 100644
+--- a/include/v8.h
++++ b/include/v8.h
+@@ -2169,6 +2169,7 @@ class V8EXPORT FunctionTemplate : public Template {
+ NamedPropertyQuery query,
+ NamedPropertyDeleter remover,
+ NamedPropertyEnumerator enumerator,
++ bool is_fallback,
+ Handle<Value> data);
+ void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,
+ IndexedPropertySetter setter,
+@@ -2253,6 +2254,13 @@ class V8EXPORT ObjectTemplate : public Template {
+ NamedPropertyEnumerator enumerator = 0,
+ Handle<Value> data = Handle<Value>());
+
++ void SetFallbackPropertyHandler(NamedPropertyGetter getter,
++ NamedPropertySetter setter = 0,
++ NamedPropertyQuery query = 0,
++ NamedPropertyDeleter deleter = 0,
++ NamedPropertyEnumerator enumerator = 0,
++ Handle<Value> data = Handle<Value>());
++
+ /**
+ * Sets an indexed property handler on the object template.
+ *
+diff --git a/src/api.cc b/src/api.cc
+index 381935b..8b0b32a 100644
+--- a/src/api.cc
++++ b/src/api.cc
+@@ -981,6 +981,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
+ NamedPropertyQuery query,
+ NamedPropertyDeleter remover,
+ NamedPropertyEnumerator enumerator,
++ bool is_fallback,
+ Handle<Value> data) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate,
+@@ -999,6 +1000,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
+ if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
+ if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
+ if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
++ obj->set_is_fallback(i::Smi::FromInt(is_fallback));
+
+ if (data.IsEmpty()) data = v8::Undefined();
+ obj->set_data(*Utils::OpenHandle(*data));
+@@ -1143,6 +1145,33 @@ void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
+ query,
+ remover,
+ enumerator,
++ false,
++ data);
++}
++
++
++void ObjectTemplate::SetFallbackPropertyHandler(NamedPropertyGetter getter,
++ NamedPropertySetter setter,
++ NamedPropertyQuery query,
++ NamedPropertyDeleter remover,
++ NamedPropertyEnumerator enumerator,
++ Handle<Value> data) {
++ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
++ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetFallbackPropertyHandler()")) {
++ return;
++ }
++ ENTER_V8(isolate);
++ i::HandleScope scope(isolate);
++ EnsureConstructor(this);
++ i::FunctionTemplateInfo* constructor =
++ i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
++ i::Handle<i::FunctionTemplateInfo> cons(constructor);
++ Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter,
++ setter,
++ query,
++ remover,
++ enumerator,
++ true,
+ data);
+ }
+
+diff --git a/src/factory.cc b/src/factory.cc
+index 7dee66f..dcdc645 100644
+--- a/src/factory.cc
++++ b/src/factory.cc
+@@ -1058,6 +1058,10 @@ Handle<JSFunction> Factory::CreateApiFunction(
+ // Set interceptor information in the map.
+ if (!obj->named_property_handler()->IsUndefined()) {
+ map->set_has_named_interceptor();
++
++ InterceptorInfo *nph = InterceptorInfo::cast(obj->named_property_handler());
++ bool is_fallback = nph->is_fallback()->IsUndefined()?false:nph->is_fallback()->value();
++ map->set_named_interceptor_is_fallback(is_fallback);
+ }
+ if (!obj->indexed_property_handler()->IsUndefined()) {
+ map->set_has_indexed_interceptor();
+diff --git a/src/handles.cc b/src/handles.cc
+index 326de86..dd3a86c 100644
+--- a/src/handles.cc
++++ b/src/handles.cc
+@@ -262,9 +262,11 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+- StrictModeFlag strict_mode) {
++ StrictModeFlag strict_mode,
++ bool skip_fallback_interceptor) {
+ CALL_HEAP_FUNCTION(object->GetIsolate(),
+- object->SetProperty(*key, *value, attributes, strict_mode),
++ object->SetProperty(*key, *value, attributes, strict_mode,
++ skip_fallback_interceptor),
+ Object);
+ }
+
+diff --git a/src/handles.h b/src/handles.h
+index 3839f37..4b42506 100644
+--- a/src/handles.h
++++ b/src/handles.h
+@@ -188,7 +188,8 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes,
+- StrictModeFlag strict_mode);
++ StrictModeFlag strict_mode,
++ bool skip_fallback_interceptor = false);
+
+ Handle<Object> SetProperty(Handle<Object> object,
+ Handle<Object> key,
+diff --git a/src/objects-inl.h b/src/objects-inl.h
+index cce3edd..6aaca2f 100644
+--- a/src/objects-inl.h
++++ b/src/objects-inl.h
+@@ -2521,6 +2521,21 @@ bool Map::is_shared() {
+ }
+
+
++void Map::set_named_interceptor_is_fallback(bool value)
++{
++ if (value) {
++ set_bit_field3(bit_field3() | (1 << kNamedInterceptorIsFallback));
++ } else {
++ set_bit_field3(bit_field3() & ~(1 << kNamedInterceptorIsFallback));
++ }
++}
++
++bool Map::named_interceptor_is_fallback()
++{
++ return ((1 << kNamedInterceptorIsFallback) & bit_field3()) != 0;
++}
++
++
+ JSFunction* Map::unchecked_constructor() {
+ return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
+ }
+@@ -2970,6 +2985,7 @@ ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
+ ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
+ ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
+ ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
++ACCESSORS(InterceptorInfo, is_fallback, Smi, kFallbackOffset)
+
+ ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
+ ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
+diff --git a/src/objects.cc b/src/objects.cc
+index 79d7240..15e2cdb 100644
+--- a/src/objects.cc
++++ b/src/objects.cc
+@@ -1712,9 +1712,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
+ MaybeObject* JSObject::SetProperty(String* name,
+ Object* value,
+ PropertyAttributes attributes,
+- StrictModeFlag strict_mode) {
++ StrictModeFlag strict_mode,
++ bool skip_fallback_interceptor) {
+ LookupResult result;
+- LocalLookup(name, &result);
++ LocalLookup(name, &result, skip_fallback_interceptor);
+ return SetProperty(&result, name, value, attributes, strict_mode);
+ }
+
+@@ -3148,7 +3149,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
+ }
+
+
+-void JSObject::LocalLookup(String* name, LookupResult* result) {
++void JSObject::LocalLookup(String* name, LookupResult* result,
++ bool skip_fallback_interceptor) {
+ ASSERT(name->IsString());
+
+ Heap* heap = GetHeap();
+@@ -3174,22 +3176,30 @@ void JSObject::LocalLookup(String* name, LookupResult* result) {
+ }
+
+ // Check for lookup interceptor except when bootstrapping.
+- if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) {
++ bool wouldIntercept = HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive();
++ if (wouldIntercept && !map()->named_interceptor_is_fallback()) {
+ result->InterceptorResult(this);
+ return;
+ }
+
+ LocalLookupRealNamedProperty(name, result);
++
++ if (wouldIntercept && !skip_fallback_interceptor && !result->IsProperty() &&
++ map()->named_interceptor_is_fallback()) {
++ result->InterceptorResult(this);
++ return;
++ }
+ }
+
+
+-void JSObject::Lookup(String* name, LookupResult* result) {
++void JSObject::Lookup(String* name, LookupResult* result,
++ bool skip_fallback_interceptor) {
+ // Ecma-262 3rd 8.6.2.4
+ Heap* heap = GetHeap();
+ for (Object* current = this;
+ current != heap->null_value();
+ current = JSObject::cast(current)->GetPrototype()) {
+- JSObject::cast(current)->LocalLookup(name, result);
++ JSObject::cast(current)->LocalLookup(name, result, skip_fallback_interceptor);
+ if (result->IsProperty()) return;
+ }
+ result->NotFound();
+diff --git a/src/objects.h b/src/objects.h
+index 07e1089..a209cd0 100644
+--- a/src/objects.h
++++ b/src/objects.h
+@@ -1405,7 +1405,8 @@ class JSObject: public HeapObject {
+ MUST_USE_RESULT MaybeObject* SetProperty(String* key,
+ Object* value,
+ PropertyAttributes attributes,
+- StrictModeFlag strict_mode);
++ StrictModeFlag strict_mode,
++ bool skip_fallback_interceptor = false);
+ MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
+ String* key,
+ Object* value,
+@@ -1637,8 +1638,8 @@ class JSObject: public HeapObject {
+
+ // Lookup a property. If found, the result is valid and has
+ // detailed information.
+- void LocalLookup(String* name, LookupResult* result);
+- void Lookup(String* name, LookupResult* result);
++ void LocalLookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
++ void Lookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
+
+ // The following lookup functions skip interceptors.
+ void LocalLookupRealNamedProperty(String* name, LookupResult* result);
+@@ -3714,6 +3715,12 @@ class Map: public HeapObject {
+ inline void set_is_access_check_needed(bool access_check_needed);
+ inline bool is_access_check_needed();
+
++
++ // Whether the named interceptor is a fallback interceptor or not
++ inline void set_named_interceptor_is_fallback(bool value);
++ inline bool named_interceptor_is_fallback();
++
++
+ // [prototype]: implicit prototype object.
+ DECL_ACCESSORS(prototype, Object)
+
+@@ -3904,6 +3911,7 @@ class Map: public HeapObject {
+ static const int kHasExternalArrayElements = 6;
+
+ // Bit positions for bit field 3
++ static const int kNamedInterceptorIsFallback = 0;
+
+ // Layout of the default cache. It holds alternating name and code objects.
+ static const int kCodeCacheEntrySize = 2;
+@@ -6276,6 +6284,7 @@ class InterceptorInfo: public Struct {
+ DECL_ACCESSORS(deleter, Object)
+ DECL_ACCESSORS(enumerator, Object)
+ DECL_ACCESSORS(data, Object)
++ DECL_ACCESSORS(is_fallback, Smi)
+
+ static inline InterceptorInfo* cast(Object* obj);
+
+@@ -6295,7 +6304,8 @@ class InterceptorInfo: public Struct {
+ static const int kDeleterOffset = kQueryOffset + kPointerSize;
+ static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
+ static const int kDataOffset = kEnumeratorOffset + kPointerSize;
+- static const int kSize = kDataOffset + kPointerSize;
++ static const int kFallbackOffset = kDataOffset + kPointerSize;
++ static const int kSize = kFallbackOffset + kPointerSize;
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
+diff --git a/src/runtime.cc b/src/runtime.cc
+index 7335da8..660352c 100644
+--- a/src/runtime.cc
++++ b/src/runtime.cc
+@@ -1097,7 +1097,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+ // Lookup the property in the global object, and don't set the
+ // value of the variable if the property is already there.
+ LookupResult lookup;
+- global->Lookup(*name, &lookup);
++ global->Lookup(*name, &lookup, true);
+ if (lookup.IsProperty()) {
+ // Determine if the property is local by comparing the holder
+ // against the global object. The information will be used to
+@@ -1152,7 +1152,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+ }
+
+ LookupResult lookup;
+- global->LocalLookup(*name, &lookup);
++ global->LocalLookup(*name, &lookup, true);
+
+ PropertyAttributes attributes = is_const_property
+ ? static_cast<PropertyAttributes>(base | READ_ONLY)
+@@ -1196,7 +1196,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+ name,
+ value,
+ attributes,
+- strict_mode));
++ strict_mode,
++ true));
+ }
+ }
+
+@@ -1343,7 +1344,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+ JSObject* real_holder = global;
+ LookupResult lookup;
+ while (true) {
+- real_holder->LocalLookup(*name, &lookup);
++ real_holder->LocalLookup(*name, &lookup, true);
+ if (lookup.IsProperty()) {
+ // Determine if this is a redeclaration of something read-only.
+ if (lookup.IsReadOnly()) {
+@@ -1400,7 +1401,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+
+ global = isolate->context()->global();
+ if (assign) {
+- return global->SetProperty(*name, args[2], attributes, strict_mode);
++ return global->SetProperty(*name, args[2], attributes, strict_mode, true);
+ }
+ return isolate->heap()->undefined_value();
+ }
+--
+1.7.2.3
+