diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-09-07 10:51:39 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-09-07 04:50:45 +0200 |
commit | bc2eac1ef3e6902f8fed65f72b70b582f93bcb19 (patch) | |
tree | 6af22cb1316b194268981bee884d17ba40dbce3a /src | |
parent | 846c5c9459331cde33ef92b665fab1457eaf1252 (diff) |
Update V8
This fixes a few bugs in QML mode name resolution and simplifies
our V8 patchset a little by folding some patches together.
Change-Id: Ia528a43ac8ccad95ac81bcdff5d05aaeab4b48b2
Reviewed-on: http://codereview.qt.nokia.com/4294
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src')
17 files changed, 670 insertions, 640 deletions
diff --git a/src/3rdparty/v8 b/src/3rdparty/v8 -Subproject 97cb46d421faebd2b139570bcf9aaf2d5eadc33 +Subproject ed5cc903d70f73780e5985e7d2de33f6b8d8640 diff --git a/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch b/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch index 4ec44e3547..2c2439601c 100644 --- a/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch +++ b/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch @@ -1,27 +1,27 @@ -From e13ce09287a56c920d5ffdc5d4662d49f1838f16 Mon Sep 17 00:00:00 2001 +From 3dff2e903674d8ab5310d44281b57de36db659c9 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Mon, 23 May 2011 15:47:20 +1000 -Subject: [PATCH 01/16] Add hashing and comparison methods to v8::String +Subject: [PATCH 01/14] Add hashing and comparison methods to v8::String This allows us to more rapidly search for a v8::String inside a hash of QStrings. --- - include/v8.h | 44 ++++++++++++++++++++++++++++++ + include/v8.h | 45 +++++++++++++++++++++++++++++++ src/api.cc | 43 +++++++++++++++++++++++++++++ src/heap-inl.h | 2 + src/heap.cc | 3 ++ src/objects-inl.h | 1 + src/objects.cc | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++- src/objects.h | 15 +++++++++- - 7 files changed, 182 insertions(+), 3 deletions(-) + 7 files changed, 183 insertions(+), 3 deletions(-) diff --git a/include/v8.h b/include/v8.h -index d15d024..bbd29e9 100644 +index d15d024..be1ee71 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -994,6 +994,48 @@ class String : public Primitive { +@@ -994,6 +994,49 @@ class String : public Primitive { V8EXPORT int Utf8Length() const; - + /** + * Returns the hash of this string. + */ @@ -35,7 +35,7 @@ index d15d024..bbd29e9 100644 + }; + + /** -+ * Returns the "complete" hash of the string. This is ++ * Returns the "complete" hash of the string. This is + * all the information about the string needed to implement + * a very efficient hash keyed on the string. + * @@ -43,7 +43,7 @@ index d15d024..bbd29e9 100644 + * length: The length of the string. Equivalent to Length() + * hash: The hash of the string. Equivalent to Hash() + * symbol_id: If the string is a sequential symbol, the symbol -+ * id, otherwise 0. If the symbol ids of two strings are ++ * id, otherwise 0. If the symbol ids of two strings are + * the same (and non-zero) the two strings are identical. + * If the symbol ids are different the strings may still be + * identical, but an Equals() check must be performed. @@ -63,15 +63,16 @@ index d15d024..bbd29e9 100644 + */ + V8EXPORT bool Equals(uint16_t *string, int length); + V8EXPORT bool Equals(char *string, int length); ++ inline bool Equals(Handle<Value> that) const { return v8::Value::Equals(that); } + + /** * Write the contents of the string to an external buffer. * If no arguments are given, expects the buffer to be large * enough to hold the entire string and NULL terminator. Copies -@@ -1023,6 +1065,8 @@ class String : public Primitive { +@@ -1023,6 +1066,8 @@ class String : public Primitive { HINT_MANY_WRITES_EXPECTED = 1 }; - + + V8EXPORT uint16_t GetCharacter(int index); + V8EXPORT int Write(uint16_t* buffer, @@ -84,7 +85,7 @@ index a2373cd..381935b 100644 @@ -3284,6 +3284,49 @@ int String::Utf8Length() const { return str->Utf8Length(); } - + +uint32_t String::Hash() const { + i::Handle<i::String> str = Utils::OpenHandle(this); + if (IsDeadCheck(str->GetIsolate(), "v8::String::Hash()")) return 0; @@ -128,7 +129,7 @@ index a2373cd..381935b 100644 + if (IsDeadCheck(str->GetIsolate(), "v8::String::Equals()")) return 0; + return str->SlowEqualsExternal(string, length); +} - + int String::WriteUtf8(char* buffer, int capacity, diff --git a/src/heap-inl.h b/src/heap-inl.h @@ -140,17 +141,17 @@ index 99737ed..f4fce7b 100644 answer->set_length(str.length()); answer->set_hash_field(hash_field); + SeqString::cast(answer)->set_symbol_id(0); - + ASSERT_EQ(size, answer->Size()); - + @@ -126,6 +127,7 @@ MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str, String* answer = String::cast(result); answer->set_length(str.length()); answer->set_hash_field(hash_field); + SeqString::cast(answer)->set_symbol_id(0); - + ASSERT_EQ(size, answer->Size()); - + diff --git a/src/heap.cc b/src/heap.cc index 2b6c11f..930c97b 100644 --- a/src/heap.cc @@ -160,9 +161,9 @@ index 2b6c11f..930c97b 100644 answer->set_length(chars); answer->set_hash_field(hash_field); + SeqString::cast(result)->set_symbol_id(0); - + ASSERT_EQ(size, answer->Size()); - + @@ -3561,6 +3562,7 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) { HeapObject::cast(result)->set_map(ascii_string_map()); String::cast(result)->set_length(length); @@ -184,12 +185,12 @@ index 65aec5d..c82080d 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1924,6 +1924,7 @@ INT_ACCESSORS(ExternalArray, length, kLengthOffset) - - + + SMI_ACCESSORS(String, length, kLengthOffset) +SMI_ACCESSORS(SeqString, symbol_id, kSymbolIdOffset) - - + + uint32_t String::hash_field() { diff --git a/src/objects.cc b/src/objects.cc index df61956..dc4b260 100644 @@ -198,7 +199,7 @@ index df61956..dc4b260 100644 @@ -5346,6 +5346,66 @@ static inline bool CompareStringContentsPartial(Isolate* isolate, } } - + +bool String::SlowEqualsExternal(uc16 *string, int length) { + int len = this->length(); + if (len != length) return false; @@ -259,11 +260,11 @@ index df61956..dc4b260 100644 + return CompareStringContents(isolate->objects_string_compare_buffer_a(), &ib); + } +} - + bool String::SlowEquals(String* other) { // Fast check: negative check with lengths. @@ -8655,9 +8715,24 @@ class AsciiSymbolKey : public SequentialSymbolKey<char> { - + MaybeObject* AsObject() { if (hash_field_ == 0) Hash(); - return HEAP->AllocateAsciiSymbol(string_, hash_field_); @@ -285,8 +286,8 @@ index df61956..dc4b260 100644 + static Atomic32 next_symbol_id; }; +Atomic32 AsciiSymbolKey::next_symbol_id = 1; - - + + class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { diff --git a/src/objects.h b/src/objects.h index e966b3d..6e26f57 100644 @@ -295,7 +296,7 @@ index e966b3d..6e26f57 100644 @@ -5359,6 +5359,9 @@ class String: public HeapObject { bool IsAsciiEqualTo(Vector<const char> str); bool IsTwoByteEqualTo(Vector<const uc16> str); - + + bool SlowEqualsExternal(uc16 *string, int length); + bool SlowEqualsExternal(char *string, int length); + @@ -305,14 +306,14 @@ index e966b3d..6e26f57 100644 @@ -5610,9 +5613,17 @@ class String: public HeapObject { class SeqString: public String { public: - + + // Get and set the symbol id of the string + inline int symbol_id(); + inline void set_symbol_id(int value); + // Casting. static inline SeqString* cast(Object* obj); - + + // Layout description. + static const int kSymbolIdOffset = String::kSize; + static const int kSize = kSymbolIdOffset + kPointerSize; @@ -322,22 +323,22 @@ index e966b3d..6e26f57 100644 }; @@ -5647,7 +5658,7 @@ class SeqAsciiString: public SeqString { } - + // Layout description. - static const int kHeaderSize = String::kSize; + static const int kHeaderSize = SeqString::kSize; static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); - + // Maximal memory usage for a single sequential ASCII string. @@ -5701,7 +5712,7 @@ class SeqTwoByteString: public SeqString { } - + // Layout description. - static const int kHeaderSize = String::kSize; + static const int kHeaderSize = SeqString::kSize; static const int kAlignedSize = POINTER_SIZE_ALIGN(kHeaderSize); - + // Maximal memory usage for a single sequential two-byte string. --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0002-Add-a-bit-field-3-to-Map.patch b/src/v8/0002-Add-a-bit-field-3-to-Map.patch index 4b21317668..e1b0d097c5 100644 --- a/src/v8/0002-Add-a-bit-field-3-to-Map.patch +++ b/src/v8/0002-Add-a-bit-field-3-to-Map.patch @@ -1,7 +1,7 @@ -From 7c9cfff80b7864d5687432d424074e51712c4a07 Mon Sep 17 00:00:00 2001 +From 01f7bd262fb1be893fe4bdc6b98a1b43c5a0bb7d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Mon, 23 May 2011 15:55:26 +1000 -Subject: [PATCH 02/16] Add a bit field 3 to Map +Subject: [PATCH 02/14] Add a bit field 3 to Map Bit field 3 will be used to add QML specific map flags. --- @@ -22,13 +22,13 @@ index 930c97b..900f462 100644 + reinterpret_cast<Map*>(result)->set_bit_field3(0); return result; } - + @@ -1599,6 +1600,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type, int instance_size) { map->set_unused_property_fields(0); map->set_bit_field(0); map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements)); + map->set_bit_field3(0); - + // If the map object is aligned fill the padding area with Smi 0 objects. if (Map::kPadStart < Map::kSize) { diff --git a/src/objects-inl.h b/src/objects-inl.h @@ -37,8 +37,8 @@ index c82080d..cce3edd 100644 +++ b/src/objects-inl.h @@ -2430,6 +2430,16 @@ void Map::set_bit_field2(byte value) { } - - + + +byte Map::bit_field3() { + return READ_BYTE_FIELD(this, kBitField3Offset); +} @@ -65,13 +65,13 @@ index dc4b260..79d7240 100644 Map::cast(result)->ClearCodeCache(heap); return result; @@ -3642,6 +3643,7 @@ MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, - + Map::cast(result)->set_bit_field(bit_field()); Map::cast(result)->set_bit_field2(bit_field2()); + Map::cast(result)->set_bit_field3(bit_field3()); - + Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); - + diff --git a/src/objects.h b/src/objects.h index 6e26f57..07e1089 100644 --- a/src/objects.h @@ -79,7 +79,7 @@ index 6e26f57..07e1089 100644 @@ -3597,6 +3597,10 @@ class Map: public HeapObject { inline byte bit_field2(); inline void set_bit_field2(byte value); - + + // Bit field 3. + inline byte bit_field3(); + inline void set_bit_field3(byte value); @@ -101,18 +101,18 @@ index 6e26f57..07e1089 100644 static const int kBitFieldOffset = kInstanceAttributesOffset + 2; static const int kBitField2Offset = kInstanceAttributesOffset + 3; + static const int kBitField3Offset = kInstanceAttributesOffset + 4; - + STATIC_CHECK(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset); - + @@ -3898,6 +3903,8 @@ class Map: public HeapObject { static const int kIsShared = 5; static const int kHasExternalArrayElements = 6; - + + // Bit positions for bit field 3 + // Layout of the default cache. It holds alternating name and code objects. static const int kCodeCacheEntrySize = 2; static const int kCodeCacheEntryNameOffset = 0; --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch index 27529ff3da..ee4410f573 100644 --- a/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch +++ b/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch @@ -1,7 +1,7 @@ -From ae8688b53d67044f2c9b0cce25fc282b078610c1 Mon Sep 17 00:00:00 2001 +From 530ded6ea634bccb96652cd3e0cf67725449ed63 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 03/16] Add a "fallback" mode for named property interceptors +Subject: [PATCH 03/14] 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 @@ -24,10 +24,10 @@ declarations. 9 files changed, 99 insertions(+), 18 deletions(-) diff --git a/include/v8.h b/include/v8.h -index bbd29e9..85452aa 100644 +index be1ee71..bb31ea0 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -2169,6 +2169,7 @@ class V8EXPORT FunctionTemplate : public Template { +@@ -2170,6 +2170,7 @@ class V8EXPORT FunctionTemplate : public Template { NamedPropertyQuery query, NamedPropertyDeleter remover, NamedPropertyEnumerator enumerator, @@ -35,10 +35,10 @@ index bbd29e9..85452aa 100644 Handle<Value> data); void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter, IndexedPropertySetter setter, -@@ -2253,6 +2254,13 @@ class V8EXPORT ObjectTemplate : public Template { +@@ -2254,6 +2255,13 @@ class V8EXPORT ObjectTemplate : public Template { NamedPropertyEnumerator enumerator = 0, Handle<Value> data = Handle<Value>()); - + + void SetFallbackPropertyHandler(NamedPropertyGetter getter, + NamedPropertySetter setter = 0, + NamedPropertyQuery query = 0, @@ -66,7 +66,7 @@ index 381935b..8b0b32a 100644 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, @@ -102,7 +102,7 @@ index 381935b..8b0b32a 100644 + true, data); } - + diff --git a/src/factory.cc b/src/factory.cc index 7dee66f..dcdc645 100644 --- a/src/factory.cc @@ -131,11 +131,11 @@ index 326de86..dd3a86c 100644 + bool skip_fallback_interceptor) { CALL_HEAP_FUNCTION(object->GetIsolate(), - object->SetProperty(*key, *value, attributes, strict_mode), -+ 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 @@ -147,7 +147,7 @@ index 3839f37..4b42506 100644 - 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 @@ -156,8 +156,8 @@ index cce3edd..6aaca2f 100644 +++ b/src/objects-inl.h @@ -2521,6 +2521,21 @@ bool Map::is_shared() { } - - + + +void Map::set_named_interceptor_is_fallback(bool value) +{ + if (value) { @@ -181,7 +181,7 @@ index cce3edd..6aaca2f 100644 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 @@ -200,20 +200,20 @@ index 79d7240..15e2cdb 100644 + 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(); @@ -221,19 +221,19 @@ index 79d7240..15e2cdb 100644 result->InterceptorResult(this); return; } - + LocalLookupRealNamedProperty(name, result); + -+ if (wouldIntercept && !skip_fallback_interceptor && !result->IsProperty() && ++ 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, ++void JSObject::Lookup(String* name, LookupResult* result, + bool skip_fallback_interceptor) { // Ecma-262 3rd 8.6.2.4 Heap* heap = GetHeap(); @@ -260,21 +260,21 @@ index 07e1089..a209cd0 100644 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(); @@ -282,13 +282,13 @@ index 07e1089..a209cd0 100644 + // [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 { @@ -296,9 +296,9 @@ index 07e1089..a209cd0 100644 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; @@ -306,7 +306,7 @@ index 07e1089..a209cd0 100644 - 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 @@ -324,11 +324,11 @@ index 7335da8..660352c 100644 // 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) { @@ -340,7 +340,7 @@ index 7335da8..660352c 100644 + true)); } } - + @@ -1343,7 +1344,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { JSObject* real_holder = global; LookupResult lookup; @@ -351,7 +351,7 @@ index 7335da8..660352c 100644 // 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); @@ -359,6 +359,6 @@ index 7335da8..660352c 100644 } return isolate->heap()->undefined_value(); } --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0004-Generalize-external-object-resources.patch b/src/v8/0004-Generalize-external-object-resources.patch index a05aad0889..3a232af619 100644 --- a/src/v8/0004-Generalize-external-object-resources.patch +++ b/src/v8/0004-Generalize-external-object-resources.patch @@ -1,7 +1,7 @@ -From 4827116b12c50f6662794017c5a662b5dbb2da0b Mon Sep 17 00:00:00 2001 +From f9368b52060c31e9532ef26f6cca1a2cb0283f51 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Mon, 23 May 2011 16:55:35 +1000 -Subject: [PATCH 04/16] Generalize external object resources +Subject: [PATCH 04/14] Generalize external object resources V8 was already able to manage and finalize an external string resource. This change generalizes that mechanism to handle a @@ -31,13 +31,13 @@ object space. 11 files changed, 280 insertions(+), 115 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 85452aa..7f06ae7 100644 +index bb31ea0..205e856 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -1630,6 +1630,25 @@ class Object : public Value { +@@ -1631,6 +1631,25 @@ class Object : public Value { /** Sets a native pointer in an internal field. */ V8EXPORT void SetPointerInInternalField(int index, void* value); - + + class V8EXPORT ExternalResource { // NOLINT + public: + ExternalResource() {} @@ -60,10 +60,10 @@ index 85452aa..7f06ae7 100644 // Testers for local properties. V8EXPORT bool HasRealNamedProperty(Handle<String> key); V8EXPORT bool HasRealIndexedProperty(uint32_t index); -@@ -2331,6 +2350,12 @@ class V8EXPORT ObjectTemplate : public Template { +@@ -2332,6 +2351,12 @@ class V8EXPORT ObjectTemplate : public Template { */ void SetInternalFieldCount(int value); - + + /** + * Sets whether the object can store an "external resource" object. + */ @@ -79,8 +79,8 @@ index 8b0b32a..1a6fbbb 100644 +++ b/src/api.cc @@ -1294,6 +1294,34 @@ void ObjectTemplate::SetInternalFieldCount(int value) { } - - + + +bool ObjectTemplate::HasExternalResource() +{ + if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(), @@ -110,12 +110,12 @@ index 8b0b32a..1a6fbbb 100644 + + // --- S c r i p t D a t a --- - - + + @@ -3652,6 +3680,34 @@ void v8::Object::SetPointerInInternalField(int index, void* value) { } - - + + +void v8::Object::SetExternalResource(v8::Object::ExternalResource *resource) { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + ENTER_V8(isolate); @@ -145,8 +145,8 @@ index 8b0b32a..1a6fbbb 100644 + + // --- E n v i r o n m e n t --- - - + + @@ -4144,7 +4200,7 @@ Local<String> v8::String::NewExternal( LOG_API(isolate, "String::NewExternal"); ENTER_V8(isolate); @@ -155,7 +155,7 @@ index 8b0b32a..1a6fbbb 100644 + isolate->heap()->external_resource_table()->AddString(*result); return Utils::ToLocal(result); } - + @@ -4162,7 +4218,7 @@ bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { } bool result = obj->MakeExternal(resource); @@ -173,7 +173,7 @@ index 8b0b32a..1a6fbbb 100644 + isolate->heap()->external_resource_table()->AddString(*result); return Utils::ToLocal(result); } - + @@ -4194,7 +4250,7 @@ bool v8::String::MakeExternal( } bool result = obj->MakeExternal(resource); @@ -211,7 +211,7 @@ index dcdc645..d530a75 100644 +++ b/src/factory.cc @@ -997,15 +997,21 @@ Handle<JSFunction> Factory::CreateApiFunction( Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); - + int internal_field_count = 0; + bool has_external_resource = false; + @@ -224,7 +224,7 @@ index dcdc645..d530a75 100644 + has_external_resource = + !instance_template->has_external_resource()->IsUndefined(); } - + int instance_size = kPointerSize * internal_field_count; + if (has_external_resource) instance_size += kPointerSize; + @@ -232,9 +232,9 @@ index dcdc645..d530a75 100644 switch (instance_type) { case JavaScriptObject: @@ -1040,6 +1046,11 @@ Handle<JSFunction> Factory::CreateApiFunction( - + Handle<Map> map = Handle<Map>(result->initial_map()); - + + // Mark as having external data object if needed + if (has_external_resource) { + map->set_has_external_resource(true); @@ -249,8 +249,8 @@ index f4fce7b..58e7adf 100644 +++ b/src/heap-inl.h @@ -205,21 +205,36 @@ MaybeObject* Heap::NumberFromUint32(uint32_t value) { } - - + + -void Heap::FinalizeExternalString(String* string) { - ASSERT(string->IsExternalString()); - v8::String::ExternalStringResourceBase** resource_addr = @@ -277,7 +277,7 @@ index f4fce7b..58e7adf 100644 + if (*resource_addr != NULL) { + (*resource_addr)->Dispose(); + } - + - // Clear the resource pointer in the string. - *resource_addr = NULL; + // Clear the resource pointer in the string. @@ -290,18 +290,18 @@ index f4fce7b..58e7adf 100644 + resource = reinterpret_cast<v8::Object::ExternalResource*>(Internals::GetExternalPointerFromSmi(value)); + } else if (value->IsProxy()) { + resource = reinterpret_cast<v8::Object::ExternalResource*>(Proxy::cast(value)->proxy()); -+ } ++ } + if (resource) { + resource->Dispose(); + } + } } - - + + @@ -556,53 +571,63 @@ inline bool Heap::allow_allocation(bool new_state) { #endif - - + + -void ExternalStringTable::AddString(String* string) { - ASSERT(string->IsExternalString()); +void ExternalResourceTable::AddString(String* string) { @@ -324,8 +324,8 @@ index f4fce7b..58e7adf 100644 + old_space_objects_.Add(object); } } - - + + -void ExternalStringTable::Iterate(ObjectVisitor* v) { - if (!new_space_strings_.is_empty()) { - Object** start = &new_space_strings_[0]; @@ -343,8 +343,8 @@ index f4fce7b..58e7adf 100644 + v->VisitPointers(start, start + old_space_objects_.length()); } } - - + + // Verify() is inline to avoid ifdef-s around its calls in release // mode. -void ExternalStringTable::Verify() { @@ -366,8 +366,8 @@ index f4fce7b..58e7adf 100644 } #endif } - - + + -void ExternalStringTable::AddOldString(String* string) { - ASSERT(string->IsExternalString()); - ASSERT(!heap_->InNewSpace(string)); @@ -377,15 +377,15 @@ index f4fce7b..58e7adf 100644 + ASSERT(!heap_->InNewSpace(object)); + old_space_objects_.Add(object); } - - + + -void ExternalStringTable::ShrinkNewStrings(int position) { - new_space_strings_.Rewind(position); +void ExternalResourceTable::ShrinkNewObjects(int position) { + new_space_objects_.Rewind(position); Verify(); } - + diff --git a/src/heap.cc b/src/heap.cc index 900f462..bf2940e 100644 --- a/src/heap.cc @@ -397,68 +397,68 @@ index 900f462..bf2940e 100644 - external_string_table_.heap_ = this; + external_resource_table_.heap_ = this; } - - + + @@ -1030,8 +1030,8 @@ void Heap::Scavenge() { - + new_space_front = DoScavenge(&scavenge_visitor, new_space_front); - + - UpdateNewSpaceReferencesInExternalStringTable( - &UpdateNewSpaceReferenceInExternalStringTableEntry); + UpdateNewSpaceReferencesInExternalResourceTable( + &UpdateNewSpaceReferenceInExternalResourceTableEntry); - + LiveObjectList::UpdateReferencesForScavengeGC(); isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); @@ -1053,38 +1053,38 @@ void Heap::Scavenge() { } - - + + -String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, - Object** p) { +HeapObject* Heap::UpdateNewSpaceReferenceInExternalResourceTableEntry(Heap* heap, + Object** p) { MapWord first_word = HeapObject::cast(*p)->map_word(); - + if (!first_word.IsForwardingAddress()) { // Unreachable external string can be finalized. - heap->FinalizeExternalString(String::cast(*p)); + heap->FinalizeExternalString(HeapObject::cast(*p)); return NULL; } - + // String is still reachable. - return String::cast(first_word.ToForwardingAddress()); + return HeapObject::cast(first_word.ToForwardingAddress()); } - - + + -void Heap::UpdateNewSpaceReferencesInExternalStringTable( - ExternalStringTableUpdaterCallback updater_func) { - external_string_table_.Verify(); +void Heap::UpdateNewSpaceReferencesInExternalResourceTable( + ExternalResourceTableUpdaterCallback updater_func) { + external_resource_table_.Verify(); - + - if (external_string_table_.new_space_strings_.is_empty()) return; + if (external_resource_table_.new_space_objects_.is_empty()) return; - + - Object** start = &external_string_table_.new_space_strings_[0]; - Object** end = start + external_string_table_.new_space_strings_.length(); + Object** start = &external_resource_table_.new_space_objects_[0]; + Object** end = start + external_resource_table_.new_space_objects_.length(); Object** last = start; - + for (Object** p = start; p < end; ++p) { ASSERT(InFromSpace(*p)); - String* target = updater_func(this, p); + HeapObject* target = updater_func(this, p); - + if (target == NULL) continue; - + - ASSERT(target->IsExternalString()); + ASSERT(target->IsExternalString() || target->map()->has_external_resource()); - + if (InNewSpace(target)) { // String is still in new space. Update the table entry. @@ -1092,12 +1092,12 @@ void Heap::UpdateNewSpaceReferencesInExternalStringTable( @@ -469,13 +469,13 @@ index 900f462..bf2940e 100644 + external_resource_table_.AddOldObject(target); } } - + ASSERT(last <= end); - external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); + external_resource_table_.ShrinkNewObjects(static_cast<int>(last - start)); } - - + + @@ -4468,7 +4468,7 @@ void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { v->Synchronize("symbol_table"); if (mode != VISIT_ALL_IN_SCAVENGE) { @@ -486,18 +486,18 @@ index 900f462..bf2940e 100644 v->Synchronize("external_string_table"); } @@ -4970,7 +4970,7 @@ void Heap::TearDown() { - + isolate_->global_handles()->TearDown(); - + - external_string_table_.TearDown(); + external_resource_table_.TearDown(); - + new_space_.TearDown(); - + @@ -5835,31 +5835,31 @@ void TranscendentalCache::Clear() { } - - + + -void ExternalStringTable::CleanUp() { +void ExternalResourceTable::CleanUp() { int last = 0; @@ -530,8 +530,8 @@ index 900f462..bf2940e 100644 + old_space_objects_.Rewind(last); Verify(); } - - + + -void ExternalStringTable::TearDown() { - new_space_strings_.Free(); - old_space_strings_.Free(); @@ -539,33 +539,33 @@ index 900f462..bf2940e 100644 + new_space_objects_.Free(); + old_space_objects_.Free(); } - - + + diff --git a/src/heap.h b/src/heap.h index ae4e9e7..8cbf378 100644 --- a/src/heap.h +++ b/src/heap.h @@ -237,8 +237,8 @@ class Isolate; class WeakObjectRetainer; - - + + -typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap, - Object** pointer); +typedef HeapObject* (*ExternalResourceTableUpdaterCallback)(Heap* heap, + Object** pointer); - + typedef bool (*DirtyRegionCallback)(Heap* heap, Address start, @@ -284,43 +284,45 @@ class PromotionQueue { }; - - + + -// External strings table is a place where all external strings are -// registered. We need to keep track of such strings to properly -// finalize them. -class ExternalStringTable { +// External resource table is a place where all external strings and -+// objects with an external resource are registered. We need to keep ++// objects with an external resource are registered. We need to keep +// track of such strings to properly finalize them. +class ExternalResourceTable { public: @@ -573,95 +573,95 @@ index ae4e9e7..8cbf378 100644 inline void AddString(String* string); + // Registers an external object. + inline void AddObject(HeapObject* object); - + inline void Iterate(ObjectVisitor* v); - + // Restores internal invariant and gets rid of collected strings. - // Must be called after each Iterate() that modified the strings. + // Must be called after each Iterate() that modified the objects. void CleanUp(); - + // Destroys all allocated memory. void TearDown(); - + private: - ExternalStringTable() { } + ExternalResourceTable() { } - + friend class Heap; - + inline void Verify(); - + - inline void AddOldString(String* string); + inline void AddOldObject(HeapObject* object); - + // Notifies the table that only a prefix of the new list is valid. - inline void ShrinkNewStrings(int position); + inline void ShrinkNewObjects(int position); - + // To speed up scavenge collections new space string are kept // separate from old space strings. - List<Object*> new_space_strings_; - List<Object*> old_space_strings_; + List<Object*> new_space_objects_; + List<Object*> old_space_objects_; - + Heap* heap_; - + - DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); + DISALLOW_COPY_AND_ASSIGN(ExternalResourceTable); }; - - + + @@ -753,7 +755,7 @@ class Heap { - + // Finalizes an external string by deleting the associated external // data and clearing the resource pointer. - inline void FinalizeExternalString(String* string); + inline void FinalizeExternalString(HeapObject* string); - + // Allocates an uninitialized object. The memory is non-executable if the // hardware and OS allow. @@ -1191,8 +1193,8 @@ class Heap { survived_since_last_expansion_ += survived; } - + - void UpdateNewSpaceReferencesInExternalStringTable( - ExternalStringTableUpdaterCallback updater_func); + void UpdateNewSpaceReferencesInExternalResourceTable( + ExternalResourceTableUpdaterCallback updater_func); - + void ProcessWeakReferences(WeakObjectRetainer* retainer); - + @@ -1228,8 +1230,8 @@ class Heap { return &mark_compact_collector_; } - + - ExternalStringTable* external_string_table() { - return &external_string_table_; + ExternalResourceTable* external_resource_table() { + return &external_resource_table_; } - + inline Isolate* isolate(); @@ -1462,7 +1464,7 @@ class Heap { // Performs a minor collection in new generation. void Scavenge(); - + - static String* UpdateNewSpaceReferenceInExternalStringTableEntry( + static HeapObject* UpdateNewSpaceReferenceInExternalResourceTableEntry( Heap* heap, Object** pointer); - + @@ -1593,7 +1595,7 @@ class Heap { // configured through the API until it is setup. bool configured_; - + - ExternalStringTable external_string_table_; + ExternalResourceTable external_resource_table_; - + bool is_safe_to_read_maps_; - + diff --git a/src/liveobjectlist.cc b/src/liveobjectlist.cc index 5795a6b..8866e58 100644 --- a/src/liveobjectlist.cc @@ -685,26 +685,26 @@ index 5795a6b..8866e58 100644 } else { delete resource; diff --git a/src/mark-compact.cc b/src/mark-compact.cc -index 68a5062..1b1e361 100644 +index 68a5062..775f787 100644 --- a/src/mark-compact.cc +++ b/src/mark-compact.cc @@ -163,7 +163,7 @@ void MarkCompactCollector::Finish() { // objects (empty string, illegal builtin). heap()->isolate()->stub_cache()->Clear(); - + - heap()->external_string_table_.CleanUp(); + heap()->external_resource_table_.CleanUp(); - + // If we've just compacted old space there's no reason to check the // fragmentation limit. Just return. @@ -1019,8 +1019,9 @@ class SymbolTableCleaner : public ObjectVisitor { - + // Since no objects have yet been moved we can safely access the map of // the object. - if ((*p)->IsExternalString()) { - heap_->FinalizeExternalString(String::cast(*p)); + if ((*p)->IsExternalString() || -+ (*p)->IsHeapObject() && HeapObject::cast(*p)->map()->has_external_resource()) { ++ ((*p)->IsHeapObject() && HeapObject::cast(*p)->map()->has_external_resource())) { + heap_->FinalizeExternalString(HeapObject::cast(*p)); } // Set the entry to null_value (as deleted). @@ -717,13 +717,13 @@ index 68a5062..1b1e361 100644 - heap()->external_string_table_.CleanUp(); + heap()->external_resource_table_.Iterate(&v); + heap()->external_resource_table_.CleanUp(); - + // Process the weak references. MarkCompactWeakObjectRetainer mark_compact_object_retainer; @@ -1948,11 +1949,11 @@ static void UpdatePointerToNewGen(HeapObject** p) { } - - + + -static String* UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, - Object** p) { +static HeapObject* UpdateNewSpaceReferenceInExternalResourceTableEntry(Heap* heap, @@ -733,17 +733,17 @@ index 68a5062..1b1e361 100644 - return String::cast(HeapObject::FromAddress(new_addr)); + return HeapObject::FromAddress(new_addr); } - - + + @@ -2083,8 +2084,8 @@ static void SweepNewSpace(Heap* heap, NewSpace* space) { updating_visitor.VisitPointer(heap->global_contexts_list_address()); - + // Update pointers from external string table. - heap->UpdateNewSpaceReferencesInExternalStringTable( - &UpdateNewSpaceReferenceInExternalStringTableEntry); + heap->UpdateNewSpaceReferencesInExternalResourceTable( + &UpdateNewSpaceReferenceInExternalResourceTableEntry); - + // All pointers were updated. Update auxiliary allocation info. heap->IncrementYoungSurvivorsCounter(survivors_size); diff --git a/src/objects-inl.h b/src/objects-inl.h @@ -757,15 +757,15 @@ index 6aaca2f..231b835 100644 - map()->inobject_properties(); + map()->inobject_properties() - map()->has_external_resource()?1:0; } - - + + int JSObject::GetInternalFieldOffset(int index) { ASSERT(index < GetInternalFieldCount() && index >= 0); - return GetHeaderSize() + (kPointerSize * index); + return GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0)); } - - + + @@ -1407,7 +1407,7 @@ Object* JSObject::GetInternalField(int index) { // Internal objects do follow immediately after the header, whereas in-object // properties are at the end of the object. Therefore there is no need @@ -773,8 +773,8 @@ index 6aaca2f..231b835 100644 - return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index)); + return READ_FIELD(this, GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0))); } - - + + @@ -1416,12 +1416,29 @@ void JSObject::SetInternalField(int index, Object* value) { // Internal objects do follow immediately after the header, whereas in-object // properties are at the end of the object. Therefore there is no need @@ -784,8 +784,8 @@ index 6aaca2f..231b835 100644 WRITE_FIELD(this, offset, value); WRITE_BARRIER(this, offset); } - - + + +void JSObject::SetExternalResourceObject(Object *value) { + ASSERT(map()->has_external_resource()); + int offset = GetHeaderSize(); @@ -794,7 +794,7 @@ index 6aaca2f..231b835 100644 +} + + -+Object *JSObject::GetExternalResourceObject() { ++Object *JSObject::GetExternalResourceObject() { + if (map()->has_external_resource()) { + return READ_FIELD(this, GetHeaderSize()); + } else { @@ -808,8 +808,8 @@ index 6aaca2f..231b835 100644 // properties stored in the properties array. @@ -2521,6 +2538,20 @@ bool Map::is_shared() { } - - + + +void Map::set_has_external_resource(bool value) { + if (value) { + set_bit_field3(bit_field3() | (1 << kHasExternalResource)); @@ -822,7 +822,7 @@ index 6aaca2f..231b835 100644 +{ + return ((1 << kHasExternalResource) & bit_field3()) != 0; +} -+ ++ + void Map::set_named_interceptor_is_fallback(bool value) { @@ -831,9 +831,9 @@ index 6aaca2f..231b835 100644 ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset) ACCESSORS(ObjectTemplateInfo, internal_field_count, Object, kInternalFieldCountOffset) -+ACCESSORS(ObjectTemplateInfo, has_external_resource, Object, ++ACCESSORS(ObjectTemplateInfo, has_external_resource, Object, + kHasExternalResourceOffset) - + ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset) ACCESSORS(SignatureInfo, args, Object, kArgsOffset) diff --git a/src/objects.h b/src/objects.h @@ -843,7 +843,7 @@ index a209cd0..1bdb5c7 100644 @@ -1636,6 +1636,9 @@ class JSObject: public HeapObject { inline Object* GetInternalField(int index); inline void SetInternalField(int index, Object* value); - + + inline void SetExternalResourceObject(Object *); + inline Object *GetExternalResourceObject(); + @@ -853,22 +853,22 @@ index a209cd0..1bdb5c7 100644 @@ -3715,6 +3718,12 @@ class Map: public HeapObject { inline void set_is_access_check_needed(bool access_check_needed); inline bool is_access_check_needed(); - + + + // Tells whether the instance has the space for an external resource + // object + inline void set_has_external_resource(bool value); + inline bool has_external_resource(); + - + // Whether the named interceptor is a fallback interceptor or not inline void set_named_interceptor_is_fallback(bool value); @@ -3912,6 +3921,7 @@ class Map: public HeapObject { - + // Bit positions for bit field 3 static const int kNamedInterceptorIsFallback = 0; + static const int kHasExternalResource = 1; - + // Layout of the default cache. It holds alternating name and code objects. static const int kCodeCacheEntrySize = 2; @@ -6426,6 +6436,7 @@ class ObjectTemplateInfo: public TemplateInfo { @@ -876,9 +876,9 @@ index a209cd0..1bdb5c7 100644 DECL_ACCESSORS(constructor, Object) DECL_ACCESSORS(internal_field_count, Object) + DECL_ACCESSORS(has_external_resource, Object) - + static inline ObjectTemplateInfo* cast(Object* obj); - + @@ -6442,7 +6453,8 @@ class ObjectTemplateInfo: public TemplateInfo { static const int kConstructorOffset = TemplateInfo::kHeaderSize; static const int kInternalFieldCountOffset = @@ -887,8 +887,8 @@ index a209cd0..1bdb5c7 100644 + static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize; + static const int kSize = kHasExternalResourceOffset + kPointerSize; }; - - --- -1.7.6 + + +-- +1.7.4.4 diff --git a/src/v8/0005-Introduce-a-QML-compilation-mode.patch b/src/v8/0005-Introduce-a-QML-compilation-mode.patch index 3c1cab2497..d1b4d4d510 100644 --- a/src/v8/0005-Introduce-a-QML-compilation-mode.patch +++ b/src/v8/0005-Introduce-a-QML-compilation-mode.patch @@ -1,7 +1,7 @@ -From fd7d475e298e5b63cd6383c78cc900635c82aa38 Mon Sep 17 00:00:00 2001 +From 60c1a26bf89d3b06bcdd8408fcee89a018120f32 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Mon, 23 May 2011 18:26:19 +1000 -Subject: [PATCH 05/16] Introduce a QML compilation mode +Subject: [PATCH 05/14] Introduce a QML compilation mode In QML mode, there is a second global object - known as the QML global object. During property resolution, if a property is not @@ -15,8 +15,8 @@ closures etc. created during the run will retain a reference to this object, so different objects can be passed in different script runs. --- - include/v8.h | 18 ++++++++-- - src/api.cc | 52 ++++++++++++++++++++++++----- + include/v8.h | 18 +++++++-- + src/api.cc | 52 ++++++++++++++++++++++----- src/arm/code-stubs-arm.cc | 4 ++ src/arm/full-codegen-arm.cc | 26 ++++++++------ src/arm/lithium-arm.cc | 2 +- @@ -27,10 +27,10 @@ runs. src/ast.h | 1 + src/code-stubs.h | 2 +- src/compiler.cc | 15 +++++++- - src/compiler.h | 22 ++++++++++-- - src/contexts.cc | 23 +++++++++++++ + src/compiler.h | 22 +++++++++-- + src/contexts.cc | 35 ++++++++++++++++++ src/contexts.h | 4 ++ - src/execution.cc | 28 +++++++++++++-- + src/execution.cc | 28 ++++++++++++-- src/execution.h | 6 +++ src/full-codegen.cc | 3 +- src/full-codegen.h | 1 + @@ -43,14 +43,14 @@ runs. src/ia32/lithium-ia32.cc | 2 +- src/ia32/lithium-ia32.h | 6 +++- src/ia32/macro-assembler-ia32.h | 5 +++ - src/objects-inl.h | 12 +++++++ + src/objects-inl.h | 12 ++++++ src/objects.h | 5 +++ - src/parser.cc | 27 +++++++++++++-- + src/parser.cc | 27 ++++++++++++-- src/parser.h | 4 ++- src/prettyprinter.cc | 3 ++ - src/runtime.cc | 68 ++++++++++++++++++++++++------------- + src/runtime.cc | 72 ++++++++++++++++++++++++------------- src/runtime.h | 8 ++-- - src/scopes.cc | 10 +++++ + src/scopes.cc | 59 +++++++++++++++++++++++++++++++ src/scopes.h | 7 ++++ src/variables.cc | 3 +- src/variables.h | 5 +++ @@ -60,10 +60,10 @@ runs. src/x64/lithium-x64.cc | 2 +- src/x64/lithium-x64.h | 6 +++ src/x64/macro-assembler-x64.h | 5 +++ - 45 files changed, 391 insertions(+), 108 deletions(-) + 45 files changed, 455 insertions(+), 109 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 7f06ae7..a858eae 100644 +index 205e856..d78ab1f 100644 --- a/include/v8.h +++ b/include/v8.h @@ -577,6 +577,10 @@ class ScriptOrigin { @@ -74,7 +74,7 @@ index 7f06ae7..a858eae 100644 + Default = 0x00, + QmlMode = 0x01 + }; - + /** * Compiles the specified script (context-independent). @@ -596,7 +600,8 @@ class V8EXPORT Script { @@ -84,7 +84,7 @@ index 7f06ae7..a858eae 100644 - Handle<String> script_data = Handle<String>()); + Handle<String> script_data = Handle<String>(), + CompileFlags = Default); - + /** * Compiles the specified script using the specified file name @@ -609,7 +614,8 @@ class V8EXPORT Script { @@ -94,7 +94,7 @@ index 7f06ae7..a858eae 100644 - Handle<Value> file_name); + Handle<Value> file_name, + CompileFlags = Default); - + /** * Compiles the specified script (bound to current context). @@ -630,7 +636,8 @@ class V8EXPORT Script { @@ -104,7 +104,7 @@ index 7f06ae7..a858eae 100644 - Handle<String> script_data = Handle<String>()); + Handle<String> script_data = Handle<String>(), + CompileFlags = Default); - + /** * Compiles the specified script using the specified file name @@ -647,7 +654,8 @@ class V8EXPORT Script { @@ -114,7 +114,7 @@ index 7f06ae7..a858eae 100644 - Handle<String> script_data = Handle<String>()); + Handle<String> script_data = Handle<String>(), + CompileFlags = Default); - + /** * Runs the script returning the resulting value. If the script is @@ -657,6 +665,7 @@ class V8EXPORT Script { @@ -122,15 +122,15 @@ index 7f06ae7..a858eae 100644 */ Local<Value> Run(); + Local<Value> Run(Handle<Object> qml); - + /** * Returns the script id value. -@@ -3326,6 +3335,7 @@ class V8EXPORT Context { +@@ -3327,6 +3336,7 @@ class V8EXPORT Context { * JavaScript frames an empty handle is returned. */ static Local<Context> GetCalling(); + static Local<Object> GetCallingQmlGlobal(); - + /** * Sets the security token for the context. To access an object in diff --git a/src/api.cc b/src/api.cc @@ -158,18 +158,18 @@ index 1a6fbbb..39767f4 100644 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>()); return Local<Script>(ToApi<Script>(result)); @@ -1417,21 +1419,23 @@ Local<Script> Script::New(v8::Handle<String> source, - - + + Local<Script> Script::New(v8::Handle<String> source, - v8::Handle<Value> file_name) { -+ v8::Handle<Value> file_name, ++ v8::Handle<Value> file_name, + v8::Script::CompileFlags compile_flags) { ScriptOrigin origin(file_name); - return New(source, &origin); + return New(source, &origin, 0, Handle<String>(), compile_flags); } - - + + Local<Script> Script::Compile(v8::Handle<String> source, v8::ScriptOrigin* origin, v8::ScriptData* pre_data, @@ -186,7 +186,7 @@ index 1a6fbbb..39767f4 100644 return generic; i::Handle<i::Object> obj = Utils::OpenHandle(*generic); @@ -1447,13 +1451,18 @@ Local<Script> Script::Compile(v8::Handle<String> source, - + Local<Script> Script::Compile(v8::Handle<String> source, v8::Handle<Value> file_name, - v8::Handle<String> script_data) { @@ -196,8 +196,8 @@ index 1a6fbbb..39767f4 100644 - return Compile(source, &origin, 0, script_data); + return Compile(source, &origin, 0, script_data, compile_flags); } - - + + Local<Value> Script::Run() { + return Run(Handle<Object>()); +} @@ -221,8 +221,8 @@ index 1a6fbbb..39767f4 100644 } @@ -3943,6 +3953,30 @@ v8::Local<v8::Context> Context::GetCalling() { } - - + + +v8::Local<v8::Object> Context::GetCallingQmlGlobal() { + i::Isolate* isolate = i::Isolate::Current(); + if (IsDeadCheck(isolate, "v8::Context::GetCallingQmlGlobal()")) { @@ -257,7 +257,7 @@ index 8c147f9..a2626bf 100644 @@ -166,6 +166,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) { __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX))); - + + // Copy the qml global object from the surrounding context. + __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); + __ str(r1, MemOperand(r0, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); @@ -270,7 +270,7 @@ index 871b453..a69f10d 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -154,12 +154,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { @@ -288,7 +288,7 @@ index 871b453..a69f10d 100644 @@ -1247,9 +1248,9 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( __ bind(&fast); } - + - __ ldr(r0, GlobalObjectOperand()); + __ ldr(r0, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); __ mov(r2, Operand(slot->var()->name())); @@ -308,7 +308,7 @@ index 871b453..a69f10d 100644 - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT); context()->Plug(r0); - + } else if (slot != NULL && slot->type() == Slot::LOOKUP) { @@ -1893,11 +1894,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, // assignment. Right-hand-side value is passed in r0, variable name in @@ -321,7 +321,7 @@ index 871b453..a69f10d 100644 : isolate()->builtins()->StoreIC_Initialize(); - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT); - + } else if (op == Token::INIT_CONST) { // Like var declarations, const declarations are hoisted to function @@ -2184,10 +2185,13 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, @@ -331,14 +331,14 @@ index 871b453..a69f10d 100644 + // Push the qml mode flag. + __ mov(r1, Operand(Smi::FromInt(is_qml_mode()))); + __ push(r1); - + __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP ? Runtime::kResolvePossiblyDirectEvalNoLookup - : Runtime::kResolvePossiblyDirectEval, 4); + : Runtime::kResolvePossiblyDirectEval, 5); } - - + + @@ -2263,9 +2267,9 @@ void FullCodeGenerator::VisitCall(Call* expr) { context()->DropAndPlug(1, r0); } else if (var != NULL && !var->is_this() && var->is_global()) { @@ -356,20 +356,20 @@ index 3f1d15b..8406a96 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - + LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { LOperand* context = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new LGlobalObject(context)); + return DefineAsRegister(new LGlobalObject(context, instr->qml_global())); } - - + + diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 6da7c86..10b901f 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -1378,13 +1378,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - + class LGlobalObject: public LTemplateInstruction<1, 1, 0> { public: - explicit LGlobalObject(LOperand* context) { @@ -377,22 +377,22 @@ index 6da7c86..10b901f 100644 inputs_[0] = context; + qml_global_ = qml_global; } - + DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") - + LOperand* context() { return InputAt(0); } + bool qml_global() { return qml_global_; } + private: + bool qml_global_; }; - - + + diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 4912449..db114ea 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -166,12 +166,13 @@ bool LCodeGen::GeneratePrologue() { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { @@ -414,16 +414,16 @@ index 4912449..db114ea 100644 - __ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX)); + __ ldr(result, ContextOperand(cp, instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX)); } - - + + diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index ab5efb0..d40cdbc 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -1056,6 +1056,11 @@ static inline MemOperand GlobalObjectOperand() { } - - + + +static inline MemOperand QmlGlobalObjectOperand() { + return ContextOperand(cp, Context::QML_GLOBAL_INDEX); +} @@ -438,15 +438,15 @@ index d80684a..adc5a1f 100644 +++ b/src/ast-inl.h @@ -106,6 +106,11 @@ bool FunctionLiteral::strict_mode() const { } - - + + +bool FunctionLiteral::qml_mode() const { + return scope()->is_qml_mode(); +} + + } } // namespace v8::internal - + #endif // V8_AST_INL_H_ diff --git a/src/ast.h b/src/ast.h index 65a25a9..f790dc0 100644 @@ -457,7 +457,7 @@ index 65a25a9..f790dc0 100644 bool is_expression() const { return is_expression_; } bool strict_mode() const; + bool qml_mode() const; - + int materialized_literal_count() { return materialized_literal_count_; } int expected_property_count() { return expected_property_count_; } diff --git a/src/code-stubs.h b/src/code-stubs.h @@ -466,12 +466,12 @@ index 56ef072..37e5383 100644 +++ b/src/code-stubs.h @@ -303,7 +303,7 @@ class FastNewContextStub : public CodeStub { static const int kMaximumSlots = 64; - + explicit FastNewContextStub(int slots) : slots_(slots) { - ASSERT(slots_ > 0 && slots <= kMaximumSlots); + ASSERT(slots_ >= 0 && slots <= kMaximumSlots); } - + void Generate(MacroAssembler* masm); diff --git a/src/compiler.cc b/src/compiler.cc index 86d5de3..d2191b9 100755 @@ -516,7 +516,7 @@ index 86d5de3..d2191b9 100755 @@ -610,6 +614,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) { info->MarkAsStrictMode(); } - + + // After parsing we know function's qml mode. Remember it. + if (info->function()->qml_mode()) { + shared->set_qml_mode(true); @@ -532,8 +532,8 @@ index 86d5de3..d2191b9 100755 function_info->set_strict_mode(lit->strict_mode()); + function_info->set_qml_mode(lit->qml_mode()); } - - + + diff --git a/src/compiler.h b/src/compiler.h index e75e869..17cd369 100644 --- a/src/compiler.h @@ -557,15 +557,15 @@ index e75e869..17cd369 100644 flags_ |= IsNativesSyntaxAllowed::encode(true); } @@ -141,6 +145,7 @@ class CompilationInfo BASE_EMBEDDED { - + // Determine whether or not we can adaptively optimize. bool AllowOptimize() { + // XXX - fix qml mode optimizations return V8::UseCrankshaft() && !closure_.is_null(); } - + @@ -163,8 +168,13 @@ class CompilationInfo BASE_EMBEDDED { - + void Initialize(Mode mode) { mode_ = V8::UseCrankshaft() ? mode : NONOPT; - if (!shared_info_.is_null() && shared_info_->strict_mode()) { @@ -579,16 +579,16 @@ index e75e869..17cd369 100644 + } } } - + @@ -187,6 +197,8 @@ class CompilationInfo BASE_EMBEDDED { class IsStrictMode: public BitField<bool, 4, 1> {}; // Native syntax (%-stuff) allowed? class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {}; + // Qml mode + class IsQmlMode: public BitField<bool, 6, 1> {}; - + unsigned flags_; - + @@ -252,13 +264,15 @@ class Compiler : public AllStatic { v8::Extension* extension, ScriptDataImpl* pre_data, @@ -596,7 +596,7 @@ index e75e869..17cd369 100644 - NativesFlag is_natives_code); + NativesFlag is_natives_code, + v8::Script::CompileFlags compile_flags = v8::Script::Default); - + // Compile a String source within a context for Eval. static Handle<SharedFunctionInfo> CompileEval(Handle<String> source, Handle<Context> context, @@ -604,51 +604,63 @@ index e75e869..17cd369 100644 - StrictModeFlag strict_mode); + StrictModeFlag strict_mode, + bool qml_mode); - + // Compile from function info (used for lazy compilation). Returns true on // success and false if the compilation resulted in a stack overflow. diff --git a/src/contexts.cc b/src/contexts.cc -index 520f3dd..da5cacb 100644 +index 520f3dd..035ac3b 100644 --- a/src/contexts.cc +++ b/src/contexts.cc -@@ -89,6 +89,8 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, +@@ -89,6 +89,9 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, PrintF(")\n"); } - + + Handle<JSObject> qml_global; ++ Handle<JSObject> qml_global_global; + do { if (FLAG_trace_contexts) { PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); -@@ -119,6 +121,10 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, +@@ -119,6 +122,11 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, } } - + + if (qml_global.is_null() && !context->qml_global()->IsUndefined()) { + qml_global = Handle<JSObject>(context->qml_global(), isolate); ++ qml_global_global = Handle<JSObject>(context->global(), isolate); + } + if (context->is_function_context()) { // we have context-local slots - -@@ -198,6 +204,23 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, + +@@ -198,6 +206,33 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags, } } while (follow_context_chain); - + + if (!qml_global.is_null()) { + if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) { -+ *attributes = qml_global->GetLocalPropertyAttribute(*name); ++ *attributes = qml_global_global->GetLocalPropertyAttribute(*name); + } else { -+ *attributes = qml_global->GetPropertyAttribute(*name); ++ *attributes = qml_global_global->GetPropertyAttribute(*name); + } + + if (*attributes != ABSENT) { -+ // property found -+ if (FLAG_trace_contexts) { -+ PrintF("=> found property in qml global object %p\n", -+ reinterpret_cast<void*>(*qml_global)); ++ *attributes = ABSENT; ++ } else { ++ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) { ++ *attributes = qml_global->GetLocalPropertyAttribute(*name); ++ } else { ++ *attributes = qml_global->GetPropertyAttribute(*name); ++ } ++ ++ if (*attributes != ABSENT) { ++ // property found ++ if (FLAG_trace_contexts) { ++ PrintF("=> found property in qml global object %p\n", ++ reinterpret_cast<void*>(*qml_global)); ++ } ++ return qml_global; + } -+ return qml_global; + } + } + @@ -666,11 +678,11 @@ index e46619e..57d8e7b 100644 + QML_GLOBAL_INDEX, GLOBAL_INDEX, MIN_CONTEXT_SLOTS, - + @@ -273,6 +274,9 @@ class Context: public FixedArray { } void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); } - + + JSObject *qml_global() { return reinterpret_cast<JSObject *>(get(QML_GLOBAL_INDEX)); } + void set_qml_global(JSObject *qml_global) { set(QML_GLOBAL_INDEX, qml_global); } + @@ -689,12 +701,12 @@ index eb26438..1632076 100644 + bool* has_pending_exception, + Handle<Object> qml) { Isolate* isolate = func->GetIsolate(); - + // Entering JavaScript. @@ -107,6 +108,12 @@ static Handle<Object> Invoke(bool construct, // make the current one is indeed a global object. ASSERT(func->context()->global()->IsGlobalObject()); - + + Handle<JSObject> oldqml; + if (!qml.is_null()) { + oldqml = Handle<JSObject>(func->context()->qml_global()); @@ -707,8 +719,8 @@ index eb26438..1632076 100644 @@ -122,6 +129,9 @@ static Handle<Object> Invoke(bool construct, receiver_pointer, argc, args); } - -+ if (!qml.is_null()) + ++ if (!qml.is_null()) + func->context()->set_qml_global(*oldqml); + #ifdef DEBUG @@ -731,23 +743,23 @@ index eb26438..1632076 100644 + Handle<Object> qml) { + return Invoke(false, func, receiver, argc, args, pending_exception, qml); } - - + + Handle<Object> Execution::New(Handle<JSFunction> func, int argc, Object*** args, bool* pending_exception) { return Invoke(true, func, Isolate::Current()->global(), argc, args, - pending_exception); + pending_exception, Handle<Object>()); } - - + + @@ -175,7 +195,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func, catcher.SetCaptureMessage(false); - + Handle<Object> result = Invoke(false, func, receiver, argc, args, - caught_exception); + caught_exception, Handle<Object>()); - + if (*caught_exception) { ASSERT(catcher.HasCaught()); diff --git a/src/execution.h b/src/execution.h @@ -764,7 +776,7 @@ index d4b80d2..a476eb4 100644 + Object*** args, + bool* pending_exception, + Handle<Object> qml); - + // Construct object from function, the caller supplies an array of // arguments. Arguments are Object* type. After function returns, diff --git a/src/full-codegen.cc b/src/full-codegen.cc @@ -799,7 +811,7 @@ index d6ed1b9..e3241aa 100644 + bool is_qml_mode() { return function()->qml_mode(); } FunctionLiteral* function() { return info_->function(); } Scope* scope() { return info_->scope(); } - + diff --git a/src/heap.cc b/src/heap.cc index bf2940e..da958c2 100644 --- a/src/heap.cc @@ -825,7 +837,7 @@ index a623775..52455bc 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -1148,7 +1148,7 @@ class HOuterContext: public HUnaryOperation { - + class HGlobalObject: public HUnaryOperation { public: - explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { @@ -836,7 +848,7 @@ index a623775..52455bc 100644 @@ -1159,8 +1159,14 @@ class HGlobalObject: public HUnaryOperation { return Representation::Tagged(); } - + + bool qml_global() { return qml_global_; } + void set_qml_global(bool v) { qml_global_ = v; } + @@ -846,14 +858,14 @@ index a623775..52455bc 100644 + private: + bool qml_global_; }; - - + + @@ -1177,7 +1183,7 @@ class HGlobalReceiver: public HUnaryOperation { virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } - -+ ++ protected: virtual bool DataEquals(HValue* other) { return true; } }; @@ -884,7 +896,7 @@ index 5d32095..afa599e 100644 @@ -147,6 +147,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) { __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX))); __ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx); - + + // Copy the qml global object from the surrounding context. We go through the + // context in the function (ecx) to match the allocation behavior we have + // in the runtime system (see Heap::AllocateFunctionContext). @@ -900,7 +912,7 @@ index 5d153a8..0ddcde2 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -142,12 +142,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { @@ -916,7 +928,7 @@ index 5d153a8..0ddcde2 100644 } else { __ CallRuntime(Runtime::kNewContext, 1); @@ -1107,10 +1108,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( - + // All extension objects were empty and it is safe to use a global // load IC call. - __ mov(eax, GlobalObjectOperand()); @@ -939,7 +951,7 @@ index 5d153a8..0ddcde2 100644 - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT); context()->Plug(eax); - + } else if (slot != NULL && slot->type() == Slot::LOOKUP) { @@ -1837,11 +1838,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, // assignment. Right-hand-side value is passed in eax, variable name in @@ -952,13 +964,13 @@ index 5d153a8..0ddcde2 100644 : isolate()->builtins()->StoreIC_Initialize(); - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT); - + } else if (op == Token::INIT_CONST) { // Like var declarations, const declarations are hoisted to function @@ -2113,9 +2114,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, // Push the strict mode flag. __ push(Immediate(Smi::FromInt(strict_mode_flag()))); - + + // Push the qml mode flag + __ push(Immediate(Smi::FromInt(is_qml_mode()))); + @@ -967,8 +979,8 @@ index 5d153a8..0ddcde2 100644 - : Runtime::kResolvePossiblyDirectEval, 4); + : Runtime::kResolvePossiblyDirectEval, 5); } - - + + @@ -2188,8 +2192,8 @@ void FullCodeGenerator::VisitCall(Call* expr) { context()->DropAndPlug(1, eax); } else if (var != NULL && !var->is_this() && var->is_global()) { @@ -985,7 +997,7 @@ index 0f96f78..c1da075 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -159,12 +159,13 @@ bool LCodeGen::GeneratePrologue() { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { @@ -1007,27 +1019,27 @@ index 0f96f78..c1da075 100644 - __ mov(result, Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ mov(result, Operand(context, Context::SlotOffset(instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX))); } - - + + diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 9ccd189..8e98b73 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1205,7 +1205,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - + LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { LOperand* context = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new LGlobalObject(context)); + return DefineAsRegister(new LGlobalObject(context, instr->qml_global())); } - - + + diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 9ace8f8..95ed001 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -1416,13 +1416,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - + class LGlobalObject: public LTemplateInstruction<1, 1, 0> { public: - explicit LGlobalObject(LOperand* context) { @@ -1035,24 +1047,24 @@ index 9ace8f8..95ed001 100644 inputs_[0] = context; + qml_global_ = qml_global; } - + DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") - + LOperand* context() { return InputAt(0); } + bool qml_global() { return qml_global_; } + private: + bool qml_global_; }; - - + + diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h index b986264..f8479ae 100644 --- a/src/ia32/macro-assembler-ia32.h +++ b/src/ia32/macro-assembler-ia32.h @@ -778,6 +778,11 @@ static inline Operand GlobalObjectOperand() { } - - + + +static inline Operand QmlGlobalObjectOperand() { + return ContextOperand(esi, Context::QML_GLOBAL_INDEX); +} @@ -1060,15 +1072,15 @@ index b986264..f8479ae 100644 + // Generates an Operand for saving parameters after PrepareCallApiFunction. Operand ApiParameterOperand(int index); - + diff --git a/src/objects-inl.h b/src/objects-inl.h index 231b835..1c7f83e 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -3242,6 +3242,18 @@ void SharedFunctionInfo::set_strict_mode(bool value) { } - - + + +bool SharedFunctionInfo::qml_mode() { + return BooleanBit::get(compiler_hints(), kQmlModeFunction); +} @@ -1083,7 +1095,7 @@ index 231b835..1c7f83e 100644 + ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) - + diff --git a/src/objects.h b/src/objects.h index 1bdb5c7..edbc47a 100644 --- a/src/objects.h @@ -1091,7 +1103,7 @@ index 1bdb5c7..edbc47a 100644 @@ -4331,6 +4331,10 @@ class SharedFunctionInfo: public HeapObject { inline bool strict_mode(); inline void set_strict_mode(bool value); - + + // Indicates whether the function is a qml mode function + inline bool qml_mode(); + inline void set_qml_mode(bool value); @@ -1104,7 +1116,7 @@ index 1bdb5c7..edbc47a 100644 static const int kOptimizationDisabled = 6; static const int kStrictModeFunction = 7; + static const int kQmlModeFunction = 8; - + private: #if V8_HOST_ARCH_32_BIT diff --git a/src/parser.cc b/src/parser.cc @@ -1112,14 +1124,14 @@ index a84ec6f..7f5c361 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -593,7 +593,8 @@ Parser::Parser(Handle<Script> script, - + FunctionLiteral* Parser::ParseProgram(Handle<String> source, bool in_global_context, - StrictModeFlag strict_mode) { + StrictModeFlag strict_mode, + bool qml_mode) { CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); - + HistogramTimerScope timer(isolate()->counters()->parse()); @@ -609,11 +610,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source, ExternalTwoByteStringUC16CharacterStream stream( @@ -1134,7 +1146,7 @@ index a84ec6f..7f5c361 100644 + return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope); } } - + @@ -621,6 +622,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source, FunctionLiteral* Parser::DoParseProgram(Handle<String> source, bool in_global_context, @@ -1160,15 +1172,15 @@ index a84ec6f..7f5c361 100644 + if (shared_info->qml_mode()) { + top_scope_->EnableQmlMode(); + } - + FunctionLiteralType type = shared_info->is_expression() ? EXPRESSION : DECLARATION; @@ -1661,6 +1669,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, arguments->Add(value); value = NULL; // zap the value to avoid the unnecessary assignment - + + int qml_mode = 0; -+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) ++ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) + qml_mode = 1; + arguments->Add(NewNumberLiteral(qml_mode)); + @@ -1178,9 +1190,9 @@ index a84ec6f..7f5c361 100644 @@ -1676,6 +1689,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, arguments->Add(NewNumberLiteral( top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); - + + int qml_mode = 0; -+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) ++ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) + qml_mode = 1; + arguments->Add(NewNumberLiteral(qml_mode)); + @@ -1196,7 +1208,7 @@ index a84ec6f..7f5c361 100644 + info->is_qml_mode()); } } - + diff --git a/src/parser.h b/src/parser.h index 64f1303..4d45e45 100644 --- a/src/parser.h @@ -1208,16 +1220,16 @@ index 64f1303..4d45e45 100644 - StrictModeFlag strict_mode); + StrictModeFlag strict_mode, + bool qml_mode); - + FunctionLiteral* ParseLazy(CompilationInfo* info); - + @@ -464,6 +465,7 @@ class Parser { FunctionLiteral* DoParseProgram(Handle<String> source, bool in_global_context, StrictModeFlag strict_mode, + bool qml_mode, ZoneScope* zone_scope); - + // Report syntax error diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc index c777ab4..1964e02 100644 @@ -1234,7 +1246,7 @@ index c777ab4..1964e02 100644 PrintLiteralIndented(buf.start(), value, true); } diff --git a/src/runtime.cc b/src/runtime.cc -index 660352c..827d954 100644 +index 660352c..c13f92d 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -1065,8 +1065,6 @@ static Failure* ThrowRedeclarationError(Isolate* isolate, @@ -1243,13 +1255,13 @@ index 660352c..827d954 100644 HandleScope scope(isolate); - Handle<GlobalObject> global = Handle<GlobalObject>( - isolate->context()->global()); - + Handle<Context> context = args.at<Context>(0); CONVERT_ARG_CHECKED(FixedArray, pairs, 1); @@ -1075,6 +1073,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { static_cast<StrictModeFlag>(Smi::cast(args[3])->value()); ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); - + + Handle<JSObject> js_global = Handle<JSObject>(isolate->context()->global()); + Handle<JSObject> qml_global = Handle<JSObject>(isolate->context()->qml_global()); + @@ -1257,7 +1269,7 @@ index 660352c..827d954 100644 // 13, page 71, the property must be read-only and // non-deletable. However, neither SpiderMonkey nor KJS creates the @@ -1083,10 +1084,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { - + // Traverse the name/value pairs and set the properties. int length = pairs->length(); - for (int i = 0; i < length; i += 2) { @@ -1268,7 +1280,7 @@ index 660352c..827d954 100644 + Handle<Smi> is_qml_global(Smi::cast(pairs->get(i + 2))); + + Handle<JSObject> global = is_qml_global->value()?qml_global:js_global; - + // We have to declare a global const property. To capture we only // assign to it when evaluating the assignment for "const x = @@ -1316,20 +1320,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { @@ -1278,21 +1290,21 @@ index 660352c..827d954 100644 - // args[2] == value (optional) + // args[2] == qml_mode + // args[3] == value (optional) - + // Determine if we need to assign to the variable if it already // exists (based on the number of arguments). - RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); - bool assign = args.length() == 3; + RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); + bool assign = args.length() == 4; - + CONVERT_ARG_CHECKED(String, name, 0); - GlobalObject* global = isolate->context()->global(); RUNTIME_ASSERT(args[1]->IsSmi()); StrictModeFlag strict_mode = static_cast<StrictModeFlag>(Smi::cast(args[1])->value()); ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); - + + RUNTIME_ASSERT(args[2]->IsSmi()); + int qml_mode = Smi::cast(args[2])->value(); + @@ -1309,7 +1321,7 @@ index 660352c..827d954 100644 + if (real_holder != global) break; return ThrowRedeclarationError(isolate, "const", name); } - + @@ -1372,7 +1381,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { // overwrite it with a variable declaration we must throw a // re-declaration error. However if we found readonly property @@ -1321,7 +1333,7 @@ index 660352c..827d954 100644 } @@ -1384,7 +1393,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { } - + // Assign the value (or undefined) to the property. - Object* value = (assign) ? args[2] : isolate->heap()->undefined_value(); + Object* value = (assign) ? args[3] : isolate->heap()->undefined_value(); @@ -1331,7 +1343,7 @@ index 660352c..827d954 100644 @@ -1399,9 +1408,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { real_holder = JSObject::cast(proto); } - + - global = isolate->context()->global(); + global = qml_mode?isolate->context()->qml_global():isolate->context()->global(); if (assign) { @@ -1348,14 +1360,14 @@ index 660352c..827d954 100644 + RUNTIME_ASSERT(args.length() == 3); CONVERT_ARG_CHECKED(String, name, 0); Handle<Object> value = args.at<Object>(1); - + + RUNTIME_ASSERT(args[2]->IsSmi()); + int qml_mode = Smi::cast(args[2])->value(); + // Get the current global object from top. - GlobalObject* global = isolate->context()->global(); + JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global(); - + // According to ECMA-262, section 12.2, page 62, the property must // not be deletable. Since it's a const, it must be READ_ONLY too. @@ -1456,7 +1468,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) { @@ -1364,7 +1376,7 @@ index 660352c..827d954 100644 HandleScope handle_scope(isolate); - Handle<GlobalObject> global(isolate->context()->global()); + Handle<JSObject> global(qml_mode?isolate->context()->qml_global():isolate->context()->global()); - + // BUG 1213575: Handle the case where we have to set a read-only // property through an interceptor and only do it if it's @@ -8160,7 +8172,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) { @@ -1392,22 +1404,22 @@ index 660352c..827d954 100644 isolate->context()->IsGlobalContext(), - strict_mode); + strict_mode, -+ qml_mode); ++ qml_mode); if (shared.is_null()) return MakePair(Failure::Exception(), NULL); Handle<JSFunction> compiled = isolate->factory()->NewFunctionFromSharedFunctionInfo( @@ -8190,7 +8205,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate, - - + + RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) { - ASSERT(args.length() == 4); + ASSERT(args.length() == 5); - + HandleScope scope(isolate); Handle<Object> callee = args.at<Object>(0); @@ -8257,16 +8272,18 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) { } - + ASSERT(args[3]->IsSmi()); + ASSERT(args[4]->IsSmi()); return CompileGlobalEval(isolate, @@ -1418,17 +1430,17 @@ index 660352c..827d954 100644 + Smi::cast(args[3])->value()), + Smi::cast(args[4])->value()); } - - + + RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { - ASSERT(args.length() == 4); + ASSERT(args.length() == 5); - + HandleScope scope(isolate); Handle<Object> callee = args.at<Object>(0); @@ -8280,11 +8297,13 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { } - + ASSERT(args[3]->IsSmi()); + ASSERT(args[4]->IsSmi()); return CompileGlobalEval(isolate, @@ -1439,19 +1451,37 @@ index 660352c..827d954 100644 + Smi::cast(args[3])->value()), + Smi::cast(args[4])->value()); } - - -@@ -10633,7 +10652,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { + + +@@ -10570,6 +10589,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { + Handle<JSFunction> function(JSFunction::cast(frame->function())); + Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); + ScopeInfo<> sinfo(*scope_info); ++ bool qml_mode = function->shared()->qml_mode(); + + // Traverse the saved contexts chain to find the active context for the + // selected frame. +@@ -10633,7 +10653,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { Compiler::CompileEval(function_source, context, context->IsGlobalContext(), - kNonStrictMode); + kNonStrictMode, -+ false); ++ qml_mode); if (shared.is_null()) return Failure::Exception(); Handle<JSFunction> compiled_function = isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); -@@ -10722,7 +10742,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { +@@ -10656,7 +10677,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { + Handle<Object>::cast(source).location() }; + Handle<Object> result = + Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver, +- argc, argv, &has_pending_exception); ++ argc, argv, &has_pending_exception, ++ Handle<Object>(function->context()->qml_global())); + if (has_pending_exception) return Failure::Exception(); + + // Skip the global proxy as it has no properties and always delegates to the +@@ -10722,7 +10744,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { // Currently, the eval code will be executed in non-strict mode, // even in the strict code context. Handle<SharedFunctionInfo> shared = @@ -1487,7 +1517,7 @@ index bf1ba68..5e97173 100644 F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ \ diff --git a/src/scopes.cc b/src/scopes.cc -index 8df93c5..734a217 100644 +index 8df93c5..b5d7ff3 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -198,6 +198,7 @@ void Scope::SetDefaults(Type type, @@ -1498,33 +1528,82 @@ index 8df93c5..734a217 100644 outer_scope_calls_eval_ = false; inner_scope_calls_eval_ = false; outer_scope_is_eval_scope_ = false; -@@ -796,6 +797,10 @@ void Scope::ResolveVariable(Scope* global_scope, +@@ -796,6 +797,25 @@ void Scope::ResolveVariable(Scope* global_scope, ASSERT(global_scope != NULL); var = global_scope->DeclareGlobal(proxy->name()); - -+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name()))) { -+ var->set_is_qml_global(true); + ++ if (qml_mode_) { ++ Handle<GlobalObject> global = Isolate::Current()->global(); ++ ++#ifdef ENABLE_DEBUGGER_SUPPORT ++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) { ++ //Get the context before the debugger was entered. ++ SaveContext *save = Isolate::Current()->save_context(); ++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context()) ++ save = save->prev(); ++ ++ global = Handle<GlobalObject>(save->context()->global()); ++ } ++#endif ++ ++ if (!global->HasProperty(*(proxy->name()))) { ++ var->set_is_qml_global(true); ++ } + } + } else if (scope_inside_with_) { // If we are inside a with statement we give up and look up // the variable at runtime. -@@ -816,6 +821,8 @@ void Scope::ResolveVariable(Scope* global_scope, - // variables. +@@ -817,6 +837,25 @@ void Scope::ResolveVariable(Scope* global_scope, if (context->GlobalIfNotShadowedByEval(proxy->name())) { var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL); -+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name()))) -+ var->set_is_qml_global(true); - + ++ if (qml_mode_) { ++ Handle<GlobalObject> global = Isolate::Current()->global(); ++ ++#ifdef ENABLE_DEBUGGER_SUPPORT ++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) { ++ //Get the context before the debugger was entered. ++ SaveContext *save = Isolate::Current()->save_context(); ++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context()) ++ save = save->prev(); ++ ++ global = Handle<GlobalObject>(save->context()->global()); ++ } ++#endif ++ ++ if (qml_mode_ && !global->HasProperty(*(proxy->name()))) { ++ var->set_is_qml_global(true); ++ } ++ } ++ } else { var = NonLocal(proxy->name(), Variable::DYNAMIC); -@@ -827,6 +834,9 @@ void Scope::ResolveVariable(Scope* global_scope, + } +@@ -827,6 +866,26 @@ void Scope::ResolveVariable(Scope* global_scope, // variable is global unless it is shadowed by eval-introduced // variables. var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL); + -+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name()))) -+ var->set_is_qml_global(true); ++ if (qml_mode_) { ++ Handle<GlobalObject> global = Isolate::Current()->global(); ++ ++#ifdef ENABLE_DEBUGGER_SUPPORT ++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) { ++ //Get the context before the debugger was entered. ++ SaveContext *save = Isolate::Current()->save_context(); ++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context()) ++ save = save->prev(); ++ ++ global = Handle<GlobalObject>(save->context()->global()); ++ } ++#endif ++ ++ if (qml_mode_ && !global->HasProperty(*(proxy->name()))) { ++ var->set_is_qml_global(true); ++ } ++ } ++ } } } @@ -1535,7 +1614,7 @@ index a0e56a4..6dd3f65 100644 @@ -210,6 +210,11 @@ class Scope: public ZoneObject { strict_mode_ = FLAG_strict_mode; } - + + // Enable qml mode for this scope + void EnableQmlMode() { + qml_mode_ = true; @@ -1543,13 +1622,13 @@ index a0e56a4..6dd3f65 100644 + // --------------------------------------------------------------------------- // Predicates. - + @@ -218,6 +223,7 @@ class Scope: public ZoneObject { bool is_function_scope() const { return type_ == FUNCTION_SCOPE; } bool is_global_scope() const { return type_ == GLOBAL_SCOPE; } bool is_strict_mode() const { return strict_mode_; } + bool is_qml_mode() const { return qml_mode_; } - + // Information about which scopes calls eval. bool calls_eval() const { return scope_calls_eval_; } @@ -376,6 +382,7 @@ class Scope: public ZoneObject { @@ -1557,7 +1636,7 @@ index a0e56a4..6dd3f65 100644 bool scope_calls_eval_; // this scope contains an 'eval' call bool strict_mode_; // this scope is a strict mode scope + bool qml_mode_; // this scope is a qml mode scope - + // Computed via PropagateScopeInfo. bool outer_scope_calls_eval_; diff --git a/src/variables.cc b/src/variables.cc @@ -1581,7 +1660,7 @@ index b1ff0db..0b31d1a 100644 @@ -141,6 +141,8 @@ class Variable: public ZoneObject { Expression* rewrite() const { return rewrite_; } void set_rewrite(Expression* expr) { rewrite_ = expr; } - + + bool is_qml_global() const { return is_qml_global_; } + void set_is_qml_global(bool is_qml_global) { is_qml_global_ = is_qml_global; } private: @@ -1595,8 +1674,8 @@ index b1ff0db..0b31d1a 100644 + // QML info + bool is_qml_global_; }; - - + + diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index c365385..d923494 100644 --- a/src/x64/code-stubs-x64.cc @@ -1604,7 +1683,7 @@ index c365385..d923494 100644 @@ -140,6 +140,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) { __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); __ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx); - + + // Copy the qml global object from the surrounding context. + __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); + __ movq(Operand(rax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), rbx); @@ -1617,11 +1696,11 @@ index 97168cd..c45cdb6 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -141,12 +141,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { -+ if (heap_slots > 0 || ++ if (heap_slots > 0 || + (scope()->is_qml_mode() && scope()->is_global_scope())) { Comment cmnt(masm_, "[ Allocate local context"); // Argument to NewContext is the function, which is still in rdi. @@ -1633,7 +1712,7 @@ index 97168cd..c45cdb6 100644 } else { __ CallRuntime(Runtime::kNewContext, 1); @@ -1119,10 +1120,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions( - + // All extension objects were empty and it is safe to use a global // load IC call. - __ movq(rax, GlobalObjectOperand()); @@ -1655,7 +1734,7 @@ index 97168cd..c45cdb6 100644 - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT); context()->Plug(rax); - + } else if (slot != NULL && slot->type() == Slot::LOOKUP) { @@ -1806,11 +1807,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, // assignment. Right-hand-side value is passed in rax, variable name in @@ -1668,13 +1747,13 @@ index 97168cd..c45cdb6 100644 : isolate()->builtins()->StoreIC_Initialize(); - EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); + EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT); - + } else if (op == Token::INIT_CONST) { // Like var declarations, const declarations are hoisted to function @@ -2085,9 +2086,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, // Push the strict mode flag. __ Push(Smi::FromInt(strict_mode_flag())); - + + // Push the qml mode flag + __ Push(Smi::FromInt(is_qml_mode())); + @@ -1683,8 +1762,8 @@ index 97168cd..c45cdb6 100644 - : Runtime::kResolvePossiblyDirectEval, 4); + : Runtime::kResolvePossiblyDirectEval, 5); } - - + + @@ -2160,8 +2164,8 @@ void FullCodeGenerator::VisitCall(Call* expr) { } else if (var != NULL && !var->is_this() && var->is_global()) { // Call to a global variable. @@ -1701,7 +1780,7 @@ index 202e7a2..45acbdf 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -174,12 +174,13 @@ bool LCodeGen::GeneratePrologue() { - + // Possibly allocate a local context. int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; - if (heap_slots > 0) { @@ -1717,53 +1796,53 @@ index 202e7a2..45acbdf 100644 } else { __ CallRuntime(Runtime::kNewContext, 1); @@ -2540,7 +2541,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) { - + void LCodeGen::DoGlobalObject(LGlobalObject* instr) { Register result = ToRegister(instr->result()); - __ movq(result, GlobalObjectOperand()); + __ movq(result, instr->qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); } - - + + diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 07ca3a5..00feeac 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1194,7 +1194,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - - + + LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { - return DefineAsRegister(new LGlobalObject); + return DefineAsRegister(new LGlobalObject(instr->qml_global())); } - - + + diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 15bb894..16f754c 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -1365,7 +1365,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - + class LGlobalObject: public LTemplateInstruction<1, 0, 0> { public: + explicit LGlobalObject(bool qml_global) : qml_global_(qml_global) {} + DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") -+ ++ + bool qml_global() { return qml_global_; } + private: + bool qml_global_; }; - - + + diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 4c17720..aa284ed 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -1233,6 +1233,11 @@ static inline Operand GlobalObjectOperand() { } - - + + +static inline Operand QmlGlobalObjectOperand() { + return ContextOperand(rsi, Context::QML_GLOBAL_INDEX); +} @@ -1772,6 +1851,6 @@ index 4c17720..aa284ed 100644 // Provides access to exit frame stack space (not GCed). static inline Operand StackSpaceOperand(int index) { #ifdef _WIN64 --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0006-Allow-access-to-the-calling-script-data.patch b/src/v8/0006-Allow-access-to-the-calling-script-data.patch index 50529d67b1..68b28ae1bb 100644 --- a/src/v8/0006-Allow-access-to-the-calling-script-data.patch +++ b/src/v8/0006-Allow-access-to-the-calling-script-data.patch @@ -1,7 +1,7 @@ -From f890f0d1a1e5bd62711815489c87755a4f382436 Mon Sep 17 00:00:00 2001 +From 1209b88e96f253cdc19aa4c95e011c84597844f0 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Wed, 25 May 2011 10:36:13 +1000 -Subject: [PATCH 06/16] Allow access to the calling script data +Subject: [PATCH 06/14] Allow access to the calling script data --- include/v8.h | 1 + @@ -9,15 +9,15 @@ Subject: [PATCH 06/16] Allow access to the calling script data 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/v8.h b/include/v8.h -index a858eae..9aba4a8 100644 +index d78ab1f..2bc0ed1 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -3336,6 +3336,7 @@ class V8EXPORT Context { +@@ -3337,6 +3337,7 @@ class V8EXPORT Context { */ static Local<Context> GetCalling(); static Local<Object> GetCallingQmlGlobal(); + static Local<Value> GetCallingScriptData(); - + /** * Sets the security token for the context. To access an object in diff --git a/src/api.cc b/src/api.cc @@ -27,7 +27,7 @@ index 39767f4..ff74efb 100644 @@ -3976,6 +3976,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() { } } - + +v8::Local<v8::Value> Context::GetCallingScriptData() +{ + i::Isolate* isolate = i::Isolate::Current(); @@ -40,9 +40,9 @@ index 39767f4..ff74efb 100644 + i::Handle<i::Script> script(i::Script::cast(i::JSFunction::cast(it.frame()->function())->shared()->script())); + return Utils::ToLocal(i::Handle<i::Object>(script->data())); +} - + v8::Local<v8::Object> Context::Global() { if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) { --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0007-Fix-warnings.patch b/src/v8/0007-Fix-warnings.patch index fe6fa59517..cd27a7be63 100644 --- a/src/v8/0007-Fix-warnings.patch +++ b/src/v8/0007-Fix-warnings.patch @@ -1,17 +1,17 @@ -From dac5d9db84cf20564621c679937ca7b9c6a8e880 Mon Sep 17 00:00:00 2001 +From 2a5cf85d7fd7912e516138db03e4cda47cc2a1ab Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Fri, 27 May 2011 13:04:15 +1000 -Subject: [PATCH 07/16] Fix warnings +Subject: [PATCH 07/14] Fix warnings --- include/v8.h | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 9aba4a8..8891dab 100644 +index 2bc0ed1..99f4b9a 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -2415,7 +2415,7 @@ class V8EXPORT Extension { // NOLINT +@@ -2416,7 +2416,7 @@ class V8EXPORT Extension { // NOLINT const char** deps = 0); virtual ~Extension() { } virtual v8::Handle<v8::FunctionTemplate> @@ -19,11 +19,11 @@ index 9aba4a8..8891dab 100644 + GetNativeFunction(v8::Handle<v8::String>) { return v8::Handle<v8::FunctionTemplate>(); } - -@@ -3721,13 +3721,13 @@ class Internals { + +@@ -3722,13 +3722,13 @@ class Internals { return *reinterpret_cast<T*>(addr); } - + - static inline bool CanCastToHeapObject(void* o) { return false; } - static inline bool CanCastToHeapObject(Context* o) { return true; } - static inline bool CanCastToHeapObject(String* o) { return true; } @@ -39,8 +39,8 @@ index 9aba4a8..8891dab 100644 + static inline bool CanCastToHeapObject(StackTrace*) { return true; } + static inline bool CanCastToHeapObject(StackFrame*) { return true; } }; - + } // namespace internal --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0008-Add-custom-object-compare-callback.patch b/src/v8/0008-Add-custom-object-compare-callback.patch index a6973969fe..f88e260dd4 100644 --- a/src/v8/0008-Add-custom-object-compare-callback.patch +++ b/src/v8/0008-Add-custom-object-compare-callback.patch @@ -1,7 +1,7 @@ -From bec11b8b7f89d135e7d9a823ac4fe98c70d017cf Mon Sep 17 00:00:00 2001 +From a7c491e6e533110a17fe9f7d47cf92a1b2263180 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Mon, 27 Jun 2011 14:57:28 +1000 -Subject: [PATCH 08/16] Add custom object compare callback +Subject: [PATCH 08/14] Add custom object compare callback A global custom object comparison callback can be set with: V8::SetUserObjectComparisonCallbackFunction() @@ -28,15 +28,15 @@ instances. 12 files changed, 218 insertions(+), 3 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 8891dab..d5d6972 100644 +index 99f4b9a..7544deb 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -2365,6 +2365,12 @@ class V8EXPORT ObjectTemplate : public Template { +@@ -2366,6 +2366,12 @@ class V8EXPORT ObjectTemplate : public Template { bool HasExternalResource(); void SetHasExternalResource(bool value); - + + /** -+ * Mark object instances of the template as using the user object ++ * Mark object instances of the template as using the user object + * comparison callback. + */ + void MarkAsUseUserObjectComparison(); @@ -44,21 +44,21 @@ index 8891dab..d5d6972 100644 private: ObjectTemplate(); static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor); -@@ -2565,6 +2571,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target, +@@ -2566,6 +2572,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target, AccessType type, Local<Value> data); - + +// --- U s e r O b j e c t C o m p a r i s o n C a l l b a c k --- -+typedef bool (*UserObjectComparisonCallback)(Local<Object> lhs, ++typedef bool (*UserObjectComparisonCallback)(Local<Object> lhs, + Local<Object> rhs); + // --- G a r b a g e C o l l e c t i o n C a l l b a c k s - + /** -@@ -2815,6 +2825,9 @@ class V8EXPORT V8 { +@@ -2816,6 +2826,9 @@ class V8EXPORT V8 { /** Callback function for reporting failed access checks.*/ static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback); - + + /** Callback for user object comparisons */ + static void SetUserObjectComparisonCallbackFunction(UserObjectComparisonCallback); + @@ -72,7 +72,7 @@ index ff74efb..2436031 100644 @@ -1321,6 +1321,16 @@ void ObjectTemplate::SetHasExternalResource(bool value) } } - + +void ObjectTemplate::MarkAsUseUserObjectComparison() +{ + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); @@ -83,13 +83,13 @@ index ff74efb..2436031 100644 + EnsureConstructor(this); + Utils::OpenHandle(this)->set_use_user_object_comparison(i::Smi::FromInt(1)); +} - + // --- S c r i p t D a t a --- - + @@ -4632,6 +4642,15 @@ void V8::SetFailedAccessCheckCallbackFunction( isolate->SetFailedAccessCheckCallback(callback); } - + +void V8::SetUserObjectComparisonCallbackFunction( + UserObjectComparisonCallback callback) { + i::Isolate* isolate = i::Isolate::Current(); @@ -109,7 +109,7 @@ index a2626bf..749c9be 100644 @@ -1563,6 +1563,36 @@ void CompareStub::Generate(MacroAssembler* masm) { // NOTICE! This code is only reached after a smi-fast-case check, so // it is certain that at least one operand isn't a smi. - + + { + Label not_user_equal, user_equal; + __ and_(r2, r1, Operand(r0)); @@ -146,7 +146,7 @@ index a2626bf..749c9be 100644 @@ -5802,10 +5832,18 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { __ tst(r2, Operand(kSmiTagMask)); __ b(eq, &miss); - + - __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE); + __ CompareObjectType(r0, r2, r3, JS_OBJECT_TYPE); __ b(ne, &miss); @@ -161,7 +161,7 @@ index a2626bf..749c9be 100644 + __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison)); + __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison)); + __ b(eq, &miss); - + ASSERT(GetCondition() == eq); __ sub(r0, r0, Operand(r1)); diff --git a/src/factory.cc b/src/factory.cc @@ -169,11 +169,11 @@ index d530a75..6f8c7de 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -998,6 +998,7 @@ Handle<JSFunction> Factory::CreateApiFunction( - + int internal_field_count = 0; bool has_external_resource = false; + bool use_user_object_comparison = false; - + if (!obj->instance_template()->IsUndefined()) { Handle<ObjectTemplateInfo> instance_template = @@ -1007,6 +1008,8 @@ Handle<JSFunction> Factory::CreateApiFunction( @@ -183,12 +183,12 @@ index d530a75..6f8c7de 100644 + use_user_object_comparison = + !instance_template->use_user_object_comparison()->IsUndefined(); } - + int instance_size = kPointerSize * internal_field_count; @@ -1051,6 +1054,11 @@ Handle<JSFunction> Factory::CreateApiFunction( map->set_has_external_resource(true); } - + + // Mark as using user object comparison if needed + if (use_user_object_comparison) { + map->set_use_user_object_comparison(true); @@ -204,7 +204,7 @@ index afa599e..0964ab9 100644 @@ -3447,6 +3447,40 @@ void CompareStub::Generate(MacroAssembler* masm) { __ Assert(not_zero, "Unexpected smi operands."); } - + + { + NearLabel not_user_equal, user_equal; + __ test(eax, Immediate(kSmiTagMask)); @@ -228,22 +228,22 @@ index afa599e..0964ab9 100644 + __ jmp(¬_user_equal); + + __ bind(&user_equal); -+ ++ + __ pop(ebx); // Return address. + __ push(eax); + __ push(edx); + __ push(ebx); + __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ ++ + __ bind(¬_user_equal); + } + + // NOTICE! This code is only reached after a smi-fast-case check, so // it is certain that at least one operand isn't a smi. - + @@ -5592,8 +5626,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { - + __ CmpObjectType(eax, JS_OBJECT_TYPE, ecx); __ j(not_equal, &miss, not_taken); + __ test_b(FieldOperand(ecx, Map::kBitField3Offset), @@ -254,7 +254,7 @@ index afa599e..0964ab9 100644 + __ test_b(FieldOperand(ecx, Map::kBitField3Offset), + 1 << Map::kUseUserObjectComparison); + __ j(not_zero, &miss); - + ASSERT(GetCondition() == equal); __ sub(eax, Operand(edx)); diff --git a/src/isolate.h b/src/isolate.h @@ -264,19 +264,19 @@ index 35ffcb4..8130397 100644 @@ -267,6 +267,9 @@ class ThreadLocalTop BASE_EMBEDDED { // Call back function to report unsafe JS accesses. v8::FailedAccessCheckCallback failed_access_check_callback_; - + + // Call back function for user object comparisons + v8::UserObjectComparisonCallback user_object_comparison_callback_; + private: void InitializeInternal(); - + @@ -699,6 +702,11 @@ class Isolate { void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback); void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type); - + + void SetUserObjectComparisonCallback(v8::UserObjectComparisonCallback callback); -+ inline v8::UserObjectComparisonCallback UserObjectComparisonCallback() { ++ inline v8::UserObjectComparisonCallback UserObjectComparisonCallback() { + return thread_local_top()->user_object_comparison_callback_; + } + @@ -289,8 +289,8 @@ index 1c7f83e..1765441 100644 +++ b/src/objects-inl.h @@ -2552,6 +2552,19 @@ bool Map::has_external_resource() } - - + + +void Map::set_use_user_object_comparison(bool value) { + if (value) { + set_bit_field3(bit_field3() | (1 << kUseUserObjectComparison)); @@ -309,11 +309,11 @@ index 1c7f83e..1765441 100644 if (value) { @@ -3050,6 +3063,8 @@ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object, kInternalFieldCountOffset) - ACCESSORS(ObjectTemplateInfo, has_external_resource, Object, + ACCESSORS(ObjectTemplateInfo, has_external_resource, Object, kHasExternalResourceOffset) -+ACCESSORS(ObjectTemplateInfo, use_user_object_comparison, Object, ++ACCESSORS(ObjectTemplateInfo, use_user_object_comparison, Object, + kUseUserObjectComparisonOffset) - + ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset) ACCESSORS(SignatureInfo, args, Object, kArgsOffset) diff --git a/src/objects.h b/src/objects.h @@ -323,13 +323,13 @@ index edbc47a..e75e9f1 100644 @@ -3724,6 +3724,11 @@ class Map: public HeapObject { inline void set_has_external_resource(bool value); inline bool has_external_resource(); - + + + // Tells whether the user object comparison callback should be used for + // comparisons involving this object + inline void set_use_user_object_comparison(bool value); + inline bool use_user_object_comparison(); - + // Whether the named interceptor is a fallback interceptor or not inline void set_named_interceptor_is_fallback(bool value); @@ -3922,6 +3927,7 @@ class Map: public HeapObject { @@ -337,7 +337,7 @@ index edbc47a..e75e9f1 100644 static const int kNamedInterceptorIsFallback = 0; static const int kHasExternalResource = 1; + static const int kUseUserObjectComparison = 2; - + // Layout of the default cache. It holds alternating name and code objects. static const int kCodeCacheEntrySize = 2; @@ -6442,6 +6448,7 @@ class ObjectTemplateInfo: public TemplateInfo { @@ -345,9 +345,9 @@ index edbc47a..e75e9f1 100644 DECL_ACCESSORS(internal_field_count, Object) DECL_ACCESSORS(has_external_resource, Object) + DECL_ACCESSORS(use_user_object_comparison, Object) - + static inline ObjectTemplateInfo* cast(Object* obj); - + @@ -6459,7 +6466,8 @@ class ObjectTemplateInfo: public TemplateInfo { static const int kInternalFieldCountOffset = kConstructorOffset + kPointerSize; @@ -356,16 +356,16 @@ index edbc47a..e75e9f1 100644 + static const int kUseUserObjectComparisonOffset = kHasExternalResourceOffset + kPointerSize; + static const int kSize = kUseUserObjectComparisonOffset + kPointerSize; }; - - + + diff --git a/src/runtime.cc b/src/runtime.cc -index 827d954..d552ddb 100644 +index c13f92d..b50de80 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -6279,6 +6279,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) { } - - + + +RUNTIME_FUNCTION(MaybeObject*, Runtime_UserObjectEquals) { + NoHandleAllocation ha; + ASSERT(args.length() == 2); @@ -419,12 +419,12 @@ index e078ee9..c345383 100644 @@ -387,6 +388,10 @@ void Isolate::SetFailedAccessCheckCallback( thread_local_top()->failed_access_check_callback_ = callback; } - + +void Isolate::SetUserObjectComparisonCallback( + v8::UserObjectComparisonCallback callback) { + thread_local_top()->user_object_comparison_callback_ = callback; +} - + void Isolate::ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type) { if (!thread_local_top()->failed_access_check_callback_) return; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc @@ -434,7 +434,7 @@ index d923494..10b9b56 100644 @@ -2443,6 +2443,37 @@ void CompareStub::Generate(MacroAssembler* masm) { __ bind(&ok); } - + + { + NearLabel not_user_equal, user_equal; + __ JumpIfSmi(rax, ¬_user_equal); @@ -456,13 +456,13 @@ index d923494..10b9b56 100644 + __ jmp(¬_user_equal); + + __ bind(&user_equal); -+ ++ + __ pop(rbx); // Return address. + __ push(rax); + __ push(rdx); + __ push(rbx); + __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ ++ + __ bind(¬_user_equal); + } + @@ -470,7 +470,7 @@ index d923494..10b9b56 100644 // value in rax, corresponding to result of comparing the two inputs. // NOTICE! This code is only reached after a smi-fast-case check, so @@ -4471,8 +4502,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) { - + __ CmpObjectType(rax, JS_OBJECT_TYPE, rcx); __ j(not_equal, &miss, not_taken); + __ testb(FieldOperand(rcx, Map::kBitField3Offset), @@ -481,9 +481,9 @@ index d923494..10b9b56 100644 + __ testb(FieldOperand(rcx, Map::kBitField3Offset), + Immediate(1 << Map::kUseUserObjectComparison)); + __ j(not_zero, &miss); - + ASSERT(GetCondition() == equal); __ subq(rax, rdx); --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch b/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch index 242161358f..f9790f98eb 100644 --- a/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch +++ b/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch @@ -1,7 +1,7 @@ -From 4183b973ed3bd603784c798dfa63ba48f6b68003 Mon Sep 17 00:00:00 2001 -From: "ager@chromium.org" <ager@chromium.org> +From 15ce2909579aef8c8f6b0c2c07fdebbaf0f4d611 Mon Sep 17 00:00:00 2001 +From: ager@chromium.org <ager@chromium.org> Date: Wed, 4 May 2011 13:03:08 +0000 -Subject: [PATCH 09/16] Add CallAsFunction method to the Object class in the +Subject: [PATCH 09/14] Add CallAsFunction method to the Object class in the API Patch by Peter Varga. @@ -21,15 +21,15 @@ git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7781 ce2b1a6d-e 5 files changed, 163 insertions(+), 37 deletions(-) diff --git a/include/v8.h b/include/v8.h -index d5d6972..8a8e1cd 100644 +index 7544deb..277153e 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -1757,6 +1757,14 @@ class Object : public Value { +@@ -1758,6 +1758,14 @@ class Object : public Value { V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType(); V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); - + + /** -+ * Call an Object as a function if a callback is set by the ++ * Call an Object as a function if a callback is set by the + * ObjectTemplate::SetCallAsFunctionHandler method. + */ + V8EXPORT Local<Value> CallAsFunction(Handle<Object> recv, @@ -45,8 +45,8 @@ index 2436031..e412e51 100644 +++ b/src/api.cc @@ -3259,6 +3259,37 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() { } - - + + +Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc, + v8::Handle<v8::Value> argv[]) { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); @@ -87,8 +87,8 @@ index 1632076..894d741 100644 +++ b/src/execution.cc @@ -254,6 +254,30 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { } - - + + +Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, + bool* has_pending_exception) { + ASSERT(!object->IsJSFunction()); @@ -126,7 +126,7 @@ index a476eb4..0a0be51 100644 static Handle<Object> GetFunctionDelegate(Handle<Object> object); + static Handle<Object> TryGetFunctionDelegate(Handle<Object> object, + bool* has_pending_exception); - + // Get a function delegate (or undefined) for the given non-function // object. Used for support calling objects as constructors. diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc @@ -136,7 +136,7 @@ index d7621d1..693d51e 100644 @@ -6962,50 +6962,111 @@ THREADED_TEST(CallAsFunction) { v8::HandleScope scope; LocalContext context; - + - Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); - Local<ObjectTemplate> instance_template = t->InstanceTemplate(); - instance_template->SetCallAsFunctionHandler(call_as_function); @@ -153,21 +153,21 @@ index d7621d1..693d51e 100644 + v8::TryCatch try_catch; + Local<Value> value; + CHECK(!try_catch.HasCaught()); - + - value = CompileRun("obj(42)"); - CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, value->Int32Value()); + value = CompileRun("obj(42)"); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(42, value->Int32Value()); - + - value = CompileRun("(function(o){return o(49)})(obj)"); - CHECK(!try_catch.HasCaught()); - CHECK_EQ(49, value->Int32Value()); + value = CompileRun("(function(o){return o(49)})(obj)"); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(49, value->Int32Value()); - + - // test special case of call as function - value = CompileRun("[obj]['0'](45)"); - CHECK(!try_catch.HasCaught()); @@ -176,7 +176,7 @@ index d7621d1..693d51e 100644 + value = CompileRun("[obj]['0'](45)"); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(45, value->Int32Value()); - + - value = CompileRun("obj.call = Function.prototype.call;" - "obj.call(null, 87)"); - CHECK(!try_catch.HasCaught()); @@ -185,7 +185,7 @@ index d7621d1..693d51e 100644 + "obj.call(null, 87)"); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(87, value->Int32Value()); - + - // Regression tests for bug #1116356: Calling call through call/apply - // must work for non-function receivers. - const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; @@ -198,7 +198,7 @@ index d7621d1..693d51e 100644 + value = CompileRun(apply_99); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(99, value->Int32Value()); - + - const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; - value = CompileRun(call_17); - CHECK(!try_catch.HasCaught()); @@ -207,7 +207,7 @@ index d7621d1..693d51e 100644 + value = CompileRun(call_17); + CHECK(!try_catch.HasCaught()); + CHECK_EQ(17, value->Int32Value()); - + - // Check that the call-as-function handler can be called through - // new. - value = CompileRun("new obj(43)"); @@ -280,8 +280,8 @@ index d7621d1..693d51e 100644 + try_catch.Reset(); + } } - - --- -1.7.6 + + +-- +1.7.4.4 diff --git a/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch b/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch index ea3802b96d..c550b20b2c 100644 --- a/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch +++ b/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch @@ -1,7 +1,7 @@ -From 3d6d4249878f7960eac4c9c94e0f2529f9a58c4a Mon Sep 17 00:00:00 2001 -From: "ager@chromium.org" <ager@chromium.org> +From 3ba270e3b93d292dc53a675a21479bdb0b50bbbe Mon Sep 17 00:00:00 2001 +From: ager@chromium.org <ager@chromium.org> Date: Fri, 6 May 2011 11:07:52 +0000 -Subject: [PATCH 10/16] Implement CallAsConstructor method for Object in the +Subject: [PATCH 10/14] Implement CallAsConstructor method for Object in the API Patch by Peter Varga. @@ -21,10 +21,10 @@ git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7803 ce2b1a6d-e 5 files changed, 276 insertions(+), 8 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 8a8e1cd..84462b5 100644 +index 277153e..18527e1 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -1765,6 +1765,14 @@ class Object : public Value { +@@ -1766,6 +1766,14 @@ class Object : public Value { int argc, Handle<Value> argv[]); @@ -96,16 +96,16 @@ index e412e51..1a585d6 100644 + } + return Local<v8::Object>(); } - - + + diff --git a/src/execution.cc b/src/execution.cc index 894d741..afb352c 100644 --- a/src/execution.cc +++ b/src/execution.cc @@ -297,6 +297,34 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { } - - + + +Handle<Object> Execution::TryGetConstructorDelegate( + Handle<Object> object, + bool* has_pending_exception) { @@ -148,8 +148,8 @@ index 0a0be51..ec2a195 100644 + static Handle<Object> TryGetConstructorDelegate(Handle<Object> object, + bool* has_pending_exception); }; - - + + diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 693d51e..1334f63 100644 --- a/test/cctest/test-api.cc @@ -157,7 +157,7 @@ index 693d51e..1334f63 100644 @@ -6746,6 +6746,200 @@ THREADED_TEST(Constructor) { CHECK(value->BooleanValue()); } - + + +static Handle<Value> ConstructorCallback(const Arguments& args) { + ApiTestFuzzer::Fuzz(); @@ -365,7 +365,7 @@ index 693d51e..1334f63 100644 + CHECK_EQ("TypeError: Property 'obj2' of object #<Object> is not a function", + *exception_value1); try_catch.Reset(); - + // Call an object without call-as-function handler through the API @@ -7040,7 +7233,7 @@ THREADED_TEST(CallAsFunction) { CHECK(value.IsEmpty()); @@ -375,7 +375,7 @@ index 693d51e..1334f63 100644 + CHECK_EQ("TypeError: [object Object] is not a function", *exception_value2); try_catch.Reset(); } - + @@ -7057,14 +7250,14 @@ THREADED_TEST(CallAsFunction) { value = CompileRun("obj3(22)"); CHECK(try_catch.HasCaught()); @@ -383,7 +383,7 @@ index 693d51e..1334f63 100644 - CHECK_EQ(*exception_value1, "22"); + CHECK_EQ("22", *exception_value1); try_catch.Reset(); - + v8::Handle<Value> args[] = { v8_num(23) }; value = instance->CallAsFunction(instance, 1, args); CHECK(try_catch.HasCaught()); @@ -393,6 +393,6 @@ index 693d51e..1334f63 100644 try_catch.Reset(); } } --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch index aefcae55cd..0a47bbbb9b 100644 --- a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch +++ b/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch @@ -1,7 +1,7 @@ -From f22d0312faeb93ced8747d9aae8c6d77e11b4aba Mon Sep 17 00:00:00 2001 +From 5f3e5dd6901b54707ea4f868d8fa7317c4ab3852 Mon Sep 17 00:00:00 2001 From: Jedrzej Nowacki <jedrzej.nowacki@nokia.com> Date: Tue, 7 Dec 2010 11:56:42 +0100 -Subject: [PATCH 11/16] QtScript/V8: Add new v8 api to check if a value is an +Subject: [PATCH 11/14] QtScript/V8: Add new v8 api to check if a value is an error. New function v8::Value::IsError was created. @@ -15,13 +15,13 @@ research. 3 files changed, 12 insertions(+), 0 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 84462b5..08b0ec2 100644 +index 18527e1..43e00f5 100644 --- a/include/v8.h +++ b/include/v8.h @@ -937,6 +937,11 @@ class Value : public Data { */ V8EXPORT bool IsRegExp() const; - + + /** + * Returns true if this value is an Error. + */ @@ -37,14 +37,14 @@ index 1a585d6..bd435eb 100644 @@ -2108,6 +2108,12 @@ bool Value::IsRegExp() const { return obj->IsJSRegExp(); } - + +bool Value::IsError() const { + if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsError()")) return false; + i::Handle<i::Object> obj = Utils::OpenHandle(this); + return obj->HasSpecificClassOf(HEAP->Error_symbol()); +} + - + Local<String> Value::ToString() const { i::Handle<i::Object> obj = Utils::OpenHandle(this); diff --git a/src/heap.h b/src/heap.h @@ -59,6 +59,6 @@ index 8cbf378..db90bb9 100644 V(this_symbol, "this") \ V(to_string_symbol, "toString") \ V(char_at_symbol, "CharAt") \ --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch b/src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch index 426458dafc..a73bfe35f5 100644 --- a/src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch +++ b/src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch @@ -1,8 +1,7 @@ -From 472c04c9e7a64e8734c76d2cf97a7cc5b773b788 Mon Sep 17 00:00:00 2001 -From: "ager@chromium.org" - <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00> +From a338d96fe138fbffd4b45c7d13a54e068daa6e12 Mon Sep 17 00:00:00 2001 +From: ager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00> Date: Mon, 9 May 2011 15:24:48 +0000 -Subject: [PATCH 12/16] Add IsCallable method for Object in the API +Subject: [PATCH 12/14] Add IsCallable method for Object in the API Patch by Peter Varga. @@ -19,12 +18,12 @@ git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7828 ce2b1a6d-e 3 files changed, 61 insertions(+), 0 deletions(-) diff --git a/include/v8.h b/include/v8.h -index 08b0ec2..4194d4a 100644 +index 43e00f5..5e1ce50 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -1763,6 +1763,13 @@ class Object : public Value { +@@ -1764,6 +1764,13 @@ class Object : public Value { V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); - + /** + * Checks whether a callback is set by the + * ObjectTemplate::SetCallAsFunctionHandler method. @@ -33,7 +32,7 @@ index 08b0ec2..4194d4a 100644 + V8EXPORT bool IsCallable(); + + /** - * Call an Object as a function if a callback is set by the + * Call an Object as a function if a callback is set by the * ObjectTemplate::SetCallAsFunctionHandler method. */ diff --git a/src/api.cc b/src/api.cc @@ -42,8 +41,8 @@ index bd435eb..a5a637f 100644 +++ b/src/api.cc @@ -3265,6 +3265,17 @@ int v8::Object::GetIndexedPropertiesExternalArrayDataLength() { } - - + + +bool v8::Object::IsCallable() { + i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); + ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false); @@ -64,8 +63,8 @@ index 1334f63..45db5a1 100644 +++ b/test/cctest/test-api.cc @@ -7263,6 +7263,49 @@ THREADED_TEST(CallAsFunction) { } - - + + +// Check whether a non-function object is callable. +THREADED_TEST(CallableObject) { + v8::HandleScope scope; @@ -112,6 +111,6 @@ index 1334f63..45db5a1 100644 static int CountHandles() { return v8::HandleScope::NumberOfHandles(); } --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch b/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch index f73785d123..b593f3ccd8 100644 --- a/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch +++ b/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch @@ -1,7 +1,7 @@ -From dc2cad4f8fc88c52fcea09b8d0262d35cd32dc44 Mon Sep 17 00:00:00 2001 +From c36be227e9d7952a1952caa529c78ecdc376bd55 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy <aaron.kennedy@nokia.com> Date: Thu, 25 Aug 2011 11:09:58 +1000 -Subject: [PATCH 13/16] Remove execute flag from v8-debug.h +Subject: [PATCH 13/14] Remove execute flag from v8-debug.h --- 0 files changed, 0 insertions(+), 0 deletions(-) @@ -10,6 +10,6 @@ Subject: [PATCH 13/16] Remove execute flag from v8-debug.h diff --git a/include/v8-debug.h b/include/v8-debug.h old mode 100755 new mode 100644 --- -1.7.6 +-- +1.7.4.4 diff --git a/src/v8/0014-Fix-build-error-suggest-parentheses-around-within.patch b/src/v8/0014-Fix-build-error-suggest-parentheses-around-within.patch deleted file mode 100644 index bb26b1493f..0000000000 --- a/src/v8/0014-Fix-build-error-suggest-parentheses-around-within.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d7e876decc00c611d327185bf890a7efecb2cf7e Mon Sep 17 00:00:00 2001 -From: Kent Hansen <kent.hansen@nokia.com> -Date: Mon, 29 Aug 2011 13:26:13 +0200 -Subject: [PATCH 14/16] Fix build error: "suggest parentheses around '&&' - within '||'" - ---- - src/mark-compact.cc | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/src/mark-compact.cc b/src/mark-compact.cc -index 1b1e361..775f787 100644 ---- a/src/mark-compact.cc -+++ b/src/mark-compact.cc -@@ -1020,7 +1020,7 @@ class SymbolTableCleaner : public ObjectVisitor { - // Since no objects have yet been moved we can safely access the map of - // the object. - if ((*p)->IsExternalString() || -- (*p)->IsHeapObject() && HeapObject::cast(*p)->map()->has_external_resource()) { -+ ((*p)->IsHeapObject() && HeapObject::cast(*p)->map()->has_external_resource())) { - heap_->FinalizeExternalString(HeapObject::cast(*p)); - } - // Set the entry to null_value (as deleted). --- -1.7.6 diff --git a/src/v8/0016-Fix-deprecated-Python-code.patch b/src/v8/0014-Fix-deprecated-Python-code.patch index 4ecf8d7e6f..1e0a0fc216 100644 --- a/src/v8/0016-Fix-deprecated-Python-code.patch +++ b/src/v8/0014-Fix-deprecated-Python-code.patch @@ -1,7 +1,7 @@ -From 97cb46d421faebd2b139570bcf9aaf2d5eadc333 Mon Sep 17 00:00:00 2001 +From ed5cc903d70f73780e5985e7d2de33f6b8d86402 Mon Sep 17 00:00:00 2001 From: Kent Hansen <kent.hansen@nokia.com> Date: Fri, 2 Sep 2011 12:03:09 +0200 -Subject: [PATCH 16/16] Fix deprecated Python code +Subject: [PATCH 14/14] Fix deprecated Python code Needed to make the scripts run on Python 3, which is the default python interpreter on some newer distros. @@ -46,5 +46,6 @@ index 646bf14..395441b 100644 new_identifier = self.CharFromNumber(identifier_first_char) if identifier_second_char != 0: new_identifier = ( --- -1.7.6 +-- +1.7.4.4 + diff --git a/src/v8/0015-Fix-source-compatibility-where-the-String-Equals-ove.patch b/src/v8/0015-Fix-source-compatibility-where-the-String-Equals-ove.patch deleted file mode 100644 index 003c430f56..0000000000 --- a/src/v8/0015-Fix-source-compatibility-where-the-String-Equals-ove.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0af1e15a3d6b28923c262a02a5ace35812c8f5d6 Mon Sep 17 00:00:00 2001 -From: Simon Hausmann <simon.hausmann@nokia.com> -Date: Thu, 4 Aug 2011 21:28:38 +0200 -Subject: [PATCH 15/16] Fix source compatibility where the String::Equals - overloads would shadow the Value::Equals function, - breaking the build. - ---- - include/v8.h | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 4194d4a..5e1ce50 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -1048,6 +1048,7 @@ class String : public Primitive { - */ - V8EXPORT bool Equals(uint16_t *string, int length); - V8EXPORT bool Equals(char *string, int length); -+ inline bool Equals(Handle<Value> that) const { return v8::Value::Equals(that); } - - /** - * Write the contents of the string to an external buffer. --- -1.7.6 |