diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-10-11 15:06:25 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-10 13:22:13 +0100 |
commit | bcd16f9453e543ba819385d87bd7061a4caeb325 (patch) | |
tree | 4296919fa02e8188be3b28ca7fa4ab548693be33 /src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch | |
parent | 95d7abb694d5d21acf0a15dcbf3feb4514bd2ab4 (diff) |
Update V8
Change-Id: Ic239ef1e55bed06260e4a04cc2199f64c2d30059
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch')
-rw-r--r-- | src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch new file mode 100644 index 0000000000..d30dc470dd --- /dev/null +++ b/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch @@ -0,0 +1,361 @@ +From 20eca1d4ce4c56b599a052d496f4660f9ca9c978 Mon Sep 17 00:00:00 2001 +From: Aaron Kennedy <aaron.kennedy@nokia.com> +Date: Thu, 27 Oct 2011 11:31:56 +0100 +Subject: [PATCH 02/11] 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 | 7 +++++++ + src/api.cc | 29 +++++++++++++++++++++++++++++ + src/factory.cc | 3 +++ + src/handles.cc | 6 ++++-- + src/handles.h | 3 ++- + src/objects-inl.h | 15 +++++++++++++++ + src/objects.cc | 24 +++++++++++++++++------- + src/objects.h | 16 ++++++++++++---- + src/runtime.cc | 11 ++++++----- + 9 files changed, 95 insertions(+), 19 deletions(-) + +diff --git a/include/v8.h b/include/v8.h +index 86ea70f..d2e6c32 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -2305,6 +2305,7 @@ class V8EXPORT FunctionTemplate : public Template { + NamedPropertyQuery query, + NamedPropertyDeleter remover, + NamedPropertyEnumerator enumerator, ++ bool is_fallback, + Handle<Value> data); + void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter, + IndexedPropertySetter setter, +@@ -2388,6 +2389,12 @@ class V8EXPORT ObjectTemplate : public Template { + NamedPropertyDeleter deleter = 0, + 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 996812e..e0f3b5a 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -1123,6 +1123,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, +@@ -1141,6 +1142,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)); +@@ -1285,6 +1287,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::SetNamedPropertyHandler()")) { ++ 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 15f640e..1b95ed1 100644 +--- a/src/factory.cc ++++ b/src/factory.cc +@@ -1213,6 +1213,9 @@ 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 62851f3..790d224 100644 +--- a/src/handles.cc ++++ b/src/handles.cc +@@ -269,9 +269,11 @@ Handle<Object> SetProperty(Handle<JSReceiver> 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 06e47fc..c359cb3 100644 +--- a/src/handles.h ++++ b/src/handles.h +@@ -190,7 +190,8 @@ Handle<Object> SetProperty(Handle<JSReceiver> 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 34cae9f..1cfea84 100644 +--- a/src/objects-inl.h ++++ b/src/objects-inl.h +@@ -2754,6 +2754,20 @@ void Map::set_is_shared(bool value) { + bool Map::is_shared() { + return ((1 << kIsShared) & bit_field3()) != 0; + } ++ ++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() { +@@ -3255,6 +3269,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 2946d02..f5b6bee 100644 +--- a/src/objects.cc ++++ b/src/objects.cc +@@ -1980,9 +1980,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor( + MaybeObject* JSReceiver::SetProperty(String* name, + Object* value, + PropertyAttributes attributes, +- StrictModeFlag strict_mode) { ++ StrictModeFlag strict_mode, ++ bool skip_fallback_interceptor) { + LookupResult result(GetIsolate()); +- LocalLookup(name, &result); ++ LocalLookup(name, &result, skip_fallback_interceptor); + return SetProperty(&result, name, value, attributes, strict_mode); + } + +@@ -4213,7 +4214,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) { + } + + +-void JSReceiver::LocalLookup(String* name, LookupResult* result) { ++void JSReceiver::LocalLookup(String* name, LookupResult* result, ++ bool skip_fallback_interceptor) { + ASSERT(name->IsString()); + + Heap* heap = GetHeap(); +@@ -4245,23 +4247,31 @@ void JSReceiver::LocalLookup(String* name, LookupResult* result) { + } + + // Check for lookup interceptor except when bootstrapping. +- if (js_object->HasNamedInterceptor() && +- !heap->isolate()->bootstrapper()->IsActive()) { ++ bool wouldIntercept = js_object->HasNamedInterceptor() && ++ !heap->isolate()->bootstrapper()->IsActive(); ++ if (wouldIntercept && !map()->named_interceptor_is_fallback()) { + result->InterceptorResult(js_object); + return; + } + + js_object->LocalLookupRealNamedProperty(name, result); ++ ++ if (wouldIntercept && !skip_fallback_interceptor && !result->IsProperty() && ++ map()->named_interceptor_is_fallback()) { ++ result->InterceptorResult(js_object); ++ return; ++ } + } + + +-void JSReceiver::Lookup(String* name, LookupResult* result) { ++void JSReceiver::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()) { +- JSReceiver::cast(current)->LocalLookup(name, result); ++ JSReceiver::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 d96e5f9..ed40061 100644 +--- a/src/objects.h ++++ b/src/objects.h +@@ -1362,7 +1362,8 @@ class JSReceiver: 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, +@@ -1414,8 +1415,8 @@ class JSReceiver: 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); + + protected: + Smi* GenerateIdentityHash(); +@@ -4242,6 +4243,10 @@ 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) + +@@ -4506,6 +4511,7 @@ class Map: public HeapObject { + + // Bit positions for bit field 3 + static const int kIsShared = 0; ++ static const int kNamedInterceptorIsFallback = 1; + + // Layout of the default cache. It holds alternating name and code objects. + static const int kCodeCacheEntrySize = 2; +@@ -7390,6 +7396,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); + +@@ -7409,7 +7416,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 9c23c2c..0e256c1 100644 +--- a/src/runtime.cc ++++ b/src/runtime.cc +@@ -1330,7 +1330,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(isolate); +- global->Lookup(*name, &lookup); ++ global->Lookup(*name, &lookup, true); + if (lookup.IsProperty()) { + // We found an existing property. Unless it was an interceptor + // that claims the property is absent, skip this declaration. +@@ -1357,7 +1357,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { + } + + LookupResult lookup(isolate); +- global->LocalLookup(*name, &lookup); ++ global->LocalLookup(*name, &lookup, true); + + // Compute the property attributes. According to ECMA-262, section + // 13, page 71, the property must be read-only and +@@ -1398,7 +1398,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { + name, + value, + static_cast<PropertyAttributes>(attr), +- strict_mode)); ++ strict_mode, ++ true)); + } + } + +@@ -1534,7 +1535,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { + while (object->IsJSObject() && + JSObject::cast(object)->map()->is_hidden_prototype()) { + JSObject* raw_holder = JSObject::cast(object); +- raw_holder->LocalLookup(*name, &lookup); ++ raw_holder->LocalLookup(*name, &lookup, true); + if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { + HandleScope handle_scope(isolate); + Handle<JSObject> holder(raw_holder); +@@ -1557,7 +1558,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { + // Reload global in case the loop above performed a GC. + 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.4.4 + |