summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------src/3rdparty/v80
-rw-r--r--src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch136
-rw-r--r--src/v8/0002-Add-a-bit-field-3-to-Map.patch118
-rw-r--r--src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch (renamed from src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch)183
-rw-r--r--src/v8/0003-Generalize-external-object-resources.patch595
-rw-r--r--src/v8/0004-Generalize-external-object-resources.patch894
-rw-r--r--src/v8/0004-Introduce-a-QML-compilation-mode.patch (renamed from src/v8/0005-Introduce-a-QML-compilation-mode.patch)1019
-rw-r--r--src/v8/0005-Allow-access-to-the-calling-script-data.patch (renamed from src/v8/0006-Allow-access-to-the-calling-script-data.patch)14
-rw-r--r--src/v8/0006-Add-custom-object-compare-callback.patch (renamed from src/v8/0008-Add-custom-object-compare-callback.patch)303
-rw-r--r--src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch (renamed from src/v8/0015-Allow-a-script-to-be-flagged-as-native.patch)12
-rw-r--r--src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch (renamed from src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch)16
-rw-r--r--src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch287
-rw-r--r--src/v8/0009-Fix-deprecated-Python-code.patch (renamed from src/v8/0014-Fix-deprecated-Python-code.patch)8
-rw-r--r--src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch398
-rw-r--r--src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch (renamed from src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch)4
-rw-r--r--src/v8/0011-Fix-warnings.patch (renamed from src/v8/0007-Fix-warnings.patch)12
-rw-r--r--src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch116
-rw-r--r--src/v8/0016-Move-external-resource-to-the-last-hidden-field.patch61
-rw-r--r--src/v8/README2
-rw-r--r--src/v8/v8.pri28
-rw-r--r--tests/auto/v8/tst_v8.cpp6
-rw-r--r--tests/auto/v8/v8main.cpp3
-rw-r--r--tests/auto/v8/v8test.cpp53
-rw-r--r--tests/auto/v8/v8test.h1
24 files changed, 1567 insertions, 2702 deletions
diff --git a/src/3rdparty/v8 b/src/3rdparty/v8
-Subproject 8f15248619bb3bf49473dc3ede8a4e631bd5d19
+Subproject 9c0d93bfae724e29ef63456942d9ddca10ca582
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 8a844f5f25..d74624b285 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,25 +1,25 @@
-From 3dff2e903674d8ab5310d44281b57de36db659c9 Mon Sep 17 00:00:00 2001
+From b0b5bcfbda218aac8e797c19ff6f6de4052d972f 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
+Date: Tue, 4 Oct 2011 15:04:21 +1000
+Subject: [PATCH 01/11] Add hashing and comparison methods to v8::String
-This allows us to more rapidly search for a v8::String inside
-a hash of QStrings.
+This allows us to more rapidly search for a v8::String inside a hash
+of QStrings.
---
- include/v8.h | 45 +++++++++++++++++++++++++++++++
- src/api.cc | 43 +++++++++++++++++++++++++++++
+ include/v8.h | 45 +++++++++++++++++++++++++++++
+ src/api.cc | 51 +++++++++++++++++++++++++++++++++
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, 183 insertions(+), 3 deletions(-)
+ src/objects.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/objects.h | 10 ++++++-
+ 7 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index d15d024..be1ee71 100644
+index 73b7fbe..86ea70f 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -994,6 +994,49 @@ class String : public Primitive {
+@@ -1021,6 +1021,49 @@ class String : public Primitive {
V8EXPORT int Utf8Length() const;
/**
@@ -69,29 +69,30 @@ index d15d024..be1ee71 100644
* 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 +1066,8 @@ class String : public Primitive {
- HINT_MANY_WRITES_EXPECTED = 1
+@@ -1051,6 +1094,8 @@ class String : public Primitive {
+ NO_NULL_TERMINATION = 2
};
+ V8EXPORT uint16_t GetCharacter(int index);
+
+ // 16-bit character codes.
V8EXPORT int Write(uint16_t* buffer,
int start = 0,
- int length = -1,
diff --git a/src/api.cc b/src/api.cc
-index a2373cd..381935b 100644
+index 7ae01d1..2d205fd 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -3284,6 +3284,49 @@ int String::Utf8Length() const {
- return str->Utf8Length();
+@@ -3652,6 +3652,57 @@ int String::Utf8Length() const {
}
+
+uint32_t String::Hash() const {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Hash()")) return 0;
+ return str->Hash();
+}
+
++
+String::CompleteHashData String::CompleteHash() const {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::CompleteHash()")) return CompleteHashData();
@@ -103,40 +104,47 @@ index a2373cd..381935b 100644
+ return result;
+}
+
++
+uint32_t String::ComputeHash(uint16_t *string, int length) {
+ return i::HashSequentialString<i::uc16>(string, length) >> i::String::kHashShift;
+}
+
++
+uint32_t String::ComputeHash(char *string, int length) {
+ return i::HashSequentialString<char>(string, length) >> i::String::kHashShift;
+}
+
++
+uint16_t String::GetCharacter(int index)
+{
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ return str->Get(index);
+}
+
++
+bool String::Equals(uint16_t *string, int length) {
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Equals()")) return 0;
+ return str->SlowEqualsExternal(string, length);
+}
+
++
+bool String::Equals(char *string, int length)
+{
+ i::Handle<i::String> str = Utils::OpenHandle(this);
+ if (IsDeadCheck(str->GetIsolate(), "v8::String::Equals()")) return 0;
+ return str->SlowEqualsExternal(string, length);
+}
-
++
++
int String::WriteUtf8(char* buffer,
int capacity,
+ int* nchars_ref,
diff --git a/src/heap-inl.h b/src/heap-inl.h
-index 99737ed..f4fce7b 100644
+index 4bd893e..a4dfa5a 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
-@@ -93,6 +93,7 @@ MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
+@@ -105,6 +105,7 @@ MaybeObject* Heap::AllocateAsciiSymbol(Vector<const char> str,
String* answer = String::cast(result);
answer->set_length(str.length());
answer->set_hash_field(hash_field);
@@ -144,7 +152,7 @@ index 99737ed..f4fce7b 100644
ASSERT_EQ(size, answer->Size());
-@@ -126,6 +127,7 @@ MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
+@@ -138,6 +139,7 @@ MaybeObject* Heap::AllocateTwoByteSymbol(Vector<const uc16> str,
String* answer = String::cast(result);
answer->set_length(str.length());
answer->set_hash_field(hash_field);
@@ -153,18 +161,18 @@ index 99737ed..f4fce7b 100644
ASSERT_EQ(size, answer->Size());
diff --git a/src/heap.cc b/src/heap.cc
-index 2b6c11f..930c97b 100644
+index 522861d..0dfd453 100644
--- a/src/heap.cc
+++ b/src/heap.cc
-@@ -3519,6 +3519,7 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
+@@ -4061,6 +4061,7 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
String* answer = String::cast(result);
answer->set_length(chars);
answer->set_hash_field(hash_field);
-+ SeqString::cast(result)->set_symbol_id(0);
++ SeqString::cast(answer)->set_symbol_id(0);
ASSERT_EQ(size, answer->Size());
-@@ -3561,6 +3562,7 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
+@@ -4103,6 +4104,7 @@ MaybeObject* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
HeapObject::cast(result)->set_map(ascii_string_map());
String::cast(result)->set_length(length);
String::cast(result)->set_hash_field(String::kEmptyHashField);
@@ -172,7 +180,7 @@ index 2b6c11f..930c97b 100644
ASSERT_EQ(size, HeapObject::cast(result)->Size());
return result;
}
-@@ -3596,6 +3598,7 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
+@@ -4138,6 +4140,7 @@ MaybeObject* Heap::AllocateRawTwoByteString(int length,
HeapObject::cast(result)->set_map(string_map());
String::cast(result)->set_length(length);
String::cast(result)->set_hash_field(String::kEmptyHashField);
@@ -181,11 +189,11 @@ index 2b6c11f..930c97b 100644
return result;
}
diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 65aec5d..c82080d 100644
+index baf271f..73d0ac9 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
-@@ -1924,6 +1924,7 @@ INT_ACCESSORS(ExternalArray, length, kLengthOffset)
-
+@@ -2192,6 +2192,7 @@ SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
+ SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
SMI_ACCESSORS(String, length, kLengthOffset)
+SMI_ACCESSORS(SeqString, symbol_id, kSymbolIdOffset)
@@ -193,13 +201,13 @@ index 65aec5d..c82080d 100644
uint32_t String::hash_field() {
diff --git a/src/objects.cc b/src/objects.cc
-index df61956..dc4b260 100644
+index 45ae49d..fe5bf97 100644
--- a/src/objects.cc
+++ b/src/objects.cc
-@@ -5346,6 +5346,66 @@ static inline bool CompareStringContentsPartial(Isolate* isolate,
- }
+@@ -6242,6 +6242,71 @@ static inline bool CompareStringContentsPartial(Isolate* isolate,
}
+
+bool String::SlowEqualsExternal(uc16 *string, int length) {
+ int len = this->length();
+ if (len != length) return false;
@@ -212,13 +220,14 @@ index df61956..dc4b260 100644
+ String* lhs = this->TryFlattenGetString();
+
+ if (lhs->IsFlat()) {
++ String::FlatContent lhs_content = lhs->GetFlatContent();
+ if (lhs->IsAsciiRepresentation()) {
-+ Vector<const char> vec1 = lhs->ToAsciiVector();
++ Vector<const char> vec1 = lhs_content.ToAsciiVector();
+ VectorIterator<char> buf1(vec1);
+ VectorIterator<uc16> ib(string, length);
+ return CompareStringContents(&buf1, &ib);
+ } else {
-+ Vector<const uc16> vec1 = lhs->ToUC16Vector();
++ Vector<const uc16> vec1 = lhs_content.ToUC16Vector();
+ Vector<const uc16> vec2(string, length);
+ return CompareRawStringContents(vec1, vec2);
+ }
@@ -230,6 +239,7 @@ index df61956..dc4b260 100644
+ }
+}
+
++
+bool String::SlowEqualsExternal(char *string, int length)
+{
+ int len = this->length();
@@ -249,10 +259,11 @@ index df61956..dc4b260 100644
+ }
+
+ if (lhs->IsFlat()) {
-+ Vector<const uc16> vec1 = lhs->ToUC16Vector();
-+ VectorIterator<const uc16> buf1(vec1);
-+ VectorIterator<char> buf2(string, length);
-+ return CompareStringContents(&buf1, &buf2);
++ String::FlatContent lhs_content = lhs->GetFlatContent();
++ Vector<const uc16> vec1 = lhs_content.ToUC16Vector();
++ VectorIterator<const uc16> buf1(vec1);
++ VectorIterator<char> buf2(string, length);
++ return CompareStringContents(&buf1, &buf2);
+ } else {
+ Isolate* isolate = GetIsolate();
+ isolate->objects_string_compare_buffer_a()->Reset(0, lhs);
@@ -260,10 +271,12 @@ 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> {
+ int len = length();
+@@ -10103,9 +10168,24 @@ class AsciiSymbolKey : public SequentialSymbolKey<char> {
MaybeObject* AsObject() {
if (hash_field_ == 0) Hash();
@@ -288,12 +301,12 @@ index df61956..dc4b260 100644
+Atomic32 AsciiSymbolKey::next_symbol_id = 1;
- class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
+ class SubStringAsciiSymbolKey : public HashTableKey {
diff --git a/src/objects.h b/src/objects.h
-index e966b3d..6e26f57 100644
+index 5a1a4a3..eb4eb0e 100644
--- a/src/objects.h
+++ b/src/objects.h
-@@ -5359,6 +5359,9 @@ class String: public HeapObject {
+@@ -5952,6 +5952,9 @@ class String: public HeapObject {
bool IsAsciiEqualTo(Vector<const char> str);
bool IsTwoByteEqualTo(Vector<const uc16> str);
@@ -303,42 +316,21 @@ index e966b3d..6e26f57 100644
// Return a UTF8 representation of the string. The string is null
// terminated but may optionally contain nulls. Length is returned
// in length_output if length_output is not a null pointer The string
-@@ -5610,9 +5613,17 @@ class String: public HeapObject {
- class SeqString: public String {
- public:
+@@ -6207,8 +6210,13 @@ class SeqString: public String {
+ // Casting.
+ static inline SeqString* cast(Object* obj);
+ // 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;
-+
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
- };
-@@ -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);
++ static const int kSymbolIdOffset = String::kSize;
++ static const int kHeaderSize = kSymbolIdOffset + kPointerSize;
- // Maximal memory usage for a single sequential two-byte string.
+ // Shortcuts for templates that know their string-type exactly.
+ bool IsExternalAsciiString() {
--
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
deleted file mode 100644
index 59dbad3135..0000000000
--- a/src/v8/0002-Add-a-bit-field-3-to-Map.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-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
-
-Bit field 3 will be used to add QML specific map flags.
----
- src/heap.cc | 2 ++
- src/objects-inl.h | 10 ++++++++++
- src/objects.cc | 2 ++
- src/objects.h | 9 ++++++++-
- 4 files changed, 22 insertions(+), 1 deletions(-)
-
-diff --git a/src/heap.cc b/src/heap.cc
-index 930c97b..900f462 100644
---- a/src/heap.cc
-+++ b/src/heap.cc
-@@ -1573,6 +1573,7 @@ MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
- reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
- reinterpret_cast<Map*>(result)->set_bit_field(0);
- reinterpret_cast<Map*>(result)->set_bit_field2(0);
-+ 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
-index c82080d..cce3edd 100644
---- a/src/objects-inl.h
-+++ 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);
-+}
-+
-+
-+void Map::set_bit_field3(byte value) {
-+ WRITE_BYTE_FIELD(this, kBitField3Offset, value);
-+}
-+
-+
- void Map::set_non_instance_prototype(bool value) {
- if (value) {
- set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
-diff --git a/src/objects.cc b/src/objects.cc
-index dc4b260..79d7240 100644
---- a/src/objects.cc
-+++ b/src/objects.cc
-@@ -3614,6 +3614,7 @@ MaybeObject* Map::CopyDropDescriptors() {
- }
- 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(false);
- 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
-+++ b/src/objects.h
-@@ -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);
-+
- // Tells whether the object in the prototype property will be used
- // for instances created from this function. If the prototype
- // property is set to a value that is not a JSObject, the prototype
-@@ -3844,7 +3848,7 @@ class Map: public HeapObject {
- // Layout description.
- static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
- static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
-- static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
-+ static const int kPrototypeOffset = POINTER_SIZE_ALIGN(kInstanceAttributesOffset + 2 * kIntSize);
- static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
- static const int kInstanceDescriptorsOffset =
- kConstructorOffset + kPointerSize;
-@@ -3876,6 +3880,7 @@ class Map: public HeapObject {
- static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 1;
- 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.4.4
-
diff --git a/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch
index 78184f6f9d..af42f1555f 100644
--- a/src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch
+++ b/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch
@@ -1,7 +1,7 @@
-From 530ded6ea634bccb96652cd3e0cf67725449ed63 Mon Sep 17 00:00:00 2001
+From a80d89daacb698b72f59cad5b83c1f1633a98c9f 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
+Date: Tue, 4 Oct 2011 15:30:20 +1000
+Subject: [PATCH 02/11] Add a "fallback" mode for named property interceptors
By default interceptors are called before the normal property
resolution on objects. When an interceptor is installed as a
@@ -12,22 +12,22 @@ In the case of a global object having an fallback interceptor,
the interceptor is not invoked at all for var or function
declarations.
---
- include/v8.h | 8 ++++++++
+ include/v8.h | 7 +++++++
src/api.cc | 29 +++++++++++++++++++++++++++++
- src/factory.cc | 4 ++++
+ src/factory.cc | 3 +++
src/handles.cc | 6 ++++--
src/handles.h | 3 ++-
- src/objects-inl.h | 16 ++++++++++++++++
- src/objects.cc | 22 ++++++++++++++++------
- src/objects.h | 18 ++++++++++++++----
+ src/objects-inl.h | 15 +++++++++++++++
+ src/objects.cc | 24 +++++++++++++++++-------
+ src/objects.h | 16 ++++++++++++----
src/runtime.cc | 11 ++++++-----
- 9 files changed, 99 insertions(+), 18 deletions(-)
+ 9 files changed, 95 insertions(+), 19 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index be1ee71..bb31ea0 100644
+index 86ea70f..d2e6c32 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -2170,6 +2170,7 @@ class V8EXPORT FunctionTemplate : public Template {
+@@ -2305,6 +2305,7 @@ class V8EXPORT FunctionTemplate : public Template {
NamedPropertyQuery query,
NamedPropertyDeleter remover,
NamedPropertyEnumerator enumerator,
@@ -35,25 +35,24 @@ index be1ee71..bb31ea0 100644
Handle<Value> data);
void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter,
IndexedPropertySetter setter,
-@@ -2254,6 +2255,13 @@ class V8EXPORT ObjectTemplate : public Template {
+@@ -2388,6 +2389,12 @@ class V8EXPORT ObjectTemplate : public Template {
+ NamedPropertyDeleter deleter = 0,
NamedPropertyEnumerator enumerator = 0,
Handle<Value> data = Handle<Value>());
-
+ void SetFallbackPropertyHandler(NamedPropertyGetter getter,
+ NamedPropertySetter setter = 0,
+ NamedPropertyQuery query = 0,
+ NamedPropertyDeleter deleter = 0,
+ NamedPropertyEnumerator enumerator = 0,
+ Handle<Value> data = Handle<Value>());
-+
+
/**
* Sets an indexed property handler on the object template.
- *
diff --git a/src/api.cc b/src/api.cc
-index 381935b..8b0b32a 100644
+index 2d205fd..e4dd694 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -981,6 +981,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
+@@ -1123,6 +1123,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
NamedPropertyQuery query,
NamedPropertyDeleter remover,
NamedPropertyEnumerator enumerator,
@@ -61,7 +60,7 @@ index 381935b..8b0b32a 100644
Handle<Value> data) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
-@@ -999,6 +1000,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
+@@ -1141,6 +1142,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler(
if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
@@ -69,7 +68,7 @@ index 381935b..8b0b32a 100644
if (data.IsEmpty()) data = v8::Undefined();
obj->set_data(*Utils::OpenHandle(*data));
-@@ -1143,6 +1145,33 @@ void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
+@@ -1285,6 +1287,33 @@ void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter,
query,
remover,
enumerator,
@@ -85,7 +84,7 @@ index 381935b..8b0b32a 100644
+ NamedPropertyEnumerator enumerator,
+ Handle<Value> data) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetFallbackPropertyHandler()")) {
++ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
+ return;
+ }
+ ENTER_V8(isolate);
@@ -104,14 +103,13 @@ index 381935b..8b0b32a 100644
}
diff --git a/src/factory.cc b/src/factory.cc
-index 7dee66f..dcdc645 100644
+index 00fc6bb..2338cda 100644
--- a/src/factory.cc
+++ b/src/factory.cc
-@@ -1058,6 +1058,10 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1180,6 +1180,9 @@ Handle<JSFunction> Factory::CreateApiFunction(
// Set interceptor information in the map.
if (!obj->named_property_handler()->IsUndefined()) {
map->set_has_named_interceptor();
-+
+ InterceptorInfo *nph = InterceptorInfo::cast(obj->named_property_handler());
+ bool is_fallback = nph->is_fallback()->IsUndefined()?false:nph->is_fallback()->value();
+ map->set_named_interceptor_is_fallback(is_fallback);
@@ -119,10 +117,10 @@ index 7dee66f..dcdc645 100644
if (!obj->indexed_property_handler()->IsUndefined()) {
map->set_has_indexed_interceptor();
diff --git a/src/handles.cc b/src/handles.cc
-index 326de86..dd3a86c 100644
+index ce4258d..104fc9c 100644
--- a/src/handles.cc
+++ b/src/handles.cc
-@@ -262,9 +262,11 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+@@ -265,9 +265,11 @@ Handle<Object> SetProperty(Handle<JSReceiver> object,
Handle<String> key,
Handle<Object> value,
PropertyAttributes attributes,
@@ -137,10 +135,10 @@ index 326de86..dd3a86c 100644
}
diff --git a/src/handles.h b/src/handles.h
-index 3839f37..4b42506 100644
+index 8dcca3e..babe763 100644
--- a/src/handles.h
+++ b/src/handles.h
-@@ -188,7 +188,8 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+@@ -192,7 +192,8 @@ Handle<Object> SetProperty(Handle<JSReceiver> object,
Handle<String> key,
Handle<Object> value,
PropertyAttributes attributes,
@@ -151,13 +149,14 @@ index 3839f37..4b42506 100644
Handle<Object> SetProperty(Handle<Object> object,
Handle<Object> key,
diff --git a/src/objects-inl.h b/src/objects-inl.h
-index cce3edd..6aaca2f 100644
+index 73d0ac9..35fbea5 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
-@@ -2521,6 +2521,21 @@ bool Map::is_shared() {
+@@ -2864,6 +2864,20 @@ void Map::set_is_shared(bool value) {
+ bool Map::is_shared() {
+ return ((1 << kIsShared) & bit_field3()) != 0;
}
-
-
++
+void Map::set_named_interceptor_is_fallback(bool value)
+{
+ if (value) {
@@ -171,12 +170,10 @@ index cce3edd..6aaca2f 100644
+{
+ return ((1 << kNamedInterceptorIsFallback) & bit_field3()) != 0;
+}
-+
-+
+
+
JSFunction* Map::unchecked_constructor() {
- return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
- }
-@@ -2970,6 +2985,7 @@ ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
+@@ -3350,6 +3364,7 @@ ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
@@ -185,71 +182,73 @@ index cce3edd..6aaca2f 100644
ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
diff --git a/src/objects.cc b/src/objects.cc
-index 79d7240..15e2cdb 100644
+index fe5bf97..8e1773f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
-@@ -1712,9 +1712,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
- MaybeObject* JSObject::SetProperty(String* name,
- Object* value,
- PropertyAttributes attributes,
-- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
-+ bool skip_fallback_interceptor) {
+@@ -1838,9 +1838,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
+ MaybeObject* JSReceiver::SetProperty(String* name,
+ Object* value,
+ PropertyAttributes attributes,
+- StrictModeFlag strict_mode) {
++ StrictModeFlag strict_mode,
++ bool skip_fallback_interceptor) {
LookupResult result;
- LocalLookup(name, &result);
+ LocalLookup(name, &result, skip_fallback_interceptor);
return SetProperty(&result, name, value, attributes, strict_mode);
}
-@@ -3148,7 +3149,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
+@@ -3832,7 +3833,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
}
--void JSObject::LocalLookup(String* name, LookupResult* result) {
-+void JSObject::LocalLookup(String* name, LookupResult* result,
-+ bool skip_fallback_interceptor) {
+-void JSReceiver::LocalLookup(String* name, LookupResult* result) {
++void JSReceiver::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) {
+@@ -3864,23 +3866,31 @@ void JSReceiver::LocalLookup(String* name, LookupResult* result) {
}
// Check for lookup interceptor except when bootstrapping.
-- if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) {
-+ bool wouldIntercept = HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive();
+- if (js_object->HasNamedInterceptor() &&
+- !heap->isolate()->bootstrapper()->IsActive()) {
++ bool wouldIntercept = js_object->HasNamedInterceptor() &&
++ !heap->isolate()->bootstrapper()->IsActive();
+ if (wouldIntercept && !map()->named_interceptor_is_fallback()) {
- result->InterceptorResult(this);
+ result->InterceptorResult(js_object);
return;
}
- LocalLookupRealNamedProperty(name, result);
+ js_object->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);
++ result->InterceptorResult(js_object);
+ return;
+ }
}
--void JSObject::Lookup(String* name, LookupResult* result) {
-+void JSObject::Lookup(String* name, LookupResult* result,
-+ bool skip_fallback_interceptor) {
+-void JSReceiver::Lookup(String* name, LookupResult* result) {
++void JSReceiver::Lookup(String* name, LookupResult* result,
++ bool skip_fallback_interceptor) {
// Ecma-262 3rd 8.6.2.4
Heap* heap = GetHeap();
for (Object* current = this;
current != heap->null_value();
current = JSObject::cast(current)->GetPrototype()) {
-- JSObject::cast(current)->LocalLookup(name, result);
-+ JSObject::cast(current)->LocalLookup(name, result, skip_fallback_interceptor);
+- JSReceiver::cast(current)->LocalLookup(name, result);
++ JSReceiver::cast(current)->LocalLookup(name, result, skip_fallback_interceptor);
if (result->IsProperty()) return;
}
result->NotFound();
diff --git a/src/objects.h b/src/objects.h
-index 07e1089..a209cd0 100644
+index eb4eb0e..b974756 100644
--- a/src/objects.h
+++ b/src/objects.h
-@@ -1405,7 +1405,8 @@ class JSObject: public HeapObject {
+@@ -1332,7 +1332,8 @@ class JSReceiver: public HeapObject {
MUST_USE_RESULT MaybeObject* SetProperty(String* key,
Object* value,
PropertyAttributes attributes,
@@ -259,7 +258,7 @@ index 07e1089..a209cd0 100644
MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
String* key,
Object* value,
-@@ -1637,8 +1638,8 @@ class JSObject: public HeapObject {
+@@ -1381,8 +1382,8 @@ class JSReceiver: public HeapObject {
// Lookup a property. If found, the result is valid and has
// detailed information.
@@ -268,30 +267,28 @@ index 07e1089..a209cd0 100644
+ 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 {
+ protected:
+ Smi* GenerateIdentityHash();
+@@ -4071,6 +4072,10 @@ class Map: public HeapObject {
inline void set_is_access_check_needed(bool access_check_needed);
inline bool is_access_check_needed();
-+
+ // Whether the named interceptor is a fallback interceptor or not
+ inline void set_named_interceptor_is_fallback(bool value);
+ inline bool named_interceptor_is_fallback();
+
-+
// [prototype]: implicit prototype object.
DECL_ACCESSORS(prototype, Object)
-@@ -3904,6 +3911,7 @@ class Map: public HeapObject {
- static const int kHasExternalArrayElements = 6;
+@@ -4307,6 +4312,7 @@ class Map: public HeapObject {
// Bit positions for bit field 3
-+ static const int kNamedInterceptorIsFallback = 0;
+ static const int kIsShared = 0;
++ static const int kNamedInterceptorIsFallback = 1;
// Layout of the default cache. It holds alternating name and code objects.
static const int kCodeCacheEntrySize = 2;
-@@ -6276,6 +6284,7 @@ class InterceptorInfo: public Struct {
+@@ -7142,6 +7148,7 @@ class InterceptorInfo: public Struct {
DECL_ACCESSORS(deleter, Object)
DECL_ACCESSORS(enumerator, Object)
DECL_ACCESSORS(data, Object)
@@ -299,7 +296,7 @@ index 07e1089..a209cd0 100644
static inline InterceptorInfo* cast(Object* obj);
-@@ -6295,7 +6304,8 @@ class InterceptorInfo: public Struct {
+@@ -7161,7 +7168,8 @@ class InterceptorInfo: public Struct {
static const int kDeleterOffset = kQueryOffset + kPointerSize;
static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
static const int kDataOffset = kEnumeratorOffset + kPointerSize;
@@ -310,48 +307,48 @@ index 07e1089..a209cd0 100644
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
diff --git a/src/runtime.cc b/src/runtime.cc
-index 7335da8..660352c 100644
+index 89abf38..5a850e9 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
-@@ -1097,7 +1097,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+@@ -1236,7 +1236,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
// Lookup the property in the global object, and don't set the
// value of the variable if the property is already there.
LookupResult lookup;
- global->Lookup(*name, &lookup);
+ global->Lookup(*name, &lookup, true);
if (lookup.IsProperty()) {
- // Determine if the property is local by comparing the holder
- // against the global object. The information will be used to
-@@ -1152,7 +1152,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+ // We found an existing property. Unless it was an interceptor
+ // that claims the property is absent, skip this declaration.
+@@ -1263,7 +1263,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) {
+ // Compute the property attributes. According to ECMA-262, section
+ // 13, page 71, the property must be read-only and
+@@ -1306,7 +1306,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
name,
value,
- attributes,
+ static_cast<PropertyAttributes>(attr),
- strict_mode));
+ strict_mode,
+ true));
}
}
-@@ -1343,7 +1344,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- JSObject* real_holder = global;
- LookupResult lookup;
- while (true) {
-- real_holder->LocalLookup(*name, &lookup);
-+ real_holder->LocalLookup(*name, &lookup, true);
- if (lookup.IsProperty()) {
- // Determine if this is a redeclaration of something read-only.
- if (lookup.IsReadOnly()) {
-@@ -1400,7 +1401,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
-
+@@ -1442,7 +1443,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+ while (object->IsJSObject() &&
+ JSObject::cast(object)->map()->is_hidden_prototype()) {
+ JSObject* raw_holder = JSObject::cast(object);
+- raw_holder->LocalLookup(*name, &lookup);
++ raw_holder->LocalLookup(*name, &lookup, true);
+ if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
+ HandleScope handle_scope(isolate);
+ Handle<JSObject> holder(raw_holder);
+@@ -1465,7 +1466,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+ // Reload global in case the loop above performed a GC.
global = isolate->context()->global();
if (assign) {
- return global->SetProperty(*name, args[2], attributes, strict_mode);
diff --git a/src/v8/0003-Generalize-external-object-resources.patch b/src/v8/0003-Generalize-external-object-resources.patch
new file mode 100644
index 0000000000..658a09126a
--- /dev/null
+++ b/src/v8/0003-Generalize-external-object-resources.patch
@@ -0,0 +1,595 @@
+From be5bc4e5ea15dd74c2753c30c25a4660598274c3 Mon Sep 17 00:00:00 2001
+From: Aaron Kennedy <aaron.kennedy@nokia.com>
+Date: Tue, 4 Oct 2011 16:06:09 +1000
+Subject: [PATCH 03/11] Generalize external object resources
+
+V8 was already able to manage and finalize an external string
+resource. This change generalizes that mechanism to handle a
+single generic external resource - a v8::Object::ExternalResource
+derived instance - on normal JSObject's.
+
+This is useful for mapping C++ objects to JS objects where the
+C++ object's memory is effectively owned by the JS Object, and
+thus needs to destroyed when the JS Object is garbage collected.
+The V8 mailing list suggests using a weak persistent handle for
+this purpose, but that seems to incur a fairly massive performance
+penalty for short lived objects as weak persistent handle callbacks
+are not called until the object has been promoted into the old
+object space.
+---
+ include/v8.h | 25 ++++++++++++++++++++
+ src/api.cc | 56 +++++++++++++++++++++++++++++++++++++++++++++
+ src/factory.cc | 11 +++++++++
+ src/heap-inl.h | 63 +++++++++++++++++++++++++++++++++++---------------
+ src/heap.cc | 29 +++++++++++++++++------
+ src/heap.h | 16 ++++++++-----
+ src/mark-compact.cc | 13 +++++-----
+ src/objects-inl.h | 35 +++++++++++++++++++++++++++-
+ src/objects.h | 19 ++++++++++++---
+ 9 files changed, 223 insertions(+), 44 deletions(-)
+
+diff --git a/include/v8.h b/include/v8.h
+index d2e6c32..3ef4dd6 100644
+--- a/include/v8.h
++++ b/include/v8.h
+@@ -1597,6 +1597,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() {}
++ virtual ~ExternalResource() {}
++
++ protected:
++ virtual void Dispose() { delete this; }
++
++ private:
++ // Disallow copying and assigning.
++ ExternalResource(const ExternalResource&);
++ void operator=(const ExternalResource&);
++
++ friend class v8::internal::Heap;
++ };
++
++ V8EXPORT void SetExternalResource(ExternalResource *);
++ V8EXPORT ExternalResource *GetExternalResource();
++
+ // Testers for local properties.
+ V8EXPORT bool HasOwnProperty(Handle<String> key);
+ V8EXPORT bool HasRealNamedProperty(Handle<String> key);
+@@ -2466,6 +2485,12 @@ class V8EXPORT ObjectTemplate : public Template {
+ */
+ void SetInternalFieldCount(int value);
+
++ /**
++ * Sets whether the object can store an "external resource" object.
++ */
++ bool HasExternalResource();
++ void SetHasExternalResource(bool value);
++
+ private:
+ ObjectTemplate();
+ static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
+diff --git a/src/api.cc b/src/api.cc
+index e4dd694..85f0d4b 100644
+--- a/src/api.cc
++++ b/src/api.cc
+@@ -1436,6 +1436,34 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
+ }
+
+
++bool ObjectTemplate::HasExternalResource()
++{
++ if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
++ "v8::ObjectTemplate::HasExternalResource()")) {
++ return 0;
++ }
++ return !Utils::OpenHandle(this)->has_external_resource()->IsUndefined();
++}
++
++
++void ObjectTemplate::SetHasExternalResource(bool value)
++{
++ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
++ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetHasExternalResource()")) {
++ return;
++ }
++ ENTER_V8(isolate);
++ if (value) {
++ EnsureConstructor(this);
++ }
++ if (value) {
++ Utils::OpenHandle(this)->set_has_external_resource(i::Smi::FromInt(1));
++ } else {
++ Utils::OpenHandle(this)->set_has_external_resource(Utils::OpenHandle(this)->GetHeap()->undefined_value());
++ }
++}
++
++
+ // --- S c r i p t D a t a ---
+
+
+@@ -4031,6 +4059,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);
++ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
++ if (CanBeEncodedAsSmi(resource)) {
++ obj->SetExternalResourceObject(EncodeAsSmi(resource));
++ } else {
++ obj->SetExternalResourceObject(*isolate->factory()->NewForeign(static_cast<i::Address>((void *)resource)));
++ }
++ if (!obj->IsSymbol()) {
++ isolate->heap()->external_string_table()->AddObject(*obj);
++ }
++}
++
++
++v8::Object::ExternalResource *v8::Object::GetExternalResource() {
++ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
++ i::Object* value = obj->GetExternalResourceObject();
++ if (value->IsSmi()) {
++ return reinterpret_cast<v8::Object::ExternalResource*>(i::Internals::GetExternalPointerFromSmi(value));
++ } else if (value->IsForeign()) {
++ return reinterpret_cast<v8::Object::ExternalResource*>(i::Foreign::cast(value)->address());
++ } else {
++ return NULL;
++ }
++}
++
++
+ // --- E n v i r o n m e n t ---
+
+
+diff --git a/src/factory.cc b/src/factory.cc
+index 2338cda..e3cccae 100644
+--- a/src/factory.cc
++++ b/src/factory.cc
+@@ -1119,15 +1119,21 @@ Handle<JSFunction> Factory::CreateApiFunction(
+ Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi();
+
+ int internal_field_count = 0;
++ bool has_external_resource = false;
++
+ if (!obj->instance_template()->IsUndefined()) {
+ Handle<ObjectTemplateInfo> instance_template =
+ Handle<ObjectTemplateInfo>(
+ ObjectTemplateInfo::cast(obj->instance_template()));
+ internal_field_count =
+ Smi::cast(instance_template->internal_field_count())->value();
++ has_external_resource =
++ !instance_template->has_external_resource()->IsUndefined();
+ }
+
+ int instance_size = kPointerSize * internal_field_count;
++ if (has_external_resource) instance_size += kPointerSize;
++
+ InstanceType type = INVALID_TYPE;
+ switch (instance_type) {
+ case JavaScriptObject:
+@@ -1162,6 +1168,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);
++ }
++
+ // Mark as undetectable if needed.
+ if (obj->undetectable()) {
+ map->set_is_undetectable();
+diff --git a/src/heap-inl.h b/src/heap-inl.h
+index a4dfa5a..b121d01 100644
+--- a/src/heap-inl.h
++++ b/src/heap-inl.h
+@@ -222,21 +222,36 @@ MaybeObject* Heap::NumberFromUint32(uint32_t value) {
+ }
+
+
+-void Heap::FinalizeExternalString(String* string) {
+- ASSERT(string->IsExternalString());
+- v8::String::ExternalStringResourceBase** resource_addr =
+- reinterpret_cast<v8::String::ExternalStringResourceBase**>(
+- reinterpret_cast<byte*>(string) +
+- ExternalString::kResourceOffset -
+- kHeapObjectTag);
+-
+- // Dispose of the C++ object if it has not already been disposed.
+- if (*resource_addr != NULL) {
+- (*resource_addr)->Dispose();
++void Heap::FinalizeExternalString(HeapObject* string) {
++ ASSERT(string->IsExternalString() || string->map()->has_external_resource());
++
++ if (string->IsExternalString()) {
++ v8::String::ExternalStringResourceBase** resource_addr =
++ reinterpret_cast<v8::String::ExternalStringResourceBase**>(
++ reinterpret_cast<byte*>(string) +
++ ExternalString::kResourceOffset -
++ kHeapObjectTag);
++
++ // Dispose of the C++ object if it has not already been disposed.
++ if (*resource_addr != NULL) {
++ (*resource_addr)->Dispose();
++ }
++
++ // Clear the resource pointer in the string.
++ *resource_addr = NULL;
++ } else {
++ JSObject *object = JSObject::cast(string);
++ Object *value = object->GetExternalResourceObject();
++ v8::Object::ExternalResource *resource = 0;
++ if (value->IsSmi()) {
++ resource = reinterpret_cast<v8::Object::ExternalResource*>(Internals::GetExternalPointerFromSmi(value));
++ } else if (value->IsForeign()) {
++ resource = reinterpret_cast<v8::Object::ExternalResource*>(Foreign::cast(value)->address());
++ }
++ if (resource) {
++ resource->Dispose();
++ }
+ }
+-
+- // Clear the resource pointer in the string.
+- *resource_addr = NULL;
+ }
+
+
+@@ -556,6 +571,16 @@ void ExternalStringTable::AddString(String* string) {
+ }
+
+
++void ExternalStringTable::AddObject(HeapObject* object) {
++ ASSERT(object->map()->has_external_resource());
++ if (heap_->InNewSpace(object)) {
++ new_space_strings_.Add(object);
++ } else {
++ old_space_strings_.Add(object);
++ }
++}
++
++
+ void ExternalStringTable::Iterate(ObjectVisitor* v) {
+ if (!new_space_strings_.is_empty()) {
+ Object** start = &new_space_strings_[0];
+@@ -584,14 +609,14 @@ void ExternalStringTable::Verify() {
+ }
+
+
+-void ExternalStringTable::AddOldString(String* string) {
+- ASSERT(string->IsExternalString());
+- ASSERT(!heap_->InNewSpace(string));
+- old_space_strings_.Add(string);
++void ExternalStringTable::AddOldObject(HeapObject* object) {
++ ASSERT(object->IsExternalString() || object->map()->has_external_resource());
++ ASSERT(!heap_->InNewSpace(object));
++ old_space_strings_.Add(object);
+ }
+
+
+-void ExternalStringTable::ShrinkNewStrings(int position) {
++void ExternalStringTable::ShrinkNewObjects(int position) {
+ new_space_strings_.Rewind(position);
+ Verify();
+ }
+diff --git a/src/heap.cc b/src/heap.cc
+index 0dfd453..c730455 100644
+--- a/src/heap.cc
++++ b/src/heap.cc
+@@ -1095,18 +1095,18 @@ void Heap::Scavenge() {
+ }
+
+
+-String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
+- Object** p) {
++HeapObject* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(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());
+ }
+
+
+@@ -1122,11 +1122,11 @@ void Heap::UpdateNewSpaceReferencesInExternalStringTable(
+
+ 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.
+@@ -1134,12 +1134,12 @@ void Heap::UpdateNewSpaceReferencesInExternalStringTable(
+ ++last;
+ } else {
+ // String got promoted. Move it to the old string list.
+- external_string_table_.AddOldString(target);
++ external_string_table_.AddOldObject(target);
+ }
+ }
+
+ ASSERT(last <= end);
+- external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
++ external_string_table_.ShrinkNewObjects(static_cast<int>(last - start));
+ }
+
+
+@@ -6426,6 +6426,19 @@ void ExternalStringTable::CleanUp() {
+
+
+ void ExternalStringTable::TearDown() {
++ for (int i = 0; i < new_space_strings_.length(); ++i) {
++ if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
++ HeapObject *object = HeapObject::cast(new_space_strings_[i]);
++ if (!object->IsExternalString())
++ heap_->FinalizeExternalString(object);
++ }
++ for (int i = 0; i < old_space_strings_.length(); ++i) {
++ if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
++ HeapObject *object = HeapObject::cast(old_space_strings_[i]);
++ if (!object->IsExternalString())
++ heap_->FinalizeExternalString(object);
++ }
++
+ new_space_strings_.Free();
+ old_space_strings_.Free();
+ }
+diff --git a/src/heap.h b/src/heap.h
+index 4a1e01d..bab4c63 100644
+--- a/src/heap.h
++++ b/src/heap.h
+@@ -243,8 +243,8 @@ class Isolate;
+ class WeakObjectRetainer;
+
+
+-typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap,
+- Object** pointer);
++typedef HeapObject* (*ExternalStringTableUpdaterCallback)(Heap* heap,
++ Object** pointer);
+
+ class StoreBufferRebuilder {
+ public:
+@@ -329,10 +329,14 @@ typedef void (*ScavengingCallback)(Map* map,
+ // External strings table is a place where all external strings are
+ // registered. We need to keep track of such strings to properly
+ // finalize them.
++// The ExternalStringTable can contain both strings and objects with
++// external resources. It was not renamed to make the patch simpler.
+ class ExternalStringTable {
+ public:
+ // Registers an external string.
+ inline void AddString(String* string);
++ // Registers an external object.
++ inline void AddObject(HeapObject* string);
+
+ inline void Iterate(ObjectVisitor* v);
+
+@@ -350,10 +354,10 @@ class ExternalStringTable {
+
+ inline void Verify();
+
+- inline void AddOldString(String* string);
++ inline void AddOldObject(HeapObject* string);
+
+ // 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.
+@@ -849,7 +853,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.
+@@ -1662,7 +1666,7 @@ class Heap {
+ // Performs a minor collection in new generation.
+ void Scavenge();
+
+- static String* UpdateNewSpaceReferenceInExternalStringTableEntry(
++ static HeapObject* UpdateNewSpaceReferenceInExternalStringTableEntry(
+ Heap* heap,
+ Object** pointer);
+
+diff --git a/src/mark-compact.cc b/src/mark-compact.cc
+index e90a23d..b9ae787 100644
+--- a/src/mark-compact.cc
++++ b/src/mark-compact.cc
+@@ -1521,8 +1521,9 @@ class SymbolTableCleaner : public ObjectVisitor {
+
+ // Since no objects have yet been moved we can safely access the map of
+ // the object.
+- if (o->IsExternalString()) {
+- heap_->FinalizeExternalString(String::cast(*p));
++ if (o->IsExternalString() ||
++ (o->IsHeapObject() && HeapObject::cast(o)->map()->has_external_resource())) {
++ heap_->FinalizeExternalString(HeapObject::cast(*p));
+ }
+ // Set the entry to null_value (as deleted).
+ *p = heap_->null_value();
+@@ -2515,15 +2516,15 @@ static void UpdatePointer(HeapObject** p, HeapObject* object) {
+ }
+
+
+-static String* UpdateReferenceInExternalStringTableEntry(Heap* heap,
+- Object** p) {
++static HeapObject* UpdateReferenceInExternalStringTableEntry(Heap* heap,
++ Object** p) {
+ MapWord map_word = HeapObject::cast(*p)->map_word();
+
+ if (map_word.IsForwardingAddress()) {
+- return String::cast(map_word.ToForwardingAddress());
++ return HeapObject::cast(map_word.ToForwardingAddress());
+ }
+
+- return String::cast(*p);
++ return HeapObject::cast(*p);
+ }
+
+
+diff --git a/src/objects-inl.h b/src/objects-inl.h
+index 35fbea5..36af868 100644
+--- a/src/objects-inl.h
++++ b/src/objects-inl.h
+@@ -1488,7 +1488,7 @@ int JSObject::GetInternalFieldCount() {
+ // Make sure to adjust for the number of in-object properties. These
+ // properties do contribute to the size, but are not internal fields.
+ return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
+- map()->inobject_properties();
++ map()->inobject_properties() - (map()->has_external_resource()?1:0);
+ }
+
+
+@@ -1518,6 +1518,23 @@ void JSObject::SetInternalField(int index, Object* value) {
+ }
+
+
++void JSObject::SetExternalResourceObject(Object *value) {
++ ASSERT(map()->has_external_resource());
++ int offset = GetHeaderSize() + kPointerSize * GetInternalFieldCount();
++ WRITE_FIELD(this, offset, value);
++ WRITE_BARRIER(GetHeap(), this, offset, value);
++}
++
++
++Object *JSObject::GetExternalResourceObject() {
++ if (map()->has_external_resource()) {
++ return READ_FIELD(this, GetHeaderSize() + kPointerSize * GetInternalFieldCount());
++ } else {
++ return GetHeap()->undefined_value();
++ }
++}
++
++
+ // Access fast-case object properties at index. The use of these routines
+ // is needed to correctly distinguish between properties stored in-object and
+ // properties stored in the properties array.
+@@ -2865,6 +2882,20 @@ bool Map::is_shared() {
+ return ((1 << kIsShared) & bit_field3()) != 0;
+ }
+
++void Map::set_has_external_resource(bool value) {
++ if (value) {
++ set_bit_field(bit_field() | (1 << kHasExternalResource));
++ } else {
++ set_bit_field(bit_field() & ~(1 << kHasExternalResource));
++ }
++}
++
++bool Map::has_external_resource()
++{
++ return ((1 << kHasExternalResource) & bit_field()) != 0;
++}
++
++
+ void Map::set_named_interceptor_is_fallback(bool value)
+ {
+ if (value) {
+@@ -3396,6 +3427,8 @@ ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
+ ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
+ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
+ kInternalFieldCountOffset)
++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
+index b974756..dea5bbd 100644
+--- a/src/objects.h
++++ b/src/objects.h
+@@ -1732,6 +1732,9 @@ class JSObject: public JSReceiver {
+ inline Object* GetInternalField(int index);
+ inline void SetInternalField(int index, Object* value);
+
++ inline void SetExternalResourceObject(Object *);
++ inline Object *GetExternalResourceObject();
++
+ // The following lookup functions skip interceptors.
+ void LocalLookupRealNamedProperty(String* name, LookupResult* result);
+ void LookupRealNamedProperty(String* name, LookupResult* result);
+@@ -4003,11 +4006,11 @@ class Map: public HeapObject {
+
+ // Tells whether the instance has a call-as-function handler.
+ inline void set_has_instance_call_handler() {
+- set_bit_field(bit_field() | (1 << kHasInstanceCallHandler));
++ set_bit_field3(bit_field3() | (1 << kHasInstanceCallHandler));
+ }
+
+ inline bool has_instance_call_handler() {
+- return ((1 << kHasInstanceCallHandler) & bit_field()) != 0;
++ return ((1 << kHasInstanceCallHandler) & bit_field3()) != 0;
+ }
+
+ inline void set_is_extensible(bool value);
+@@ -4076,6 +4079,11 @@ class Map: public HeapObject {
+ inline void set_named_interceptor_is_fallback(bool value);
+ inline bool named_interceptor_is_fallback();
+
++ // 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();
++
+ // [prototype]: implicit prototype object.
+ DECL_ACCESSORS(prototype, Object)
+
+@@ -4288,7 +4296,7 @@ class Map: public HeapObject {
+ static const int kHasNamedInterceptor = 3;
+ static const int kHasIndexedInterceptor = 4;
+ static const int kIsUndetectable = 5;
+- static const int kHasInstanceCallHandler = 6;
++ static const int kHasExternalResource = 6;
+ static const int kIsAccessCheckNeeded = 7;
+
+ // Bit positions for bit field 2
+@@ -4313,6 +4321,7 @@ class Map: public HeapObject {
+ // Bit positions for bit field 3
+ static const int kIsShared = 0;
+ static const int kNamedInterceptorIsFallback = 1;
++ static const int kHasInstanceCallHandler = 2;
+
+ // Layout of the default cache. It holds alternating name and code objects.
+ static const int kCodeCacheEntrySize = 2;
+@@ -7292,6 +7301,7 @@ class ObjectTemplateInfo: public TemplateInfo {
+ public:
+ DECL_ACCESSORS(constructor, Object)
+ DECL_ACCESSORS(internal_field_count, Object)
++ DECL_ACCESSORS(has_external_resource, Object)
+
+ static inline ObjectTemplateInfo* cast(Object* obj);
+
+@@ -7308,7 +7318,8 @@ class ObjectTemplateInfo: public TemplateInfo {
+ static const int kConstructorOffset = TemplateInfo::kHeaderSize;
+ static const int kInternalFieldCountOffset =
+ kConstructorOffset + kPointerSize;
+- static const int kSize = kInternalFieldCountOffset + kPointerSize;
++ static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize;
++ static const int kSize = kHasExternalResourceOffset + kPointerSize;
+ };
+
+
+--
+1.7.4.4
+
diff --git a/src/v8/0004-Generalize-external-object-resources.patch b/src/v8/0004-Generalize-external-object-resources.patch
deleted file mode 100644
index ece0f197d8..0000000000
--- a/src/v8/0004-Generalize-external-object-resources.patch
+++ /dev/null
@@ -1,894 +0,0 @@
-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
-
-V8 was already able to manage and finalize an external string
-resource. This change generalizes that mechanism to handle a
-single generic external resource - a v8::Object::ExternalResource
-derived instance - on normal JSObject's.
-
-This is useful for mapping C++ objects to JS objects where the
-C++ object's memory is effectively owned by the JS Object, and
-thus needs to destroyed when the JS Object is garbage collected.
-The V8 mailing list suggests using a weak persistent handle for
-this purpose, but that seems to incur a fairly massive performance
-penalty for short lived objects as weak persistent handle callbacks
-are not called until the object has been promoted into the old
-object space.
----
- include/v8.h | 25 ++++++
- src/api.cc | 64 ++++++++++++++-
- src/extensions/externalize-string-extension.cc | 4 +-
- src/factory.cc | 11 +++
- src/heap-inl.h | 101 +++++++++++++++---------
- src/heap.cc | 68 ++++++++--------
- src/heap.h | 42 +++++-----
- src/liveobjectlist.cc | 4 +-
- src/mark-compact.cc | 21 +++---
- src/objects-inl.h | 41 +++++++++-
- src/objects.h | 14 +++-
- 11 files changed, 280 insertions(+), 115 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index bb31ea0..205e856 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -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() {}
-+ virtual ~ExternalResource() {}
-+
-+ protected:
-+ virtual void Dispose() { delete this; }
-+
-+ private:
-+ // Disallow copying and assigning.
-+ ExternalResource(const ExternalResource&);
-+ void operator=(const ExternalResource&);
-+
-+ friend class v8::internal::Heap;
-+ };
-+
-+ V8EXPORT void SetExternalResource(ExternalResource *);
-+ V8EXPORT ExternalResource *GetExternalResource();
-+
- // Testers for local properties.
- V8EXPORT bool HasRealNamedProperty(Handle<String> key);
- V8EXPORT bool HasRealIndexedProperty(uint32_t index);
-@@ -2332,6 +2351,12 @@ class V8EXPORT ObjectTemplate : public Template {
- */
- void SetInternalFieldCount(int value);
-
-+ /**
-+ * Sets whether the object can store an "external resource" object.
-+ */
-+ bool HasExternalResource();
-+ void SetHasExternalResource(bool value);
-+
- private:
- ObjectTemplate();
- static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
-diff --git a/src/api.cc b/src/api.cc
-index 8b0b32a..1a6fbbb 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -1294,6 +1294,34 @@ void ObjectTemplate::SetInternalFieldCount(int value) {
- }
-
-
-+bool ObjectTemplate::HasExternalResource()
-+{
-+ if (IsDeadCheck(Utils::OpenHandle(this)->GetIsolate(),
-+ "v8::ObjectTemplate::HasExternalResource()")) {
-+ return 0;
-+ }
-+ return !Utils::OpenHandle(this)->has_external_resource()->IsUndefined();
-+}
-+
-+
-+void ObjectTemplate::SetHasExternalResource(bool value)
-+{
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetHasExternalResource()")) {
-+ return;
-+ }
-+ ENTER_V8(isolate);
-+ if (value) {
-+ EnsureConstructor(this);
-+ }
-+ if (value) {
-+ Utils::OpenHandle(this)->set_has_external_resource(i::Smi::FromInt(1));
-+ } else {
-+ Utils::OpenHandle(this)->set_has_external_resource(Utils::OpenHandle(this)->GetHeap()->undefined_value());
-+ }
-+}
-+
-+
- // --- 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);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ if (CanBeEncodedAsSmi(resource)) {
-+ obj->SetExternalResourceObject(EncodeAsSmi(resource));
-+ } else {
-+ obj->SetExternalResourceObject(*isolate->factory()->NewProxy(static_cast<i::Address>((void *)resource)));
-+ }
-+ if (!obj->IsSymbol()) {
-+ isolate->heap()->external_resource_table()->AddObject(*obj);
-+ }
-+}
-+
-+
-+v8::Object::ExternalResource *v8::Object::GetExternalResource() {
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ i::Object* value = obj->GetExternalResourceObject();
-+ if (value->IsSmi()) {
-+ return reinterpret_cast<v8::Object::ExternalResource*>(i::Internals::GetExternalPointerFromSmi(value));
-+ } else if (value->IsProxy()) {
-+ return reinterpret_cast<v8::Object::ExternalResource*>(i::Proxy::cast(value)->proxy());
-+ } else {
-+ return NULL;
-+ }
-+}
-+
-+
- // --- 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);
- i::Handle<i::String> result = NewExternalStringHandle(isolate, resource);
-- isolate->heap()->external_string_table()->AddString(*result);
-+ 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);
- if (result && !obj->IsSymbol()) {
-- isolate->heap()->external_string_table()->AddString(*obj);
-+ isolate->heap()->external_resource_table()->AddString(*obj);
- }
- return result;
- }
-@@ -4175,7 +4231,7 @@ Local<String> v8::String::NewExternal(
- LOG_API(isolate, "String::NewExternal");
- ENTER_V8(isolate);
- i::Handle<i::String> result = NewExternalAsciiStringHandle(isolate, resource);
-- isolate->heap()->external_string_table()->AddString(*result);
-+ isolate->heap()->external_resource_table()->AddString(*result);
- return Utils::ToLocal(result);
- }
-
-@@ -4194,7 +4250,7 @@ bool v8::String::MakeExternal(
- }
- bool result = obj->MakeExternal(resource);
- if (result && !obj->IsSymbol()) {
-- isolate->heap()->external_string_table()->AddString(*obj);
-+ isolate->heap()->external_resource_table()->AddString(*obj);
- }
- return result;
- }
-diff --git a/src/extensions/externalize-string-extension.cc b/src/extensions/externalize-string-extension.cc
-index b3f83fe..8e50904 100644
---- a/src/extensions/externalize-string-extension.cc
-+++ b/src/extensions/externalize-string-extension.cc
-@@ -100,7 +100,7 @@ v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
- data, string->length());
- result = string->MakeExternal(resource);
- if (result && !string->IsSymbol()) {
-- HEAP->external_string_table()->AddString(*string);
-+ HEAP->external_resource_table()->AddString(*string);
- }
- if (!result) delete resource;
- } else {
-@@ -110,7 +110,7 @@ v8::Handle<v8::Value> ExternalizeStringExtension::Externalize(
- data, string->length());
- result = string->MakeExternal(resource);
- if (result && !string->IsSymbol()) {
-- HEAP->external_string_table()->AddString(*string);
-+ HEAP->external_resource_table()->AddString(*string);
- }
- if (!result) delete resource;
- }
-diff --git a/src/factory.cc b/src/factory.cc
-index dcdc645..d530a75 100644
---- a/src/factory.cc
-+++ 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;
-+
- if (!obj->instance_template()->IsUndefined()) {
- Handle<ObjectTemplateInfo> instance_template =
- Handle<ObjectTemplateInfo>(
- ObjectTemplateInfo::cast(obj->instance_template()));
- internal_field_count =
- Smi::cast(instance_template->internal_field_count())->value();
-+ has_external_resource =
-+ !instance_template->has_external_resource()->IsUndefined();
- }
-
- int instance_size = kPointerSize * internal_field_count;
-+ if (has_external_resource) instance_size += kPointerSize;
-+
- InstanceType type = INVALID_TYPE;
- 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);
-+ }
-+
- // Mark as undetectable if needed.
- if (obj->undetectable()) {
- map->set_is_undetectable();
-diff --git a/src/heap-inl.h b/src/heap-inl.h
-index f4fce7b..58e7adf 100644
---- a/src/heap-inl.h
-+++ 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 =
-- reinterpret_cast<v8::String::ExternalStringResourceBase**>(
-- reinterpret_cast<byte*>(string) +
-- ExternalString::kResourceOffset -
-- kHeapObjectTag);
--
-- // Dispose of the C++ object if it has not already been disposed.
-- if (*resource_addr != NULL) {
-- (*resource_addr)->Dispose();
-- }
-+void Heap::FinalizeExternalString(HeapObject* string) {
-+ ASSERT(string->IsExternalString() || string->map()->has_external_resource());
-+
-+ if (string->IsExternalString()) {
-+ v8::String::ExternalStringResourceBase** resource_addr =
-+ reinterpret_cast<v8::String::ExternalStringResourceBase**>(
-+ reinterpret_cast<byte*>(string) +
-+ ExternalString::kResourceOffset -
-+ kHeapObjectTag);
-+
-+ // Dispose of the C++ object if it has not already been disposed.
-+ if (*resource_addr != NULL) {
-+ (*resource_addr)->Dispose();
-+ }
-
-- // Clear the resource pointer in the string.
-- *resource_addr = NULL;
-+ // Clear the resource pointer in the string.
-+ *resource_addr = NULL;
-+ } else {
-+ JSObject *object = JSObject::cast(string);
-+ Object *value = object->GetExternalResourceObject();
-+ v8::Object::ExternalResource *resource = 0;
-+ if (value->IsSmi()) {
-+ 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) {
-+ ASSERT(string->IsExternalString() );
- if (heap_->InNewSpace(string)) {
-- new_space_strings_.Add(string);
-+ new_space_objects_.Add(string);
-+ } else {
-+ old_space_objects_.Add(string);
-+ }
-+}
-+
-+
-+void ExternalResourceTable::AddObject(HeapObject* object) {
-+ ASSERT(object->map()->has_external_resource());
-+ if (heap_->InNewSpace(object)) {
-+ new_space_objects_.Add(object);
- } else {
-- old_space_strings_.Add(string);
-+ old_space_objects_.Add(object);
- }
- }
-
-
--void ExternalStringTable::Iterate(ObjectVisitor* v) {
-- if (!new_space_strings_.is_empty()) {
-- Object** start = &new_space_strings_[0];
-- v->VisitPointers(start, start + new_space_strings_.length());
-+void ExternalResourceTable::Iterate(ObjectVisitor* v) {
-+ if (!new_space_objects_.is_empty()) {
-+ Object** start = &new_space_objects_[0];
-+ v->VisitPointers(start, start + new_space_objects_.length());
- }
-- if (!old_space_strings_.is_empty()) {
-- Object** start = &old_space_strings_[0];
-- v->VisitPointers(start, start + old_space_strings_.length());
-+ if (!old_space_objects_.is_empty()) {
-+ Object** start = &old_space_objects_[0];
-+ v->VisitPointers(start, start + old_space_objects_.length());
- }
- }
-
-
- // Verify() is inline to avoid ifdef-s around its calls in release
- // mode.
--void ExternalStringTable::Verify() {
-+void ExternalResourceTable::Verify() {
- #ifdef DEBUG
-- for (int i = 0; i < new_space_strings_.length(); ++i) {
-- ASSERT(heap_->InNewSpace(new_space_strings_[i]));
-- ASSERT(new_space_strings_[i] != HEAP->raw_unchecked_null_value());
-+ for (int i = 0; i < new_space_objects_.length(); ++i) {
-+ ASSERT(heap_->InNewSpace(new_space_objects_[i]));
-+ ASSERT(new_space_objects_[i] != HEAP->raw_unchecked_null_value());
- }
-- for (int i = 0; i < old_space_strings_.length(); ++i) {
-- ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
-- ASSERT(old_space_strings_[i] != HEAP->raw_unchecked_null_value());
-+ for (int i = 0; i < old_space_objects_.length(); ++i) {
-+ ASSERT(!heap_->InNewSpace(old_space_objects_[i]));
-+ ASSERT(old_space_objects_[i] != HEAP->raw_unchecked_null_value());
- }
- #endif
- }
-
-
--void ExternalStringTable::AddOldString(String* string) {
-- ASSERT(string->IsExternalString());
-- ASSERT(!heap_->InNewSpace(string));
-- old_space_strings_.Add(string);
-+void ExternalResourceTable::AddOldObject(HeapObject* object) {
-+ ASSERT(object->IsExternalString() || object->map()->has_external_resource());
-+ 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
-+++ b/src/heap.cc
-@@ -155,7 +155,7 @@ Heap::Heap()
- memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
- global_contexts_list_ = NULL;
- mark_compact_collector_.heap_ = this;
-- 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(
- ++last;
- } else {
- // String got promoted. Move it to the old string list.
-- external_string_table_.AddOldString(target);
-+ 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) {
- // Scavenge collections have special processing for this.
-- external_string_table_.Iterate(v);
-+ external_resource_table_.Iterate(v);
- }
- 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;
-- for (int i = 0; i < new_space_strings_.length(); ++i) {
-- if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
-- if (heap_->InNewSpace(new_space_strings_[i])) {
-- new_space_strings_[last++] = new_space_strings_[i];
-+ for (int i = 0; i < new_space_objects_.length(); ++i) {
-+ if (new_space_objects_[i] == heap_->raw_unchecked_null_value()) continue;
-+ if (heap_->InNewSpace(new_space_objects_[i])) {
-+ new_space_objects_[last++] = new_space_objects_[i];
- } else {
-- old_space_strings_.Add(new_space_strings_[i]);
-+ old_space_objects_.Add(new_space_objects_[i]);
- }
- }
-- new_space_strings_.Rewind(last);
-+ new_space_objects_.Rewind(last);
- last = 0;
-- for (int i = 0; i < old_space_strings_.length(); ++i) {
-- if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
-- ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
-- old_space_strings_[last++] = old_space_strings_[i];
-+ for (int i = 0; i < old_space_objects_.length(); ++i) {
-+ if (old_space_objects_[i] == heap_->raw_unchecked_null_value()) continue;
-+ ASSERT(!heap_->InNewSpace(old_space_objects_[i]));
-+ old_space_objects_[last++] = old_space_objects_[i];
- }
-- old_space_strings_.Rewind(last);
-+ old_space_objects_.Rewind(last);
- Verify();
- }
-
-
--void ExternalStringTable::TearDown() {
-- new_space_strings_.Free();
-- old_space_strings_.Free();
-+void ExternalResourceTable::TearDown() {
-+ 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
-+// track of such strings to properly finalize them.
-+class ExternalResourceTable {
- public:
- // Registers an external string.
- 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
-+++ b/src/liveobjectlist.cc
-@@ -1989,7 +1989,7 @@ Object* LiveObjectList::PrintObj(int obj_id) {
- ASSERT(resource->IsAscii());
- Handle<String> dump_string =
- Factory::NewExternalStringFromAscii(resource);
-- ExternalStringTable::AddString(*dump_string);
-+ ExternalResourceTable::AddString(*dump_string);
- return *dump_string;
- } else {
- delete resource;
-@@ -2193,7 +2193,7 @@ Object* LiveObjectList::GetPathPrivate(HeapObject* obj1, HeapObject* obj2) {
- ASSERT(resource->IsAscii());
- Handle<String> path_string =
- Factory::NewExternalStringFromAscii(resource);
-- ExternalStringTable::AddString(*path_string);
-+ ExternalResourceTable::AddString(*path_string);
- return *path_string;
- } else {
- delete resource;
-diff --git a/src/mark-compact.cc b/src/mark-compact.cc
-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())) {
-+ heap_->FinalizeExternalString(HeapObject::cast(*p));
- }
- // Set the entry to null_value (as deleted).
- *p = heap_->raw_unchecked_null_value();
-@@ -1433,8 +1434,8 @@ void MarkCompactCollector::MarkLiveObjects() {
- SymbolTableCleaner v(heap());
- symbol_table->IterateElements(&v);
- symbol_table->ElementsRemoved(v.PointersRemoved());
-- heap()->external_string_table_.Iterate(&v);
-- 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,
-+ Object** p) {
- Address old_addr = HeapObject::cast(*p)->address();
- Address new_addr = Memory::Address_at(old_addr);
-- 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
-index 6aaca2f..231b835 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -1392,13 +1392,13 @@ int JSObject::GetInternalFieldCount() {
- // Make sure to adjust for the number of in-object properties. These
- // properties do contribute to the size, but are not internal fields.
- return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
-- 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
- // to adjust the index here.
-- 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
- // to adjust the index here.
-- int offset = GetHeaderSize() + (kPointerSize * index);
-+ int offset = GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0));
- WRITE_FIELD(this, offset, value);
- WRITE_BARRIER(this, offset);
- }
-
-
-+void JSObject::SetExternalResourceObject(Object *value) {
-+ ASSERT(map()->has_external_resource());
-+ int offset = GetHeaderSize();
-+ WRITE_FIELD(this, offset, value);
-+ WRITE_BARRIER(this, offset);
-+}
-+
-+
-+Object *JSObject::GetExternalResourceObject() {
-+ if (map()->has_external_resource()) {
-+ return READ_FIELD(this, GetHeaderSize());
-+ } else {
-+ return GetHeap()->undefined_value();
-+ }
-+}
-+
-+
- // Access fast-case object properties at index. The use of these routines
- // is needed to correctly distinguish between properties stored in-object and
- // 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));
-+ } else {
-+ set_bit_field3(bit_field3() & ~(1 << kHasExternalResource));
-+ }
-+}
-+
-+bool Map::has_external_resource()
-+{
-+ return ((1 << kHasExternalResource) & bit_field3()) != 0;
-+}
-+
-+
- void Map::set_named_interceptor_is_fallback(bool value)
- {
- if (value) {
-@@ -3017,6 +3048,8 @@ ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
- ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
- ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
- kInternalFieldCountOffset)
-+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
-index a209cd0..1bdb5c7 100644
---- a/src/objects.h
-+++ b/src/objects.h
-@@ -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();
-+
- // Lookup a property. If found, the result is valid and has
- // detailed information.
- void LocalLookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false);
-@@ -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 {
- public:
- 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 =
- kConstructorOffset + kPointerSize;
-- static const int kSize = kInternalFieldCountOffset + kPointerSize;
-+ static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize;
-+ static const int kSize = kHasExternalResourceOffset + kPointerSize;
- };
-
-
---
-1.7.4.4
-
diff --git a/src/v8/0005-Introduce-a-QML-compilation-mode.patch b/src/v8/0004-Introduce-a-QML-compilation-mode.patch
index c5c36a1f95..4b79d94e68 100644
--- a/src/v8/0005-Introduce-a-QML-compilation-mode.patch
+++ b/src/v8/0004-Introduce-a-QML-compilation-mode.patch
@@ -1,7 +1,7 @@
-From 60c1a26bf89d3b06bcdd8408fcee89a018120f32 Mon Sep 17 00:00:00 2001
+From 27ef7b7b37255a9965fe31fb7597720f57ed5154 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
+Date: Wed, 5 Oct 2011 13:01:30 +1000
+Subject: [PATCH 04/11] 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,10 +15,10 @@ 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 | 19 ++++++++--
+ src/api.cc | 52 ++++++++++++++++++++++++-----
src/arm/code-stubs-arm.cc | 4 ++
- src/arm/full-codegen-arm.cc | 26 ++++++++------
+ src/arm/full-codegen-arm.cc | 28 +++++++++-------
src/arm/lithium-arm.cc | 2 +-
src/arm/lithium-arm.h | 6 +++-
src/arm/lithium-codegen-arm.cc | 7 ++--
@@ -27,46 +27,46 @@ runs.
src/ast.h | 1 +
src/code-stubs.h | 2 +-
src/compiler.cc | 15 +++++++-
- src/compiler.h | 22 +++++++++--
- src/contexts.cc | 35 ++++++++++++++++++
+ src/compiler.h | 16 +++++++--
+ src/contexts.cc | 35 +++++++++++++++++++
src/contexts.h | 4 ++
- src/execution.cc | 28 ++++++++++++--
- src/execution.h | 6 +++
+ src/execution.cc | 31 ++++++++++++++---
+ src/execution.h | 8 ++++
src/full-codegen.cc | 3 +-
src/full-codegen.h | 1 +
- src/heap.cc | 2 +
- src/hydrogen-instructions.h | 10 ++++-
+ src/heap.cc | 4 ++
+ src/hydrogen-instructions.h | 8 ++++-
src/hydrogen.cc | 2 +
- src/ia32/code-stubs-ia32.cc | 7 ++++
- src/ia32/full-codegen-ia32.cc | 26 ++++++++------
+ src/ia32/code-stubs-ia32.cc | 5 +++
+ src/ia32/full-codegen-ia32.cc | 28 +++++++++-------
src/ia32/lithium-codegen-ia32.cc | 7 ++--
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.h | 5 +++
- src/parser.cc | 27 ++++++++++++--
+ src/ia32/macro-assembler-ia32.h | 3 ++
+ src/objects-inl.h | 2 +
+ src/objects.h | 4 ++
+ src/parser.cc | 27 +++++++++++++--
src/parser.h | 4 ++-
src/prettyprinter.cc | 3 ++
- src/runtime.cc | 72 ++++++++++++++++++++++++-------------
+ src/runtime.cc | 68 +++++++++++++++++++++++++-------------
src/runtime.h | 8 ++--
- src/scopes.cc | 59 +++++++++++++++++++++++++++++++
- src/scopes.h | 7 ++++
+ src/scopes.cc | 61 ++++++++++++++++++++++++++++++++++
+ src/scopes.h | 8 ++++
src/variables.cc | 3 +-
src/variables.h | 5 +++
src/x64/code-stubs-x64.cc | 4 ++
- src/x64/full-codegen-x64.cc | 26 ++++++++------
+ src/x64/full-codegen-x64.cc | 28 +++++++++-------
src/x64/lithium-codegen-x64.cc | 7 ++--
src/x64/lithium-x64.cc | 2 +-
src/x64/lithium-x64.h | 6 +++
src/x64/macro-assembler-x64.h | 5 +++
- 45 files changed, 455 insertions(+), 109 deletions(-)
+ 45 files changed, 445 insertions(+), 109 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 205e856..d78ab1f 100644
+index 3ef4dd6..193e2fe 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -577,6 +577,10 @@ class ScriptOrigin {
+@@ -587,6 +587,11 @@ class ScriptOrigin {
*/
class V8EXPORT Script {
public:
@@ -74,10 +74,11 @@ index 205e856..d78ab1f 100644
+ Default = 0x00,
+ QmlMode = 0x01
+ };
-
++
/**
* Compiles the specified script (context-independent).
-@@ -596,7 +600,8 @@ class V8EXPORT Script {
+ *
+@@ -605,7 +610,8 @@ class V8EXPORT Script {
static Local<Script> New(Handle<String> source,
ScriptOrigin* origin = NULL,
ScriptData* pre_data = NULL,
@@ -87,7 +88,7 @@ index 205e856..d78ab1f 100644
/**
* Compiles the specified script using the specified file name
-@@ -609,7 +614,8 @@ class V8EXPORT Script {
+@@ -618,7 +624,8 @@ class V8EXPORT Script {
* will use the currently entered context).
*/
static Local<Script> New(Handle<String> source,
@@ -97,7 +98,7 @@ index 205e856..d78ab1f 100644
/**
* Compiles the specified script (bound to current context).
-@@ -630,7 +636,8 @@ class V8EXPORT Script {
+@@ -639,7 +646,8 @@ class V8EXPORT Script {
static Local<Script> Compile(Handle<String> source,
ScriptOrigin* origin = NULL,
ScriptData* pre_data = NULL,
@@ -107,7 +108,7 @@ index 205e856..d78ab1f 100644
/**
* Compiles the specified script using the specified file name
-@@ -647,7 +654,8 @@ class V8EXPORT Script {
+@@ -656,7 +664,8 @@ class V8EXPORT Script {
*/
static Local<Script> Compile(Handle<String> source,
Handle<Value> file_name,
@@ -117,7 +118,7 @@ index 205e856..d78ab1f 100644
/**
* Runs the script returning the resulting value. If the script is
-@@ -657,6 +665,7 @@ class V8EXPORT Script {
+@@ -666,6 +675,7 @@ class V8EXPORT Script {
* compiled.
*/
Local<Value> Run();
@@ -125,7 +126,7 @@ index 205e856..d78ab1f 100644
/**
* Returns the script id value.
-@@ -3327,6 +3336,7 @@ class V8EXPORT Context {
+@@ -3506,6 +3516,7 @@ class V8EXPORT Context {
* JavaScript frames an empty handle is returned.
*/
static Local<Context> GetCalling();
@@ -134,10 +135,10 @@ index 205e856..d78ab1f 100644
/**
* Sets the security token for the context. To access an object in
diff --git a/src/api.cc b/src/api.cc
-index 1a6fbbb..39767f4 100644
+index 85f0d4b..fd718c8 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -1372,7 +1372,8 @@ ScriptData* ScriptData::New(const char* data, int length) {
+@@ -1514,7 +1514,8 @@ ScriptData* ScriptData::New(const char* data, int length) {
Local<Script> Script::New(v8::Handle<String> source,
v8::ScriptOrigin* origin,
v8::ScriptData* pre_data,
@@ -147,7 +148,7 @@ index 1a6fbbb..39767f4 100644
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>());
LOG_API(isolate, "Script::New");
-@@ -1409,7 +1410,8 @@ Local<Script> Script::New(v8::Handle<String> source,
+@@ -1551,7 +1552,8 @@ Local<Script> Script::New(v8::Handle<String> source,
NULL,
pre_data_impl,
Utils::OpenHandle(*script_data),
@@ -157,12 +158,12 @@ index 1a6fbbb..39767f4 100644
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
return Local<Script>(ToApi<Script>(result));
-@@ -1417,21 +1419,23 @@ Local<Script> Script::New(v8::Handle<String> source,
+@@ -1559,21 +1561,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);
@@ -185,7 +186,7 @@ index 1a6fbbb..39767f4 100644
if (generic.IsEmpty())
return generic;
i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
-@@ -1447,13 +1451,18 @@ Local<Script> Script::Compile(v8::Handle<String> source,
+@@ -1589,13 +1593,18 @@ Local<Script> Script::Compile(v8::Handle<String> source,
Local<Script> Script::Compile(v8::Handle<String> source,
v8::Handle<Value> file_name,
@@ -206,7 +207,7 @@ index 1a6fbbb..39767f4 100644
i::Isolate* isolate = i::Isolate::Current();
ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
LOG_API(isolate, "Script::Run");
-@@ -1472,10 +1481,11 @@ Local<Value> Script::Run() {
+@@ -1614,10 +1623,11 @@ Local<Value> Script::Run() {
fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate);
}
EXCEPTION_PREAMBLE(isolate);
@@ -215,11 +216,11 @@ index 1a6fbbb..39767f4 100644
isolate->context()->global_proxy(), isolate);
i::Handle<i::Object> result =
- i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
-+ i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception, qmlglobal);
++ i::Execution::Call(fun, receiver, 0, NULL, &has_pending_exception, false, qmlglobal);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
raw_result = *result;
}
-@@ -3943,6 +3953,30 @@ v8::Local<v8::Context> Context::GetCalling() {
+@@ -4328,6 +4338,30 @@ v8::Local<v8::Context> Context::GetCalling() {
}
@@ -251,10 +252,10 @@ index 1a6fbbb..39767f4 100644
if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) {
return Local<v8::Object>();
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
-index 8c147f9..a2626bf 100644
+index 17dfbd7..00ac676 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
-@@ -166,6 +166,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
+@@ -172,6 +172,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
@@ -266,13 +267,13 @@ index 8c147f9..a2626bf 100644
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
-index 871b453..a69f10d 100644
+index 2ee1594..a1841f2 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
-@@ -154,12 +154,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
+@@ -182,12 +182,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+ int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
+ if (heap_slots > 0 ||
+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
@@ -284,49 +285,44 @@ index 871b453..a69f10d 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1247,9 +1248,9 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -1168,9 +1169,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ bind(&fast);
}
- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(r2, Operand(slot->var()->name()));
++ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
+ __ mov(r2, Operand(var->name()));
- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
++ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || var->is_qml_global())
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-@@ -1268,10 +1269,10 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- Comment cmnt(masm_, "Global variable");
- // Use inline caching. Variable name is passed in r2 and the global
- // object (receiver) in r0.
-- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(r2, Operand(var->name()));
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- 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
- // r2, and the global object in r1.
+@@ -1246,10 +1247,10 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+ Comment cmnt(masm_, "Global variable");
+ // Use inline caching. Variable name is passed in r2 and the global
+ // object (receiver) in r0.
+- __ ldr(r0, GlobalObjectOperand());
++ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
+ __ mov(r2, Operand(var->name()));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+- __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
++ __ Call(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
+ context()->Plug(r0);
+ break;
+ }
+@@ -1840,7 +1841,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
+ if (var->IsUnallocated()) {
+ // Global var, const, or let.
__ mov(r2, Operand(var->name()));
- __ ldr(r1, GlobalObjectOperand());
+ __ ldr(r1, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
Handle<Code> ic = is_strict_mode()
? isolate()->builtins()->StoreIC_Initialize_Strict()
: 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,
- // Push the strict mode flag.
- __ mov(r1, Operand(Smi::FromInt(strict_mode_flag())));
+@@ -2141,10 +2142,13 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+ }
+ __ mov(r1, Operand(Smi::FromInt(strict_mode)));
__ push(r1);
+ // Push the qml mode flag.
+ __ mov(r1, Operand(Smi::FromInt(is_qml_mode())));
@@ -339,23 +335,41 @@ index 871b453..a69f10d 100644
}
-@@ -2263,9 +2267,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
+@@ -2217,9 +2221,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
context()->DropAndPlug(1, r0);
- } else if (var != NULL && !var->is_this() && var->is_global()) {
+ } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
// Push global object as receiver for the call IC.
- __ ldr(r0, GlobalObjectOperand());
-+ __ ldr(r0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
++ __ ldr(r0, proxy->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
__ push(r0);
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
+- EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT);
++ EmitCallWithIC(expr, proxy->name(), proxy->var()->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
+ } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
// Call to a lookup slot (dynamically introduced variable).
+ Label slow, done;
+@@ -3630,7 +3634,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
+ // but "delete this" is allowed.
+ ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
+ if (var->IsUnallocated()) {
+- __ ldr(r2, GlobalObjectOperand());
++ __ ldr(r2, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ mov(r1, Operand(var->name()));
+ __ mov(r0, Operand(Smi::FromInt(kNonStrictMode)));
+ __ Push(r2, r1, r0);
+@@ -3916,7 +3920,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
+ VariableProxy* proxy = expr->AsVariableProxy();
+ if (proxy != NULL && proxy->var()->IsUnallocated()) {
+ Comment cmnt(masm_, "Global variable");
+- __ ldr(r0, GlobalObjectOperand());
++ __ ldr(r0, proxy->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ mov(r2, Operand(proxy->name()));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ // Use a regular load, not a contextual load, to avoid a reference
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
-index 3f1d15b..8406a96 100644
+index 8495939..00582ea 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
-@@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1122,7 +1122,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
@@ -365,10 +379,10 @@ index 3f1d15b..8406a96 100644
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
-index 6da7c86..10b901f 100644
+index 73c7e45..49cdccc 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
-@@ -1378,13 +1378,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1301,13 +1301,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
public:
@@ -388,10 +402,10 @@ index 6da7c86..10b901f 100644
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
-index 4912449..db114ea 100644
+index f6750a2..63c8463 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
-@@ -166,12 +166,13 @@ bool LCodeGen::GeneratePrologue() {
+@@ -190,12 +190,13 @@ bool LCodeGen::GeneratePrologue() {
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
@@ -406,10 +420,10 @@ index 4912449..db114ea 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2664,7 +2665,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -2798,7 +2799,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
+
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
- Register context = ToRegister(instr->context());
Register result = ToRegister(instr->result());
- __ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ ldr(result, ContextOperand(cp, instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX));
@@ -417,10 +431,10 @@ index 4912449..db114ea 100644
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
-index ab5efb0..d40cdbc 100644
+index d42ccec..9adeb36 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
-@@ -1056,6 +1056,11 @@ static inline MemOperand GlobalObjectOperand() {
+@@ -1260,6 +1260,11 @@ static inline MemOperand GlobalObjectOperand() {
}
@@ -433,10 +447,10 @@ index ab5efb0..d40cdbc 100644
#define CODE_COVERAGE_STRINGIFY(x) #x
#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
diff --git a/src/ast-inl.h b/src/ast-inl.h
-index d80684a..adc5a1f 100644
+index 731ad2f..15702cf 100644
--- a/src/ast-inl.h
+++ b/src/ast-inl.h
-@@ -106,6 +106,11 @@ bool FunctionLiteral::strict_mode() const {
+@@ -116,6 +116,11 @@ bool FunctionLiteral::strict_mode() const {
}
@@ -449,22 +463,22 @@ index d80684a..adc5a1f 100644
#endif // V8_AST_INL_H_
diff --git a/src/ast.h b/src/ast.h
-index 65a25a9..f790dc0 100644
+index 00cfd7f..319d090 100644
--- a/src/ast.h
+++ b/src/ast.h
-@@ -1712,6 +1712,7 @@ class FunctionLiteral: public Expression {
- int end_position() const { return end_position_; }
+@@ -1658,6 +1658,7 @@ class FunctionLiteral: public Expression {
bool is_expression() const { return is_expression_; }
+ bool is_anonymous() const { return is_anonymous_; }
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
-index 56ef072..37e5383 100644
+index 9d4baf4..b7cac89 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
-@@ -303,7 +303,7 @@ class FastNewContextStub : public CodeStub {
+@@ -323,7 +323,7 @@ class FastNewContextStub : public CodeStub {
static const int kMaximumSlots = 64;
explicit FastNewContextStub(int slots) : slots_(slots) {
@@ -474,10 +488,10 @@ index 56ef072..37e5383 100644
void Generate(MacroAssembler* masm);
diff --git a/src/compiler.cc b/src/compiler.cc
-index 86d5de3..d2191b9 100755
+index 5a86b4e..596df4a 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
-@@ -462,7 +462,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+@@ -450,7 +450,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
v8::Extension* extension,
ScriptDataImpl* input_pre_data,
Handle<Object> script_data,
@@ -487,15 +501,15 @@ index 86d5de3..d2191b9 100755
Isolate* isolate = source->GetIsolate();
int source_length = source->length();
isolate->counters()->total_load_size()->Increment(source_length);
-@@ -523,6 +524,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+@@ -517,6 +518,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
info.MarkAsGlobal();
info.SetExtension(extension);
info.SetPreParseData(pre_data);
+ if (compile_flags & v8::Script::QmlMode) info.MarkAsQmlMode();
- if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
- result = MakeFunctionInfo(&info);
- if (extension == NULL && !result.is_null()) {
-@@ -543,7 +545,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+ if (natives == NATIVES_CODE) {
+ info.MarkAsAllowingNativesSyntax();
+ }
+@@ -539,7 +541,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
Handle<Context> context,
bool is_global,
@@ -505,7 +519,7 @@ index 86d5de3..d2191b9 100755
Isolate* isolate = source->GetIsolate();
int source_length = source->length();
isolate->counters()->total_eval_size()->Increment(source_length);
-@@ -567,6 +570,7 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
+@@ -563,6 +566,7 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
CompilationInfo info(script);
info.MarkAsEval();
if (is_global) info.MarkAsGlobal();
@@ -513,7 +527,7 @@ index 86d5de3..d2191b9 100755
if (strict_mode == kStrictMode) info.MarkAsStrictMode();
info.SetCallingContext(context);
result = MakeFunctionInfo(&info);
-@@ -610,6 +614,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
+@@ -607,6 +611,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
info->MarkAsStrictMode();
}
@@ -526,23 +540,23 @@ index 86d5de3..d2191b9 100755
// Compile the code.
if (!MakeCode(info)) {
if (!isolate->has_pending_exception()) {
-@@ -755,6 +765,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
+@@ -752,6 +762,7 @@ void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
*lit->this_property_assignments());
function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
function_info->set_strict_mode(lit->strict_mode());
+ function_info->set_qml_mode(lit->qml_mode());
+ function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
+ function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
}
-
-
diff --git a/src/compiler.h b/src/compiler.h
-index e75e869..17cd369 100644
+index 09aa23d..8eacb71 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -54,6 +54,7 @@ class CompilationInfo BASE_EMBEDDED {
- bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; }
- bool is_strict_mode() const { return (flags_ & IsStrictMode::mask()) != 0; }
- bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
-+ bool is_qml_mode() const { return (flags_ & IsQmlMode::mask()) != 0; }
+ bool is_global() const { return IsGlobal::decode(flags_); }
+ bool is_strict_mode() const { return IsStrictMode::decode(flags_); }
+ bool is_in_loop() const { return IsInLoop::decode(flags_); }
++ bool is_qml_mode() const { return IsQmlMode::decode(flags_); }
FunctionLiteral* function() const { return function_; }
Scope* scope() const { return scope_; }
Handle<Code> code() const { return code_; }
@@ -556,46 +570,33 @@ index e75e869..17cd369 100644
void MarkAsAllowingNativesSyntax() {
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()) {
-- MarkAsStrictMode();
-+ if (!shared_info_.is_null()) {
-+ if (shared_info_->strict_mode()) {
-+ MarkAsStrictMode();
-+ }
-+ if (shared_info_->qml_mode()) {
-+ MarkAsQmlMode();
-+ }
+@@ -180,6 +184,9 @@ class CompilationInfo BASE_EMBEDDED {
+ if (!shared_info_.is_null() && shared_info_->strict_mode()) {
+ MarkAsStrictMode();
}
++ if (!shared_info_.is_null() && shared_info_->qml_mode()) {
++ MarkAsQmlMode();
++ }
}
-@@ -187,6 +197,8 @@ class CompilationInfo BASE_EMBEDDED {
- class IsStrictMode: public BitField<bool, 4, 1> {};
- // Native syntax (%-stuff) allowed?
+ void SetMode(Mode mode) {
+@@ -203,7 +210,8 @@ class CompilationInfo BASE_EMBEDDED {
class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
+ // Is this a function from our natives.
+ class IsNative: public BitField<bool, 6, 1> {};
+-
+ // Qml mode
-+ class IsQmlMode: public BitField<bool, 6, 1> {};
++ class IsQmlMode: public BitField<bool, 7, 1> {};
unsigned flags_;
-@@ -252,13 +264,15 @@ class Compiler : public AllStatic {
+@@ -269,13 +277,15 @@ class Compiler : public AllStatic {
v8::Extension* extension,
ScriptDataImpl* pre_data,
Handle<Object> script_data,
- NativesFlag is_natives_code);
+ NativesFlag is_natives_code,
-+ v8::Script::CompileFlags compile_flags = v8::Script::Default);
++ v8::Script::CompileFlags = v8::Script::Default);
// Compile a String source within a context for Eval.
static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
@@ -608,10 +609,10 @@ index e75e869..17cd369 100644
// 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..035ac3b 100644
+index 007d30d..825493a 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
-@@ -89,6 +89,9 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
+@@ -103,6 +103,9 @@ Handle<Object> Context::Lookup(Handle<String> name,
PrintF(")\n");
}
@@ -621,8 +622,8 @@ index 520f3dd..035ac3b 100644
do {
if (FLAG_trace_contexts) {
PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
-@@ -119,6 +122,11 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
- }
+@@ -110,6 +113,11 @@ Handle<Object> Context::Lookup(Handle<String> name,
+ PrintF("\n");
}
+ if (qml_global.is_null() && !context->qml_global()->IsUndefined()) {
@@ -630,10 +631,10 @@ index 520f3dd..035ac3b 100644
+ qml_global_global = Handle<JSObject>(context->global(), isolate);
+ }
+
- if (context->is_function_context()) {
- // we have context-local slots
-
-@@ -198,6 +206,33 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
+ // 1. Check global objects, subjects of with, and extension objects.
+ if (context->IsGlobalContext() ||
+ context->IsWithContext() ||
+@@ -221,6 +229,33 @@ Handle<Object> Context::Lookup(Handle<String> name,
}
} while (follow_context_chain);
@@ -664,22 +665,22 @@ index 520f3dd..035ac3b 100644
+ }
+ }
+
- // slot not found
if (FLAG_trace_contexts) {
PrintF("=> no property/slot found\n");
+ }
diff --git a/src/contexts.h b/src/contexts.h
-index e46619e..57d8e7b 100644
+index b80475f..28ba69e 100644
--- a/src/contexts.h
+++ b/src/contexts.h
-@@ -182,6 +182,7 @@ class Context: public FixedArray {
- FCONTEXT_INDEX,
- PREVIOUS_INDEX,
+@@ -196,6 +196,7 @@ class Context: public FixedArray {
+ // contexts), eval extension object (function contexts), subject of with
+ // (with contexts), or the variable name (catch contexts).
EXTENSION_INDEX,
+ QML_GLOBAL_INDEX,
GLOBAL_INDEX,
MIN_CONTEXT_SLOTS,
-@@ -273,6 +274,9 @@ class Context: public FixedArray {
+@@ -297,6 +298,9 @@ class Context: public FixedArray {
}
void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
@@ -690,10 +691,10 @@ index e46619e..57d8e7b 100644
JSObject* global_proxy();
void set_global_proxy(JSObject* global);
diff --git a/src/execution.cc b/src/execution.cc
-index eb26438..1632076 100644
+index 2021c0f..c64c9ea 100644
--- a/src/execution.cc
+++ b/src/execution.cc
-@@ -70,7 +70,8 @@ static Handle<Object> Invoke(bool construct,
+@@ -71,7 +71,8 @@ static Handle<Object> Invoke(bool construct,
Handle<Object> receiver,
int argc,
Object*** args,
@@ -703,7 +704,7 @@ index eb26438..1632076 100644
Isolate* isolate = func->GetIsolate();
// Entering JavaScript.
-@@ -107,6 +108,12 @@ static Handle<Object> Invoke(bool construct,
+@@ -106,6 +107,12 @@ static Handle<Object> Invoke(bool construct,
// make the current one is indeed a global object.
ASSERT(func->context()->global()->IsGlobalObject());
@@ -716,7 +717,7 @@ index eb26438..1632076 100644
{
// Save and restore context around invocation and block the
// allocation of handles without explicit handle scopes.
-@@ -122,6 +129,9 @@ static Handle<Object> Invoke(bool construct,
+@@ -121,6 +128,9 @@ static Handle<Object> Invoke(bool construct,
receiver_pointer, argc, args);
}
@@ -726,21 +727,31 @@ index eb26438..1632076 100644
#ifdef DEBUG
value->Verify();
#endif
-@@ -150,14 +160,24 @@ Handle<Object> Execution::Call(Handle<JSFunction> func,
+@@ -149,7 +159,18 @@ Handle<Object> Execution::Call(Handle<Object> callable,
int argc,
Object*** args,
- bool* pending_exception) {
-- return Invoke(false, func, receiver, argc, args, pending_exception);
-+ return Invoke(false, func, receiver, argc, args, pending_exception, Handle<Object>());
+ bool* pending_exception,
+- bool convert_receiver) {
++ bool convert_receiver)
++{
++ return Call(callable, receiver, argc, args, pending_exception, convert_receiver, Handle<Object>());
+}
+
-+
-+Handle<Object> Execution::Call(Handle<JSFunction> func,
++Handle<Object> Execution::Call(Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Object*** args,
+ bool* pending_exception,
++ bool convert_receiver,
+ Handle<Object> qml) {
+ *pending_exception = false;
+
+ if (!callable->IsJSFunction()) {
+@@ -173,14 +194,14 @@ Handle<Object> Execution::Call(Handle<Object> callable,
+ if (*pending_exception) return callable;
+ }
+
+- return Invoke(false, func, receiver, argc, args, pending_exception);
+ return Invoke(false, func, receiver, argc, args, pending_exception, qml);
}
@@ -753,8 +764,8 @@ index eb26438..1632076 100644
}
-@@ -175,7 +195,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
- catcher.SetCaptureMessage(false);
+@@ -199,7 +220,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
+ *caught_exception = false;
Handle<Object> result = Invoke(false, func, receiver, argc, args,
- caught_exception);
@@ -763,36 +774,38 @@ index eb26438..1632076 100644
if (*caught_exception) {
ASSERT(catcher.HasCaught());
diff --git a/src/execution.h b/src/execution.h
-index d4b80d2..a476eb4 100644
+index 9fa6e78..baa58b5 100644
--- a/src/execution.h
+++ b/src/execution.h
-@@ -56,6 +56,12 @@ class Execution : public AllStatic {
- int argc,
- Object*** args,
- bool* pending_exception);
-+ static Handle<Object> Call(Handle<JSFunction> func,
+@@ -65,6 +65,14 @@ class Execution : public AllStatic {
+ bool* pending_exception,
+ bool convert_receiver = false);
+
++ static Handle<Object> Call(Handle<Object> callable,
+ Handle<Object> receiver,
+ int argc,
+ Object*** args,
+ bool* pending_exception,
++ bool convert_receiver,
+ Handle<Object> qml);
-
++
// Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns,
+ // pointers in 'args' might be invalid.
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
-index d6ba56e..2eaef0f 100644
+index e822588..516d237 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
-@@ -542,7 +542,7 @@ void FullCodeGenerator::VisitDeclarations(
- // Do nothing in case of no declared global functions or variables.
- if (globals > 0) {
+@@ -512,7 +512,7 @@ void FullCodeGenerator::VisitDeclarations(
+ // Batch declare global functions and variables.
+ if (global_count > 0) {
Handle<FixedArray> array =
-- isolate()->factory()->NewFixedArray(2 * globals, TENURED);
-+ isolate()->factory()->NewFixedArray(3 * globals, TENURED);
+- isolate()->factory()->NewFixedArray(2 * global_count, TENURED);
++ isolate()->factory()->NewFixedArray(3 * global_count, TENURED);
for (int j = 0, i = 0; i < length; i++) {
Declaration* decl = declarations->at(i);
Variable* var = decl->proxy()->var();
-@@ -567,6 +567,7 @@ void FullCodeGenerator::VisitDeclarations(
+@@ -536,6 +536,7 @@ void FullCodeGenerator::VisitDeclarations(
}
array->set(j++, *function);
}
@@ -801,42 +814,58 @@ index d6ba56e..2eaef0f 100644
}
// Invoke the platform-dependent code generator to do the actual
diff --git a/src/full-codegen.h b/src/full-codegen.h
-index d6ed1b9..e3241aa 100644
+index 6958dae..48753c5 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
-@@ -505,6 +505,7 @@ class FullCodeGenerator: public AstVisitor {
+@@ -581,6 +581,7 @@ class FullCodeGenerator: public AstVisitor {
StrictModeFlag strict_mode_flag() {
return is_strict_mode() ? kStrictMode : kNonStrictMode;
}
+ bool is_qml_mode() { return function()->qml_mode(); }
FunctionLiteral* function() { return info_->function(); }
- Scope* scope() { return info_->scope(); }
+ Scope* scope() { return scope_; }
diff --git a/src/heap.cc b/src/heap.cc
-index bf2940e..da958c2 100644
+index c730455..447dce1 100644
--- a/src/heap.cc
+++ b/src/heap.cc
-@@ -3795,6 +3795,7 @@ MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
- context->set_previous(NULL);
+@@ -4407,6 +4407,7 @@ MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
+ context->set_previous(function->context());
context->set_extension(NULL);
context->set_global(function->context()->global());
+ context->set_qml_global(function->context()->qml_global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(context->is_function_context());
- ASSERT(result->IsContext());
-@@ -3817,6 +3818,7 @@ MaybeObject* Heap::AllocateWithContext(Context* previous,
+ return context;
+ }
+
+@@ -4427,6 +4428,7 @@ MaybeObject* Heap::AllocateCatchContext(JSFunction* function,
+ context->set_previous(previous);
+ context->set_extension(name);
+ context->set_global(previous->global());
++ context->set_qml_global(previous->qml_global());
+ context->set(Context::THROWN_OBJECT_INDEX, thrown_object);
+ return context;
+ }
+@@ -4445,6 +4447,7 @@ MaybeObject* Heap::AllocateWithContext(JSFunction* function,
context->set_previous(previous);
context->set_extension(extension);
context->set_global(previous->global());
+ context->set_qml_global(previous->qml_global());
- ASSERT(!context->IsGlobalContext());
- ASSERT(!context->is_function_context());
- ASSERT(result->IsContext());
+ return context;
+ }
+
+@@ -4463,6 +4466,7 @@ MaybeObject* Heap::AllocateBlockContext(JSFunction* function,
+ context->set_previous(previous);
+ context->set_extension(scope_info);
+ context->set_global(previous->global());
++ context->set_qml_global(previous->qml_global());
+ return context;
+ }
+
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
-index a623775..52455bc 100644
+index 6b43f53..d0e6fb0 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
-@@ -1148,7 +1148,7 @@ class HOuterContext: public HUnaryOperation {
+@@ -1394,7 +1394,7 @@ class HOuterContext: public HUnaryOperation {
class HGlobalObject: public HUnaryOperation {
public:
@@ -845,7 +874,7 @@ index a623775..52455bc 100644
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
}
-@@ -1159,8 +1159,14 @@ class HGlobalObject: public HUnaryOperation {
+@@ -1405,8 +1405,14 @@ class HGlobalObject: public HUnaryOperation {
return Representation::Tagged();
}
@@ -860,61 +889,50 @@ index a623775..52455bc 100644
};
-@@ -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; }
- };
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
-index 73ea97d..d17e304 100644
+index 64a6ae5..f0c1763 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
-@@ -2918,6 +2918,7 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
- HContext* context = new(zone()) HContext;
- AddInstruction(context);
- HGlobalObject* global_object = new(zone()) HGlobalObject(context);
-+ if (variable->is_qml_global()) global_object->set_qml_global(true);
- AddInstruction(global_object);
- HLoadGlobalGeneric* instr =
- new(zone()) HLoadGlobalGeneric(context,
-@@ -3307,6 +3308,7 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
- HContext* context = new(zone()) HContext;
- AddInstruction(context);
+@@ -3174,6 +3174,7 @@ void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
+ } else {
+ HValue* context = environment()->LookupContext();
+ HGlobalObject* global_object = new(zone()) HGlobalObject(context);
++ if (variable->is_qml_global()) global_object->set_qml_global(true);
+ AddInstruction(global_object);
+ HLoadGlobalGeneric* instr =
+ new(zone()) HLoadGlobalGeneric(context,
+@@ -3640,6 +3641,7 @@ void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
+ } else {
+ HValue* context = environment()->LookupContext();
HGlobalObject* global_object = new(zone()) HGlobalObject(context);
+ if (var->is_qml_global()) global_object->set_qml_global(true);
AddInstruction(global_object);
HStoreGlobalGeneric* instr =
new(zone()) HStoreGlobalGeneric(context,
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
-index 5d32095..afa599e 100644
+index 1ca577c..6cc80d3 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
-@@ -147,6 +147,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
- __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
+@@ -143,6 +143,11 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
+ __ mov(ebx, Operand(esi, 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).
-+ __ mov(ebx, FieldOperand(ecx, JSFunction::kContextOffset));
-+ __ mov(ebx, Operand(ebx, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
++ // Copy the qml global object from the previous context.
++ __ mov(ebx, Operand(esi, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
+ __ mov(Operand(eax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), ebx);
+
++
// Initialize the rest of the slots to undefined.
__ mov(ebx, factory->undefined_value());
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
-index 5d153a8..0ddcde2 100644
+index d45a9cd..a5883a2 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
-@@ -142,12 +142,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
+@@ -178,12 +178,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+ int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
+ if (heap_slots > 0 ||
+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
@@ -926,50 +944,45 @@ index 5d153a8..0ddcde2 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1107,10 +1108,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -1152,10 +1153,10 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
// All extension objects were empty and it is safe to use a global
// load IC call.
- __ mov(eax, GlobalObjectOperand());
-+ __ mov(eax, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(ecx, slot->var()->name());
++ __ mov(eax, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
+ __ mov(ecx, var->name());
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
++ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || var->is_qml_global())
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
- EmitCallIC(ic, mode);
-@@ -1214,10 +1215,10 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- Comment cmnt(masm_, "Global variable");
- // Use inline caching. Variable name is passed in ecx and the global
- // object on the stack.
-- __ mov(eax, GlobalObjectOperand());
-+ __ mov(eax, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
- __ mov(ecx, var->name());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- 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
- // ecx, and the global object on the stack.
+ __ call(ic, mode);
+@@ -1229,10 +1230,10 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+ Comment cmnt(masm_, "Global variable");
+ // Use inline caching. Variable name is passed in ecx and the global
+ // object in eax.
+- __ mov(eax, GlobalObjectOperand());
++ __ mov(eax, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
+ __ mov(ecx, var->name());
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+- __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
++ __ call(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
+ context()->Plug(eax);
+ break;
+ }
+@@ -1833,7 +1834,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
+ if (var->IsUnallocated()) {
+ // Global var, const, or let.
__ mov(ecx, var->name());
- __ mov(edx, GlobalObjectOperand());
+ __ mov(edx, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
Handle<Code> ic = is_strict_mode()
? isolate()->builtins()->StoreIC_Initialize_Strict()
: 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())));
+@@ -2147,9 +2148,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+ }
+ __ push(Immediate(Smi::FromInt(strict_mode)));
+ // Push the qml mode flag
+ __ push(Immediate(Smi::FromInt(is_qml_mode())));
@@ -981,22 +994,41 @@ index 5d153a8..0ddcde2 100644
}
-@@ -2188,8 +2192,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
- context()->DropAndPlug(1, eax);
- } else if (var != NULL && !var->is_this() && var->is_global()) {
+@@ -2220,9 +2224,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
+
+ } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
// Push global object as receiver for the call IC.
- __ push(GlobalObjectOperand());
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ __ push(var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
++ __ push(proxy->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
+ increment_stack_height();
+- EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT);
++ EmitCallWithIC(expr, proxy->name(), proxy->var()->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
+
+ } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
// Call to a lookup slot (dynamically introduced variable).
+@@ -3688,7 +3692,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
+ // but "delete this" is allowed.
+ ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
+ if (var->IsUnallocated()) {
+- __ push(GlobalObjectOperand());
++ __ push(var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ push(Immediate(var->name()));
+ __ push(Immediate(Smi::FromInt(kNonStrictMode)));
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+@@ -3996,7 +4000,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
+
+ if (proxy != NULL && proxy->var()->IsUnallocated()) {
+ Comment cmnt(masm_, "Global variable");
+- __ mov(eax, GlobalObjectOperand());
++ __ mov(eax, proxy->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ mov(ecx, Immediate(proxy->name()));
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ // Use a regular load, not a contextual load, to avoid a reference
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
-index 0f96f78..c1da075 100644
+index 9e1fd34..1abcdd3 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
-@@ -159,12 +159,13 @@ bool LCodeGen::GeneratePrologue() {
+@@ -211,12 +211,13 @@ bool LCodeGen::GeneratePrologue() {
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
@@ -1011,8 +1043,8 @@ index 0f96f78..c1da075 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2525,7 +2526,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -2635,7 +2636,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register context = ToRegister(instr->context());
Register result = ToRegister(instr->result());
@@ -1022,10 +1054,10 @@ index 0f96f78..c1da075 100644
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
-index 9ccd189..8e98b73 100644
+index 856106c..0b058e6 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
-@@ -1205,7 +1205,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1138,7 +1138,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
@@ -1035,10 +1067,10 @@ index 9ccd189..8e98b73 100644
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
-index 9ace8f8..95ed001 100644
+index 3a06ac3..087d5cb 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
-@@ -1416,13 +1416,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1336,13 +1336,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
public:
@@ -1058,82 +1090,69 @@ index 9ace8f8..95ed001 100644
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
-index b986264..f8479ae 100644
+index a1b42c2..7a64b9a 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
-@@ -778,6 +778,11 @@ static inline Operand GlobalObjectOperand() {
+@@ -931,6 +931,9 @@ static inline Operand GlobalObjectOperand() {
+ return ContextOperand(esi, Context::GLOBAL_INDEX);
}
-
+static inline Operand QmlGlobalObjectOperand() {
+ return ContextOperand(esi, Context::QML_GLOBAL_INDEX);
+}
-+
-+
+
// 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
+index 36af868..375df0f 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);
-+}
-+
-+
-+void SharedFunctionInfo::set_qml_mode(bool value) {
-+ set_compiler_hints(BooleanBit::set(compiler_hints(),
-+ kQmlModeFunction,
-+ value));
-+}
-+
-+
- ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
- ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
-
+@@ -3615,6 +3615,8 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) {
+
+ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
+ kStrictModeFunction)
++BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, qml_mode,
++ kQmlModeFunction)
+ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
+ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
+ name_should_print_as_anonymous,
diff --git a/src/objects.h b/src/objects.h
-index 1bdb5c7..edbc47a 100644
+index dea5bbd..71895be 100644
--- a/src/objects.h
+++ b/src/objects.h
-@@ -4331,6 +4331,10 @@ class SharedFunctionInfo: public HeapObject {
- inline bool strict_mode();
- inline void set_strict_mode(bool value);
+@@ -4725,6 +4725,9 @@ class SharedFunctionInfo: public HeapObject {
+ // Indicates whether the function is a strict mode function.
+ DECL_BOOLEAN_ACCESSORS(strict_mode)
-+ // Indicates whether the function is a qml mode function
-+ inline bool qml_mode();
-+ inline void set_qml_mode(bool value);
++ // Indicates whether the function is a qml mode function.
++ DECL_BOOLEAN_ACCESSORS(qml_mode)
+
- // Indicates whether or not the code in the shared function support
- // deoptimization.
- inline bool has_deoptimization_support();
-@@ -4511,6 +4515,7 @@ class SharedFunctionInfo: public HeapObject {
- static const int kCodeAgeMask = 0x7;
- static const int kOptimizationDisabled = 6;
- static const int kStrictModeFunction = 7;
-+ static const int kQmlModeFunction = 8;
-
- private:
- #if V8_HOST_ARCH_32_BIT
+ // False if the function definitely does not allocate an arguments object.
+ DECL_BOOLEAN_ACCESSORS(uses_arguments)
+
+@@ -4939,6 +4942,7 @@ class SharedFunctionInfo: public HeapObject {
+ kCodeAgeShift,
+ kOptimizationDisabled = kCodeAgeShift + kCodeAgeSize,
+ kStrictModeFunction,
++ kQmlModeFunction,
+ kUsesArguments,
+ kHasDuplicateParameters,
+ kNative,
diff --git a/src/parser.cc b/src/parser.cc
-index a84ec6f..7f5c361 100644
+index ad8850e..a9af8eb 100644
--- a/src/parser.cc
+++ b/src/parser.cc
-@@ -593,7 +593,8 @@ Parser::Parser(Handle<Script> script,
+@@ -594,7 +594,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);
+ ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(isolate()->counters()->parse());
-@@ -609,11 +610,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
+@@ -610,11 +611,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
ExternalTwoByteStringUC16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source), 0, source->length());
scanner_.Initialize(&stream);
@@ -1147,7 +1166,7 @@ index a84ec6f..7f5c361 100644
}
}
-@@ -621,6 +622,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
+@@ -622,6 +623,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
bool in_global_context,
StrictModeFlag strict_mode,
@@ -1155,17 +1174,17 @@ index a84ec6f..7f5c361 100644
ZoneScope* zone_scope) {
ASSERT(target_stack_ == NULL);
if (pre_data_ != NULL) pre_data_->Initialize();
-@@ -641,6 +643,9 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
+@@ -642,6 +644,9 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
if (strict_mode == kStrictMode) {
top_scope_->EnableStrictMode();
}
+ if (qml_mode) {
+ scope->EnableQmlMode();
+ }
- ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
+ ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
bool ok = true;
int beg_loc = scanner().location().beg_pos;
-@@ -729,6 +734,9 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
+@@ -736,6 +741,9 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
if (shared_info->strict_mode()) {
top_scope_->EnableStrictMode();
}
@@ -1173,9 +1192,9 @@ index a84ec6f..7f5c361 100644
+ top_scope_->EnableQmlMode();
+ }
- FunctionLiteralType type =
- shared_info->is_expression() ? EXPRESSION : DECLARATION;
-@@ -1661,6 +1669,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
+ FunctionLiteral::Type type = shared_info->is_expression()
+ ? (shared_info->is_anonymous()
+@@ -1806,6 +1814,11 @@ Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
arguments->Add(value);
value = NULL; // zap the value to avoid the unnecessary assignment
@@ -1187,9 +1206,9 @@ index a84ec6f..7f5c361 100644
// Construct the call to Runtime_InitializeConstGlobal
// and add it to the initialization statement block.
// Note that the function does different things depending on
-@@ -1676,6 +1689,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
- arguments->Add(NewNumberLiteral(
- top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
+@@ -1824,6 +1837,11 @@ Block* Parser::ParseVariableDeclarations(VariableDeclarationContext var_context,
+ : kNonStrictMode;
+ arguments->Add(NewNumberLiteral(flag));
+ int qml_mode = 0;
+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
@@ -1199,7 +1218,7 @@ index a84ec6f..7f5c361 100644
// Be careful not to assign a value to the global variable if
// we're in a with. The initialization value should not
// necessarily be stored in the global object in that case,
-@@ -5157,7 +5175,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
+@@ -5217,7 +5235,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
Handle<String> source = Handle<String>(String::cast(script->source()));
result = parser.ParseProgram(source,
info->is_global(),
@@ -1208,12 +1227,12 @@ index a84ec6f..7f5c361 100644
+ info->is_qml_mode());
}
}
-
+ info->SetFunction(result);
diff --git a/src/parser.h b/src/parser.h
-index 64f1303..4d45e45 100644
+index d834ed1..d88d1ef 100644
--- a/src/parser.h
+++ b/src/parser.h
-@@ -431,7 +431,8 @@ class Parser {
+@@ -426,7 +426,8 @@ class Parser {
// Returns NULL if parsing failed.
FunctionLiteral* ParseProgram(Handle<String> source,
bool in_global_context,
@@ -1223,7 +1242,7 @@ index 64f1303..4d45e45 100644
FunctionLiteral* ParseLazy(CompilationInfo* info);
-@@ -464,6 +465,7 @@ class Parser {
+@@ -466,6 +467,7 @@ class Parser {
FunctionLiteral* DoParseProgram(Handle<String> source,
bool in_global_context,
StrictModeFlag strict_mode,
@@ -1232,10 +1251,10 @@ index 64f1303..4d45e45 100644
// Report syntax error
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
-index c777ab4..1964e02 100644
+index 37c76ce..73812fd 100644
--- a/src/prettyprinter.cc
+++ b/src/prettyprinter.cc
-@@ -656,6 +656,9 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info,
+@@ -618,6 +618,9 @@ void AstPrinter::PrintLiteralWithModeIndented(const char* info,
EmbeddedVector<char, 256> buf;
int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
Variable::Mode2String(var->mode()));
@@ -1246,30 +1265,23 @@ index c777ab4..1964e02 100644
PrintLiteralIndented(buf.start(), value, true);
}
diff --git a/src/runtime.cc b/src/runtime.cc
-index 660352c..c13f92d 100644
+index 5a850e9..0388a77 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
-@@ -1065,8 +1065,6 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,
+@@ -1213,19 +1213,23 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,
RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
- ASSERT(args.length() == 4);
+ ASSERT(args.length() == 3);
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);
+ CONVERT_SMI_ARG_CHECKED(flags, 2);
+ Handle<JSObject> js_global = Handle<JSObject>(isolate->context()->global());
+ Handle<JSObject> qml_global = Handle<JSObject>(isolate->context()->qml_global());
+
- // Compute the property attributes. According to ECMA-262, section
- // 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) {
@@ -1283,7 +1295,7 @@ index 660352c..c13f92d 100644
// 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) {
+@@ -1414,19 +1418,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
NoHandleAllocation nha;
// args[0] == name
// args[1] == strict_mode
@@ -1301,8 +1313,7 @@ index 660352c..c13f92d 100644
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());
+ StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1));
ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
+ RUNTIME_ASSERT(args[2]->IsSmi());
@@ -1313,37 +1324,19 @@ index 660352c..c13f92d 100644
// According to ECMA-262, section 12.2, page 62, the property must
// not be deletable.
PropertyAttributes attributes = DONT_DELETE;
-@@ -1350,7 +1359,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- if (lookup.IsReadOnly()) {
- // If we found readonly property on one of hidden prototypes,
- // just shadow it.
-- if (real_holder != isolate->context()->global()) break;
-+ 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
- // on one of hidden prototypes, just shadow it.
-- if (real_holder != isolate->context()->global()) break;
-+ if (real_holder != global) break;
- return ThrowRedeclarationError(isolate, "const", name);
+@@ -1454,7 +1463,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+ // Found an interceptor that's not read only.
+ if (assign) {
+ return raw_holder->SetProperty(
+- &lookup, *name, args[2], attributes, strict_mode);
++ &lookup, *name, args[3], attributes, strict_mode);
+ } else {
+ return isolate->heap()->undefined_value();
}
- }
-@@ -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();
- return real_holder->SetProperty(
- &lookup, *name, value, attributes, strict_mode);
- }
-@@ -1399,9 +1408,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
- real_holder = JSObject::cast(proto);
+@@ -1464,9 +1473,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
}
+ // Reload global in case the loop above performed a GC.
- global = isolate->context()->global();
+ global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
if (assign) {
@@ -1352,7 +1345,7 @@ index 660352c..c13f92d 100644
}
return isolate->heap()->undefined_value();
}
-@@ -1411,12 +1420,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
+@@ -1476,12 +1485,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
// All constants are declared with an initial value. The name
// of the constant is the first argument and the initial value
// is the second.
@@ -1370,16 +1363,16 @@ index 660352c..c13f92d 100644
// 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) {
- // with setting the value because the property is either absent or
- // read-only. We also have to do redo the lookup.
+@@ -1505,7 +1517,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
+ // Restore global object from context (in case of GC) and continue
+ // with setting the value.
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) {
+@@ -9204,7 +9216,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
context,
true,
@@ -1389,26 +1382,27 @@ index 660352c..c13f92d 100644
if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> fun =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
-@@ -8173,14 +8186,16 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
+@@ -9217,7 +9230,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
static ObjectPair CompileGlobalEval(Isolate* isolate,
Handle<String> source,
Handle<Object> receiver,
- StrictModeFlag strict_mode) {
-+ StrictModeFlag strict_mode,
++ StrictModeFlag strict_mode,
+ bool qml_mode) {
- // Deal with a normal eval call with a string argument. Compile it
- // and return the compiled function bound in the local context.
- Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
+ Handle<Context> context = Handle<Context>(isolate->context());
+ Handle<Context> global_context = Handle<Context>(context->global_context());
+
+@@ -9235,7 +9249,8 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
source,
Handle<Context>(isolate->context()),
- isolate->context()->IsGlobalContext(),
+ 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,
+@@ -9245,7 +9260,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
@@ -1417,7 +1411,7 @@ index 660352c..c13f92d 100644
HandleScope scope(isolate);
Handle<Object> callee = args.at<Object>(0);
-@@ -8257,16 +8272,18 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
+@@ -9308,15 +9323,17 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
}
ASSERT(args[3]->IsSmi());
@@ -1425,9 +1419,8 @@ index 660352c..c13f92d 100644
return CompileGlobalEval(isolate,
args.at<String>(1),
args.at<Object>(2),
- static_cast<StrictModeFlag>(
-- Smi::cast(args[3])->value()));
-+ Smi::cast(args[3])->value()),
+- static_cast<StrictModeFlag>(args.smi_at(3)));
++ static_cast<StrictModeFlag>(args.smi_at(3)),
+ Smi::cast(args[4])->value());
}
@@ -1438,7 +1431,7 @@ index 660352c..c13f92d 100644
HandleScope scope(isolate);
Handle<Object> callee = args.at<Object>(0);
-@@ -8280,11 +8297,13 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
+@@ -9329,10 +9346,12 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
}
ASSERT(args[3]->IsSmi());
@@ -1446,14 +1439,13 @@ index 660352c..c13f92d 100644
return CompileGlobalEval(isolate,
args.at<String>(1),
args.at<Object>(2),
- static_cast<StrictModeFlag>(
-- Smi::cast(args[3])->value()));
-+ Smi::cast(args[3])->value()),
+- static_cast<StrictModeFlag>(args.smi_at(3)));
++ static_cast<StrictModeFlag>(args.smi_at(3)),
+ Smi::cast(args[4])->value());
}
-@@ -10570,6 +10589,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+@@ -11771,6 +11790,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);
@@ -1461,7 +1453,7 @@ index 660352c..c13f92d 100644
// Traverse the saved contexts chain to find the active context for the
// selected frame.
-@@ -10633,7 +10653,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+@@ -11840,7 +11860,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Compiler::CompileEval(function_source,
context,
context->IsGlobalContext(),
@@ -1471,17 +1463,17 @@ index 660352c..c13f92d 100644
if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
-@@ -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,
+@@ -11850,7 +11871,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+ Handle<Object> receiver(frame->receiver(), isolate);
+ Handle<Object> evaluation_function =
+ Execution::Call(compiled_function, receiver, 0, NULL,
+- &has_pending_exception);
++ &has_pending_exception, false,
+ 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) {
+ Handle<Object> arguments = GetArgumentsObject(isolate,
+@@ -11930,7 +11952,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 =
@@ -1491,10 +1483,10 @@ index 660352c..c13f92d 100644
Handle<JSFunction> compiled_function =
Handle<JSFunction>(
diff --git a/src/runtime.h b/src/runtime.h
-index bf1ba68..5e97173 100644
+index c6f7773..284f723 100644
--- a/src/runtime.h
+++ b/src/runtime.h
-@@ -241,8 +241,8 @@ namespace internal {
+@@ -257,8 +257,8 @@ namespace internal {
\
/* Eval */ \
F(GlobalReceiver, 1, 1) \
@@ -1505,9 +1497,9 @@ index bf1ba68..5e97173 100644
\
F(SetProperty, -1 /* 4 or 5 */, 1) \
F(DefineOrRedefineDataProperty, 4, 1) \
-@@ -296,8 +296,8 @@ namespace internal {
+@@ -325,8 +325,8 @@ namespace internal {
/* Declarations and initialization */ \
- F(DeclareGlobals, 4, 1) \
+ F(DeclareGlobals, 3, 1) \
F(DeclareContextSlot, 4, 1) \
- F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \
- F(InitializeConstGlobal, 2, 1) \
@@ -1517,18 +1509,27 @@ index bf1ba68..5e97173 100644
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
\
diff --git a/src/scopes.cc b/src/scopes.cc
-index 8df93c5..b5d7ff3 100644
+index d5a7a9f..25921fa 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
-@@ -198,6 +198,7 @@ void Scope::SetDefaults(Type type,
+@@ -35,6 +35,8 @@
+
+ #include "allocation-inl.h"
+
++#include "debug.h"
++
+ namespace v8 {
+ namespace internal {
+
+@@ -202,6 +204,7 @@ void Scope::SetDefaults(Type type,
scope_calls_eval_ = false;
// Inherit the strict mode from the parent scope.
strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_;
+ qml_mode_ = (outer_scope != NULL) && outer_scope->qml_mode_;
outer_scope_calls_eval_ = false;
+ outer_scope_calls_non_strict_eval_ = false;
inner_scope_calls_eval_ = false;
- outer_scope_is_eval_scope_ = false;
-@@ -796,6 +797,25 @@ void Scope::ResolveVariable(Scope* global_scope,
+@@ -923,6 +926,25 @@ void Scope::ResolveVariable(Scope* global_scope,
ASSERT(global_scope != NULL);
var = global_scope->DeclareGlobal(proxy->name());
@@ -1554,7 +1555,7 @@ index 8df93c5..b5d7ff3 100644
} else if (scope_inside_with_) {
// If we are inside a with statement we give up and look up
// the variable at runtime.
-@@ -817,6 +837,25 @@ void Scope::ResolveVariable(Scope* global_scope,
+@@ -944,6 +966,25 @@ void Scope::ResolveVariable(Scope* global_scope,
if (context->GlobalIfNotShadowedByEval(proxy->name())) {
var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
@@ -1580,7 +1581,7 @@ index 8df93c5..b5d7ff3 100644
} else {
var = NonLocal(proxy->name(), Variable::DYNAMIC);
}
-@@ -827,6 +866,26 @@ void Scope::ResolveVariable(Scope* global_scope,
+@@ -954,6 +995,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);
@@ -1608,10 +1609,10 @@ index 8df93c5..b5d7ff3 100644
}
}
diff --git a/src/scopes.h b/src/scopes.h
-index a0e56a4..6dd3f65 100644
+index 2917a63..0f1ed6d 100644
--- a/src/scopes.h
+++ b/src/scopes.h
-@@ -210,6 +210,11 @@ class Scope: public ZoneObject {
+@@ -206,6 +206,11 @@ class Scope: public ZoneObject {
strict_mode_ = FLAG_strict_mode;
}
@@ -1623,28 +1624,29 @@ 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; }
+@@ -216,6 +221,7 @@ class Scope: public ZoneObject {
+ bool is_catch_scope() const { return type_ == CATCH_SCOPE; }
+ bool is_block_scope() const { return type_ == BLOCK_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 {
- bool scope_contains_with_; // this scope contains a 'with' statement
- 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
+ bool is_strict_mode_eval_scope() const {
+ return is_eval_scope() && is_strict_mode();
+ }
+@@ -381,6 +387,8 @@ class Scope: public ZoneObject {
+ bool scope_calls_eval_;
+ // This scope is a strict mode scope.
+ bool strict_mode_;
++ // This scope is a qml mode scope.
++ bool qml_mode_;
// Computed via PropagateScopeInfo.
bool outer_scope_calls_eval_;
diff --git a/src/variables.cc b/src/variables.cc
-index 0502722..190baf6 100644
+index 971061b..da07620 100644
--- a/src/variables.cc
+++ b/src/variables.cc
-@@ -99,7 +99,8 @@ Variable::Variable(Scope* scope,
- rewrite_(NULL),
+@@ -67,7 +67,8 @@ Variable::Variable(Scope* scope,
+ local_if_not_shadowed_(NULL),
is_valid_LHS_(is_valid_LHS),
is_accessed_from_inner_scope_(false),
- is_used_(false) {
@@ -1654,19 +1656,19 @@ index 0502722..190baf6 100644
ASSERT(name->IsSymbol());
}
diff --git a/src/variables.h b/src/variables.h
-index b1ff0db..0b31d1a 100644
+index 56c8dab..4d27f98 100644
--- a/src/variables.h
+++ b/src/variables.h
-@@ -141,6 +141,8 @@ class Variable: public ZoneObject {
- Expression* rewrite() const { return rewrite_; }
- void set_rewrite(Expression* expr) { rewrite_ = expr; }
+@@ -174,6 +174,8 @@ class Variable: public ZoneObject {
+ index_ = index;
+ }
+ 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:
Scope* scope_;
Handle<String> name_;
-@@ -159,6 +161,9 @@ class Variable: public ZoneObject {
+@@ -190,6 +192,9 @@ class Variable: public ZoneObject {
// Usage info.
bool is_accessed_from_inner_scope_; // set by variable resolver
bool is_used_;
@@ -1677,14 +1679,14 @@ index b1ff0db..0b31d1a 100644
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
-index c365385..d923494 100644
+index 8d9dba7..6ab12fc 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
-@@ -140,6 +140,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
+@@ -139,6 +139,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.
++ // Copy the qmlglobal object from the previous context.
+ __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
+ __ movq(Operand(rax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), rbx);
+
@@ -1692,15 +1694,15 @@ index c365385..d923494 100644
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) {
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
-index 97168cd..c45cdb6 100644
+index 1d9b8ff..08b3872 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
-@@ -141,12 +141,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
+@@ -173,12 +173,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
// Possibly allocate a local context.
- int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+ int heap_slots = info->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.
@@ -1710,49 +1712,44 @@ index 97168cd..c45cdb6 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -1119,10 +1120,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -1129,10 +1130,10 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
// All extension objects were empty and it is safe to use a global
// load IC call.
- __ movq(rax, GlobalObjectOperand());
-+ __ movq(rax, slot->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
- __ Move(rcx, slot->var()->name());
++ __ movq(rax, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ Move(rcx, var->name());
Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
-+ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || slot->var()->is_qml_global())
++ RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF || var->is_qml_global())
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
- EmitCallIC(ic, mode);
-@@ -1227,9 +1228,9 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var) {
- // Use inline caching. Variable name is passed in rcx and the global
- // object on the stack.
- __ Move(rcx, var->name());
-- __ movq(rax, GlobalObjectOperand());
-+ __ movq(rax, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
- Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
-- 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
- // rcx, and the global object on the stack.
+ __ call(ic, mode);
+@@ -1207,9 +1208,9 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+ // Use inline caching. Variable name is passed in rcx and the global
+ // object on the stack.
+ __ Move(rcx, var->name());
+- __ movq(rax, GlobalObjectOperand());
++ __ movq(rax, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+- __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
++ __ call(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
+ context()->Plug(rax);
+ break;
+ }
+@@ -1750,7 +1751,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
+ if (var->IsUnallocated()) {
+ // Global var, const, or let.
__ Move(rcx, var->name());
- __ movq(rdx, GlobalObjectOperand());
+ __ movq(rdx, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
Handle<Code> ic = is_strict_mode()
? isolate()->builtins()->StoreIC_Initialize_Strict()
: 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()));
+@@ -2034,9 +2035,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+ }
+ __ Push(Smi::FromInt(strict_mode));
+ // Push the qml mode flag
+ __ Push(Smi::FromInt(is_qml_mode()));
@@ -1764,22 +1761,40 @@ index 97168cd..c45cdb6 100644
}
-@@ -2160,8 +2164,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
- } else if (var != NULL && !var->is_this() && var->is_global()) {
- // Call to a global variable.
- // Push global object as receiver for the call IC lookup.
+@@ -2105,8 +2109,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
+ } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
+ // Call to a global variable. Push global object as receiver for the
+ // call IC lookup.
- __ push(GlobalObjectOperand());
-- EmitCallWithIC(expr, var->name(), RelocInfo::CODE_TARGET_CONTEXT);
-+ __ push(var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
-+ EmitCallWithIC(expr, var->name(), var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
- } else if (var != NULL && var->AsSlot() != NULL &&
- var->AsSlot()->type() == Slot::LOOKUP) {
+- EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT);
++ __ push(proxy->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
++ EmitCallWithIC(expr, proxy->name(), proxy->var()->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
+ } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
// Call to a lookup slot (dynamically introduced variable).
+ Label slow, done;
+@@ -3552,7 +3556,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
+ // but "delete this" is allowed.
+ ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this());
+ if (var->IsUnallocated()) {
+- __ push(GlobalObjectOperand());
++ __ push(var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ __ Push(var->name());
+ __ Push(Smi::FromInt(kNonStrictMode));
+ __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+@@ -3850,7 +3854,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
+ if (proxy != NULL && proxy->var()->IsUnallocated()) {
+ Comment cmnt(masm_, "Global variable");
+ __ Move(rcx, proxy->name());
+- __ movq(rax, GlobalObjectOperand());
++ __ movq(rax, proxy->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand());
+ Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
+ // Use a regular load, not a contextual load, to avoid a reference
+ // error.
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
-index 202e7a2..45acbdf 100644
+index 45aaad7..08050f0 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
-@@ -174,12 +174,13 @@ bool LCodeGen::GeneratePrologue() {
+@@ -196,12 +196,13 @@ bool LCodeGen::GeneratePrologue() {
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
@@ -1794,8 +1809,8 @@ index 202e7a2..45acbdf 100644
+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kNewContext, 1);
-@@ -2540,7 +2541,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
+@@ -2581,7 +2582,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register result = ToRegister(instr->result());
@@ -1805,10 +1820,10 @@ index 202e7a2..45acbdf 100644
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
-index 07ca3a5..00feeac 100644
+index a67a593..a243fef 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
-@@ -1194,7 +1194,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1117,7 +1117,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
@@ -1818,10 +1833,10 @@ index 07ca3a5..00feeac 100644
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
-index 15bb894..16f754c 100644
+index d43a86a..cf89181 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
-@@ -1365,7 +1365,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1301,7 +1301,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
public:
@@ -1836,10 +1851,10 @@ index 15bb894..16f754c 100644
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
-index 4c17720..aa284ed 100644
+index 7e0ba00..744ce20 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
-@@ -1233,6 +1233,11 @@ static inline Operand GlobalObjectOperand() {
+@@ -1413,6 +1413,11 @@ static inline Operand GlobalObjectOperand() {
}
diff --git a/src/v8/0006-Allow-access-to-the-calling-script-data.patch b/src/v8/0005-Allow-access-to-the-calling-script-data.patch
index 356142d654..a8cdc1dd54 100644
--- a/src/v8/0006-Allow-access-to-the-calling-script-data.patch
+++ b/src/v8/0005-Allow-access-to-the-calling-script-data.patch
@@ -1,7 +1,7 @@
-From 1209b88e96f253cdc19aa4c95e011c84597844f0 Mon Sep 17 00:00:00 2001
+From 2608243d70a8fcb0335f3520d5de1ac3cd854e87 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
+Date: Fri, 14 Oct 2011 17:03:06 +1000
+Subject: [PATCH 05/11] Allow access to the calling script data
---
include/v8.h | 1 +
@@ -9,10 +9,10 @@ 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 d78ab1f..2bc0ed1 100644
+index 193e2fe..c094d08 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -3337,6 +3337,7 @@ class V8EXPORT Context {
+@@ -3517,6 +3517,7 @@ class V8EXPORT Context {
*/
static Local<Context> GetCalling();
static Local<Object> GetCallingQmlGlobal();
@@ -21,10 +21,10 @@ index d78ab1f..2bc0ed1 100644
/**
* Sets the security token for the context. To access an object in
diff --git a/src/api.cc b/src/api.cc
-index 39767f4..ff74efb 100644
+index fd718c8..526aa02 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -3976,6 +3976,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
+@@ -4361,6 +4361,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
}
}
diff --git a/src/v8/0008-Add-custom-object-compare-callback.patch b/src/v8/0006-Add-custom-object-compare-callback.patch
index 125668805e..f024009d41 100644
--- a/src/v8/0008-Add-custom-object-compare-callback.patch
+++ b/src/v8/0006-Add-custom-object-compare-callback.patch
@@ -1,7 +1,7 @@
-From a7c491e6e533110a17fe9f7d47cf92a1b2263180 Mon Sep 17 00:00:00 2001
+From 1c747846df3be9021aff2b0fc402cdd3a239e86b 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
+Date: Wed, 25 May 2011 10:36:13 +1000
+Subject: [PATCH 06/11] Add custom object compare callback
A global custom object comparison callback can be set with:
V8::SetUserObjectComparisonCallbackFunction()
@@ -14,24 +14,25 @@ compare as equal, even though they are actually different JS object
instances.
---
include/v8.h | 13 +++++++++++++
- src/api.cc | 19 +++++++++++++++++++
- src/arm/code-stubs-arm.cc | 42 ++++++++++++++++++++++++++++++++++++++++--
+ src/api.cc | 22 ++++++++++++++++++++++
+ src/arm/code-stubs-arm.cc | 43 +++++++++++++++++++++++++++++++++++++++++--
src/factory.cc | 8 ++++++++
- src/ia32/code-stubs-ia32.cc | 40 ++++++++++++++++++++++++++++++++++++++++
+ src/ia32/code-stubs-ia32.cc | 39 +++++++++++++++++++++++++++++++++++++++
+ src/isolate.cc | 7 +++++++
src/isolate.h | 8 ++++++++
- src/objects-inl.h | 15 +++++++++++++++
- src/objects.h | 10 +++++++++-
+ src/objects-inl.h | 21 ++++++++++++++++++---
+ src/objects.cc | 8 ++++----
+ src/objects.h | 12 ++++++++++--
src/runtime.cc | 23 +++++++++++++++++++++++
src/runtime.h | 1 +
- src/top.cc | 5 +++++
src/x64/code-stubs-x64.cc | 37 +++++++++++++++++++++++++++++++++++++
- 12 files changed, 218 insertions(+), 3 deletions(-)
+ 13 files changed, 231 insertions(+), 11 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 99f4b9a..7544deb 100644
+index c094d08..6baf2b2 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -2366,6 +2366,12 @@ class V8EXPORT ObjectTemplate : public Template {
+@@ -2501,6 +2501,12 @@ class V8EXPORT ObjectTemplate : public Template {
bool HasExternalResource();
void SetHasExternalResource(bool value);
@@ -44,18 +45,18 @@ index 99f4b9a..7544deb 100644
private:
ObjectTemplate();
static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor);
-@@ -2566,6 +2572,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target,
+@@ -2720,6 +2726,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 ---
++// --- User Object Comparisoa nCallback ---
+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
+ // --- AllowCodeGenerationFromStrings callbacks ---
/**
-@@ -2816,6 +2826,9 @@ class V8EXPORT V8 {
+@@ -3046,6 +3056,9 @@ class V8EXPORT V8 {
/** Callback function for reporting failed access checks.*/
static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
@@ -66,13 +67,13 @@ index 99f4b9a..7544deb 100644
* Enables the host application to receive a notification before a
* garbage collection. Allocations are not allowed in the
diff --git a/src/api.cc b/src/api.cc
-index ff74efb..2436031 100644
+index 526aa02..6f6297d 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -1321,6 +1321,16 @@ void ObjectTemplate::SetHasExternalResource(bool value)
- }
+@@ -1464,6 +1464,17 @@ void ObjectTemplate::SetHasExternalResource(bool value)
}
+
+void ObjectTemplate::MarkAsUseUserObjectComparison()
+{
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
@@ -83,13 +84,15 @@ 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(
+
+@@ -5106,6 +5117,17 @@ void V8::SetFailedAccessCheckCallbackFunction(
isolate->SetFailedAccessCheckCallback(callback);
}
++
+void V8::SetUserObjectComparisonCallbackFunction(
+ UserObjectComparisonCallback callback) {
+ i::Isolate* isolate = i::Isolate::Current();
@@ -99,14 +102,15 @@ index ff74efb..2436031 100644
+ isolate->SetUserObjectComparisonCallback(callback);
+}
+
++
void V8::AddObjectGroup(Persistent<Value>* objects,
size_t length,
RetainedObjectInfo* info) {
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
-index a2626bf..749c9be 100644
+index 00ac676..a67b3a0 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
-@@ -1563,6 +1563,36 @@ void CompareStub::Generate(MacroAssembler* masm) {
+@@ -1494,6 +1494,37 @@ 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.
@@ -122,12 +126,12 @@ index a2626bf..749c9be 100644
+ __ CompareObjectType(r1, r3, r4, JS_OBJECT_TYPE);
+ __ b(ne, &not_user_equal);
+
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
++ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ b(eq, &user_equal);
+
-+ __ ldrb(r3, FieldMemOperand(r3, Map::kBitField3Offset));
++ __ ldrb(r3, FieldMemOperand(r3, Map::kBitField2Offset));
+ __ and_(r3, r3, Operand(1 << Map::kUseUserObjectComparison));
+ __ cmp(r3, Operand(1 << Map::kUseUserObjectComparison));
+ __ b(ne, &not_user_equal);
@@ -140,24 +144,25 @@ index a2626bf..749c9be 100644
+ __ bind(&not_user_equal);
+ }
+
++
// Handle the case where the objects are identical. Either returns the answer
// or goes to slow. Only falls through if the objects were not identical.
EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_);
-@@ -5802,10 +5832,18 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
- __ tst(r2, Operand(kSmiTagMask));
- __ b(eq, &miss);
+@@ -6544,10 +6575,18 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
+ __ and_(r2, r1, Operand(r0));
+ __ JumpIfSmi(r2, &miss);
- __ CompareObjectType(r0, r2, r2, JS_OBJECT_TYPE);
+ __ CompareObjectType(r0, r2, r3, JS_OBJECT_TYPE);
__ b(ne, &miss);
- __ CompareObjectType(r1, r2, r2, JS_OBJECT_TYPE);
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
++ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ b(eq, &miss);
+ __ CompareObjectType(r1, r2, r3, JS_OBJECT_TYPE);
__ b(ne, &miss);
-+ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField3Offset));
++ __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison));
+ __ b(eq, &miss);
@@ -165,10 +170,10 @@ index a2626bf..749c9be 100644
ASSERT(GetCondition() == eq);
__ sub(r0, r0, Operand(r1));
diff --git a/src/factory.cc b/src/factory.cc
-index d530a75..6f8c7de 100644
+index e3cccae..96d3458 100644
--- a/src/factory.cc
+++ b/src/factory.cc
-@@ -998,6 +998,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1120,6 +1120,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
int internal_field_count = 0;
bool has_external_resource = false;
@@ -176,7 +181,7 @@ index d530a75..6f8c7de 100644
if (!obj->instance_template()->IsUndefined()) {
Handle<ObjectTemplateInfo> instance_template =
-@@ -1007,6 +1008,8 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1129,6 +1130,8 @@ Handle<JSFunction> Factory::CreateApiFunction(
Smi::cast(instance_template->internal_field_count())->value();
has_external_resource =
!instance_template->has_external_resource()->IsUndefined();
@@ -185,7 +190,7 @@ index d530a75..6f8c7de 100644
}
int instance_size = kPointerSize * internal_field_count;
-@@ -1051,6 +1054,11 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1173,6 +1176,11 @@ Handle<JSFunction> Factory::CreateApiFunction(
map->set_has_external_resource(true);
}
@@ -198,15 +203,15 @@ index d530a75..6f8c7de 100644
if (obj->undetectable()) {
map->set_is_undetectable();
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
-index afa599e..0964ab9 100644
+index 6cc80d3..cabf78f 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
-@@ -3447,6 +3447,40 @@ void CompareStub::Generate(MacroAssembler* masm) {
- __ Assert(not_zero, "Unexpected smi operands.");
- }
+@@ -3931,6 +3931,39 @@ 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.
+ {
-+ NearLabel not_user_equal, user_equal;
++ Label not_user_equal, user_equal;
+ __ test(eax, Immediate(kSmiTagMask));
+ __ j(zero, &not_user_equal);
+ __ test(edx, Immediate(kSmiTagMask));
@@ -218,10 +223,10 @@ index afa599e..0964ab9 100644
+ __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx);
+ __ j(not_equal, &not_user_equal);
+
-+ __ test_b(FieldOperand(ebx, Map::kBitField3Offset),
++ __ test_b(FieldOperand(ebx, Map::kBitField2Offset),
+ 1 << Map::kUseUserObjectComparison);
+ __ j(not_zero, &user_equal);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
++ __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
+ 1 << Map::kUseUserObjectComparison);
+ __ j(not_zero, &user_equal);
+
@@ -238,40 +243,64 @@ index afa599e..0964ab9 100644
+ __ bind(&not_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) {
+ // Identical objects can be compared fast, but there are some tricky cases
+ // for NaN and undefined.
+ {
+@@ -6409,8 +6442,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
__ CmpObjectType(eax, JS_OBJECT_TYPE, ecx);
- __ j(not_equal, &miss, not_taken);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
+ __ j(not_equal, &miss, Label::kNear);
++ __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &miss);
++ __ j(not_zero, &miss, Label::kNear);
__ CmpObjectType(edx, JS_OBJECT_TYPE, ecx);
- __ j(not_equal, &miss, not_taken);
-+ __ test_b(FieldOperand(ecx, Map::kBitField3Offset),
+ __ j(not_equal, &miss, Label::kNear);
++ __ test_b(FieldOperand(ecx, Map::kBitField2Offset),
+ 1 << Map::kUseUserObjectComparison);
-+ __ j(not_zero, &miss);
++ __ j(not_zero, &miss, Label::kNear);
ASSERT(GetCondition() == equal);
- __ sub(eax, Operand(edx));
+ __ sub(eax, edx);
+diff --git a/src/isolate.cc b/src/isolate.cc
+index 951f428..6a86bf1 100644
+--- a/src/isolate.cc
++++ b/src/isolate.cc
+@@ -96,6 +96,7 @@ void ThreadLocalTop::InitializeInternal() {
+ thread_id_ = ThreadId::Invalid();
+ external_caught_exception_ = false;
+ failed_access_check_callback_ = NULL;
++ user_object_comparison_callback_ = NULL;
+ save_context_ = NULL;
+ catcher_ = NULL;
+ }
+@@ -717,6 +718,12 @@ 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/isolate.h b/src/isolate.h
-index 35ffcb4..8130397 100644
+index 01ab04e..06ef22d 100644
--- a/src/isolate.h
+++ b/src/isolate.h
-@@ -267,6 +267,9 @@ class ThreadLocalTop BASE_EMBEDDED {
+@@ -255,6 +255,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();
+ // Whether out of memory exceptions should be ignored.
+ bool ignore_out_of_memory_;
-@@ -699,6 +702,11 @@ class Isolate {
+@@ -701,6 +704,11 @@ class Isolate {
void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
@@ -284,63 +313,116 @@ index 35ffcb4..8130397 100644
// of Throw() as its return value.
Failure* Throw(Object* exception, MessageLocation* location = NULL);
diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 1c7f83e..1765441 100644
+index 375df0f..4657482 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
-@@ -2552,6 +2552,19 @@ bool Map::has_external_resource()
+@@ -2859,14 +2859,14 @@ bool Map::is_extensible() {
+
+ void Map::set_attached_to_shared_function_info(bool value) {
+ if (value) {
+- set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
++ set_bit_field3(bit_field3() | (1 << kAttachedToSharedFunctionInfo));
+ } else {
+- set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
++ set_bit_field3(bit_field3() & ~(1 << kAttachedToSharedFunctionInfo));
+ }
+ }
+
+ bool Map::attached_to_shared_function_info() {
+- return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
++ return ((1 << kAttachedToSharedFunctionInfo) & bit_field3()) != 0;
+ }
+
+
+@@ -2896,6 +2896,19 @@ bool Map::has_external_resource()
}
+void Map::set_use_user_object_comparison(bool value) {
+ if (value) {
-+ set_bit_field3(bit_field3() | (1 << kUseUserObjectComparison));
++ set_bit_field2(bit_field2() | (1 << kUseUserObjectComparison));
+ } else {
-+ set_bit_field3(bit_field3() & ~(1 << kUseUserObjectComparison));
++ set_bit_field2(bit_field2() & ~(1 << kUseUserObjectComparison));
+ }
+}
+
+bool Map::use_user_object_comparison() {
-+ return ((1 << kUseUserObjectComparison) & bit_field3()) != 0;
++ return ((1 << kUseUserObjectComparison) & bit_field2()) != 0;
+}
+
+
void Map::set_named_interceptor_is_fallback(bool value)
{
if (value) {
-@@ -3050,6 +3063,8 @@ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
+@@ -3429,6 +3442,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,
+ kUseUserObjectComparisonOffset)
ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
+diff --git a/src/objects.cc b/src/objects.cc
+index 8e1773f..28e6d79 100644
+--- a/src/objects.cc
++++ b/src/objects.cc
+@@ -7159,8 +7159,8 @@ void SharedFunctionInfo::DetachInitialMap() {
+ Map* map = reinterpret_cast<Map*>(initial_map());
+
+ // Make the map remember to restore the link if it survives the GC.
+- map->set_bit_field2(
+- map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo));
++ map->set_bit_field3(
++ map->bit_field3() | (1 << Map::kAttachedToSharedFunctionInfo));
+
+ // Undo state changes made by StartInobjectTracking (except the
+ // construction_count). This way if the initial map does not survive the GC
+@@ -7180,8 +7180,8 @@ void SharedFunctionInfo::DetachInitialMap() {
+
+ // Called from GC, hence reinterpret_cast and unchecked accessors.
+ void SharedFunctionInfo::AttachInitialMap(Map* map) {
+- map->set_bit_field2(
+- map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo));
++ map->set_bit_field3(
++ map->bit_field3() & ~(1 << Map::kAttachedToSharedFunctionInfo));
+
+ // Resume inobject slack tracking.
+ set_initial_map(map);
diff --git a/src/objects.h b/src/objects.h
-index edbc47a..e75e9f1 100644
+index 71895be..881c24e 100644
--- a/src/objects.h
+++ b/src/objects.h
-@@ -3724,6 +3724,11 @@ class Map: public HeapObject {
+@@ -4084,6 +4084,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 {
- // Bit positions for bit field 3
- static const int kNamedInterceptorIsFallback = 0;
- static const int kHasExternalResource = 1;
-+ static const int kUseUserObjectComparison = 2;
++
+ // [prototype]: implicit prototype object.
+ DECL_ACCESSORS(prototype, Object)
+
+@@ -4303,7 +4308,7 @@ class Map: public HeapObject {
+ static const int kIsExtensible = 0;
+ static const int kFunctionWithPrototype = 1;
+ static const int kStringWrapperSafeForDefaultValueOf = 2;
+- static const int kAttachedToSharedFunctionInfo = 3;
++ static const int kUseUserObjectComparison = 3;
+ // No bits can be used after kElementsKindFirstBit, they are all reserved for
+ // storing ElementKind.
+ static const int kElementsKindShift = 4;
+@@ -4322,6 +4327,7 @@ class Map: public HeapObject {
+ static const int kIsShared = 0;
+ static const int kNamedInterceptorIsFallback = 1;
+ static const int kHasInstanceCallHandler = 2;
++ static const int kAttachedToSharedFunctionInfo = 3;
// 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 {
+@@ -7306,6 +7312,7 @@ class ObjectTemplateInfo: public TemplateInfo {
DECL_ACCESSORS(constructor, Object)
DECL_ACCESSORS(internal_field_count, Object)
DECL_ACCESSORS(has_external_resource, Object)
@@ -348,7 +430,7 @@ index edbc47a..e75e9f1 100644
static inline ObjectTemplateInfo* cast(Object* obj);
-@@ -6459,7 +6466,8 @@ class ObjectTemplateInfo: public TemplateInfo {
+@@ -7323,7 +7330,8 @@ class ObjectTemplateInfo: public TemplateInfo {
static const int kInternalFieldCountOffset =
kConstructorOffset + kPointerSize;
static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize;
@@ -359,10 +441,10 @@ index edbc47a..e75e9f1 100644
diff --git a/src/runtime.cc b/src/runtime.cc
-index c13f92d..b50de80 100644
+index 0388a77..24b3de0 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
-@@ -6279,6 +6279,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
+@@ -7008,6 +7008,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
}
@@ -393,10 +475,10 @@ index c13f92d..b50de80 100644
NoHandleAllocation ha;
ASSERT(args.length() == 3);
diff --git a/src/runtime.h b/src/runtime.h
-index 5e97173..0d754f9 100644
+index 284f723..5d6bf5e 100644
--- a/src/runtime.h
+++ b/src/runtime.h
-@@ -146,6 +146,7 @@ namespace internal {
+@@ -157,6 +157,7 @@ namespace internal {
/* Comparisons */ \
F(NumberEquals, 2, 1) \
F(StringEquals, 2, 1) \
@@ -404,39 +486,16 @@ index 5e97173..0d754f9 100644
\
F(NumberCompare, 3, 1) \
F(SmiLexicographicCompare, 2, 1) \
-diff --git a/src/top.cc b/src/top.cc
-index e078ee9..c345383 100644
---- a/src/top.cc
-+++ b/src/top.cc
-@@ -68,6 +68,7 @@ void ThreadLocalTop::InitializeInternal() {
- thread_id_ = ThreadId::Invalid();
- external_caught_exception_ = false;
- failed_access_check_callback_ = NULL;
-+ user_object_comparison_callback_ = NULL;
- save_context_ = NULL;
- catcher_ = NULL;
- }
-@@ -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
-index d923494..10b9b56 100644
+index 6ab12fc..3be2c4b 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
-@@ -2443,6 +2443,37 @@ void CompareStub::Generate(MacroAssembler* masm) {
- __ bind(&ok);
- }
+@@ -3005,6 +3005,37 @@ 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.
+ {
-+ NearLabel not_user_equal, user_equal;
++ Label not_user_equal, user_equal;
+ __ JumpIfSmi(rax, &not_user_equal);
+ __ JumpIfSmi(rdx, &not_user_equal);
+
@@ -446,10 +505,10 @@ index d923494..10b9b56 100644
+ __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
+ __ j(not_equal, &not_user_equal);
+
-+ __ testb(FieldOperand(rbx, Map::kBitField3Offset),
++ __ testb(FieldOperand(rbx, Map::kBitField2Offset),
+ Immediate(1 << Map::kUseUserObjectComparison));
+ __ j(not_zero, &user_equal);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
++ __ testb(FieldOperand(rcx, Map::kBitField2Offset),
+ Immediate(1 << Map::kUseUserObjectComparison));
+ __ j(not_zero, &user_equal);
+
@@ -466,21 +525,21 @@ index d923494..10b9b56 100644
+ __ bind(&not_user_equal);
+ }
+
- // The compare stub returns a positive, negative, or zero 64-bit integer
- // 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) {
+ // Two identical objects are equal unless they are both NaN or undefined.
+ {
+ Label not_identical;
+@@ -5337,8 +5368,14 @@ void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
__ CmpObjectType(rax, JS_OBJECT_TYPE, rcx);
- __ j(not_equal, &miss, not_taken);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
+ __ j(not_equal, &miss, Label::kNear);
++ __ testb(FieldOperand(rcx, Map::kBitField2Offset),
+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &miss);
++ __ j(not_zero, &miss, Label::kNear);
__ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx);
- __ j(not_equal, &miss, not_taken);
-+ __ testb(FieldOperand(rcx, Map::kBitField3Offset),
+ __ j(not_equal, &miss, Label::kNear);
++ __ testb(FieldOperand(rcx, Map::kBitField2Offset),
+ Immediate(1 << Map::kUseUserObjectComparison));
-+ __ j(not_zero, &miss);
++ __ j(not_zero, &miss, Label::kNear);
ASSERT(GetCondition() == equal);
__ subq(rax, rdx);
diff --git a/src/v8/0015-Allow-a-script-to-be-flagged-as-native.patch b/src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch
index d66e370217..396d1f7add 100644
--- a/src/v8/0015-Allow-a-script-to-be-flagged-as-native.patch
+++ b/src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch
@@ -1,7 +1,7 @@
-From 523f03f03b1ac16d272a13389f8a5654d9ff12e6 Mon Sep 17 00:00:00 2001
+From a1572a979803dda787be4a7095d5c37e926443a7 Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Fri, 9 Sep 2011 14:16:12 +1000
-Subject: [PATCH 15/16] Allow a script to be flagged as "native"
+Subject: [PATCH 07/11] Allow a script to be flagged as "native"
Native scripts do not appear in backtraces, or in the source and
line number when exceptions are thrown from within them. This is
@@ -13,10 +13,10 @@ still have it appear sensibly to the user.
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 5e1ce50..a2d61d1 100644
+index 6baf2b2..229ddbd 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -578,8 +578,9 @@ class ScriptOrigin {
+@@ -588,8 +588,9 @@ class ScriptOrigin {
class V8EXPORT Script {
public:
enum CompileFlags {
@@ -29,10 +29,10 @@ index 5e1ce50..a2d61d1 100644
/**
diff --git a/src/compiler.cc b/src/compiler.cc
-index d2191b9..873018c 100755
+index 596df4a..b760b71 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
-@@ -507,7 +507,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+@@ -501,7 +501,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
// Create a script object describing the script to be compiled.
Handle<Script> script = FACTORY->NewScript(source);
diff --git a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch
index 7cbc2d474b..007f14a821 100644
--- a/src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch
+++ b/src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch
@@ -1,7 +1,7 @@
-From 5f3e5dd6901b54707ea4f868d8fa7317c4ab3852 Mon Sep 17 00:00:00 2001
+From 3c304e3712ebf9f0df0b544032f0f83945d08028 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 08/11] QtScript/V8: Add new v8 api to check if a value is an
error.
New function v8::Value::IsError was created.
@@ -15,10 +15,10 @@ research.
3 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 18527e1..43e00f5 100644
+index 229ddbd..d995e54 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -937,6 +937,11 @@ class Value : public Data {
+@@ -967,6 +967,11 @@ class Value : public Data {
*/
V8EXPORT bool IsRegExp() const;
@@ -31,10 +31,10 @@ index 18527e1..43e00f5 100644
V8EXPORT Local<Number> ToNumber() const;
V8EXPORT Local<String> ToString() const;
diff --git a/src/api.cc b/src/api.cc
-index 1a585d6..bd435eb 100644
+index 6f6297d..c21af67 100644
--- a/src/api.cc
+++ b/src/api.cc
-@@ -2108,6 +2108,12 @@ bool Value::IsRegExp() const {
+@@ -2316,6 +2316,12 @@ bool Value::IsRegExp() const {
return obj->IsJSRegExp();
}
@@ -48,10 +48,10 @@ index 1a585d6..bd435eb 100644
Local<String> Value::ToString() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
diff --git a/src/heap.h b/src/heap.h
-index 8cbf378..db90bb9 100644
+index bab4c63..ad83b70 100644
--- a/src/heap.h
+++ b/src/heap.h
-@@ -169,6 +169,7 @@ inline Heap* _inline_get_heap_();
+@@ -188,6 +188,7 @@ inline Heap* _inline_get_heap_();
V(string_symbol, "string") \
V(String_symbol, "String") \
V(Date_symbol, "Date") \
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
deleted file mode 100644
index b89f152a04..0000000000
--- a/src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-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
- API
-
-Patch by Peter Varga.
-
-BUG=v8:1336
-TEST=cctest/test-api/CallAsFunction
-
-Review URL: http://codereview.chromium.org/6883045
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7781 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 8 +++
- src/api.cc | 31 +++++++++++
- src/execution.cc | 24 ++++++++
- src/execution.h | 2 +
- test/cctest/test-api.cc | 135 ++++++++++++++++++++++++++++++++++-------------
- 5 files changed, 163 insertions(+), 37 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 7544deb..277153e 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -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
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ */
-+ V8EXPORT Local<Value> CallAsFunction(Handle<Object> recv,
-+ int argc,
-+ Handle<Value> argv[]);
-+
- V8EXPORT static Local<Object> New();
- static inline Object* Cast(Value* obj);
- private:
-diff --git a/src/api.cc b/src/api.cc
-index 2436031..e412e51 100644
---- a/src/api.cc
-+++ 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();
-+ ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
-+ return Local<v8::Value>());
-+ LOG_API(isolate, "Object::CallAsFunction");
-+ ENTER_V8(isolate);
-+ HandleScope scope;
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
-+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
-+ if (obj->IsJSFunction()) {
-+ fun = i::Handle<i::JSFunction>::cast(obj);
-+ } else {
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> delegate =
-+ i::Execution::TryGetFunctionDelegate(obj, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-+ fun = i::Handle<i::JSFunction>::cast(delegate);
-+ recv_obj = obj;
-+ }
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-+ return scope.Close(Utils::ToLocal(returned));
-+}
-+
-+
- Local<v8::Object> Function::NewInstance() const {
- return NewInstance(0, NULL);
- }
-diff --git a/src/execution.cc b/src/execution.cc
-index 1632076..894d741 100644
---- a/src/execution.cc
-+++ 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());
-+ Isolate* isolate = Isolate::Current();
-+
-+ // Objects created through the API can have an instance-call handler
-+ // that should be used when calling the object as a function.
-+ if (object->IsHeapObject() &&
-+ HeapObject::cast(*object)->map()->has_instance_call_handler()) {
-+ return Handle<JSFunction>(
-+ isolate->global_context()->call_as_function_delegate());
-+ }
-+
-+ // If the Object doesn't have an instance-call handler we should
-+ // throw a non-callable exception.
-+ i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-+ "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-+ isolate->Throw(*error_obj);
-+ *has_pending_exception = true;
-+
-+ return isolate->factory()->undefined_value();
-+}
-+
-+
- Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
- ASSERT(!object->IsJSFunction());
- Isolate* isolate = Isolate::Current();
-diff --git a/src/execution.h b/src/execution.h
-index a476eb4..0a0be51 100644
---- a/src/execution.h
-+++ b/src/execution.h
-@@ -144,6 +144,8 @@ class Execution : public AllStatic {
- // Get a function delegate (or undefined) for the given non-function
- // object. Used for support calling objects as functions.
- 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
-index d7621d1..693d51e 100644
---- a/test/cctest/test-api.cc
-+++ b/test/cctest/test-api.cc
-@@ -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);
-- Local<v8::Object> instance = t->GetFunction()->NewInstance();
-- context->Global()->Set(v8_str("obj"), instance);
-- v8::TryCatch try_catch;
-- Local<Value> value;
-- CHECK(!try_catch.HasCaught());
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ instance_template->SetCallAsFunctionHandler(call_as_function);
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj"), instance);
-+ 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());
-- CHECK_EQ(45, value->Int32Value());
-+ // test special case of call as function
-+ 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());
-- CHECK_EQ(87, value->Int32Value());
-+ value = CompileRun("obj.call = Function.prototype.call;"
-+ "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])";
-- value = CompileRun(apply_99);
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(99, 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])";
-+ 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());
-- CHECK_EQ(17, value->Int32Value());
-+ const char* call_17 = "Function.prototype.call.call(obj, this, 17)";
-+ 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)");
-- CHECK(!try_catch.HasCaught());
-- CHECK_EQ(-43, value->Int32Value());
-+ // Check that the call-as-function handler can be called through
-+ // new.
-+ value = CompileRun("new obj(43)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(-43, value->Int32Value());
-+
-+ // Check that the call-as-function handler can be called through
-+ // the API.
-+ v8::Handle<Value> args[] = { v8_num(28) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(28, value->Int32Value());
-+ }
-+
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj2"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Call an object without call-as-function handler through the JS
-+ value = CompileRun("obj2(28)");
-+ CHECK(value.IsEmpty());
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ(*exception_value1,
-+ "TypeError: Property 'obj2' of object "
-+ "#<Object> is not a function");
-+ try_catch.Reset();
-+
-+ // Call an object without call-as-function handler through the API
-+ value = CompileRun("obj2(28)");
-+ v8::Handle<Value> args[] = { v8_num(28) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(value.IsEmpty());
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function");
-+ try_catch.Reset();
-+ }
-+
-+ { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
-+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
-+ instance_template->SetCallAsFunctionHandler(ThrowValue);
-+ Local<v8::Object> instance = t->GetFunction()->NewInstance();
-+ context->Global()->Set(v8_str("obj3"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Catch the exception which is thrown by call-as-function handler
-+ value = CompileRun("obj3(22)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ(*exception_value1, "22");
-+ try_catch.Reset();
-+
-+ v8::Handle<Value> args[] = { v8_num(23) };
-+ value = instance->CallAsFunction(instance, 1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ(*exception_value2, "23");
-+ try_catch.Reset();
-+ }
- }
-
-
---
-1.7.4.4
-
diff --git a/src/v8/0014-Fix-deprecated-Python-code.patch b/src/v8/0009-Fix-deprecated-Python-code.patch
index 9745a5c129..a5d2d084fb 100644
--- a/src/v8/0014-Fix-deprecated-Python-code.patch
+++ b/src/v8/0009-Fix-deprecated-Python-code.patch
@@ -1,7 +1,7 @@
-From ed5cc903d70f73780e5985e7d2de33f6b8d86402 Mon Sep 17 00:00:00 2001
+From 234a7bf490c4870f2d015221bb5158de4933519c 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 14/16] Fix deprecated Python code
+Subject: [PATCH 09/11] Fix deprecated Python code
Needed to make the scripts run on Python 3, which is the
default python interpreter on some newer distros.
@@ -13,10 +13,10 @@ Patch from http://code.google.com/p/v8/issues/detail?id=1391
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/js2c.py b/tools/js2c.py
-index 2da132f..d13d53d 100755
+index a2ea8ea..fe6a72e 100644
--- a/tools/js2c.py
+++ b/tools/js2c.py
-@@ -187,14 +187,14 @@ def ReadMacros(lines):
+@@ -194,14 +194,14 @@ def ReadMacros(lines):
macro_match = MACRO_PATTERN.match(line)
if macro_match:
name = macro_match.group(1)
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
deleted file mode 100644
index 847cb8657e..0000000000
--- a/src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch
+++ /dev/null
@@ -1,398 +0,0 @@
-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
- API
-
-Patch by Peter Varga.
-
-BUG=v8:1348
-TEST=cctest/test-api/ConstructorForObject
-
-Review URL: http://codereview.chromium.org/6902108
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 8 ++
- src/api.cc | 41 +++++++++-
- src/execution.cc | 28 +++++++
- src/execution.h | 2 +
- test/cctest/test-api.cc | 205 +++++++++++++++++++++++++++++++++++++++++++++--
- 5 files changed, 276 insertions(+), 8 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 277153e..18527e1 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1766,6 +1766,14 @@ class Object : public Value {
- int argc,
- Handle<Value> argv[]);
-
-+ /**
-+ * Call an Object as a consturctor if a callback is set by the
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ * Note: This method behaves like the Function::NewInstance method.
-+ */
-+ V8EXPORT Local<Value> CallAsConstructor(int argc,
-+ Handle<Value> argv[]);
-+
- V8EXPORT static Local<Object> New();
- static inline Object* Cast(Value* obj);
- private:
-diff --git a/src/api.cc b/src/api.cc
-index e412e51..1a585d6 100644
---- a/src/api.cc
-+++ b/src/api.cc
-@@ -3266,7 +3266,7 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- return Local<v8::Value>());
- LOG_API(isolate, "Object::CallAsFunction");
- ENTER_V8(isolate);
-- HandleScope scope;
-+ i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-@@ -3286,7 +3286,44 @@ Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- i::Handle<i::Object> returned =
- i::Execution::Call(fun, recv_obj, argc, args, &has_pending_exception);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
-- return scope.Close(Utils::ToLocal(returned));
-+ return Utils::ToLocal(scope.CloseAndEscape(returned));
-+}
-+
-+
-+Local<v8::Value> Object::CallAsConstructor(int argc,
-+ v8::Handle<v8::Value> argv[]) {
-+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-+ ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
-+ return Local<v8::Object>());
-+ LOG_API(isolate, "Object::CallAsConstructor");
-+ ENTER_V8(isolate);
-+ i::HandleScope scope(isolate);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
-+ i::Object*** args = reinterpret_cast<i::Object***>(argv);
-+ if (obj->IsJSFunction()) {
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::New(fun, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ return Utils::ToLocal(scope.CloseAndEscape(
-+ i::Handle<i::JSObject>::cast(returned)));
-+ }
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> delegate =
-+ i::Execution::TryGetConstructorDelegate(obj, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ if (!delegate->IsUndefined()) {
-+ i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
-+ EXCEPTION_PREAMBLE(isolate);
-+ i::Handle<i::Object> returned =
-+ i::Execution::Call(fun, obj, argc, args, &has_pending_exception);
-+ EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
-+ ASSERT(!delegate->IsUndefined());
-+ return Utils::ToLocal(scope.CloseAndEscape(returned));
-+ }
-+ 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) {
-+ ASSERT(!object->IsJSFunction());
-+ Isolate* isolate = Isolate::Current();
-+
-+ // If you return a function from here, it will be called when an
-+ // attempt is made to call the given object as a constructor.
-+
-+ // Objects created through the API can have an instance-call handler
-+ // that should be used when calling the object as a function.
-+ if (object->IsHeapObject() &&
-+ HeapObject::cast(*object)->map()->has_instance_call_handler()) {
-+ return Handle<JSFunction>(
-+ isolate->global_context()->call_as_constructor_delegate());
-+ }
-+
-+ // If the Object doesn't have an instance-call handler we should
-+ // throw a non-callable exception.
-+ i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
-+ "called_non_callable", i::HandleVector<i::Object>(&object, 1));
-+ isolate->Throw(*error_obj);
-+ *has_pending_exception = true;
-+
-+ return isolate->factory()->undefined_value();
-+}
-+
-+
- bool StackGuard::IsStackOverflow() {
- ExecutionAccess access(isolate_);
- return (thread_local_.jslimit_ != kInterruptLimit &&
-diff --git a/src/execution.h b/src/execution.h
-index 0a0be51..ec2a195 100644
---- a/src/execution.h
-+++ b/src/execution.h
-@@ -150,6 +150,8 @@ class Execution : public AllStatic {
- // Get a function delegate (or undefined) for the given non-function
- // object. Used for support calling objects as constructors.
- static Handle<Object> GetConstructorDelegate(Handle<Object> object);
-+ 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
-+++ b/test/cctest/test-api.cc
-@@ -6746,6 +6746,200 @@ THREADED_TEST(Constructor) {
- CHECK(value->BooleanValue());
- }
-
-+
-+static Handle<Value> ConstructorCallback(const Arguments& args) {
-+ ApiTestFuzzer::Fuzz();
-+ Local<Object> This;
-+
-+ if (args.IsConstructCall()) {
-+ Local<Object> Holder = args.Holder();
-+ This = Object::New();
-+ Local<Value> proto = Holder->GetPrototype();
-+ if (proto->IsObject()) {
-+ This->SetPrototype(proto);
-+ }
-+ } else {
-+ This = args.This();
-+ }
-+
-+ This->Set(v8_str("a"), args[0]);
-+ return This;
-+}
-+
-+
-+static Handle<Value> FakeConstructorCallback(const Arguments& args) {
-+ ApiTestFuzzer::Fuzz();
-+ return args[0];
-+}
-+
-+
-+THREADED_TEST(ConstructorForObject) {
-+ v8::HandleScope handle_scope;
-+ LocalContext context;
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(ConstructorCallback);
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ // Call the Object's constructor with a 32-bit signed integer.
-+ value = CompileRun("(function() { var o = new obj(28); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsInt32());
-+ CHECK_EQ(28, value->Int32Value());
-+
-+ Local<Value> args1[] = { v8_num(28) };
-+ Local<Value> value_obj1 = instance->CallAsConstructor(1, args1);
-+ CHECK(value_obj1->IsObject());
-+ Local<Object> object1 = Local<Object>::Cast(value_obj1);
-+ value = object1->Get(v8_str("a"));
-+ CHECK(value->IsInt32());
-+ CHECK(!try_catch.HasCaught());
-+ CHECK_EQ(28, value->Int32Value());
-+
-+ // Call the Object's constructor with a String.
-+ value = CompileRun(
-+ "(function() { var o = new obj('tipli'); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsString());
-+ String::AsciiValue string_value1(value->ToString());
-+ CHECK_EQ("tipli", *string_value1);
-+
-+ Local<Value> args2[] = { v8_str("tipli") };
-+ Local<Value> value_obj2 = instance->CallAsConstructor(1, args2);
-+ CHECK(value_obj2->IsObject());
-+ Local<Object> object2 = Local<Object>::Cast(value_obj2);
-+ value = object2->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsString());
-+ String::AsciiValue string_value2(value->ToString());
-+ CHECK_EQ("tipli", *string_value2);
-+
-+ // Call the Object's constructor with a Boolean.
-+ value = CompileRun("(function() { var o = new obj(true); return o.a; })()");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsBoolean());
-+ CHECK_EQ(true, value->BooleanValue());
-+
-+ Handle<Value> args3[] = { v8::Boolean::New(true) };
-+ Local<Value> value_obj3 = instance->CallAsConstructor(1, args3);
-+ CHECK(value_obj3->IsObject());
-+ Local<Object> object3 = Local<Object>::Cast(value_obj3);
-+ value = object3->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsBoolean());
-+ CHECK_EQ(true, value->BooleanValue());
-+
-+ // Call the Object's constructor with undefined.
-+ Handle<Value> args4[] = { v8::Undefined() };
-+ Local<Value> value_obj4 = instance->CallAsConstructor(1, args4);
-+ CHECK(value_obj4->IsObject());
-+ Local<Object> object4 = Local<Object>::Cast(value_obj4);
-+ value = object4->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsUndefined());
-+
-+ // Call the Object's constructor with null.
-+ Handle<Value> args5[] = { v8::Null() };
-+ Local<Value> value_obj5 = instance->CallAsConstructor(1, args5);
-+ CHECK(value_obj5->IsObject());
-+ Local<Object> object5 = Local<Object>::Cast(value_obj5);
-+ value = object5->Get(v8_str("a"));
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsNull());
-+ }
-+
-+ // Check exception handling when there is no constructor set for the Object.
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj2"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ value = CompileRun("new obj2(28)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ("TypeError: object is not a function", *exception_value1);
-+ try_catch.Reset();
-+
-+ Local<Value> args[] = { v8_num(29) };
-+ value = instance->CallAsConstructor(1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ("TypeError: #<Object> is not a function", *exception_value2);
-+ try_catch.Reset();
-+ }
-+
-+ // Check the case when constructor throws exception.
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(ThrowValue);
-+ Local<Object> instance = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj3"), instance);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ value = CompileRun("new obj3(22)");
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value1(try_catch.Exception());
-+ CHECK_EQ("22", *exception_value1);
-+ try_catch.Reset();
-+
-+ Local<Value> args[] = { v8_num(23) };
-+ value = instance->CallAsConstructor(1, args);
-+ CHECK(try_catch.HasCaught());
-+ String::AsciiValue exception_value2(try_catch.Exception());
-+ CHECK_EQ("23", *exception_value2);
-+ try_catch.Reset();
-+ }
-+
-+ // Check whether constructor returns with an object or non-object.
-+ { Local<FunctionTemplate> function_template =
-+ FunctionTemplate::New(FakeConstructorCallback);
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance1 = function;
-+ context->Global()->Set(v8_str("obj4"), instance1);
-+ v8::TryCatch try_catch;
-+ Local<Value> value;
-+ CHECK(!try_catch.HasCaught());
-+
-+ CHECK(instance1->IsObject());
-+ CHECK(instance1->IsFunction());
-+
-+ value = CompileRun("new obj4(28)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsObject());
-+
-+ Local<Value> args1[] = { v8_num(28) };
-+ value = instance1->CallAsConstructor(1, args1);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(value->IsObject());
-+
-+ Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(FakeConstructorCallback);
-+ Local<Object> instance2 = instance_template->NewInstance();
-+ context->Global()->Set(v8_str("obj5"), instance2);
-+ CHECK(!try_catch.HasCaught());
-+
-+ CHECK(instance2->IsObject());
-+ CHECK(!instance2->IsFunction());
-+
-+ value = CompileRun("new obj5(28)");
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(!value->IsObject());
-+
-+ Local<Value> args2[] = { v8_num(28) };
-+ value = instance2->CallAsConstructor(1, args2);
-+ CHECK(!try_catch.HasCaught());
-+ CHECK(!value->IsObject());
-+ }
-+}
-+
-+
- THREADED_TEST(FunctionDescriptorException) {
- v8::HandleScope handle_scope;
- LocalContext context;
-@@ -7028,9 +7222,8 @@ THREADED_TEST(CallAsFunction) {
- CHECK(value.IsEmpty());
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value1(try_catch.Exception());
-- CHECK_EQ(*exception_value1,
-- "TypeError: Property 'obj2' of object "
-- "#<Object> is not a function");
-+ 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());
- CHECK(try_catch.HasCaught());
- String::AsciiValue exception_value2(try_catch.Exception());
-- CHECK_EQ(*exception_value2, "TypeError: [object Object] is not a function");
-+ 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());
- String::AsciiValue exception_value1(try_catch.Exception());
-- 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());
- String::AsciiValue exception_value2(try_catch.Exception());
-- CHECK_EQ(*exception_value2, "23");
-+ CHECK_EQ("23", *exception_value2);
- try_catch.Reset();
- }
- }
---
-1.7.4.4
-
diff --git a/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch b/src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch
index 9d987dd3c1..b353f5fcca 100644
--- a/src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch
+++ b/src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch
@@ -1,7 +1,7 @@
-From c36be227e9d7952a1952caa529c78ecdc376bd55 Mon Sep 17 00:00:00 2001
+From 8796bc9571db9f7049c96a9829281fedc54f8f38 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 10/11] Remove execute flag from v8-debug.h
---
0 files changed, 0 insertions(+), 0 deletions(-)
diff --git a/src/v8/0007-Fix-warnings.patch b/src/v8/0011-Fix-warnings.patch
index b4e39cc521..37f4043a30 100644
--- a/src/v8/0007-Fix-warnings.patch
+++ b/src/v8/0011-Fix-warnings.patch
@@ -1,18 +1,18 @@
-From 2a5cf85d7fd7912e516138db03e4cda47cc2a1ab Mon Sep 17 00:00:00 2001
+From 9c0d93bfae724e29ef63456942d9ddca10ca5825 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 11/11] Fix warnings
---
include/v8.h | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 2bc0ed1..99f4b9a 100644
+index d995e54..a7b5c8a 100644
--- a/include/v8.h
+++ b/include/v8.h
-@@ -2416,7 +2416,7 @@ class V8EXPORT Extension { // NOLINT
- const char** deps = 0);
+@@ -2579,7 +2579,7 @@ class V8EXPORT Extension { // NOLINT
+ int source_length = -1);
virtual ~Extension() { }
virtual v8::Handle<v8::FunctionTemplate>
- GetNativeFunction(v8::Handle<v8::String> name) {
@@ -20,7 +20,7 @@ index 2bc0ed1..99f4b9a 100644
return v8::Handle<v8::FunctionTemplate>();
}
-@@ -3722,13 +3722,13 @@ class Internals {
+@@ -3946,13 +3946,13 @@ class Internals {
return *reinterpret_cast<T*>(addr);
}
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
deleted file mode 100644
index 412cebd4d7..0000000000
--- a/src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-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
-
-Patch by Peter Varga.
-
-BUG=none
-TEST=cctest/test-api/CallableObject
-
-Review URL: http://codereview.chromium.org/6964005
-
-git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@7828 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
----
- include/v8.h | 7 +++++++
- src/api.cc | 11 +++++++++++
- test/cctest/test-api.cc | 43 +++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 61 insertions(+), 0 deletions(-)
-
-diff --git a/include/v8.h b/include/v8.h
-index 43e00f5..5e1ce50 100644
---- a/include/v8.h
-+++ b/include/v8.h
-@@ -1764,6 +1764,13 @@ class Object : public Value {
- V8EXPORT int GetIndexedPropertiesExternalArrayDataLength();
-
- /**
-+ * Checks whether a callback is set by the
-+ * ObjectTemplate::SetCallAsFunctionHandler method.
-+ * When an Object is callable this method returns true.
-+ */
-+ V8EXPORT bool IsCallable();
-+
-+ /**
- * 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
-index bd435eb..a5a637f 100644
---- a/src/api.cc
-+++ 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);
-+ ENTER_V8(isolate);
-+ i::HandleScope scope(isolate);
-+ i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
-+ if (obj->IsJSFunction()) return true;
-+ return i::Execution::GetFunctionDelegate(obj)->IsJSFunction();
-+}
-+
-+
- Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Object> recv, int argc,
- v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
-diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
-index 1334f63..45db5a1 100644
---- a/test/cctest/test-api.cc
-+++ 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;
-+ LocalContext context;
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ instance_template->SetCallAsFunctionHandler(call_as_function);
-+ Local<Object> instance = instance_template->NewInstance();
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<ObjectTemplate> instance_template = ObjectTemplate::New();
-+ Local<Object> instance = instance_template->NewInstance();
-+ v8::TryCatch try_catch;
-+
-+ CHECK(!instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<FunctionTemplate> function_template =
-+ FunctionTemplate::New(call_as_function);
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance = function;
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+
-+ { Local<FunctionTemplate> function_template = FunctionTemplate::New();
-+ Local<Function> function = function_template->GetFunction();
-+ Local<Object> instance = function;
-+ v8::TryCatch try_catch;
-+
-+ CHECK(instance->IsCallable());
-+ CHECK(!try_catch.HasCaught());
-+ }
-+}
-+
-+
- static int CountHandles() {
- return v8::HandleScope::NumberOfHandles();
- }
---
-1.7.4.4
-
diff --git a/src/v8/0016-Move-external-resource-to-the-last-hidden-field.patch b/src/v8/0016-Move-external-resource-to-the-last-hidden-field.patch
deleted file mode 100644
index b6dde1e024..0000000000
--- a/src/v8/0016-Move-external-resource-to-the-last-hidden-field.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 8f15248619bb3bf49473dc3ede8a4e631bd5d199 Mon Sep 17 00:00:00 2001
-From: Aaron Kennedy <aaron.kennedy@nokia.com>
-Date: Tue, 4 Oct 2011 14:22:54 +1000
-Subject: [PATCH 16/16] Move external resource to the last hidden field
-
----
- src/objects-inl.h | 10 +++++-----
- 1 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/src/objects-inl.h b/src/objects-inl.h
-index 1765441..c02e037 100644
---- a/src/objects-inl.h
-+++ b/src/objects-inl.h
-@@ -1398,7 +1398,7 @@ int JSObject::GetInternalFieldCount() {
-
- int JSObject::GetInternalFieldOffset(int index) {
- ASSERT(index < GetInternalFieldCount() && index >= 0);
-- return GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0));
-+ return GetHeaderSize() + (kPointerSize * index);
- }
-
-
-@@ -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
- // to adjust the index here.
-- return READ_FIELD(this, GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0)));
-+ return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
- }
-
-
-@@ -1416,7 +1416,7 @@ 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
- // to adjust the index here.
-- int offset = GetHeaderSize() + (kPointerSize * (index + map()->has_external_resource()?1:0));
-+ int offset = GetHeaderSize() + (kPointerSize * index);
- WRITE_FIELD(this, offset, value);
- WRITE_BARRIER(this, offset);
- }
-@@ -1424,7 +1424,7 @@ void JSObject::SetInternalField(int index, Object* value) {
-
- void JSObject::SetExternalResourceObject(Object *value) {
- ASSERT(map()->has_external_resource());
-- int offset = GetHeaderSize();
-+ int offset = GetHeaderSize() + kPointerSize * GetInternalFieldCount();
- WRITE_FIELD(this, offset, value);
- WRITE_BARRIER(this, offset);
- }
-@@ -1432,7 +1432,7 @@ void JSObject::SetExternalResourceObject(Object *value) {
-
- Object *JSObject::GetExternalResourceObject() {
- if (map()->has_external_resource()) {
-- return READ_FIELD(this, GetHeaderSize());
-+ return READ_FIELD(this, GetHeaderSize() + kPointerSize * GetInternalFieldCount());
- } else {
- return GetHeap()->undefined_value();
- }
---
-1.7.4.4
-
diff --git a/src/v8/README b/src/v8/README
index 2dc39705aa..2cf8611831 100644
--- a/src/v8/README
+++ b/src/v8/README
@@ -1 +1 @@
-These patches apply cleanly against v8 at 2eaa4b29586fdbd5d41f7b7d9e72ecca6d53dbd2
+These patches apply cleanly against v8 at bd43701b639856950d7cb461d777193a51c4859c
diff --git a/src/v8/v8.pri b/src/v8/v8.pri
index 1d1abc85c0..2d369d9166 100644
--- a/src/v8/v8.pri
+++ b/src/v8/v8.pri
@@ -72,10 +72,10 @@ SOURCES += \
$$V8SRC/disassembler.cc \
$$V8SRC/diy-fp.cc \
$$V8SRC/dtoa.cc \
+ $$V8SRC/elements.cc \
$$V8SRC/execution.cc \
$$V8SRC/factory.cc \
$$V8SRC/flags.cc \
- $$V8SRC/frame-element.cc \
$$V8SRC/frames.cc \
$$V8SRC/full-codegen.cc \
$$V8SRC/func-name-inferrer.cc \
@@ -90,6 +90,7 @@ SOURCES += \
$$V8SRC/hydrogen.cc \
$$V8SRC/hydrogen-instructions.cc \
$$V8SRC/ic.cc \
+ $$V8SRC/incremental-marking.cc \
$$V8SRC/inspector.cc \
$$V8SRC/interpreter-irregexp.cc \
$$V8SRC/isolate.cc \
@@ -117,8 +118,8 @@ SOURCES += \
$$V8SRC/runtime.cc \
$$V8SRC/runtime-profiler.cc \
$$V8SRC/safepoint-table.cc \
- $$V8SRC/scanner-base.cc \
$$V8SRC/scanner.cc \
+ $$V8SRC/scanner-character-streams.cc \
$$V8SRC/scopeinfo.cc \
$$V8SRC/scopes.cc \
$$V8SRC/serialize.cc \
@@ -129,15 +130,17 @@ SOURCES += \
$$V8SRC/strtod.cc \
$$V8SRC/stub-cache.cc \
$$V8SRC/token.cc \
- $$V8SRC/top.cc \
$$V8SRC/type-info.cc \
$$V8SRC/unicode.cc \
$$V8SRC/utils.cc \
$$V8SRC/v8-counters.cc \
$$V8SRC/v8.cc \
+ $$V8SRC/v8conversions.cc \
$$V8SRC/v8threads.cc \
+ $$V8SRC/v8utils.cc \
$$V8SRC/variables.cc \
$$V8SRC/version.cc \
+ $$V8SRC/store-buffer.cc \
$$V8SRC/zone.cc \
$$V8SRC/extensions/gc-extension.cc \
$$V8SRC/extensions/externalize-string-extension.cc
@@ -258,7 +261,11 @@ V8_LIBRARY_FILES = \
$$V8SRC/mirror-debugger.js \
$$V8SRC/debug-debugger.js
-v8_js2c.commands = python $$V8DIR/tools/js2c.py $$V8_GENERATED_SOURCES_DIR/libraries.cpp $$V8_GENERATED_SOURCES_DIR/libraries-empty.cpp CORE
+V8_EXPERIMENTAL_LIBRARY_FILES = \
+ $$V8SRC/proxy.js \
+ $$V8SRC/weakmap.js
+
+v8_js2c.commands = python $$V8DIR/tools/js2c.py $$V8_GENERATED_SOURCES_DIR/libraries.cpp CORE off
v8_js2c.commands += $$V8SRC/macros.py ${QMAKE_FILE_IN}
v8_js2c.output = $$V8_GENERATED_SOURCES_DIR/libraries.cpp
v8_js2c.input = V8_LIBRARY_FILES
@@ -268,4 +275,15 @@ v8_js2c.depends = $$V8DIR/tools/js2c.py $$V8SRC/macros.py
v8_js2c.CONFIG += combine
v8_js2c.name = generating[v8] ${QMAKE_FILE_IN}
silent:v8_js2c.commands = @echo generating[v8] ${QMAKE_FILE_IN} && $$v8_js2c.commands
-QMAKE_EXTRA_COMPILERS += v8_js2c
+
+v8_js2c_experimental.commands = python $$V8DIR/tools/js2c.py $$V8_GENERATED_SOURCES_DIR/experimental-libraries.cpp EXPERIMENTAL off
+v8_js2c_experimental.commands += $$V8SRC/macros.py ${QMAKE_FILE_IN}
+v8_js2c_experimental.output = $$V8_GENERATED_SOURCES_DIR/experimental-libraries.cpp
+v8_js2c_experimental.input = V8_EXPERIMENTAL_LIBRARY_FILES
+v8_js2c_experimental.variable_out = SOURCES
+v8_js2c_experimental.dependency_type = TYPE_C
+v8_js2c_experimental.depends = $$V8DIR/tools/js2c.py $$V8SRC/macros.py
+v8_js2c_experimental.CONFIG += combine
+v8_js2c_experimental.name = generating[v8] ${QMAKE_FILE_IN}
+
+QMAKE_EXTRA_COMPILERS += v8_js2c v8_js2c_experimental
diff --git a/tests/auto/v8/tst_v8.cpp b/tests/auto/v8/tst_v8.cpp
index c753806518..fcb49f84e0 100644
--- a/tests/auto/v8/tst_v8.cpp
+++ b/tests/auto/v8/tst_v8.cpp
@@ -57,6 +57,7 @@ private slots:
void eval();
void evalwithinwith();
void userobjectcompare();
+ void externalteardown();
};
void tst_v8::eval()
@@ -74,6 +75,11 @@ void tst_v8::userobjectcompare()
QVERIFY(v8test_userobjectcompare());
}
+void tst_v8::externalteardown()
+{
+ QVERIFY(v8test_externalteardown());
+}
+
int main(int argc, char *argv[])
{
V8::SetFlagsFromCommandLine(&argc, argv, true);
diff --git a/tests/auto/v8/v8main.cpp b/tests/auto/v8/v8main.cpp
index b38bbabbd5..882c2b99bb 100644
--- a/tests/auto/v8/v8main.cpp
+++ b/tests/auto/v8/v8main.cpp
@@ -45,6 +45,8 @@
#define RUN_TEST(testname) { \
if (!v8test_ ## testname()) \
printf ("Test %s FAILED\n", # testname); \
+ else \
+ printf ("Test %s PASS\n", # testname); \
}
int main(int argc, char *argv[])
@@ -54,6 +56,7 @@ int main(int argc, char *argv[])
RUN_TEST(eval);
RUN_TEST(evalwithinwith);
RUN_TEST(userobjectcompare);
+ RUN_TEST(externalteardown);
return -1;
}
diff --git a/tests/auto/v8/v8test.cpp b/tests/auto/v8/v8test.cpp
index 0b299ed23c..b2734af8c3 100644
--- a/tests/auto/v8/v8test.cpp
+++ b/tests/auto/v8/v8test.cpp
@@ -54,6 +54,59 @@ using namespace v8;
} \
}
+struct MyStringResource : public String::ExternalAsciiStringResource
+{
+ static bool wasDestroyed;
+ virtual ~MyStringResource() { wasDestroyed = true; }
+ virtual const char* data() const { return "v8test"; }
+ virtual size_t length() const { return 6; }
+};
+bool MyStringResource::wasDestroyed = false;
+
+struct MyResource : public Object::ExternalResource
+{
+ static bool wasDestroyed;
+ virtual ~MyResource() { wasDestroyed = true; }
+};
+bool MyResource::wasDestroyed = false;
+
+bool v8test_externalteardown()
+{
+ BEGINTEST();
+
+ Isolate *isolate = v8::Isolate::New();
+ isolate->Enter();
+
+ {
+ HandleScope handle_scope;
+ Persistent<Context> context = Context::New();
+ Context::Scope context_scope(context);
+
+ Local<String> str = String::NewExternal(new MyStringResource);
+
+ Local<FunctionTemplate> ft = FunctionTemplate::New();
+ ft->InstanceTemplate()->SetHasExternalResource(true);
+
+ Local<Object> obj = ft->GetFunction()->NewInstance();
+ obj->SetExternalResource(new MyResource);
+
+ context.Dispose();
+ }
+
+ // while (!v8::V8::IdleNotification()) ;
+ isolate->Exit();
+ isolate->Dispose();
+
+ // ExternalString resources aren't guaranteed to be freed by v8 at this
+ // point. Uncommenting the IdleNotification() line above helps.
+// VERIFY(MyStringResource::wasDestroyed);
+
+ VERIFY(MyResource::wasDestroyed);
+
+cleanup:
+
+ ENDTEST();
+}
bool v8test_eval()
{
diff --git a/tests/auto/v8/v8test.h b/tests/auto/v8/v8test.h
index fa9bbe9f02..cb737971cb 100644
--- a/tests/auto/v8/v8test.h
+++ b/tests/auto/v8/v8test.h
@@ -51,6 +51,7 @@
bool v8test_eval();
bool v8test_evalwithinwith();
bool v8test_userobjectcompare();
+bool v8test_externalteardown();
#endif // V8TEST_H