Update V8
authorAaron Kennedy <aaron.kennedy@nokia.com>
Tue, 11 Oct 2011 05:06:25 +0000 (15:06 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 10 Nov 2011 12:22:13 +0000 (13:22 +0100)
Change-Id: Ic239ef1e55bed06260e4a04cc2199f64c2d30059
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
24 files changed:
src/3rdparty/v8
src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch
src/v8/0002-Add-a-bit-field-3-to-Map.patch [deleted file]
src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch [moved from src/v8/0003-Add-a-fallback-mode-for-named-property-interceptors.patch with 69% similarity]
src/v8/0003-Generalize-external-object-resources.patch [new file with mode: 0644]
src/v8/0004-Generalize-external-object-resources.patch [deleted file]
src/v8/0004-Introduce-a-QML-compilation-mode.patch [moved from src/v8/0005-Introduce-a-QML-compilation-mode.patch with 56% similarity]
src/v8/0005-Allow-access-to-the-calling-script-data.patch [moved from src/v8/0006-Allow-access-to-the-calling-script-data.patch with 77% similarity]
src/v8/0006-Add-custom-object-compare-callback.patch [moved from src/v8/0008-Add-custom-object-compare-callback.patch with 64% similarity]
src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch [moved from src/v8/0015-Allow-a-script-to-be-flagged-as-native.patch with 80% similarity]
src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch [moved from src/v8/0011-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch with 82% similarity]
src/v8/0009-Add-CallAsFunction-method-to-the-Object-class-in-the.patch [deleted file]
src/v8/0009-Fix-deprecated-Python-code.patch [moved from src/v8/0014-Fix-deprecated-Python-code.patch with 90% similarity]
src/v8/0010-Implement-CallAsConstructor-method-for-Object-in-the.patch [deleted file]
src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch [moved from src/v8/0013-Remove-execute-flag-from-v8-debug.h.patch with 70% similarity]
src/v8/0011-Fix-warnings.patch [moved from src/v8/0007-Fix-warnings.patch with 85% similarity]
src/v8/0012-Add-IsCallable-method-for-Object-in-the-API.patch [deleted file]
src/v8/0016-Move-external-resource-to-the-last-hidden-field.patch [deleted file]
src/v8/README
src/v8/v8.pri
tests/auto/v8/tst_v8.cpp
tests/auto/v8/v8main.cpp
tests/auto/v8/v8test.cpp
tests/auto/v8/v8test.h

index 8f15248..36be1e6 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8f15248619bb3bf49473dc3ede8a4e631bd5d199
+Subproject commit 36be1e6b4af4601faa40ea4a222539c6b48f0e03
index 8a844f5..7172cbf 100644 (file)
@@ -1,25 +1,25 @@
-From 3dff2e903674d8ab5310d44281b57de36db659c9 Mon Sep 17 00:00:00 2001
+From 0a86a97f554c4aaa727da1c4481ca6368c68bf85 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     |   1++++++-
+ 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 ac4f07f..996812e 100644
 --- a/src/api.cc
 +++ b/src/api.cc
-@@ -3284,6 +3284,49 @@ int String::Utf8Length() const {
-   return str->Utf8Length();
+@@ -3633,6 +3633,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 aaf2927..4c55d63 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 bbb9d3e..d287ead 100644
 --- a/src/heap.cc
 +++ b/src/heap.cc
-@@ -3519,6 +3519,7 @@ MaybeObject* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
+@@ -4009,6 +4009,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) {
+@@ -4051,6 +4052,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,
+@@ -4086,6 +4088,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 dc3aa46..34cae9f 100644
 --- a/src/objects-inl.h
 +++ b/src/objects-inl.h
-@@ -1924,6 +1924,7 @@ INT_ACCESSORS(ExternalArray, length, kLengthOffset)
+@@ -2082,6 +2082,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 9a87ac5..2946d02 100644
 --- a/src/objects.cc
 +++ b/src/objects.cc
-@@ -5346,6 +5346,66 @@ static inline bool CompareStringContentsPartial(Isolate* isolate,
-   }
+@@ -6716,6 +6716,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();
+@@ -10716,9 +10781,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 f7d2180..d96e5f9 100644
 --- a/src/objects.h
 +++ b/src/objects.h
-@@ -5359,6 +5359,9 @@ class String: public HeapObject {
+@@ -6201,6 +6201,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:
+@@ -6457,8 +6460,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.
+  private:
+   DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString);
 -- 
 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 (file)
index 59dbad3..0000000
+++ /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
-
@@ -1,7 +1,7 @@
-From 530ded6ea634bccb96652cd3e0cf67725449ed63 Mon Sep 17 00:00:00 2001
+From 20eca1d4ce4c56b599a052d496f4660f9ca9c978 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: Thu, 27 Oct 2011 11:31:56 +0100
+Subject: [PATCH 02/11] Add a "fallback" mode for named property interceptors
 
 By default interceptors are called before the normal property
 resolution on objects.  When an interceptor is installed as a
@@ -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      |    +++++++
  src/api.cc        |   29 +++++++++++++++++++++++++++++
- src/factory.cc    |    4 ++++
+ src/factory.cc    |    +++
  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 |   1+++++++++++++++
+ src/objects.cc    |   24 +++++++++++++++++-------
+ src/objects.h     |   1++++++++++++----
  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 996812e..e0f3b5a 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 15f640e..1b95ed1 100644
 --- a/src/factory.cc
 +++ b/src/factory.cc
-@@ -1058,6 +1058,10 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1213,6 +1213,9 @@ Handle<JSFunction> Factory::CreateApiFunction(
    // Set interceptor information in the map.
    if (!obj->named_property_handler()->IsUndefined()) {
      map->set_has_named_interceptor();
-+
 +    InterceptorInfo *nph = InterceptorInfo::cast(obj->named_property_handler());
 +    bool is_fallback = nph->is_fallback()->IsUndefined()?false:nph->is_fallback()->value();
 +    map->set_named_interceptor_is_fallback(is_fallback);
@@ -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 62851f3..790d224 100644
 --- a/src/handles.cc
 +++ b/src/handles.cc
-@@ -262,9 +262,11 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+@@ -269,9 +269,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 06e47fc..c359cb3 100644
 --- a/src/handles.h
 +++ b/src/handles.h
-@@ -188,7 +188,8 @@ Handle<Object> SetProperty(Handle<JSObject> object,
+@@ -190,7 +190,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 34cae9f..1cfea84 100644
 --- a/src/objects-inl.h
 +++ b/src/objects-inl.h
-@@ -2521,6 +2521,21 @@ bool Map::is_shared() {
+@@ -2754,6 +2754,20 @@ void Map::set_is_shared(bool value) {
+ bool Map::is_shared() {
+   return ((1 << kIsShared) & bit_field3()) != 0;
  }
++ 
 +void Map::set_named_interceptor_is_fallback(bool value)
 +{
 +  if (value) {
@@ -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)
+@@ -3255,6 +3269,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 2946d02..f5b6bee 100644
 --- a/src/objects.cc
 +++ b/src/objects.cc
-@@ -1712,9 +1712,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
- MaybeObject* JSObject::SetProperty(String* name,
-                                    Object* value,
-                                    PropertyAttributes attributes,
--                                   StrictModeFlag strict_mode) {
-+                                   StrictModeFlag strict_mode,
-+                                   bool skip_fallback_interceptor) {
-   LookupResult result;
+@@ -1980,9 +1980,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor(
+ MaybeObject* JSReceiver::SetProperty(String* name,
+                                      Object* value,
+                                      PropertyAttributes attributes,
+-                                     StrictModeFlag strict_mode) {
++                                     StrictModeFlag strict_mode,
++                                     bool skip_fallback_interceptor) {
+   LookupResult result(GetIsolate());
 -  LocalLookup(name, &result);
 +  LocalLookup(name, &result, skip_fallback_interceptor);
    return SetProperty(&result, name, value, attributes, strict_mode);
  }
  
-@@ -3148,7 +3149,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) {
+@@ -4213,7 +4214,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) {
+@@ -4245,23 +4247,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 d96e5f9..ed40061 100644
 --- a/src/objects.h
 +++ b/src/objects.h
-@@ -1405,7 +1405,8 @@ class JSObject: public HeapObject {
+@@ -1362,7 +1362,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 {
+@@ -1414,8 +1415,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();
+@@ -4242,6 +4243,10 @@ class Map: public HeapObject {
    inline void set_is_access_check_needed(bool access_check_needed);
    inline bool is_access_check_needed();
  
-+ 
 +  // Whether the named interceptor is a fallback interceptor or not
 +  inline void set_named_interceptor_is_fallback(bool value);
 +  inline bool named_interceptor_is_fallback();
 +
-+
    // [prototype]: implicit prototype object.
    DECL_ACCESSORS(prototype, Object)
  
-@@ -3904,6 +3911,7 @@ class Map: public HeapObject {
-   static const int kHasExternalArrayElements = 6;
+@@ -4506,6 +4511,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 {
+@@ -7390,6 +7396,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 {
+@@ -7409,7 +7416,8 @@ class InterceptorInfo: public Struct {
    static const int kDeleterOffset = kQueryOffset + kPointerSize;
    static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
    static const int kDataOffset = kEnumeratorOffset + kPointerSize;
@@ -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 9c23c2c..0e256c1 100644
 --- a/src/runtime.cc
 +++ b/src/runtime.cc
-@@ -1097,7 +1097,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
+@@ -1330,7 +1330,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
        // Lookup the property in the global object, and don't set the
        // value of the variable if the property is already there.
-       LookupResult lookup;
+       LookupResult lookup(isolate);
 -      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.
+@@ -1357,7 +1357,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
      }
  
-     LookupResult lookup;
+     LookupResult lookup(isolate);
 -    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
+@@ -1398,7 +1398,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) {
+@@ -1534,7 +1535,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+   while (object->IsJSObject() &&
+          JSObject::cast(object)->map()->is_hidden_prototype()) {
+     JSObject* raw_holder = JSObject::cast(object);
+-    raw_holder->LocalLookup(*name, &lookup);
++    raw_holder->LocalLookup(*name, &lookup, true);
+     if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
+       HandleScope handle_scope(isolate);
+       Handle<JSObject> holder(raw_holder);
+@@ -1557,7 +1558,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
+   // Reload global in case the loop above performed a GC.
    global = isolate->context()->global();
    if (assign) {
 -    return global->SetProperty(*name, args[2], attributes, strict_mode);
diff --git a/src/v8/0003-Generalize-external-object-resources.patch b/src/v8/0003-Generalize-external-object-resources.patch
new file mode 100644 (file)
index 0000000..7d532c4
--- /dev/null
@@ -0,0 +1,595 @@
+From 74974cee335e6c22ea99fd9a4bbb9c7fa7323d80 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 e0f3b5a..7d54252 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 ---
+@@ -4029,6 +4057,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 1b95ed1..8c96944 100644
+--- a/src/factory.cc
++++ b/src/factory.cc
+@@ -1152,15 +1152,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:
+@@ -1195,6 +1201,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 4c55d63..bca57cb 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;
+ }
+@@ -555,6 +570,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];
+@@ -583,14 +608,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);
+   if (FLAG_verify_heap) {
+     Verify();
+diff --git a/src/heap.cc b/src/heap.cc
+index d287ead..53a0f27 100644
+--- a/src/heap.cc
++++ b/src/heap.cc
+@@ -1099,18 +1099,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());
+ }
+@@ -1128,11 +1128,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.
+@@ -1140,12 +1140,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));
+ }
+@@ -6367,6 +6367,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 7c0b0ea..5e90964 100644
+--- a/src/heap.h
++++ b/src/heap.h
+@@ -245,8 +245,8 @@ class Isolate;
+ class WeakObjectRetainer;
+-typedef String* (*ExternalStringTableUpdaterCallback)(Heap* heap,
+-                                                      Object** pointer);
++typedef HeapObject* (*ExternalStringTableUpdaterCallback)(Heap* heap,
++                                                          Object** pointer);
+ class StoreBufferRebuilder {
+  public:
+@@ -331,10 +331,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);
+@@ -352,10 +356,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.
+@@ -851,7 +855,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.
+@@ -1656,7 +1660,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 b41b033..bf0aab8 100644
+--- a/src/mark-compact.cc
++++ b/src/mark-compact.cc
+@@ -1513,8 +1513,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();
+@@ -2487,15 +2488,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 1cfea84..6a80c9c 100644
+--- a/src/objects-inl.h
++++ b/src/objects-inl.h
+@@ -1343,7 +1343,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);
+ }
+@@ -1373,6 +1373,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.
+@@ -2755,6 +2772,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) {
+@@ -3301,6 +3332,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 ed40061..c38d461 100644
+--- a/src/objects.h
++++ b/src/objects.h
+@@ -1760,6 +1760,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);
+@@ -4171,11 +4174,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);
+@@ -4247,6 +4250,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)
+@@ -4487,7 +4495,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
+@@ -4512,6 +4520,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;
+@@ -7539,6 +7548,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);
+@@ -7555,7 +7565,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 (file)
index ece0f19..0000000
+++ /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
-
@@ -1,7 +1,7 @@
-From 60c1a26bf89d3b06bcdd8408fcee89a018120f32 Mon Sep 17 00:00:00 2001
+From 6f97385cf3cb17d245e7f3d61ba975183a786220 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: Thu, 27 Oct 2011 13:34:16 +0100
+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,58 +15,60 @@ 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                     |   1+++++++--
- 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/lithium-arm.cc           |    2 +-
- src/arm/lithium-arm.h            |    6 +++-
- src/arm/lithium-codegen-arm.cc   |    ++--
+ src/arm/full-codegen-arm.cc      |   28 +++++++++-------
+ src/arm/lithium-arm.cc           |    4 +-
+ src/arm/lithium-arm.h            |   12 ++++++-
+ src/arm/lithium-codegen-arm.cc   |    9 +++--
  src/arm/macro-assembler-arm.h    |    5 +++
  src/ast-inl.h                    |    5 +++
+ src/ast.cc                       |    5 +++
  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                  |    +++
+ 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/hydrogen.cc                  |    2 +
- src/ia32/code-stubs-ia32.cc      |    7 ++++
- src/ia32/full-codegen-ia32.cc    |   26 ++++++++------
- 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/heap.cc                      |    4 ++
+ src/hydrogen-instructions.cc     |    5 +++
+ src/hydrogen-instructions.h      |   16 ++++++++-
+ src/hydrogen.cc                  |    4 ++
+ src/ia32/code-stubs-ia32.cc      |    5 +++
+ src/ia32/full-codegen-ia32.cc    |   28 +++++++++-------
+ src/ia32/lithium-codegen-ia32.cc |    9 +++--
+ src/ia32/lithium-ia32.cc         |    4 +-
+ src/ia32/lithium-ia32.h          |   12 +++++-
+ src/ia32/macro-assembler-ia32.h  |    3 ++
+ src/objects-inl.h                |    2 +
+ src/objects.h                    |    4 ++
+ src/parser.cc                    |   28 +++++++++++++--
  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                    |   63 +++++++++++++++++++++++++++++++++++
+ 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/lithium-codegen-x64.cc   |    ++--
- src/x64/lithium-x64.cc           |    2 +-
- src/x64/lithium-x64.h            |    6 +++
+ src/x64/full-codegen-x64.cc      |   28 +++++++++-------
+ src/x64/lithium-codegen-x64.cc   |    9 +++--
+ src/x64/lithium-x64.cc           |    4 +-
+ src/x64/lithium-x64.h            |   12 +++++++
  src/x64/macro-assembler-x64.h    |    5 +++
- 45 files changed, 455 insertions(+), 109 deletions(-)
+ 47 files changed, 490 insertions(+), 117 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 +76,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 +90,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 +100,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 +110,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 +120,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 +128,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 +137,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 7d54252..2d3d97a 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 +150,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 +160,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 +188,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 +209,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 +218,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() {
+@@ -4337,6 +4347,30 @@ v8::Local<v8::Context> Context::GetCalling() {
  }
  
  
@@ -251,10 +254,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 cb3bc88..f5be938 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 +269,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 497a295..b8e3f30 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 +287,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);
+@@ -1193,9 +1194,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.
+@@ -1280,10 +1281,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;
+     }
+@@ -1920,7 +1921,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())));
+@@ -2220,10 +2221,13 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+       FLAG_harmony_scoping ? kStrictMode : strict_mode_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 +337,41 @@ index 871b453..a69f10d 100644
  }
  
  
-@@ -2263,9 +2267,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
+@@ -2296,9 +2300,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;
+@@ -3711,7 +3715,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);
+@@ -3997,7 +4001,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 5197842..943bc82 100644
 --- a/src/arm/lithium-arm.cc
 +++ b/src/arm/lithium-arm.cc
-@@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1128,7 +1128,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
  
  LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
    LOperand* context = UseRegisterAtStart(instr->value());
@@ -364,11 +380,20 @@ index 3f1d15b..8406a96 100644
  }
  
  
+@@ -1198,7 +1198,7 @@ LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
+ LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
+   argument_count_ -= instr->argument_count();
+-  return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr);
++  return MarkAsCall(DefineFixed(new LCallGlobal(instr->qml_global()), r0), instr);
+ }
 diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
-index 6da7c86..10b901f 100644
+index 5733bd0..a7e1704 100644
 --- a/src/arm/lithium-arm.h
 +++ b/src/arm/lithium-arm.h
-@@ -1378,13 +1378,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1303,13 +1303,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
  
  class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
   public:
@@ -387,11 +412,28 @@ index 6da7c86..10b901f 100644
  };
  
  
+@@ -1396,10 +1400,16 @@ class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
+   DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
+   DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
++  explicit LCallGlobal(bool qml_global) : qml_global_(qml_global) {}
++
+   virtual void PrintDataTo(StringStream* stream);
+   Handle<String> name() const {return hydrogen()->name(); }
+   int arity() const { return hydrogen()->argument_count() - 1; }
++
++  bool qml_global() { return qml_global_; }
++ private:
++  bool qml_global_;
+ };
 diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
-index 4912449..db114ea 100644
+index 4cf7df4..2e1e6fa 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,21 +448,30 @@ 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);
+@@ -2826,7 +2827,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));
  }
  
  
+@@ -3280,7 +3281,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
+   ASSERT(ToRegister(instr->result()).is(r0));
+   int arity = instr->arity();
+-  RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
++  RelocInfo::Mode mode = instr->qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT;
+   Handle<Code> ic =
+       isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
+   __ mov(r2, Operand(instr->name()));
 diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
-index ab5efb0..d40cdbc 100644
+index 90c4b37..5947e6a 100644
 --- a/src/arm/macro-assembler-arm.h
 +++ b/src/arm/macro-assembler-arm.h
-@@ -1056,6 +1056,11 @@ static inline MemOperand GlobalObjectOperand()  {
+@@ -1326,6 +1326,11 @@ static inline MemOperand GlobalObjectOperand()  {
  }
  
  
@@ -433,10 +484,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 f8b460d..217c71f 100644
 --- a/src/ast-inl.h
 +++ b/src/ast-inl.h
-@@ -106,6 +106,11 @@ bool FunctionLiteral::strict_mode() const {
+@@ -126,6 +126,11 @@ StrictModeFlag FunctionLiteral::strict_mode_flag() const {
  }
  
  
@@ -448,36 +499,52 @@ index d80684a..adc5a1f 100644
  } }  // namespace v8::internal
  
  #endif  // V8_AST_INL_H_
+diff --git a/src/ast.cc b/src/ast.cc
+index 9e34bc0..0dc3c1c 100644
+--- a/src/ast.cc
++++ b/src/ast.cc
+@@ -764,6 +764,11 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
+   is_monomorphic_ = oracle->CallIsMonomorphic(this);
+   Property* property = expression()->AsProperty();
+   if (property == NULL) {
++    if (VariableProxy *proxy = expression()->AsVariableProxy()) {
++        if (proxy->var()->is_qml_global())
++            return;
++    }
++
+     // Function call.  Specialize for monomorphic calls.
+     if (is_monomorphic_) target_ = oracle->GetCallTarget(this);
+   } else {
 diff --git a/src/ast.h b/src/ast.h
-index 65a25a9..f790dc0 100644
+index 3de00ef..8920b50 100644
 --- a/src/ast.h
 +++ b/src/ast.h
-@@ -1712,6 +1712,7 @@ class FunctionLiteral: public Expression {
-   int end_position() const { return end_position_; }
-   bool is_expression() const { return is_expression_; }
-   bool strict_mode() const;
+@@ -1653,6 +1653,7 @@ class FunctionLiteral: public Expression {
+   bool is_anonymous() const { return is_anonymous_; }
+   bool strict_mode() const { return strict_mode_flag() == kStrictMode; }
+   StrictModeFlag strict_mode_flag() 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 fc7000b..4380764 100644
 --- a/src/code-stubs.h
 +++ b/src/code-stubs.h
-@@ -303,7 +303,7 @@ class FastNewContextStub : public CodeStub {
+@@ -326,7 +326,7 @@ class FastNewContextStub : public CodeStub {
    static const int kMaximumSlots = 64;
  
    explicit FastNewContextStub(int slots) : slots_(slots) {
--    ASSERT(slots_ > 0 && slots <= kMaximumSlots);
+-    ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
 +    ASSERT(slots_ >= 0 && slots <= kMaximumSlots);
    }
  
    void Generate(MacroAssembler* masm);
 diff --git a/src/compiler.cc b/src/compiler.cc
-index 86d5de3..d2191b9 100755
+index 88db467..4902e72 100644
 --- a/src/compiler.cc
 +++ b/src/compiler.cc
-@@ -462,7 +462,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+@@ -447,7 +447,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
                                               v8::Extension* extension,
                                               ScriptDataImpl* input_pre_data,
                                               Handle<Object> script_data,
@@ -487,15 +554,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,
+@@ -515,6 +516,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,
+       compilation_cache->PutScript(source, result);
+@@ -534,7 +536,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
  Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
                                                   Handle<Context> context,
                                                   bool is_global,
@@ -505,17 +572,17 @@ 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,
-     CompilationInfo info(script);
+@@ -559,6 +562,7 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
      info.MarkAsEval();
      if (is_global) info.MarkAsGlobal();
+     info.SetStrictModeFlag(strict_mode);
 +    if (qml_mode) info.MarkAsQmlMode();
-     if (strict_mode == kStrictMode) info.MarkAsStrictMode();
      info.SetCallingContext(context);
      result = MakeFunctionInfo(&info);
-@@ -610,6 +614,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
-       info->MarkAsStrictMode();
-     }
+     if (!result.is_null()) {
+@@ -606,6 +610,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
+     info->SetStrictModeFlag(strict_mode);
+     shared->set_strict_mode_flag(strict_mode);
  
 +    // After parsing we know function's qml mode. Remember it.
 +    if (info->function()->qml_mode()) {
@@ -526,76 +593,63 @@ 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,
+@@ -751,6 +761,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_strict_mode_flag(lit->strict_mode_flag());
 +  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 bedf5ee..054e3b9 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; }
+@@ -57,6 +57,7 @@ class CompilationInfo BASE_EMBEDDED {
+     return StrictModeFlagField::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_; }
-@@ -83,6 +84,9 @@ class CompilationInfo BASE_EMBEDDED {
+@@ -85,6 +86,9 @@ class CompilationInfo BASE_EMBEDDED {
      ASSERT(is_lazy());
      flags_ |= IsInLoop::encode(true);
    }
 +  void MarkAsQmlMode() {
 +    flags_ |= IsQmlMode::encode(true);
 +  }
-   void MarkAsAllowingNativesSyntax() {
-     flags_ |= IsNativesSyntaxAllowed::encode(true);
+   void MarkAsNative() {
+     flags_ |= IsNative::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();
-+      }
+@@ -192,6 +196,9 @@ class CompilationInfo BASE_EMBEDDED {
+       ASSERT(strict_mode_flag() == kNonStrictMode);
+       SetStrictModeFlag(shared_info_->strict_mode_flag());
      }
++    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?
-   class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
+   void SetMode(Mode mode) {
+@@ -218,7 +225,8 @@ class CompilationInfo BASE_EMBEDDED {
+   // If compiling for debugging produce just full code matching the
+   // initial mode setting.
+   class IsCompilingForDebugging: public BitField<bool, 8, 1> {};
+-
 +  // Qml mode
-+  class IsQmlMode: public BitField<bool, 6, 1> {};
++  class IsQmlMode: public BitField<bool, 9, 1> {};
  
    unsigned flags_;
  
-@@ -252,13 +264,15 @@ class Compiler : public AllStatic {
+@@ -283,13 +291,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 +662,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 b25ffac..3129af0 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 +675,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 +684,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() ||
+@@ -228,6 +236,33 @@ Handle<Object> Context::Lookup(Handle<String> name,
      }
    } while (follow_context_chain);
  
@@ -664,22 +718,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 7021ff8..c3cfeee 100644
 --- a/src/contexts.h
 +++ b/src/contexts.h
-@@ -182,6 +182,7 @@ class Context: public FixedArray {
-     FCONTEXT_INDEX,
-     PREVIOUS_INDEX,
+@@ -218,6 +218,7 @@ class Context: public FixedArray {
+     // (with contexts), or the variable name (catch contexts), the serialized
+     // scope info (block contexts).
      EXTENSION_INDEX,
 +    QML_GLOBAL_INDEX,
      GLOBAL_INDEX,
      MIN_CONTEXT_SLOTS,
  
-@@ -273,6 +274,9 @@ class Context: public FixedArray {
+@@ -321,6 +322,9 @@ class Context: public FixedArray {
    }
    void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
  
@@ -690,71 +744,82 @@ 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 29955fa..4261ac2 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 is_construct,
                               Handle<Object> receiver,
                               int argc,
-                              Object*** args,
+                              Handle<Object> args[],
 -                             bool* has_pending_exception) {
 +                             bool* has_pending_exception,
 +                             Handle<Object> qml) {
-   Isolate* isolate = func->GetIsolate();
+   Isolate* isolate = function->GetIsolate();
  
    // Entering JavaScript.
-@@ -107,6 +108,12 @@ static Handle<Object> Invoke(bool construct,
+@@ -102,6 +103,12 @@ static Handle<Object> Invoke(bool is_construct,
    // make the current one is indeed a global object.
-   ASSERT(func->context()->global()->IsGlobalObject());
+   ASSERT(function->context()->global()->IsGlobalObject());
  
 +  Handle<JSObject> oldqml;
 +  if (!qml.is_null()) {
-+    oldqml = Handle<JSObject>(func->context()->qml_global());
-+    func->context()->set_qml_global(JSObject::cast(*qml));
++    oldqml = Handle<JSObject>(function->context()->qml_global());
++    function->context()->set_qml_global(JSObject::cast(*qml));
 +  }
 +
    {
      // 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,
-                                 receiver_pointer, argc, args);
+@@ -118,6 +125,9 @@ static Handle<Object> Invoke(bool is_construct,
+         CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
    }
  
 +  if (!qml.is_null()) 
-+    func->context()->set_qml_global(*oldqml);
++    function->context()->set_qml_global(*oldqml);
 +
  #ifdef DEBUG
    value->Verify();
  #endif
-@@ -150,14 +160,24 @@ Handle<Object> Execution::Call(Handle<JSFunction> func,
+@@ -146,7 +156,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>());
+                                Handle<Object> argv[],
+                                bool* pending_exception,
+-                               bool convert_receiver) {
++                               bool convert_receiver)
++{
++    return Call(callable, receiver, argc, argv, 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,
++                               Handle<Object> argv[],
 +                               bool* pending_exception,
++                               bool convert_receiver,
 +                               Handle<Object> qml) {
-+  return Invoke(false, func, receiver, argc, args, pending_exception, qml);
+   *pending_exception = false;
+   if (!callable->IsJSFunction()) {
+@@ -170,7 +191,7 @@ Handle<Object> Execution::Call(Handle<Object> callable,
+     if (*pending_exception) return callable;
+   }
+-  return Invoke(false, func, receiver, argc, argv, pending_exception);
++  return Invoke(false, func, receiver, argc, argv, pending_exception, qml);
  }
  
  
- Handle<Object> Execution::New(Handle<JSFunction> func, int argc,
-                               Object*** args, bool* pending_exception) {
-   return Invoke(true, func, Isolate::Current()->global(), argc, args,
+@@ -179,7 +200,7 @@ Handle<Object> Execution::New(Handle<JSFunction> func,
+                               Handle<Object> argv[],
+                               bool* pending_exception) {
+   return Invoke(true, func, Isolate::Current()->global(), argc, argv,
 -                pending_exception);
 +                pending_exception, Handle<Object>());
  }
  
  
-@@ -175,7 +195,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
-   catcher.SetCaptureMessage(false);
+@@ -198,7 +219,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
+   *caught_exception = false;
  
    Handle<Object> result = Invoke(false, func, receiver, argc, args,
 -                                 caught_exception);
@@ -763,36 +828,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 f2d17d0..532e5d8 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,
++                             Handle<Object> argv[],
 +                             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 27c509f..f099d25 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) {
+@@ -513,7 +513,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(
+@@ -537,6 +537,7 @@ void FullCodeGenerator::VisitDeclarations(
            }
            array->set(j++, *function);
          }
@@ -801,42 +868,74 @@ 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 9132502..78e6089 100644
 --- a/src/full-codegen.h
 +++ b/src/full-codegen.h
-@@ -505,6 +505,7 @@ class FullCodeGenerator: public AstVisitor {
+@@ -583,6 +583,7 @@ class FullCodeGenerator: public AstVisitor {
    StrictModeFlag strict_mode_flag() {
-     return is_strict_mode() ? kStrictMode : kNonStrictMode;
+     return function()->strict_mode_flag();
    }
 +  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 53a0f27..881a876 100644
 --- a/src/heap.cc
 +++ b/src/heap.cc
-@@ -3795,6 +3795,7 @@ MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
-   context->set_previous(NULL);
+@@ -4355,6 +4355,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;
+ }
+@@ -4375,6 +4376,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;
+ }
+@@ -4393,6 +4395,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;
+ }
+@@ -4411,6 +4414,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.cc b/src/hydrogen-instructions.cc
+index 6f46509..ac9728c 100644
+--- a/src/hydrogen-instructions.cc
++++ b/src/hydrogen-instructions.cc
+@@ -655,6 +655,11 @@ void HCallNamed::PrintDataTo(StringStream* stream) {
+ }
++void HGlobalObject::PrintDataTo(StringStream* stream) {
++  stream->Add("qml_global: %s ", qml_global()?"true":"false");
++  HUnaryOperation::PrintDataTo(stream);
++}
++
+ void HCallGlobal::PrintDataTo(StringStream* stream) {
+   stream->Add("%o ", *name());
+   HUnaryCall::PrintDataTo(stream);
 diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
-index a623775..52455bc 100644
+index 65fc4df..c29d781 100644
 --- a/src/hydrogen-instructions.h
 +++ b/src/hydrogen-instructions.h
-@@ -1148,7 +1148,7 @@ class HOuterContext: public HUnaryOperation {
+@@ -1410,19 +1410,27 @@ class HOuterContext: public HUnaryOperation {
  
  class HGlobalObject: public HUnaryOperation {
   public:
@@ -845,7 +944,12 @@ index a623775..52455bc 100644
      set_representation(Representation::Tagged());
      SetFlag(kUseGVN);
    }
-@@ -1159,8 +1159,14 @@ class HGlobalObject: public HUnaryOperation {
++  virtual void PrintDataTo(StringStream* stream);
++
+   DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
+   virtual Representation RequiredInputRepresentation(int index) {
      return Representation::Tagged();
    }
  
@@ -860,61 +964,88 @@ index a623775..52455bc 100644
  };
  
  
-@@ -1177,7 +1183,7 @@ class HGlobalReceiver: public HUnaryOperation {
-   virtual Representation RequiredInputRepresentation(int index) const {
+@@ -1601,7 +1609,7 @@ class HCallFunction: public HUnaryCall {
+ class HCallGlobal: public HUnaryCall {
+  public:
+   HCallGlobal(HValue* context, Handle<String> name, int argument_count)
+-      : HUnaryCall(context, argument_count), name_(name) {
++      : HUnaryCall(context, argument_count), name_(name), qml_global_(false) {
+   }
+   virtual void PrintDataTo(StringStream* stream);
+@@ -1613,10 +1621,14 @@ class HCallGlobal: public HUnaryCall {
      return Representation::Tagged();
    }
--
-+  
-  protected:
-   virtual bool DataEquals(HValue* other) { return true; }
++  bool qml_global() { return qml_global_; }
++  void set_qml_global(bool v) { qml_global_ = v; }
++
+   DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
+  private:
+   Handle<String> name_;
++  bool qml_global_;
  };
 diff --git a/src/hydrogen.cc b/src/hydrogen.cc
-index 73ea97d..d17e304 100644
+index 3a4d172..0a7fad1 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);
+@@ -3185,6 +3185,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,
+@@ -3644,6 +3645,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,
+@@ -5106,11 +5108,13 @@ void HGraphBuilder::VisitCall(Call* expr) {
+       } else {
+         HValue* context = environment()->LookupContext();
+         HGlobalObject* receiver = new(zone()) HGlobalObject(context);
++        if (var->is_qml_global()) receiver->set_qml_global(true);
+         AddInstruction(receiver);
+         PushAndAdd(new(zone()) HPushArgument(receiver));
+         CHECK_ALIVE(VisitArgumentList(expr->arguments()));
+         call = new(zone()) HCallGlobal(context, var->name(), argument_count);
++        if (var->is_qml_global()) static_cast<HCallGlobal*>(call)->set_qml_global(true);
+         Drop(argument_count);
+       }
 diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
-index 5d32095..afa599e 100644
+index 37b519a..8a94a06 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)));
+@@ -144,6 +144,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 25588c8..9cee4a3 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 +1057,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);
+@@ -1179,10 +1180,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);
+@@ -1263,10 +1264,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;
+     }
+@@ -1920,7 +1921,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())));
+@@ -2235,9 +2236,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+       FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
+   __ push(Immediate(Smi::FromInt(strict_mode)));
  
 +  // Push the qml mode flag
 +  __ push(Immediate(Smi::FromInt(is_qml_mode())));
@@ -981,22 +1107,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()) {
+@@ -2308,9 +2312,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).
+@@ -3777,7 +3781,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);
+@@ -4085,7 +4089,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 d4cbbce..b381227 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 +1156,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);
+@@ -2661,7 +2662,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
  void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
    Register context = ToRegister(instr->context());
    Register result = ToRegister(instr->result());
@@ -1021,11 +1166,20 @@ index 0f96f78..c1da075 100644
  }
  
  
+@@ -3131,7 +3132,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
+   ASSERT(ToRegister(instr->result()).is(eax));
+   int arity = instr->arity();
+-  RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
++  RelocInfo::Mode mode = instr->qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT;
+   Handle<Code> ic =
+       isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
+   __ mov(ecx, instr->name());
 diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
-index 9ccd189..8e98b73 100644
+index 626f899..d09d55f 100644
 --- a/src/ia32/lithium-ia32.cc
 +++ b/src/ia32/lithium-ia32.cc
-@@ -1205,7 +1205,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1144,7 +1144,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
  
  LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
    LOperand* context = UseRegisterAtStart(instr->value());
@@ -1034,11 +1188,20 @@ index 9ccd189..8e98b73 100644
  }
  
  
+@@ -1228,7 +1228,7 @@ LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
+ LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
+   LOperand* context = UseFixed(instr->context(), esi);
+   argument_count_ -= instr->argument_count();
+-  LCallGlobal* result = new LCallGlobal(context);
++  LCallGlobal* result = new LCallGlobal(context, instr->qml_global());
+   return MarkAsCall(DefineFixed(result, eax), instr);
+ }
 diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
-index 9ace8f8..95ed001 100644
+index 5f23afa..22541c8 100644
 --- a/src/ia32/lithium-ia32.h
 +++ b/src/ia32/lithium-ia32.h
-@@ -1416,13 +1416,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1338,13 +1338,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
  
  class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
   public:
@@ -1057,83 +1220,90 @@ index 9ace8f8..95ed001 100644
  };
  
  
+@@ -1443,7 +1447,7 @@ class LCallFunction: public LTemplateInstruction<1, 1, 0> {
+ class LCallGlobal: public LTemplateInstruction<1, 1, 0> {
+  public:
+-  explicit LCallGlobal(LOperand* context) {
++  explicit LCallGlobal(LOperand* context, bool qml_global) : qml_global_(qml_global) {
+     inputs_[0] = context;
+   }
+@@ -1455,6 +1459,10 @@ class LCallGlobal: public LTemplateInstruction<1, 1, 0> {
+   LOperand* context() { return inputs_[0]; }
+   Handle<String> name() const {return hydrogen()->name(); }
+   int arity() const { return hydrogen()->argument_count() - 1; }
++
++  bool qml_global() { return qml_global_; }
++ private:
++  bool qml_global_;
+ };
 diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
-index b986264..f8479ae 100644
+index 8528c55..de3c3a0 100644
 --- a/src/ia32/macro-assembler-ia32.h
 +++ b/src/ia32/macro-assembler-ia32.h
-@@ -778,6 +778,11 @@ static inline Operand GlobalObjectOperand() {
+@@ -935,6 +935,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 6a80c9c..2e83fb7 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)
+@@ -3535,6 +3535,8 @@ void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
+ BOOL_GETTER(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 c38d461..73e7f8b 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);
-+  // Indicates whether the function is a qml mode function
-+  inline bool qml_mode();
-+  inline void set_qml_mode(bool value);
-+
-   // 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;
+@@ -4929,6 +4929,9 @@ class SharedFunctionInfo: public HeapObject {
+   inline StrictModeFlag strict_mode_flag();
+   inline void set_strict_mode_flag(StrictModeFlag strict_mode_flag);
  
-  private:
- #if V8_HOST_ARCH_32_BIT
++  // Indicates whether the function is a qml mode function.
++  DECL_BOOLEAN_ACCESSORS(qml_mode)
++
+   // False if the function definitely does not allocate an arguments object.
+   DECL_BOOLEAN_ACCESSORS(uses_arguments)
+@@ -5150,6 +5153,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 37204c9..357d340 100644
 --- a/src/parser.cc
 +++ b/src/parser.cc
-@@ -593,7 +593,8 @@ Parser::Parser(Handle<Script> script,
+@@ -607,7 +607,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,
+@@ -623,11 +624,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
      ExternalTwoByteStringUC16CharacterStream stream(
          Handle<ExternalTwoByteString>::cast(source), 0, source->length());
      scanner_.Initialize(&stream);
@@ -1147,35 +1317,36 @@ index a84ec6f..7f5c361 100644
    }
  }
  
-@@ -621,6 +622,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
+@@ -635,6 +636,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
  FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
                                          bool in_global_context,
                                          StrictModeFlag strict_mode,
 +                                        bool qml_mode,
                                          ZoneScope* zone_scope) {
+   ASSERT(top_scope_ == NULL);
    ASSERT(target_stack_ == NULL);
-   if (pre_data_ != NULL) pre_data_->Initialize();
-@@ -641,6 +643,9 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
-     if (strict_mode == kStrictMode) {
-       top_scope_->EnableStrictMode();
-     }
+@@ -654,6 +656,9 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
+     LexicalScope lexical_scope(this, scope, isolate());
+     ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode);
+     top_scope_->SetStrictModeFlag(strict_mode);
 +    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,
-     if (shared_info->strict_mode()) {
-       top_scope_->EnableStrictMode();
-     }
+@@ -747,6 +752,10 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
+            scope->strict_mode_flag() == info->strict_mode_flag());
+     ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag());
+     scope->SetStrictModeFlag(shared_info->strict_mode_flag());
 +    if (shared_info->qml_mode()) {
 +      top_scope_->EnableQmlMode();
 +    }
-     FunctionLiteralType type =
-         shared_info->is_expression() ? EXPRESSION : DECLARATION;
-@@ -1661,6 +1669,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
++
+     FunctionLiteral::Type type = shared_info->is_expression()
+         ? (shared_info->is_anonymous()
+               ? FunctionLiteral::ANONYMOUS_EXPRESSION
+@@ -1856,6 +1865,11 @@ Block* Parser::ParseVariableDeclarations(
          arguments->Add(value);
          value = NULL;  // zap the value to avoid the unnecessary assignment
  
@@ -1187,9 +1358,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));
+@@ -1872,6 +1886,11 @@ Block* Parser::ParseVariableDeclarations(
+         StrictModeFlag flag = initialization_scope->strict_mode_flag();
+         arguments->Add(NewNumberLiteral(flag));
  
 +        int qml_mode = 0;
 +        if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) 
@@ -1199,31 +1370,31 @@ 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) {
+@@ -5418,7 +5437,8 @@ bool ParserApi::Parse(CompilationInfo* info) {
        Handle<String> source = Handle<String>(String::cast(script->source()));
        result = parser.ParseProgram(source,
                                     info->is_global(),
--                                   info->StrictMode());
-+                                   info->StrictMode(),
+-                                   info->strict_mode_flag());
++                                   info->strict_mode_flag(),
 +                                   info->is_qml_mode());
      }
    }
+   info->SetFunction(result);
 diff --git a/src/parser.h b/src/parser.h
-index 64f1303..4d45e45 100644
+index eaae6f7..a60951d 100644
 --- a/src/parser.h
 +++ b/src/parser.h
-@@ -431,7 +431,8 @@ class Parser {
+@@ -430,7 +430,8 @@ class Parser {
    // Returns NULL if parsing failed.
    FunctionLiteral* ParseProgram(Handle<String> source,
                                  bool in_global_context,
 -                                StrictModeFlag strict_mode);
 +                                StrictModeFlag strict_mode,
-+                                bool qml_mode);
++                                bool qml_mode = false);
  
    FunctionLiteral* ParseLazy(CompilationInfo* info);
  
-@@ -464,6 +465,7 @@ class Parser {
+@@ -476,6 +477,7 @@ class Parser {
    FunctionLiteral* DoParseProgram(Handle<String> source,
                                    bool in_global_context,
                                    StrictModeFlag strict_mode,
@@ -1232,10 +1403,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 +1417,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 0e256c1..5746c20 100644
 --- a/src/runtime.cc
 +++ b/src/runtime.cc
-@@ -1065,8 +1065,6 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,
+@@ -1307,19 +1307,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 +1447,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) {
+@@ -1506,19 +1510,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
    NoHandleAllocation nha;
    // args[0] == name
    // args[1] == strict_mode
@@ -1301,8 +1465,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 +1476,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);
+@@ -1546,7 +1555,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);
+@@ -1556,9 +1565,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 +1497,7 @@ index 660352c..c13f92d 100644
    }
    return isolate->heap()->undefined_value();
  }
-@@ -1411,12 +1420,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
+@@ -1568,12 +1577,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 +1515,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.
+@@ -1597,7 +1609,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) {
+@@ -9386,7 +9398,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
    Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
                                                              context,
                                                              true,
@@ -1389,26 +1534,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) {
+@@ -9399,7 +9412,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());
+@@ -9417,7 +9431,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,
+@@ -9427,7 +9442,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
  
  
  RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
@@ -1417,7 +1563,7 @@ index 660352c..c13f92d 100644
  
    HandleScope scope(isolate);
    Handle<Object> callee = args.at<Object>(0);
-@@ -8257,16 +8272,18 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
+@@ -9490,15 +9505,17 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
    }
  
    ASSERT(args[3]->IsSmi());
@@ -1425,9 +1571,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 +1583,7 @@ index 660352c..c13f92d 100644
  
    HandleScope scope(isolate);
    Handle<Object> callee = args.at<Object>(0);
-@@ -8280,11 +8297,13 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
+@@ -9511,10 +9528,12 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
    }
  
    ASSERT(args[3]->IsSmi());
@@ -1446,14 +1591,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) {
+@@ -12034,6 +12053,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 +1605,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) {
+@@ -12107,7 +12127,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
        Compiler::CompileEval(function_source,
                              context,
                              context->IsGlobalContext(),
@@ -1471,17 +1615,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,
+@@ -12117,7 +12138,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,
+@@ -12198,7 +12220,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 +1635,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 67fc628..aada06d 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 +1649,9 @@ index bf1ba68..5e97173 100644
    \
    F(SetProperty, -1 /* 4 or 5 */, 1) \
    F(DefineOrRedefineDataProperty, 4, 1) \
-@@ -296,8 +296,8 @@ namespace internal {
+@@ -336,8 +336,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,102 +1661,112 @@ index bf1ba68..5e97173 100644
    F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
    \
 diff --git a/src/scopes.cc b/src/scopes.cc
-index 8df93c5..b5d7ff3 100644
+index 3167c4d..6503d07 100644
 --- a/src/scopes.cc
 +++ b/src/scopes.cc
-@@ -198,6 +198,7 @@ void Scope::SetDefaults(Type type,
-   scope_calls_eval_ = false;
+@@ -35,6 +35,8 @@
+ #include "allocation-inl.h"
++#include "debug.h"
++
+ namespace v8 {
+ namespace internal {
+@@ -202,6 +204,7 @@ void Scope::SetDefaults(ScopeType type,
    // Inherit the strict mode from the parent scope.
-   strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_;
+   strict_mode_flag_ = (outer_scope != NULL)
+       ? outer_scope->strict_mode_flag_ : kNonStrictMode;
 +  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,
-         ASSERT(global_scope != NULL);
-         var = global_scope->DeclareGlobal(proxy->name());
+   force_eager_compilation_ = false;
+@@ -907,6 +910,26 @@ void Scope::ResolveVariable(Scope* global_scope,
+       // by 'eval' introduced variable bindings.
+       if (var->is_global()) {
+         var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
++
 +        if (qml_mode_) {
-+          Handle<GlobalObject> global = Isolate::Current()->global();
++          Handle<GlobalObject> global = isolate_->global();
 +
 +#ifdef ENABLE_DEBUGGER_SUPPORT
-+          if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
++          if (isolate_->debug()->IsLoaded() && isolate_->debug()->InDebugger()) {
 +            //Get the context before the debugger was entered.
-+            SaveContext *save = Isolate::Current()->save_context();
-+            while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
++            SaveContext *save = isolate_->save_context();
++            while (save != NULL && *save->context() == *isolate_->debug()->debug_context())
 +              save = save->prev();
 +
 +            global = Handle<GlobalObject>(save->context()->global());
 +          }
 +#endif
 +
-+          if (!global->HasProperty(*(proxy->name()))) {
++          if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
 +            var->set_is_qml_global(true);
 +          }
 +        }
 +
-       } else if (scope_inside_with_) {
-         // If we are inside a with statement we give up and look up
-         // the variable at runtime.
-@@ -817,6 +837,25 @@ void Scope::ResolveVariable(Scope* global_scope,
-         if (context->GlobalIfNotShadowedByEval(proxy->name())) {
-           var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
-+          if (qml_mode_) {
-+            Handle<GlobalObject> global = Isolate::Current()->global();
+       } else {
+         Variable* invalidated = var;
+         var = NonLocal(proxy->name(), DYNAMIC_LOCAL);
+@@ -918,12 +941,52 @@ void Scope::ResolveVariable(Scope* global_scope,
+       // No binding has been found. Declare a variable in global scope.
+       ASSERT(global_scope != NULL);
+       var = global_scope->DeclareGlobal(proxy->name());
++
++      if (qml_mode_) {
++        Handle<GlobalObject> global = isolate_->global();
 +
 +#ifdef ENABLE_DEBUGGER_SUPPORT
-+            if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
-+              //Get the context before the debugger was entered.
-+              SaveContext *save = Isolate::Current()->save_context();
-+              while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
-+                save = save->prev();
-+
-+              global = Handle<GlobalObject>(save->context()->global());
-+            }
++        if (isolate_->debug()->IsLoaded() && isolate_->debug()->InDebugger()) {
++          //Get the context before the debugger was entered.
++          SaveContext *save = isolate_->save_context();
++          while (save != NULL && *save->context() == *isolate_->debug()->debug_context())
++            save = save->prev();
++
++          global = Handle<GlobalObject>(save->context()->global());
++        }
 +#endif
 +
-+            if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
-+              var->set_is_qml_global(true);
-+            }
-+          }
++        if (!global->HasProperty(*(proxy->name()))) {
++          var->set_is_qml_global(true);
++        }
++      }
 +
-         } else {
-           var = NonLocal(proxy->name(), Variable::DYNAMIC);
-         }
-@@ -827,6 +866,26 @@ void Scope::ResolveVariable(Scope* global_scope,
-         // variable is global unless it is shadowed by eval-introduced
-         // variables.
-         var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
+       break;
+     case UNBOUND_EVAL_SHADOWED:
+       // No binding has been found. But some scope makes a
+       // non-strict 'eval' call.
+       var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
 +
-+        if (qml_mode_) {
-+          Handle<GlobalObject> global = Isolate::Current()->global();
++      if (qml_mode_) {
++        Handle<GlobalObject> global = isolate_->global();
 +
 +#ifdef ENABLE_DEBUGGER_SUPPORT
-+          if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
-+            //Get the context before the debugger was entered.
-+            SaveContext *save = Isolate::Current()->save_context();
-+            while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
-+              save = save->prev();
++        if (isolate_->debug()->IsLoaded() && isolate_->debug()->InDebugger()) {
++          //Get the context before the debugger was entered.
++          SaveContext *save = isolate_->save_context();
++          while (save != NULL && *save->context() == *isolate_->debug()->debug_context())
++            save = save->prev();
 +
-+            global = Handle<GlobalObject>(save->context()->global());
-+          }
++          global = Handle<GlobalObject>(save->context()->global());
++        }
 +#endif
 +
-+          if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
-+            var->set_is_qml_global(true);
-+          }
++        if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
++          var->set_is_qml_global(true);
 +        }
++      }
 +
-       }
-     }
-   }
+       break;
+     case DYNAMIC_LOOKUP:
 diff --git a/src/scopes.h b/src/scopes.h
-index a0e56a4..6dd3f65 100644
+index a141887..41e5f5c 100644
 --- a/src/scopes.h
 +++ b/src/scopes.h
-@@ -210,6 +210,11 @@ class Scope: public ZoneObject {
-     strict_mode_ = FLAG_strict_mode;
+@@ -228,6 +228,11 @@ class Scope: public ZoneObject {
+     end_position_ = statement_pos;
    }
  
 +  // Enable qml mode for this scope
@@ -1623,28 +1777,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; }
-   bool is_strict_mode() const { return strict_mode_; }
+@@ -242,6 +247,7 @@ class Scope: public ZoneObject {
+     return is_eval_scope() || is_function_scope() || is_global_scope();
+   }
+   bool is_strict_mode() const { return strict_mode_flag() == kStrictMode; }
 +  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();
+   }
+@@ -427,6 +433,8 @@ class Scope: public ZoneObject {
+   // Source positions.
+   int start_position_;
+   int end_position_;
++  // This scope is a qml mode scope.
++  bool qml_mode_;
  
    // Computed via PropagateScopeInfo.
-   bool outer_scope_calls_eval_;
+   bool outer_scope_calls_non_strict_eval_;
 diff --git a/src/variables.cc b/src/variables.cc
-index 0502722..190baf6 100644
+index d85e1b2..1887935 100644
 --- a/src/variables.cc
 +++ b/src/variables.cc
-@@ -99,7 +99,8 @@ Variable::Variable(Scope* scope,
-     rewrite_(NULL),
+@@ -68,7 +68,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 +1809,19 @@ index 0502722..190baf6 100644
    ASSERT(name->IsSymbol());
  }
 diff --git a/src/variables.h b/src/variables.h
-index b1ff0db..0b31d1a 100644
+index 8b2d869..33561b0 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; }
+@@ -155,6 +155,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 {
+@@ -175,6 +177,9 @@ class Variable: public ZoneObject {
    // Usage info.
    bool is_accessed_from_inner_scope_;  // set by variable resolver
    bool is_used_;
@@ -1677,14 +1832,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 f62c517..f30221f 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 +1847,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 bf640db..b1e5d35 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 +1865,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);
+@@ -1155,10 +1156,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);
+@@ -1240,9 +1241,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;
+     }
+@@ -1834,7 +1835,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()));
+@@ -2117,9 +2118,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
+       FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
+   __ Push(Smi::FromInt(strict_mode));
  
 +  // Push the qml mode flag
 +  __ Push(Smi::FromInt(is_qml_mode()));
@@ -1764,22 +1914,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.
+@@ -2188,8 +2192,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;
+@@ -3638,7 +3642,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);
+@@ -3936,7 +3940,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 38a8c18..2a95fee 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 +1962,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);
+@@ -2610,7 +2611,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
  
  void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
    Register result = ToRegister(instr->result());
@@ -1804,11 +1972,20 @@ index 202e7a2..45acbdf 100644
  }
  
  
+@@ -3049,7 +3050,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
+ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
+   ASSERT(ToRegister(instr->result()).is(rax));
+   int arity = instr->arity();
+-  RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
++  RelocInfo::Mode mode = instr->qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT;
+   Handle<Code> ic =
+       isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
+   __ Move(rcx, instr->name());
 diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
-index 07ca3a5..00feeac 100644
+index 0af2ce4..9e2731f 100644
 --- a/src/x64/lithium-x64.cc
 +++ b/src/x64/lithium-x64.cc
-@@ -1194,7 +1194,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
+@@ -1123,7 +1123,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
  
  
  LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
@@ -1817,11 +1994,20 @@ index 07ca3a5..00feeac 100644
  }
  
  
+@@ -1193,7 +1193,7 @@ LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
+ LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
+   argument_count_ -= instr->argument_count();
+-  return MarkAsCall(DefineFixed(new LCallGlobal, rax), instr);
++  return MarkAsCall(DefineFixed(new LCallGlobal(instr->qml_global()), rax), instr);
+ }
 diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
-index 15bb894..16f754c 100644
+index 20a6937..8f1a3d8 100644
 --- a/src/x64/lithium-x64.h
 +++ b/src/x64/lithium-x64.h
-@@ -1365,7 +1365,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
+@@ -1303,7 +1303,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
  
  class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
   public:
@@ -1835,11 +2021,28 @@ index 15bb894..16f754c 100644
  };
  
  
+@@ -1393,10 +1399,16 @@ class LCallGlobal: public LTemplateInstruction<1, 0, 0> {
+   DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call-global")
+   DECLARE_HYDROGEN_ACCESSOR(CallGlobal)
++  explicit LCallGlobal(bool qml_global) : qml_global_(qml_global) {}
++
+   virtual void PrintDataTo(StringStream* stream);
+   Handle<String> name() const {return hydrogen()->name(); }
+   int arity() const { return hydrogen()->argument_count() - 1; }
++
++  bool qml_global() { return qml_global_; }
++ private:
++  bool qml_global_;
+ };
 diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
-index 4c17720..aa284ed 100644
+index f5f81b1..5caa6cf 100644
 --- a/src/x64/macro-assembler-x64.h
 +++ b/src/x64/macro-assembler-x64.h
-@@ -1233,6 +1233,11 @@ static inline Operand GlobalObjectOperand() {
+@@ -1418,6 +1418,11 @@ static inline Operand GlobalObjectOperand() {
  }
  
  
@@ -1,7 +1,7 @@
-From 1209b88e96f253cdc19aa4c95e011c84597844f0 Mon Sep 17 00:00:00 2001
+From a321f382dd8a63ed71cd00a57d011f966a35645f 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 2d3d97a..54df40d 100644
 --- a/src/api.cc
 +++ b/src/api.cc
-@@ -3976,6 +3976,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
+@@ -4370,6 +4370,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
    }
  }
  
@@ -1,7 +1,7 @@
-From a7c491e6e533110a17fe9f7d47cf92a1b2263180 Mon Sep 17 00:00:00 2001
+From 15e2b05fae59aa4ed7c0974ba296ec8893c4d7f2 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: Thu, 27 Oct 2011 13:40:00 +0100
+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   |   4++++++++++++++++++++++++++++++++++++++++--
+ 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 54df40d..974d702 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(
+@@ -5113,6 +5124,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 f5be938..1e1aebd 100644
 --- a/src/arm/code-stubs-arm.cc
 +++ b/src/arm/code-stubs-arm.cc
-@@ -1563,6 +1563,36 @@ void CompareStub::Generate(MacroAssembler* masm) {
+@@ -1569,6 +1569,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);
+@@ -6615,10 +6646,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 8c96944..76ca69d 100644
 --- a/src/factory.cc
 +++ b/src/factory.cc
-@@ -998,6 +998,7 @@ Handle<JSFunction> Factory::CreateApiFunction(
+@@ -1153,6 +1153,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(
+@@ -1162,6 +1163,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(
+@@ -1206,6 +1209,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 8a94a06..e73753e 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.");
-   }
+@@ -4020,6 +4020,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.
+   {
+@@ -6497,8 +6530,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 a073af9..36c1dfd 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;
+   top_lookup_result_ = NULL;
+@@ -729,6 +730,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 5453bf2..9919e83 100644
 --- a/src/isolate.h
 +++ b/src/isolate.h
-@@ -267,6 +267,9 @@ class ThreadLocalTop BASE_EMBEDDED {
-   // Call back function to report unsafe JS accesses.
-   v8::FailedAccessCheckCallback failed_access_check_callback_;
+@@ -258,6 +258,9 @@ class ThreadLocalTop BASE_EMBEDDED {
+   // Head of the list of live LookupResults.
+   LookupResult* top_lookup_result_;
  
 +  // 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 {
+@@ -703,6 +706,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 2e83fb7..13d7591 100644
 --- a/src/objects-inl.h
 +++ b/src/objects-inl.h
-@@ -2552,6 +2552,19 @@ bool Map::has_external_resource()
+@@ -2749,14 +2749,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;
+ }
+@@ -2786,6 +2786,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,
+@@ -3334,6 +3347,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 f5b6bee..6a4eff9 100644
+--- a/src/objects.cc
++++ b/src/objects.cc
+@@ -7686,8 +7686,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
+@@ -7707,8 +7707,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 73e7f8b..9dcacac 100644
 --- a/src/objects.h
 +++ b/src/objects.h
-@@ -3724,6 +3724,11 @@ class Map: public HeapObject {
+@@ -4255,6 +4255,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)
+@@ -4502,7 +4507,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;
+@@ -4521,6 +4526,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 {
+@@ -7553,6 +7559,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 {
+@@ -7570,7 +7577,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 5746c20..542e62b 100644
 --- a/src/runtime.cc
 +++ b/src/runtime.cc
-@@ -6279,6 +6279,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) {
+@@ -7095,6 +7095,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 aada06d..cd36da9 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 f30221f..ff8337f 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);
-   }
+@@ -3088,6 +3088,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;
+@@ -5421,8 +5452,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);
@@ -1,7 +1,7 @@
-From 523f03f03b1ac16d272a13389f8a5654d9ff12e6 Mon Sep 17 00:00:00 2001
+From c9277f820ae47f32f127b156ac2e1200458ab876 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 4902e72..cabca74 100644
 --- a/src/compiler.cc
 +++ b/src/compiler.cc
-@@ -507,7 +507,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
+@@ -499,7 +499,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
  
      // Create a script object describing the script to be compiled.
      Handle<Script> script = FACTORY->NewScript(source);
@@ -1,7 +1,7 @@
-From 5f3e5dd6901b54707ea4f868d8fa7317c4ab3852 Mon Sep 17 00:00:00 2001
+From 8e095c6171d6be5ac3c90fd2a8707579050d5e47 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 974d702..a16ef65 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 5e90964..6166cde 100644
 --- a/src/heap.h
 +++ b/src/heap.h
-@@ -169,6 +169,7 @@ inline Heap* _inline_get_heap_();
+@@ -190,6 +190,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 (file)
index b89f152..0000000
+++ /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
-
similarity index 90%
rename from src/v8/0014-Fix-deprecated-Python-code.patch
rename to src/v8/0009-Fix-deprecated-Python-code.patch
index 9745a5c..253f4fd 100644 (file)
@@ -1,7 +1,7 @@
-From ed5cc903d70f73780e5985e7d2de33f6b8d86402 Mon Sep 17 00:00:00 2001
+From bf0c62b53bf018a7f0b3e9ea3dcdcbcc0ee6fd53 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 (file)
index 847cb86..0000000
+++ /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
-
@@ -1,7 +1,7 @@
-From c36be227e9d7952a1952caa529c78ecdc376bd55 Mon Sep 17 00:00:00 2001
+From b79ebeab15653e37390ccfca1f6ee252979844ce 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(-)
similarity index 85%
rename from src/v8/0007-Fix-warnings.patch
rename to src/v8/0011-Fix-warnings.patch
index b4e39cc..d4d8d3a 100644 (file)
@@ -1,18 +1,18 @@
-From 2a5cf85d7fd7912e516138db03e4cda47cc2a1ab Mon Sep 17 00:00:00 2001
+From 36be1e6b4af4601faa40ea4a222539c6b48f0e03 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 (file)
index 412cebd..0000000
+++ /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 (file)
index b6dde1e..0000000
+++ /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
-
index 2dc3970..850f703 100644 (file)
@@ -1 +1 @@
-These patches apply cleanly against v8 at 2eaa4b29586fdbd5d41f7b7d9e72ecca6d53dbd2
+These patches apply cleanly against v8 at e123c9dfe54146f8bfca38841255f63a95a00a19
index 1d1abc8..1c72592 100644 (file)
@@ -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,10 @@ 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 \
+
+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 +274,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
index c753806..77a3413 100644 (file)
@@ -57,6 +57,8 @@ private slots:
     void eval();
     void evalwithinwith();
     void userobjectcompare();
+    void externalteardown();
+    void globalcall();
 };
 
 void tst_v8::eval()
@@ -74,6 +76,16 @@ void tst_v8::userobjectcompare()
     QVERIFY(v8test_userobjectcompare());
 }
 
+void tst_v8::externalteardown()
+{
+    QVERIFY(v8test_externalteardown());
+}
+
+void tst_v8::globalcall()
+{
+    QVERIFY(v8test_globalcall());
+}
+
 int main(int argc, char *argv[])
 {
     V8::SetFlagsFromCommandLine(&argc, argv, true);
index b38bbab..091d2ca 100644 (file)
 
 #include "v8test.h"
 #include <stdio.h>
+#include <strings.h>
 
 #define RUN_TEST(testname) { \
-    if (!v8test_ ## testname()) \
-        printf ("Test %s FAILED\n", # testname); \
+    if (argc == 1 || 0 == ::strcmp(argv[1], # 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 +59,8 @@ int main(int argc, char *argv[])
     RUN_TEST(eval);
     RUN_TEST(evalwithinwith);
     RUN_TEST(userobjectcompare);
+    RUN_TEST(externalteardown);
+    RUN_TEST(globalcall);
 
     return -1;
 }
index 0b299ed..d9a71dd 100644 (file)
@@ -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()
 {
@@ -81,6 +134,35 @@ cleanup:
     ENDTEST();
 }
 
+bool v8test_globalcall()
+{
+    BEGINTEST();
+
+    HandleScope handle_scope;
+    Persistent<Context> context = Context::New();
+    Context::Scope context_scope(context);
+
+    Local<Object> qmlglobal = Object::New();
+
+#define SOURCE "function func1() { return 1; }\n" \
+               "function func2() { var sum = 0; for (var ii = 0; ii < 10000000; ++ii) { sum += func1(); } return sum; }\n" \
+               "func2();"
+
+    Local<Script> script = Script::Compile(String::New(SOURCE), NULL, NULL,
+                                           Handle<String>(), Script::QmlMode);
+    Local<Value> result = script->Run(qmlglobal);
+    VERIFY(!result.IsEmpty());
+    VERIFY(result->IsInt32());
+    VERIFY(result->Int32Value() == 10000000);
+
+#undef SOURCE
+
+cleanup:
+    context.Dispose();
+
+    ENDTEST();
+}
+
 bool v8test_evalwithinwith()
 {
     BEGINTEST();
index fa9bbe9..7d389f8 100644 (file)
@@ -51,6 +51,8 @@
 bool v8test_eval();
 bool v8test_evalwithinwith();
 bool v8test_userobjectcompare();
+bool v8test_externalteardown();
+bool v8test_globalcall();
 
 #endif // V8TEST_H