diff --git a/.gitignore b/.gitignore index 03883f652e8a57724258059e6293b7bb5ea76724..87d3f62aa73fa5d8a08d8bfbc499c74a8c93ccca 100644 --- a/.gitignore +++ b/.gitignore @@ -128,13 +128,10 @@ src/openvg/qtopenvgversion.h src/sql/qtsqlversion.h src/testlib/qttestversion.h src/xml/qtxmlversion.h -src/v8/qtv8version.h src/platformsupport/qtplatformsupportversion.h src/printsupport/qtprintsupportversion.h src/widgets/qtwidgetsversion.h -src/v8/generated-debug/ - # Test generated files QObject.log tst_* diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 183f5b46cc105990d057a6998203c7b1a2deb12e..0000000000000000000000000000000000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/3rdparty/v8"] - path = src/3rdparty/v8 - url = git://github.com/aaronkennedy/v8.git diff --git a/src/3rdparty/v8 b/src/3rdparty/v8 deleted file mode 160000 index a07f617da094b83b7a9e5b2d37e8bf9172c61109..0000000000000000000000000000000000000000 --- a/src/3rdparty/v8 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a07f617da094b83b7a9e5b2d37e8bf9172c61109 diff --git a/src/modules/qt_v8.pri b/src/modules/qt_v8.pri deleted file mode 100644 index 89d6c263e866f2da9853d11912bada17d73203bc..0000000000000000000000000000000000000000 --- a/src/modules/qt_v8.pri +++ /dev/null @@ -1,16 +0,0 @@ -QT.v8.VERSION = 5.0.0 -QT.v8.MAJOR_VERSION = 5 -QT.v8.MINOR_VERSION = 0 -QT.v8.PATCH_VERSION = 0 - -QT.v8.name = QtV8 -QT.v8.bins = $$QT_MODULE_BIN_BASE -QT.v8.includes = $$QT_MODULE_INCLUDE_BASE/QtV8 -QT.v8.private_includes = $$QT_MODULE_INCLUDE_BASE/QtV8/$$QT.v8.VERSION -QT.v8.sources = $$QT_MODULE_BASE/src/v8 -QT.v8.libs = $$QT_MODULE_LIB_BASE -QT.v8.plugins = $$QT_MODULE_PLUGIN_BASE -QT.v8.imports = $$QT_MODULE_IMPORT_BASE -QT.v8.depends = -QT.v8.DEFINES = -!contains(QT_CONFIG, static): QT.v8.DEFINES += V8_SHARED USING_V8_SHARED diff --git a/src/src.pro b/src/src.pro index 04e3688900f9ddd6f5a2119cb5be4d318890ab6f..80d1c4e3bd8b12a14c034a77c521105702ed6439 100644 --- a/src/src.pro +++ b/src/src.pro @@ -10,7 +10,6 @@ nacl: SRC_SUBDIRS -= src_network src_testlib contains(QT_CONFIG, dbus):SRC_SUBDIRS += src_dbus contains(QT_CONFIG, no-gui): SRC_SUBDIRS -= src_gui -contains(QT_CONFIG, v8): SRC_SUBDIRS += src_v8 contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles2): SRC_SUBDIRS += src_opengl SRC_SUBDIRS += src_plugins @@ -19,8 +18,6 @@ src_winmain.subdir = $$QT_SOURCE_TREE/src/winmain src_winmain.target = sub-winmain src_corelib.subdir = $$QT_SOURCE_TREE/src/corelib src_corelib.target = sub-corelib -src_v8.subdir = $$QT_SOURCE_TREE/src/v8 -src_v8.target = sub-v8 src_xml.subdir = $$QT_SOURCE_TREE/src/xml src_xml.target = sub-xml src_dbus.subdir = $$QT_SOURCE_TREE/src/dbus @@ -65,7 +62,6 @@ src_platformsupport.target = sub-platformsupport src_declarative.depends += src_opengl src_webkit.depends += src_opengl } - contains(QT_CONFIG, v8snapshot):src_v8.depends += src_tools_mkv8snapshot } diff --git a/src/tools/mkv8snapshot/mkv8snapshot.pro b/src/tools/mkv8snapshot/mkv8snapshot.pro deleted file mode 100644 index 41fa5df11b32876886e1b8f6a81a5cb19196f0c3..0000000000000000000000000000000000000000 --- a/src/tools/mkv8snapshot/mkv8snapshot.pro +++ /dev/null @@ -1,39 +0,0 @@ -TEMPLATE = app -TARGET = mkv8snapshot -QT = -CONFIG -= app_bundle -CONFIG -= qt -CONFIG += console -CONFIG += warn_off - -DESTDIR = ../../../bin -INCLUDEPATH += . -DEPENDPATH += . -LIBS = -OBJECTS_DIR = . - -contains(QT_CONFIG, build_all): CONFIG += build_all -win32|mac:!macx-xcode: CONFIG += debug_and_release - -TARGET = $$TARGET$$qtPlatformTargetSuffix() - -cross_compile { - equals(QT_ARCH, arm): V8_TARGET_ARCH = arm -} - -include(../../v8/v8.pri) - -cross_compile { - equals(V8_TARGET_ARCH, arm): SOURCES += $$V8SRC/arm/simulator-arm.cc -} - -SOURCES += \ - $$V8SRC/snapshot-empty.cc \ - $$V8SRC/mksnapshot.cc - -unix:LIBS += -lpthread - -# We don't need to install this tool, it's only used for building v8. -# However we do have to make sure that 'make install' builds it. -dummytarget.CONFIG = dummy_install -INSTALLS += dummytarget diff --git a/src/tools/tools.pro b/src/tools/tools.pro index 89ce0be05576e7e4ef7134d854478438befd9c96..5cbe92309e144a488b8dc122755df43cdb761140 100644 --- a/src/tools/tools.pro +++ b/src/tools/tools.pro @@ -2,7 +2,6 @@ TEMPLATE = subdirs TOOLS_SUBDIRS = src_tools_bootstrap src_tools_moc src_tools_rcc !contains(QT_CONFIG, no-gui): TOOLS_SUBDIRS += src_tools_uic -contains(QT_CONFIG, v8):contains(QT_CONFIG, v8snapshot): TOOLS_SUBDIRS += src_tools_mkv8snapshot # Set subdir and respective target name src_tools_bootstrap.subdir = $$QT_SOURCE_TREE/src/tools/bootstrap src_tools_bootstrap.target = sub-tools-bootstrap @@ -12,8 +11,6 @@ src_tools_rcc.subdir = $$QT_SOURCE_TREE/src/tools/rcc src_tools_rcc.target = sub-rcc src_tools_uic.subdir = $$QT_SOURCE_TREE/src/tools/uic src_tools_uic.target = sub-uic -src_tools_mkv8snapshot.subdir = $$QT_SOURCE_TREE/src/tools/mkv8snapshot -src_tools_mkv8snapshot.target = sub-mkv8snapshot !wince*:!ordered { # Set dependencies for each subdir diff --git a/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch b/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch deleted file mode 100644 index dd6374a9cb3da4caa584c3487cf1e9a51c31067d..0000000000000000000000000000000000000000 --- a/src/v8/0001-Add-hashing-and-comparison-methods-to-v8-String.patch +++ /dev/null @@ -1,336 +0,0 @@ -From d97195f011cdaa8b859d759f8a34dd50c3092f30 Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Tue, 4 Oct 2011 15:04:21 +1000 -Subject: [PATCH 01/13] Add hashing and comparison methods to v8::String - -This allows us to more rapidly search for a v8::String inside a hash -of QStrings. ---- - include/v8.h | 45 +++++++++++++++++++++++++++++ - src/api.cc | 51 +++++++++++++++++++++++++++++++++ - src/heap-inl.h | 2 + - src/heap.cc | 3 ++ - src/objects-inl.h | 1 + - src/objects.cc | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - src/objects.h | 10 ++++++- - 7 files changed, 192 insertions(+), 2 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 73b7fbe..86ea70f 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -1021,6 +1021,49 @@ class String : public Primitive { - V8EXPORT int Utf8Length() const; - - /** -+ * Returns the hash of this string. -+ */ -+ V8EXPORT uint32_t Hash() const; -+ -+ struct CompleteHashData { -+ CompleteHashData() : length(0), hash(0), symbol_id(0) {} -+ int length; -+ uint32_t hash; -+ uint32_t symbol_id; -+ }; -+ -+ /** -+ * Returns the "complete" hash of the string. This is -+ * all the information about the string needed to implement -+ * a very efficient hash keyed on the string. -+ * -+ * The members of CompleteHashData are: -+ * length: The length of the string. Equivalent to Length() -+ * hash: The hash of the string. Equivalent to Hash() -+ * symbol_id: If the string is a sequential symbol, the symbol -+ * id, otherwise 0. If the symbol ids of two strings are -+ * the same (and non-zero) the two strings are identical. -+ * If the symbol ids are different the strings may still be -+ * identical, but an Equals() check must be performed. -+ */ -+ V8EXPORT CompleteHashData CompleteHash() const; -+ -+ /** -+ * Compute a hash value for the passed UTF16 string -+ * data. -+ */ -+ V8EXPORT static uint32_t ComputeHash(uint16_t *string, int length); -+ V8EXPORT static uint32_t ComputeHash(char *string, int length); -+ -+ /** -+ * Returns true if this string is equal to the external -+ * string data provided. -+ */ -+ V8EXPORT bool Equals(uint16_t *string, int length); -+ V8EXPORT bool Equals(char *string, int length); -+ inline bool Equals(Handle<Value> that) const { return v8::Value::Equals(that); } -+ -+ /** - * Write the contents of the string to an external buffer. - * If no arguments are given, expects the buffer to be large - * enough to hold the entire string and NULL terminator. Copies -@@ -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, -diff --git a/src/api.cc b/src/api.cc -index ac4f07f..996812e 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -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(); -+ CompleteHashData result; -+ result.length = str->length(); -+ result.hash = str->Hash(); -+ if (str->IsSeqString()) -+ result.symbol_id = i::SeqString::cast(*str)->symbol_id(); -+ 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 aaf2927..4c55d63 100644 ---- a/src/heap-inl.h -+++ b/src/heap-inl.h -@@ -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); -+ SeqString::cast(answer)->set_symbol_id(0); - - ASSERT_EQ(size, answer->Size()); - -@@ -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); -+ SeqString::cast(answer)->set_symbol_id(0); - - ASSERT_EQ(size, answer->Size()); - -diff --git a/src/heap.cc b/src/heap.cc -index bbb9d3e..d287ead 100644 ---- a/src/heap.cc -+++ b/src/heap.cc -@@ -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(answer)->set_symbol_id(0); - - ASSERT_EQ(size, answer->Size()); - -@@ -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); -+ SeqString::cast(result)->set_symbol_id(0); - ASSERT_EQ(size, HeapObject::cast(result)->Size()); - return result; - } -@@ -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); -+ SeqString::cast(result)->set_symbol_id(0); - ASSERT_EQ(size, HeapObject::cast(result)->Size()); - return result; - } -diff --git a/src/objects-inl.h b/src/objects-inl.h -index dc3aa46..34cae9f 100644 ---- a/src/objects-inl.h -+++ b/src/objects-inl.h -@@ -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) - - - uint32_t String::hash_field() { -diff --git a/src/objects.cc b/src/objects.cc -index 9a87ac5..2946d02 100644 ---- a/src/objects.cc -+++ b/src/objects.cc -@@ -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; -+ if (len == 0) return true; -+ -+ // We know the strings are both non-empty. Compare the first chars -+ // before we try to flatten the strings. -+ if (this->Get(0) != string[0]) return false; -+ -+ String* lhs = this->TryFlattenGetString(); -+ -+ if (lhs->IsFlat()) { -+ String::FlatContent lhs_content = lhs->GetFlatContent(); -+ if (lhs->IsAsciiRepresentation()) { -+ 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_content.ToUC16Vector(); -+ Vector<const uc16> vec2(string, length); -+ return CompareRawStringContents(vec1, vec2); -+ } -+ } else { -+ Isolate* isolate = GetIsolate(); -+ isolate->objects_string_compare_buffer_a()->Reset(0, lhs); -+ VectorIterator<uc16> ib(string, length); -+ return CompareStringContents(isolate->objects_string_compare_buffer_a(), &ib); -+ } -+} -+ -+ -+bool String::SlowEqualsExternal(char *string, int length) -+{ -+ int len = this->length(); -+ if (len != length) return false; -+ if (len == 0) return true; -+ -+ // We know the strings are both non-empty. Compare the first chars -+ // before we try to flatten the strings. -+ if (this->Get(0) != string[0]) return false; -+ -+ String* lhs = this->TryFlattenGetString(); -+ -+ if (StringShape(lhs).IsSequentialAscii()) { -+ const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); -+ return CompareRawStringContents(Vector<const char>(str1, len), -+ Vector<const char>(string, len)); -+ } -+ -+ if (lhs->IsFlat()) { -+ 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); -+ VectorIterator<char> ib(string, length); -+ return CompareStringContents(isolate->objects_string_compare_buffer_a(), &ib); -+ } -+} -+ -+ - bool String::SlowEquals(String* other) { - // Fast check: negative check with lengths. - int len = length(); -@@ -10716,9 +10781,24 @@ class AsciiSymbolKey : public SequentialSymbolKey<char> { - - MaybeObject* AsObject() { - if (hash_field_ == 0) Hash(); -- return HEAP->AllocateAsciiSymbol(string_, hash_field_); -+ MaybeObject *result = HEAP->AllocateAsciiSymbol(string_, hash_field_); -+ if (!result->IsFailure() && result->ToObjectUnchecked()->IsSeqString()) { -+ while (true) { -+ Atomic32 my_symbol_id = next_symbol_id; -+ if (my_symbol_id > Smi::kMaxValue) -+ break; -+ if (my_symbol_id == NoBarrier_CompareAndSwap(&next_symbol_id, my_symbol_id, my_symbol_id + 1)) { -+ SeqString::cast(result->ToObjectUnchecked())->set_symbol_id(my_symbol_id); -+ break; -+ } -+ } -+ } -+ return result; - } -+ -+ static Atomic32 next_symbol_id; - }; -+Atomic32 AsciiSymbolKey::next_symbol_id = 1; - - - class SubStringAsciiSymbolKey : public HashTableKey { -diff --git a/src/objects.h b/src/objects.h -index f7d2180..d96e5f9 100644 ---- a/src/objects.h -+++ b/src/objects.h -@@ -6201,6 +6201,9 @@ class String: public HeapObject { - bool IsAsciiEqualTo(Vector<const char> str); - bool IsTwoByteEqualTo(Vector<const uc16> str); - -+ bool SlowEqualsExternal(uc16 *string, int length); -+ bool SlowEqualsExternal(char *string, int length); -+ - // 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 -@@ -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); -+ - // Layout description. -- static const int kHeaderSize = String::kSize; -+ static const int kSymbolIdOffset = String::kSize; -+ static const int kHeaderSize = kSymbolIdOffset + kPointerSize; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(SeqString); --- -1.7.4.1 - diff --git a/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch b/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch deleted file mode 100644 index 7ee05caea2b4917aaab86c59b36c410311e298ba..0000000000000000000000000000000000000000 --- a/src/v8/0002-Add-a-fallback-mode-for-named-property-interceptors.patch +++ /dev/null @@ -1,361 +0,0 @@ -From e30b202d683e36731d9674ebf75803990a33816e Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Thu, 27 Oct 2011 11:31:56 +0100 -Subject: [PATCH 02/13] Add a "fallback" mode for named property interceptors - -By default interceptors are called before the normal property -resolution on objects. When an interceptor is installed as a -"fallback" interceptor, it is only called if the object doesn't -already have the property. - -In the case of a global object having an fallback interceptor, -the interceptor is not invoked at all for var or function -declarations. ---- - include/v8.h | 7 +++++++ - src/api.cc | 29 +++++++++++++++++++++++++++++ - src/factory.cc | 3 +++ - src/handles.cc | 6 ++++-- - src/handles.h | 3 ++- - src/objects-inl.h | 15 +++++++++++++++ - src/objects.cc | 24 +++++++++++++++++------- - src/objects.h | 16 ++++++++++++---- - src/runtime.cc | 11 ++++++----- - 9 files changed, 95 insertions(+), 19 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 86ea70f..d2e6c32 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -2305,6 +2305,7 @@ class V8EXPORT FunctionTemplate : public Template { - NamedPropertyQuery query, - NamedPropertyDeleter remover, - NamedPropertyEnumerator enumerator, -+ bool is_fallback, - Handle<Value> data); - void SetIndexedInstancePropertyHandler(IndexedPropertyGetter getter, - IndexedPropertySetter setter, -@@ -2388,6 +2389,12 @@ class V8EXPORT ObjectTemplate : public Template { - NamedPropertyDeleter deleter = 0, - NamedPropertyEnumerator enumerator = 0, - Handle<Value> data = Handle<Value>()); -+ void SetFallbackPropertyHandler(NamedPropertyGetter getter, -+ NamedPropertySetter setter = 0, -+ NamedPropertyQuery query = 0, -+ NamedPropertyDeleter deleter = 0, -+ NamedPropertyEnumerator enumerator = 0, -+ Handle<Value> data = Handle<Value>()); - - /** - * Sets an indexed property handler on the object template. -diff --git a/src/api.cc b/src/api.cc -index 996812e..e0f3b5a 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -1123,6 +1123,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler( - NamedPropertyQuery query, - NamedPropertyDeleter remover, - NamedPropertyEnumerator enumerator, -+ bool is_fallback, - Handle<Value> data) { - i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); - if (IsDeadCheck(isolate, -@@ -1141,6 +1142,7 @@ void FunctionTemplate::SetNamedInstancePropertyHandler( - if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query); - if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover); - if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator); -+ obj->set_is_fallback(i::Smi::FromInt(is_fallback)); - - if (data.IsEmpty()) data = v8::Undefined(); - obj->set_data(*Utils::OpenHandle(*data)); -@@ -1285,6 +1287,33 @@ void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter, - query, - remover, - enumerator, -+ false, -+ data); -+} -+ -+ -+void ObjectTemplate::SetFallbackPropertyHandler(NamedPropertyGetter getter, -+ NamedPropertySetter setter, -+ NamedPropertyQuery query, -+ NamedPropertyDeleter remover, -+ NamedPropertyEnumerator enumerator, -+ Handle<Value> data) { -+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); -+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) { -+ return; -+ } -+ ENTER_V8(isolate); -+ i::HandleScope scope(isolate); -+ EnsureConstructor(this); -+ i::FunctionTemplateInfo* constructor = -+ i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor()); -+ i::Handle<i::FunctionTemplateInfo> cons(constructor); -+ Utils::ToLocal(cons)->SetNamedInstancePropertyHandler(getter, -+ setter, -+ query, -+ remover, -+ enumerator, -+ true, - data); - } - -diff --git a/src/factory.cc b/src/factory.cc -index 15f640e..1b95ed1 100644 ---- a/src/factory.cc -+++ b/src/factory.cc -@@ -1213,6 +1213,9 @@ Handle<JSFunction> Factory::CreateApiFunction( - // Set interceptor information in the map. - if (!obj->named_property_handler()->IsUndefined()) { - map->set_has_named_interceptor(); -+ InterceptorInfo *nph = InterceptorInfo::cast(obj->named_property_handler()); -+ bool is_fallback = nph->is_fallback()->IsUndefined()?false:nph->is_fallback()->value(); -+ map->set_named_interceptor_is_fallback(is_fallback); - } - if (!obj->indexed_property_handler()->IsUndefined()) { - map->set_has_indexed_interceptor(); -diff --git a/src/handles.cc b/src/handles.cc -index 62851f3..790d224 100644 ---- a/src/handles.cc -+++ b/src/handles.cc -@@ -269,9 +269,11 @@ Handle<Object> SetProperty(Handle<JSReceiver> object, - Handle<String> key, - Handle<Object> value, - PropertyAttributes attributes, -- StrictModeFlag strict_mode) { -+ StrictModeFlag strict_mode, -+ bool skip_fallback_interceptor) { - CALL_HEAP_FUNCTION(object->GetIsolate(), -- object->SetProperty(*key, *value, attributes, strict_mode), -+ object->SetProperty(*key, *value, attributes, strict_mode, -+ skip_fallback_interceptor), - Object); - } - -diff --git a/src/handles.h b/src/handles.h -index 06e47fc..c359cb3 100644 ---- a/src/handles.h -+++ b/src/handles.h -@@ -190,7 +190,8 @@ Handle<Object> SetProperty(Handle<JSReceiver> object, - Handle<String> key, - Handle<Object> value, - PropertyAttributes attributes, -- StrictModeFlag strict_mode); -+ StrictModeFlag strict_mode, -+ bool skip_fallback_interceptor = false); - - Handle<Object> SetProperty(Handle<Object> object, - Handle<Object> key, -diff --git a/src/objects-inl.h b/src/objects-inl.h -index 34cae9f..1cfea84 100644 ---- a/src/objects-inl.h -+++ b/src/objects-inl.h -@@ -2754,6 +2754,20 @@ void Map::set_is_shared(bool value) { - bool Map::is_shared() { - return ((1 << kIsShared) & bit_field3()) != 0; - } -+ -+void Map::set_named_interceptor_is_fallback(bool value) -+{ -+ if (value) { -+ set_bit_field3(bit_field3() | (1 << kNamedInterceptorIsFallback)); -+ } else { -+ set_bit_field3(bit_field3() & ~(1 << kNamedInterceptorIsFallback)); -+ } -+} -+ -+bool Map::named_interceptor_is_fallback() -+{ -+ return ((1 << kNamedInterceptorIsFallback) & bit_field3()) != 0; -+} - - - JSFunction* Map::unchecked_constructor() { -@@ -3255,6 +3269,7 @@ ACCESSORS(InterceptorInfo, query, Object, kQueryOffset) - ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset) - ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset) - ACCESSORS(InterceptorInfo, data, Object, kDataOffset) -+ACCESSORS(InterceptorInfo, is_fallback, Smi, kFallbackOffset) - - ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset) - ACCESSORS(CallHandlerInfo, data, Object, kDataOffset) -diff --git a/src/objects.cc b/src/objects.cc -index 2946d02..f5b6bee 100644 ---- a/src/objects.cc -+++ b/src/objects.cc -@@ -1980,9 +1980,10 @@ MaybeObject* JSObject::SetPropertyWithInterceptor( - MaybeObject* JSReceiver::SetProperty(String* name, - Object* value, - PropertyAttributes attributes, -- StrictModeFlag strict_mode) { -+ StrictModeFlag strict_mode, -+ bool skip_fallback_interceptor) { - LookupResult result(GetIsolate()); -- LocalLookup(name, &result); -+ LocalLookup(name, &result, skip_fallback_interceptor); - return SetProperty(&result, name, value, attributes, strict_mode); - } - -@@ -4213,7 +4214,8 @@ AccessorDescriptor* Map::FindAccessor(String* name) { - } - - --void JSReceiver::LocalLookup(String* name, LookupResult* result) { -+void JSReceiver::LocalLookup(String* name, LookupResult* result, -+ bool skip_fallback_interceptor) { - ASSERT(name->IsString()); - - Heap* heap = GetHeap(); -@@ -4245,23 +4247,31 @@ void JSReceiver::LocalLookup(String* name, LookupResult* result) { - } - - // Check for lookup interceptor except when bootstrapping. -- if (js_object->HasNamedInterceptor() && -- !heap->isolate()->bootstrapper()->IsActive()) { -+ bool wouldIntercept = js_object->HasNamedInterceptor() && -+ !heap->isolate()->bootstrapper()->IsActive(); -+ if (wouldIntercept && !map()->named_interceptor_is_fallback()) { - result->InterceptorResult(js_object); - return; - } - - js_object->LocalLookupRealNamedProperty(name, result); -+ -+ if (wouldIntercept && !skip_fallback_interceptor && !result->IsProperty() && -+ map()->named_interceptor_is_fallback()) { -+ result->InterceptorResult(js_object); -+ return; -+ } - } - - --void JSReceiver::Lookup(String* name, LookupResult* result) { -+void JSReceiver::Lookup(String* name, LookupResult* result, -+ bool skip_fallback_interceptor) { - // Ecma-262 3rd 8.6.2.4 - Heap* heap = GetHeap(); - for (Object* current = this; - current != heap->null_value(); - current = JSObject::cast(current)->GetPrototype()) { -- JSReceiver::cast(current)->LocalLookup(name, result); -+ JSReceiver::cast(current)->LocalLookup(name, result, skip_fallback_interceptor); - if (result->IsProperty()) return; - } - result->NotFound(); -diff --git a/src/objects.h b/src/objects.h -index d96e5f9..ed40061 100644 ---- a/src/objects.h -+++ b/src/objects.h -@@ -1362,7 +1362,8 @@ class JSReceiver: public HeapObject { - MUST_USE_RESULT MaybeObject* SetProperty(String* key, - Object* value, - PropertyAttributes attributes, -- StrictModeFlag strict_mode); -+ StrictModeFlag strict_mode, -+ bool skip_fallback_interceptor = false); - MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result, - String* key, - Object* value, -@@ -1414,8 +1415,8 @@ class JSReceiver: public HeapObject { - - // Lookup a property. If found, the result is valid and has - // detailed information. -- void LocalLookup(String* name, LookupResult* result); -- void Lookup(String* name, LookupResult* result); -+ void LocalLookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false); -+ void Lookup(String* name, LookupResult* result, bool skip_fallback_interceptor = false); - - protected: - Smi* GenerateIdentityHash(); -@@ -4242,6 +4243,10 @@ class Map: public HeapObject { - inline void set_is_access_check_needed(bool access_check_needed); - inline bool is_access_check_needed(); - -+ // Whether the named interceptor is a fallback interceptor or not -+ inline void set_named_interceptor_is_fallback(bool value); -+ inline bool named_interceptor_is_fallback(); -+ - // [prototype]: implicit prototype object. - DECL_ACCESSORS(prototype, Object) - -@@ -4506,6 +4511,7 @@ class Map: public HeapObject { - - // Bit positions for bit field 3 - static const int kIsShared = 0; -+ static const int kNamedInterceptorIsFallback = 1; - - // Layout of the default cache. It holds alternating name and code objects. - static const int kCodeCacheEntrySize = 2; -@@ -7390,6 +7396,7 @@ class InterceptorInfo: public Struct { - DECL_ACCESSORS(deleter, Object) - DECL_ACCESSORS(enumerator, Object) - DECL_ACCESSORS(data, Object) -+ DECL_ACCESSORS(is_fallback, Smi) - - static inline InterceptorInfo* cast(Object* obj); - -@@ -7409,7 +7416,8 @@ class InterceptorInfo: public Struct { - static const int kDeleterOffset = kQueryOffset + kPointerSize; - static const int kEnumeratorOffset = kDeleterOffset + kPointerSize; - static const int kDataOffset = kEnumeratorOffset + kPointerSize; -- static const int kSize = kDataOffset + kPointerSize; -+ static const int kFallbackOffset = kDataOffset + kPointerSize; -+ static const int kSize = kFallbackOffset + kPointerSize; - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo); -diff --git a/src/runtime.cc b/src/runtime.cc -index 9c23c2c..0e256c1 100644 ---- a/src/runtime.cc -+++ b/src/runtime.cc -@@ -1330,7 +1330,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { - // Lookup the property in the global object, and don't set the - // value of the variable if the property is already there. - LookupResult lookup(isolate); -- global->Lookup(*name, &lookup); -+ global->Lookup(*name, &lookup, true); - if (lookup.IsProperty()) { - // We found an existing property. Unless it was an interceptor - // that claims the property is absent, skip this declaration. -@@ -1357,7 +1357,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { - } - - LookupResult lookup(isolate); -- global->LocalLookup(*name, &lookup); -+ global->LocalLookup(*name, &lookup, true); - - // Compute the property attributes. According to ECMA-262, section - // 13, page 71, the property must be read-only and -@@ -1398,7 +1398,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { - name, - value, - static_cast<PropertyAttributes>(attr), -- strict_mode)); -+ strict_mode, -+ true)); - } - } - -@@ -1534,7 +1535,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { - while (object->IsJSObject() && - JSObject::cast(object)->map()->is_hidden_prototype()) { - JSObject* raw_holder = JSObject::cast(object); -- raw_holder->LocalLookup(*name, &lookup); -+ raw_holder->LocalLookup(*name, &lookup, true); - if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { - HandleScope handle_scope(isolate); - Handle<JSObject> holder(raw_holder); -@@ -1557,7 +1558,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { - // Reload global in case the loop above performed a GC. - global = isolate->context()->global(); - if (assign) { -- return global->SetProperty(*name, args[2], attributes, strict_mode); -+ return global->SetProperty(*name, args[2], attributes, strict_mode, true); - } - return isolate->heap()->undefined_value(); - } --- -1.7.4.1 - diff --git a/src/v8/0003-Generalize-external-object-resources.patch b/src/v8/0003-Generalize-external-object-resources.patch deleted file mode 100644 index 580b8f0f24d2348bc838ac494c58d4af86467385..0000000000000000000000000000000000000000 --- a/src/v8/0003-Generalize-external-object-resources.patch +++ /dev/null @@ -1,595 +0,0 @@ -From 501255df9cb6241a1f6c8d8a3361b9582fa481ef 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/13] 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.1 - diff --git a/src/v8/0004-Introduce-a-QML-compilation-mode.patch b/src/v8/0004-Introduce-a-QML-compilation-mode.patch deleted file mode 100644 index 84823ca4a719a133da9eddbe79a306a4635d54b7..0000000000000000000000000000000000000000 --- a/src/v8/0004-Introduce-a-QML-compilation-mode.patch +++ /dev/null @@ -1,2355 +0,0 @@ -From c49c39afa016b176c933ff01e748a2eddb26e131 Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Thu, 27 Oct 2011 13:34:16 +0100 -Subject: [PATCH 04/13] 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 -present on the JS global object, it is resolved on the QML global -object. - -This global object behavior is only enabled if a script is being -compiled in QML mode. The object to use as the QML global object -is passed as a parameter to the Script::Run() method. Any function -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 | 19 +++++++-- - src/api.cc | 52 +++++++++++++++++++---- - src/arm/code-stubs-arm.cc | 4 ++ - 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 | 16 ++++++- - src/contexts.cc | 35 ++++++++++++++++ - src/contexts.h | 4 ++ - src/execution.cc | 31 ++++++++++++-- - src/execution.h | 8 ++++ - src/full-codegen.cc | 3 +- - src/full-codegen.h | 1 + - src/heap.cc | 4 ++ - src/hydrogen-instructions.cc | 5 ++ - src/hydrogen-instructions.h | 21 ++++++++- - 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/mips/code-stubs-mips.cc | 5 ++ - src/mips/full-codegen-mips.cc | 30 ++++++++----- - src/mips/macro-assembler-mips.h | 5 ++ - src/objects-inl.h | 2 + - src/objects.h | 7 +++ - src/parser.cc | 28 +++++++++++-- - src/parser.h | 4 +- - src/prettyprinter.cc | 3 + - src/runtime.cc | 84 +++++++++++++++++++++++++------------- - src/runtime.h | 8 ++-- - src/scopeinfo.cc | 28 ++++++++++--- - src/scopeinfo.h | 1 + - 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 | 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 ++ - 52 files changed, 559 insertions(+), 141 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 3ef4dd6..193e2fe 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -587,6 +587,11 @@ class ScriptOrigin { - */ - class V8EXPORT Script { - public: -+ enum CompileFlags { -+ Default = 0x00, -+ QmlMode = 0x01 -+ }; -+ - /** - * Compiles the specified script (context-independent). - * -@@ -605,7 +610,8 @@ class V8EXPORT Script { - static Local<Script> New(Handle<String> source, - ScriptOrigin* origin = NULL, - ScriptData* pre_data = NULL, -- Handle<String> script_data = Handle<String>()); -+ Handle<String> script_data = Handle<String>(), -+ CompileFlags = Default); - - /** - * Compiles the specified script using the specified file name -@@ -618,7 +624,8 @@ class V8EXPORT Script { - * will use the currently entered context). - */ - static Local<Script> New(Handle<String> source, -- Handle<Value> file_name); -+ Handle<Value> file_name, -+ CompileFlags = Default); - - /** - * Compiles the specified script (bound to current context). -@@ -639,7 +646,8 @@ class V8EXPORT Script { - static Local<Script> Compile(Handle<String> source, - ScriptOrigin* origin = NULL, - ScriptData* pre_data = NULL, -- Handle<String> script_data = Handle<String>()); -+ Handle<String> script_data = Handle<String>(), -+ CompileFlags = Default); - - /** - * Compiles the specified script using the specified file name -@@ -656,7 +664,8 @@ class V8EXPORT Script { - */ - static Local<Script> Compile(Handle<String> source, - Handle<Value> file_name, -- Handle<String> script_data = Handle<String>()); -+ Handle<String> script_data = Handle<String>(), -+ CompileFlags = Default); - - /** - * Runs the script returning the resulting value. If the script is -@@ -666,6 +675,7 @@ class V8EXPORT Script { - * compiled. - */ - Local<Value> Run(); -+ Local<Value> Run(Handle<Object> qml); - - /** - * Returns the script id value. -@@ -3506,6 +3516,7 @@ class V8EXPORT Context { - * JavaScript frames an empty handle is returned. - */ - static Local<Context> GetCalling(); -+ static Local<Object> GetCallingQmlGlobal(); - - /** - * Sets the security token for the context. To access an object in -diff --git a/src/api.cc b/src/api.cc -index 7d54252..2d3d97a 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -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, -- v8::Handle<String> script_data) { -+ v8::Handle<String> script_data, -+ v8::Script::CompileFlags compile_flags) { - i::Isolate* isolate = i::Isolate::Current(); - ON_BAILOUT(isolate, "v8::Script::New()", return Local<Script>()); - LOG_API(isolate, "Script::New"); -@@ -1551,7 +1552,8 @@ Local<Script> Script::New(v8::Handle<String> source, - NULL, - pre_data_impl, - Utils::OpenHandle(*script_data), -- i::NOT_NATIVES_CODE); -+ i::NOT_NATIVES_CODE, -+ compile_flags); - has_pending_exception = result.is_null(); - EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>()); - return Local<Script>(ToApi<Script>(result)); -@@ -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::Script::CompileFlags compile_flags) { - ScriptOrigin origin(file_name); -- return New(source, &origin); -+ return New(source, &origin, 0, Handle<String>(), compile_flags); - } - - - Local<Script> Script::Compile(v8::Handle<String> source, - v8::ScriptOrigin* origin, - v8::ScriptData* pre_data, -- v8::Handle<String> script_data) { -+ v8::Handle<String> script_data, -+ v8::Script::CompileFlags compile_flags) { - i::Isolate* isolate = i::Isolate::Current(); - ON_BAILOUT(isolate, "v8::Script::Compile()", return Local<Script>()); - LOG_API(isolate, "Script::Compile"); - ENTER_V8(isolate); -- Local<Script> generic = New(source, origin, pre_data, script_data); -+ Local<Script> generic = New(source, origin, pre_data, script_data, compile_flags); - if (generic.IsEmpty()) - return generic; - i::Handle<i::Object> obj = Utils::OpenHandle(*generic); -@@ -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, -- v8::Handle<String> script_data) { -+ v8::Handle<String> script_data, -+ v8::Script::CompileFlags compile_flags) { - ScriptOrigin origin(file_name); -- return Compile(source, &origin, 0, script_data); -+ return Compile(source, &origin, 0, script_data, compile_flags); - } - - - Local<Value> Script::Run() { -+ return Run(Handle<Object>()); -+} -+ -+Local<Value> Script::Run(Handle<Object> qml) { - i::Isolate* isolate = i::Isolate::Current(); - ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>()); - LOG_API(isolate, "Script::Run"); -@@ -1614,10 +1623,11 @@ Local<Value> Script::Run() { - fun = i::Handle<i::JSFunction>(i::JSFunction::cast(*obj), isolate); - } - EXCEPTION_PREAMBLE(isolate); -+ i::Handle<i::Object> qmlglobal = Utils::OpenHandle(*qml); - i::Handle<i::Object> receiver( - 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, false, qmlglobal); - EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>()); - raw_result = *result; - } -@@ -4337,6 +4347,30 @@ v8::Local<v8::Context> Context::GetCalling() { - } - - -+v8::Local<v8::Object> Context::GetCallingQmlGlobal() { -+ i::Isolate* isolate = i::Isolate::Current(); -+ if (IsDeadCheck(isolate, "v8::Context::GetCallingQmlGlobal()")) { -+ return Local<Object>(); -+ } -+ -+ i::Context *context = isolate->context(); -+ if (!context->qml_global()->IsUndefined()) { -+ i::Handle<i::Object> qmlglobal(context->qml_global()); -+ return Utils::ToLocal(i::Handle<i::JSObject>::cast(qmlglobal)); -+ } -+ -+ i::JavaScriptFrameIterator it; -+ if (it.done()) return Local<Object>(); -+ context = i::Context::cast(it.frame()->context()); -+ if (!context->qml_global()->IsUndefined()) { -+ i::Handle<i::Object> qmlglobal(context->qml_global()); -+ return Utils::ToLocal(i::Handle<i::JSObject>::cast(qmlglobal)); -+ } else { -+ return Local<Object>(); -+ } -+} -+ -+ - v8::Local<v8::Object> Context::Global() { - 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 cb3bc88..f5be938 100644 ---- a/src/arm/code-stubs-arm.cc -+++ b/src/arm/code-stubs-arm.cc -@@ -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))); - -+ // Copy the qml global object from the surrounding context. -+ __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); -+ __ str(r1, MemOperand(r0, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); -+ - // Initialize the rest of the slots to undefined. - __ 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 497a295..b8e3f30 100644 ---- a/src/arm/full-codegen-arm.cc -+++ b/src/arm/full-codegen-arm.cc -@@ -182,12 +182,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - - // Possibly allocate a local context. - 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())) { - Comment cmnt(masm_, "[ Allocate local context"); - // Argument to NewContext is the function, which is in r1. - __ push(r1); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ CallRuntime(Runtime::kNewFunctionContext, 1); -@@ -1193,9 +1194,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, - __ bind(&fast); - } - -- __ ldr(r0, GlobalObjectOperand()); -+ __ 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 || var->is_qml_global()) - ? RelocInfo::CODE_TARGET - : RelocInfo::CODE_TARGET_CONTEXT; - Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); -@@ -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(); -@@ -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()))); -+ __ push(r1); - - __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP - ? Runtime::kResolvePossiblyDirectEvalNoLookup -- : Runtime::kResolvePossiblyDirectEval, 4); -+ : Runtime::kResolvePossiblyDirectEval, 5); - } - - -@@ -2296,9 +2300,9 @@ void FullCodeGenerator::VisitCall(Call* expr) { - context()->DropAndPlug(1, r0); - } else if (proxy != NULL && proxy->var()->IsUnallocated()) { - // Push global object as receiver for the call IC. -- __ ldr(r0, GlobalObjectOperand()); -+ __ ldr(r0, proxy->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); - __ push(r0); -- 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 5197842..943bc82 100644 ---- a/src/arm/lithium-arm.cc -+++ b/src/arm/lithium-arm.cc -@@ -1128,7 +1128,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - - LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { - LOperand* context = UseRegisterAtStart(instr->value()); -- return DefineAsRegister(new LGlobalObject(context)); -+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global())); - } - - -@@ -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 5733bd0..a7e1704 100644 ---- a/src/arm/lithium-arm.h -+++ b/src/arm/lithium-arm.h -@@ -1303,13 +1303,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - - class LGlobalObject: public LTemplateInstruction<1, 1, 0> { - public: -- explicit LGlobalObject(LOperand* context) { -+ explicit LGlobalObject(LOperand* context, bool qml_global) { - inputs_[0] = context; -+ qml_global_ = qml_global; - } - - DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") - - LOperand* context() { return InputAt(0); } -+ bool qml_global() { return qml_global_; } -+ private: -+ bool qml_global_; - }; - - -@@ -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 4cf7df4..2e1e6fa 100644 ---- a/src/arm/lithium-codegen-arm.cc -+++ b/src/arm/lithium-codegen-arm.cc -@@ -190,12 +190,13 @@ bool LCodeGen::GeneratePrologue() { - - // Possibly allocate a local context. - int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; -- if (heap_slots > 0) { -+ if (heap_slots > 0 || -+ (scope()->is_qml_mode() && scope()->is_global_scope())) { - Comment(";;; Allocate local context"); - // Argument to NewContext is the function, which is in r1. - __ push(r1); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ CallRuntime(Runtime::kNewFunctionContext, 1); -@@ -2826,7 +2827,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) { - - void LCodeGen::DoGlobalObject(LGlobalObject* instr) { - 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 90c4b37..5947e6a 100644 ---- a/src/arm/macro-assembler-arm.h -+++ b/src/arm/macro-assembler-arm.h -@@ -1326,6 +1326,11 @@ static inline MemOperand GlobalObjectOperand() { - } - - -+static inline MemOperand QmlGlobalObjectOperand() { -+ return ContextOperand(cp, Context::QML_GLOBAL_INDEX); -+} -+ -+ - #ifdef GENERATED_CODE_COVERAGE - #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 f8b460d..217c71f 100644 ---- a/src/ast-inl.h -+++ b/src/ast-inl.h -@@ -126,6 +126,11 @@ StrictModeFlag FunctionLiteral::strict_mode_flag() const { - } - - -+bool FunctionLiteral::qml_mode() const { -+ return scope()->is_qml_mode(); -+} -+ -+ - } } // 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 3de00ef..8920b50 100644 ---- a/src/ast.h -+++ b/src/ast.h -@@ -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 fc7000b..4380764 100644 ---- a/src/code-stubs.h -+++ b/src/code-stubs.h -@@ -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); - } - - void Generate(MacroAssembler* masm); -diff --git a/src/compiler.cc b/src/compiler.cc -index 88db467..4902e72 100644 ---- a/src/compiler.cc -+++ b/src/compiler.cc -@@ -447,7 +447,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, - v8::Extension* extension, - ScriptDataImpl* input_pre_data, - Handle<Object> script_data, -- NativesFlag natives) { -+ NativesFlag natives, -+ v8::Script::CompileFlags compile_flags) { - Isolate* isolate = source->GetIsolate(); - int source_length = source->length(); - isolate->counters()->total_load_size()->Increment(source_length); -@@ -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(); - result = MakeFunctionInfo(&info); - if (extension == NULL && !result.is_null()) { - 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, -- StrictModeFlag strict_mode) { -+ StrictModeFlag strict_mode, -+ bool qml_mode) { - Isolate* isolate = source->GetIsolate(); - int source_length = source->length(); - isolate->counters()->total_eval_size()->Increment(source_length); -@@ -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(); - info.SetCallingContext(context); - result = MakeFunctionInfo(&info); - 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()) { -+ shared->set_qml_mode(true); -+ info->MarkAsQmlMode(); -+ } -+ - // Compile the code. - if (!MakeCode(info)) { - if (!isolate->has_pending_exception()) { -@@ -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_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 bedf5ee..054e3b9 100644 ---- a/src/compiler.h -+++ b/src/compiler.h -@@ -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_; } -@@ -85,6 +86,9 @@ class CompilationInfo BASE_EMBEDDED { - ASSERT(is_lazy()); - flags_ |= IsInLoop::encode(true); - } -+ void MarkAsQmlMode() { -+ flags_ |= IsQmlMode::encode(true); -+ } - void MarkAsNative() { - flags_ |= IsNative::encode(true); - } -@@ -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(); -+ } - } - - 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, 9, 1> {}; - - unsigned flags_; - -@@ -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 = v8::Script::Default); - - // Compile a String source within a context for Eval. - static Handle<SharedFunctionInfo> CompileEval(Handle<String> source, - Handle<Context> context, - bool is_global, -- StrictModeFlag strict_mode); -+ StrictModeFlag strict_mode, -+ bool qml_mode); - - // Compile from function info (used for lazy compilation). Returns true on - // success and false if the compilation resulted in a stack overflow. -diff --git a/src/contexts.cc b/src/contexts.cc -index b25ffac..3129af0 100644 ---- a/src/contexts.cc -+++ b/src/contexts.cc -@@ -103,6 +103,9 @@ Handle<Object> Context::Lookup(Handle<String> name, - PrintF(")\n"); - } - -+ Handle<JSObject> qml_global; -+ Handle<JSObject> qml_global_global; -+ - do { - if (FLAG_trace_contexts) { - PrintF(" - looking in context %p", reinterpret_cast<void*>(*context)); -@@ -110,6 +113,11 @@ Handle<Object> Context::Lookup(Handle<String> name, - PrintF("\n"); - } - -+ if (qml_global.is_null() && !context->qml_global()->IsUndefined()) { -+ qml_global = Handle<JSObject>(context->qml_global(), isolate); -+ qml_global_global = Handle<JSObject>(context->global(), isolate); -+ } -+ - // 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); - -+ if (!qml_global.is_null()) { -+ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) { -+ *attributes = qml_global_global->GetLocalPropertyAttribute(*name); -+ } else { -+ *attributes = qml_global_global->GetPropertyAttribute(*name); -+ } -+ -+ if (*attributes != ABSENT) { -+ *attributes = ABSENT; -+ } else { -+ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) { -+ *attributes = qml_global->GetLocalPropertyAttribute(*name); -+ } else { -+ *attributes = qml_global->GetPropertyAttribute(*name); -+ } -+ -+ if (*attributes != ABSENT) { -+ // property found -+ if (FLAG_trace_contexts) { -+ PrintF("=> found property in qml global object %p\n", -+ reinterpret_cast<void*>(*qml_global)); -+ } -+ return qml_global; -+ } -+ } -+ } -+ - if (FLAG_trace_contexts) { - PrintF("=> no property/slot found\n"); - } -diff --git a/src/contexts.h b/src/contexts.h -index 7021ff8..c3cfeee 100644 ---- a/src/contexts.h -+++ b/src/contexts.h -@@ -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, - -@@ -321,6 +322,9 @@ class Context: public FixedArray { - } - void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); } - -+ JSObject *qml_global() { return reinterpret_cast<JSObject *>(get(QML_GLOBAL_INDEX)); } -+ void set_qml_global(JSObject *qml_global) { set(QML_GLOBAL_INDEX, qml_global); } -+ - // Returns a JSGlobalProxy object or null. - JSObject* global_proxy(); - void set_global_proxy(JSObject* global); -diff --git a/src/execution.cc b/src/execution.cc -index 29955fa..4261ac2 100644 ---- a/src/execution.cc -+++ b/src/execution.cc -@@ -71,7 +71,8 @@ static Handle<Object> Invoke(bool is_construct, - Handle<Object> receiver, - int argc, - Handle<Object> args[], -- bool* has_pending_exception) { -+ bool* has_pending_exception, -+ Handle<Object> qml) { - Isolate* isolate = function->GetIsolate(); - - // Entering JavaScript. -@@ -102,6 +103,12 @@ static Handle<Object> Invoke(bool is_construct, - // make the current one is indeed a global object. - ASSERT(function->context()->global()->IsGlobalObject()); - -+ Handle<JSObject> oldqml; -+ if (!qml.is_null()) { -+ 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. -@@ -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()) -+ function->context()->set_qml_global(*oldqml); -+ - #ifdef DEBUG - value->Verify(); - #endif -@@ -146,7 +156,18 @@ Handle<Object> Execution::Call(Handle<Object> callable, - int argc, - 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<Object> callable, -+ Handle<Object> receiver, -+ int argc, -+ Handle<Object> argv[], -+ bool* pending_exception, -+ bool convert_receiver, -+ Handle<Object> 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); - } - - -@@ -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>()); - } - - -@@ -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); -+ caught_exception, Handle<Object>()); - - if (*caught_exception) { - ASSERT(catcher.HasCaught()); -diff --git a/src/execution.h b/src/execution.h -index f2d17d0..532e5d8 100644 ---- a/src/execution.h -+++ b/src/execution.h -@@ -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, -+ 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 27c509f..f099d25 100644 ---- a/src/full-codegen.cc -+++ b/src/full-codegen.cc -@@ -513,7 +513,7 @@ void FullCodeGenerator::VisitDeclarations( - // Batch declare global functions and variables. - if (global_count > 0) { - Handle<FixedArray> array = -- 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(); -@@ -537,6 +537,7 @@ void FullCodeGenerator::VisitDeclarations( - } - array->set(j++, *function); - } -+ array->set(j++, Smi::FromInt(var->is_qml_global())); - } - } - // Invoke the platform-dependent code generator to do the actual -diff --git a/src/full-codegen.h b/src/full-codegen.h -index 9132502..78e6089 100644 ---- a/src/full-codegen.h -+++ b/src/full-codegen.h -@@ -583,6 +583,7 @@ class FullCodeGenerator: public AstVisitor { - StrictModeFlag strict_mode_flag() { - return function()->strict_mode_flag(); - } -+ bool is_qml_mode() { return function()->qml_mode(); } - FunctionLiteral* function() { return info_->function(); } - Scope* scope() { return scope_; } - -diff --git a/src/heap.cc b/src/heap.cc -index 53a0f27..881a876 100644 ---- a/src/heap.cc -+++ b/src/heap.cc -@@ -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()); - 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()); - 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 65fc4df..ebf0030 100644 ---- a/src/hydrogen-instructions.h -+++ b/src/hydrogen-instructions.h -@@ -1410,19 +1410,30 @@ class HOuterContext: public HUnaryOperation { - - class HGlobalObject: public HUnaryOperation { - public: -- explicit HGlobalObject(HValue* context) : HUnaryOperation(context) { -+ explicit HGlobalObject(HValue* context) : HUnaryOperation(context), qml_global_(false) { - set_representation(Representation::Tagged()); - SetFlag(kUseGVN); - } - -+ virtual void PrintDataTo(StringStream* stream); -+ - DECLARE_CONCRETE_INSTRUCTION(GlobalObject) - - virtual Representation RequiredInputRepresentation(int index) { - return Representation::Tagged(); - } - -+ bool qml_global() { return qml_global_; } -+ void set_qml_global(bool v) { qml_global_ = v; } -+ - protected: -- virtual bool DataEquals(HValue* other) { return true; } -+ virtual bool DataEquals(HValue* other) { -+ HGlobalObject* o = HGlobalObject::cast(other); -+ return o->qml_global_ == qml_global_; -+ } -+ -+ private: -+ bool qml_global_; - }; - - -@@ -1601,7 +1612,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 +1624,14 @@ class HCallGlobal: public HUnaryCall { - return Representation::Tagged(); - } - -+ 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 3a4d172..0a7fad1 100644 ---- a/src/hydrogen.cc -+++ b/src/hydrogen.cc -@@ -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 37b519a..8a94a06 100644 ---- a/src/ia32/code-stubs-ia32.cc -+++ b/src/ia32/code-stubs-ia32.cc -@@ -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 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 25588c8..9cee4a3 100644 ---- a/src/ia32/full-codegen-ia32.cc -+++ b/src/ia32/full-codegen-ia32.cc -@@ -178,12 +178,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - - // Possibly allocate a local context. - 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())) { - Comment cmnt(masm_, "[ Allocate local context"); - // Argument to NewContext is the function, which is still in edi. - __ push(edi); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ 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, 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 || var->is_qml_global()) - ? RelocInfo::CODE_TARGET - : RelocInfo::CODE_TARGET_CONTEXT; - __ 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(); -@@ -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()))); -+ - __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP - ? Runtime::kResolvePossiblyDirectEvalNoLookup -- : Runtime::kResolvePossiblyDirectEval, 4); -+ : Runtime::kResolvePossiblyDirectEval, 5); - } - - -@@ -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()); -+ __ 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 d4cbbce..b381227 100644 ---- a/src/ia32/lithium-codegen-ia32.cc -+++ b/src/ia32/lithium-codegen-ia32.cc -@@ -211,12 +211,13 @@ bool LCodeGen::GeneratePrologue() { - - // Possibly allocate a local context. - int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; -- if (heap_slots > 0) { -+ if (heap_slots > 0 || -+ (scope()->is_qml_mode() && scope()->is_global_scope())) { - Comment(";;; Allocate local context"); - // Argument to NewContext is the function, which is still in edi. - __ push(edi); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ 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()); -- __ mov(result, Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX))); -+ __ mov(result, Operand(context, Context::SlotOffset(instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX))); - } - - -@@ -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 626f899..d09d55f 100644 ---- a/src/ia32/lithium-ia32.cc -+++ b/src/ia32/lithium-ia32.cc -@@ -1144,7 +1144,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - - LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { - LOperand* context = UseRegisterAtStart(instr->value()); -- return DefineAsRegister(new LGlobalObject(context)); -+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global())); - } - - -@@ -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 5f23afa..22541c8 100644 ---- a/src/ia32/lithium-ia32.h -+++ b/src/ia32/lithium-ia32.h -@@ -1338,13 +1338,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - - class LGlobalObject: public LTemplateInstruction<1, 1, 0> { - public: -- explicit LGlobalObject(LOperand* context) { -+ explicit LGlobalObject(LOperand* context, bool qml_global) { - inputs_[0] = context; -+ qml_global_ = qml_global; - } - - DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") - - LOperand* context() { return InputAt(0); } -+ bool qml_global() { return qml_global_; } -+ private: -+ bool qml_global_; - }; - - -@@ -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 8528c55..de3c3a0 100644 ---- a/src/ia32/macro-assembler-ia32.h -+++ b/src/ia32/macro-assembler-ia32.h -@@ -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/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc -index 85e929d..a534b78 100644 ---- a/src/mips/code-stubs-mips.cc -+++ b/src/mips/code-stubs-mips.cc -@@ -173,6 +173,11 @@ void FastNewContextStub::Generate(MacroAssembler* masm) { - __ lw(a1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::GLOBAL_INDEX))); - -+ // Copy the qml global object from the surrounding context. -+ __ lw(a1, MemOperand(cp, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); -+ __ sw(a1, MemOperand(v0, Context::SlotOffset(Context::QML_GLOBAL_INDEX))); -+ -+ - // Initialize the rest of the slots to undefined. - __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); - for (int i = Context::MIN_CONTEXT_SLOTS; i < length; i++) { -diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc -index 2f989bc..b6bd407 100644 ---- a/src/mips/full-codegen-mips.cc -+++ b/src/mips/full-codegen-mips.cc -@@ -191,12 +191,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - - // Possibly allocate a local context. - 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())) { - Comment cmnt(masm_, "[ Allocate local context"); - // Argument to NewContext is the function, which is in a1. - __ push(a1); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ CallRuntime(Runtime::kNewFunctionContext, 1); -@@ -1199,9 +1200,9 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, - __ bind(&fast); - } - -- __ lw(a0, GlobalObjectOperand()); -+ __ lw(a0, var->is_qml_global() ? QmlGlobalObjectOperand():GlobalObjectOperand()); - __ li(a2, Operand(var->name())); -- RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) -+ 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(); -@@ -1286,10 +1287,10 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { - Comment cmnt(masm_, "Global variable"); - // Use inline caching. Variable name is passed in a2 and the global - // object (receiver) in a0. -- __ lw(a0, GlobalObjectOperand()); -+ __ lw(a0, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); - __ li(a2, 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(v0); - break; - } -@@ -1937,7 +1938,7 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, - // Global var, const, or let. - __ mov(a0, result_register()); - __ li(a2, Operand(var->name())); -- __ lw(a1, GlobalObjectOperand()); -+ __ lw(a1, var->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); - Handle<Code> ic = is_strict_mode() - ? isolate()->builtins()->StoreIC_Initialize_Strict() - : isolate()->builtins()->StoreIC_Initialize(); -@@ -2246,9 +2247,14 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, - __ li(a1, Operand(Smi::FromInt(strict_mode))); - __ push(a1); - -+ -+ // Push the qml mode flag. -+ __ li(a1, Operand(Smi::FromInt(is_qml_mode()))); -+ __ push(a1); -+ - __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP - ? Runtime::kResolvePossiblyDirectEvalNoLookup -- : Runtime::kResolvePossiblyDirectEval, 4); -+ : Runtime::kResolvePossiblyDirectEval, 5); - } - - -@@ -2320,9 +2326,9 @@ void FullCodeGenerator::VisitCall(Call* expr) { - context()->DropAndPlug(1, v0); - } else if (proxy != NULL && proxy->var()->IsUnallocated()) { - // Push global object as receiver for the call IC. -- __ lw(a0, GlobalObjectOperand()); -+ __ lw(a0, proxy->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); - __ push(a0); -- 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; -@@ -3743,7 +3749,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { - // but "delete this" is allowed. - ASSERT(strict_mode_flag() == kNonStrictMode || var->is_this()); - if (var->IsUnallocated()) { -- __ lw(a2, GlobalObjectOperand()); -+ __ lw(a2, var->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand()); - __ li(a1, Operand(var->name())); - __ li(a0, Operand(Smi::FromInt(kNonStrictMode))); - __ Push(a2, a1, a0); -@@ -4032,7 +4038,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { - VariableProxy* proxy = expr->AsVariableProxy(); - if (proxy != NULL && proxy->var()->IsUnallocated()) { - Comment cmnt(masm_, "Global variable"); -- __ lw(a0, GlobalObjectOperand()); -+ __ lw(a0, proxy->var()->is_qml_global() ? QmlGlobalObjectOperand() : GlobalObjectOperand()); - __ li(a2, 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/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h -index 84c55f7..5224db9 100644 ---- a/src/mips/macro-assembler-mips.h -+++ b/src/mips/macro-assembler-mips.h -@@ -112,6 +112,11 @@ static inline MemOperand GlobalObjectOperand() { - } - - -+static inline MemOperand QmlGlobalObjectOperand() { -+ return ContextOperand(cp, Context::QML_GLOBAL_INDEX); -+} -+ -+ - // Generate a MemOperand for loading a field from an object. - static inline MemOperand FieldMemOperand(Register object, int offset) { - return MemOperand(object, offset - kHeapObjectTag); -diff --git a/src/objects-inl.h b/src/objects-inl.h -index 6a80c9c..2e83fb7 100644 ---- a/src/objects-inl.h -+++ b/src/objects-inl.h -@@ -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 c38d461..b71eaac 100644 ---- a/src/objects.h -+++ b/src/objects.h -@@ -3120,6 +3120,9 @@ class SerializedScopeInfo : public FixedArray { - // Is this scope a strict mode scope? - bool IsStrictMode(); - -+ // Is this scope a qml mode scope? -+ bool IsQmlMode(); -+ - // Return the number of stack slots for code. - int NumberOfStackSlots(); - -@@ -4929,6 +4932,9 @@ class SharedFunctionInfo: public HeapObject { - inline StrictModeFlag strict_mode_flag(); - inline void set_strict_mode_flag(StrictModeFlag strict_mode_flag); - -+ // 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 +5156,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 37204c9..357d340 100644 ---- a/src/parser.cc -+++ b/src/parser.cc -@@ -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) { - ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); - - HistogramTimerScope timer(isolate()->counters()->parse()); -@@ -623,11 +624,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source, - ExternalTwoByteStringUC16CharacterStream stream( - Handle<ExternalTwoByteString>::cast(source), 0, source->length()); - scanner_.Initialize(&stream); -- return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); -+ return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope); - } else { - GenericStringUC16CharacterStream stream(source, 0, source->length()); - scanner_.Initialize(&stream); -- return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); -+ return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope); - } - } - -@@ -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); -@@ -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(zone()) ZoneList<Statement*>(16); - bool ok = true; - int beg_loc = scanner().location().beg_pos; -@@ -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(); -+ } -+ - 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 - -+ int qml_mode = 0; -+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name)) -+ qml_mode = 1; -+ arguments->Add(NewNumberLiteral(qml_mode)); -+ - // Construct the call to Runtime_InitializeConstGlobal - // and add it to the initialization statement block. - // Note that the function does different things depending on -@@ -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)) -+ qml_mode = 1; -+ arguments->Add(NewNumberLiteral(qml_mode)); -+ - // 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, -@@ -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->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 eaae6f7..a60951d 100644 ---- a/src/parser.h -+++ b/src/parser.h -@@ -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 = false); - - FunctionLiteral* ParseLazy(CompilationInfo* info); - -@@ -476,6 +477,7 @@ class Parser { - FunctionLiteral* DoParseProgram(Handle<String> source, - bool in_global_context, - StrictModeFlag strict_mode, -+ bool qml_mode, - ZoneScope* zone_scope); - - // Report syntax error -diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc -index 37c76ce..73812fd 100644 ---- a/src/prettyprinter.cc -+++ b/src/prettyprinter.cc -@@ -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())); -+ if (var->is_qml_global()) { -+ pos += OS::SNPrintF(buf + pos, ":QML"); -+ } - OS::SNPrintF(buf + pos, ")"); - PrintLiteralIndented(buf.start(), value, true); - } -diff --git a/src/runtime.cc b/src/runtime.cc -index 0e256c1..b64e66b 100644 ---- a/src/runtime.cc -+++ b/src/runtime.cc -@@ -1307,19 +1307,23 @@ static Failure* ThrowRedeclarationError(Isolate* isolate, - RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { - 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); - 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()); -+ - // Traverse the name/value pairs and set the properties. - int length = pairs->length(); -- for (int i = 0; i < length; i += 2) { -+ for (int i = 0; i < length; i += 3) { - HandleScope scope(isolate); - Handle<String> name(String::cast(pairs->get(i))); - Handle<Object> value(pairs->get(i + 1), isolate); -+ Handle<Smi> is_qml_global(Smi::cast(pairs->get(i + 2))); -+ -+ Handle<JSObject> global = is_qml_global->value()?qml_global:js_global; - - // We have to declare a global const property. To capture we only - // assign to it when evaluating the assignment for "const x = -@@ -1506,19 +1510,24 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { - NoHandleAllocation nha; - // args[0] == name - // args[1] == strict_mode -- // args[2] == value (optional) -+ // args[2] == qml_mode -+ // args[3] == value (optional) - - // Determine if we need to assign to the variable if it already - // exists (based on the number of arguments). -- RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); -- bool assign = args.length() == 3; -+ RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); -+ bool assign = args.length() == 4; - - CONVERT_ARG_CHECKED(String, name, 0); -- GlobalObject* global = isolate->context()->global(); - RUNTIME_ASSERT(args[1]->IsSmi()); - StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(1)); - ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode); - -+ RUNTIME_ASSERT(args[2]->IsSmi()); -+ int qml_mode = Smi::cast(args[2])->value(); -+ -+ JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global(); -+ - // According to ECMA-262, section 12.2, page 62, the property must - // not be deletable. - PropertyAttributes attributes = DONT_DELETE; -@@ -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(); - } -@@ -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) { -- return global->SetProperty(*name, args[2], attributes, strict_mode, true); -+ return global->SetProperty(*name, args[3], attributes, strict_mode, true); - } - return isolate->heap()->undefined_value(); - } -@@ -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. -- RUNTIME_ASSERT(args.length() == 2); -+ RUNTIME_ASSERT(args.length() == 3); - CONVERT_ARG_CHECKED(String, name, 0); - Handle<Object> value = args.at<Object>(1); - -+ RUNTIME_ASSERT(args[2]->IsSmi()); -+ int qml_mode = Smi::cast(args[2])->value(); -+ - // Get the current global object from top. -- GlobalObject* global = isolate->context()->global(); -+ JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global(); - - // According to ECMA-262, section 12.2, page 62, the property must - // not be deletable. Since it's a const, it must be READ_ONLY too. -@@ -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 -@@ -9386,7 +9398,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) { - Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, - context, - true, -- kNonStrictMode); -+ kNonStrictMode, -+ false); - if (shared.is_null()) return Failure::Exception(); - Handle<JSFunction> fun = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, -@@ -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, -+ bool qml_mode) { - 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()), - context->IsGlobalContext(), -- strict_mode); -+ strict_mode, -+ qml_mode); - if (shared.is_null()) return MakePair(Failure::Exception(), NULL); - Handle<JSFunction> compiled = - isolate->factory()->NewFunctionFromSharedFunctionInfo( -@@ -9427,7 +9442,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate, - - - RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) { -- ASSERT(args.length() == 4); -+ ASSERT(args.length() == 5); - - HandleScope scope(isolate); - Handle<Object> callee = args.at<Object>(0); -@@ -9490,15 +9505,17 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) { - } - - ASSERT(args[3]->IsSmi()); -+ ASSERT(args[4]->IsSmi()); - return CompileGlobalEval(isolate, - args.at<String>(1), - args.at<Object>(2), -- static_cast<StrictModeFlag>(args.smi_at(3))); -+ static_cast<StrictModeFlag>(args.smi_at(3)), -+ Smi::cast(args[4])->value()); - } - - - RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { -- ASSERT(args.length() == 4); -+ ASSERT(args.length() == 5); - - HandleScope scope(isolate); - Handle<Object> callee = args.at<Object>(0); -@@ -9511,10 +9528,12 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) { - } - - ASSERT(args[3]->IsSmi()); -+ ASSERT(args[4]->IsSmi()); - return CompileGlobalEval(isolate, - args.at<String>(1), - args.at<Object>(2), -- static_cast<StrictModeFlag>(args.smi_at(3))); -+ static_cast<StrictModeFlag>(args.smi_at(3)), -+ Smi::cast(args[4])->value()); - } - - -@@ -11220,10 +11239,12 @@ class ScopeIterator { - ZoneScope zone_scope(isolate, DELETE_ON_EXIT); - Handle<Script> script(Script::cast(shared_info->script())); - Scope* scope; -- if (index >= 0) { -+ if (index >= 0 || shared_info->qml_mode()) { - // Global code - CompilationInfo info(script); - info.MarkAsGlobal(); -+ if (shared_info->qml_mode()) -+ info.MarkAsQmlMode(); - bool result = ParserApi::Parse(&info); - ASSERT(result); - result = Scope::Analyze(&info); -@@ -11253,7 +11274,6 @@ class ScopeIterator { - ScopeType scope_type = Type(); - if (scope_type == ScopeTypeGlobal) { - // The global scope is always the last in the chain. -- ASSERT(context_->IsGlobalContext()); - context_ = Handle<Context>(); - return; - } -@@ -11277,7 +11297,7 @@ class ScopeIterator { - !scope_info->HasContext()); - return ScopeTypeLocal; - case GLOBAL_SCOPE: -- ASSERT(context_->IsGlobalContext()); -+ ASSERT(context_->IsGlobalContext() || scope_info->IsQmlMode()); - return ScopeTypeGlobal; - case WITH_SCOPE: - ASSERT(context_->IsWithContext()); -@@ -11315,10 +11335,15 @@ class ScopeIterator { - switch (Type()) { - case ScopeIterator::ScopeTypeGlobal: - return Handle<JSObject>(CurrentContext()->global()); -- case ScopeIterator::ScopeTypeLocal: -+ case ScopeIterator::ScopeTypeLocal: { -+ Handle<SerializedScopeInfo> scope_info = nested_scope_chain_.last(); -+ if (scope_info->IsQmlMode()) -+ ASSERT(nested_scope_chain_.length() == 2); -+ else -+ ASSERT(nested_scope_chain_.length() == 1); - // Materialize the content of the local scope into a JSObject. -- ASSERT(nested_scope_chain_.length() == 1); - return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); -+ } - case ScopeIterator::ScopeTypeWith: - // Return the with object. - return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); -@@ -12034,6 +12059,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { - Handle<JSFunction> function(JSFunction::cast(frame->function())); - Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info()); - ScopeInfo<> sinfo(*scope_info); -+ bool qml_mode = function->shared()->qml_mode(); - - // Traverse the saved contexts chain to find the active context for the - // selected frame. -@@ -12107,7 +12133,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { - Compiler::CompileEval(function_source, - context, - context->IsGlobalContext(), -- kNonStrictMode); -+ kNonStrictMode, -+ qml_mode); - if (shared.is_null()) return Failure::Exception(); - Handle<JSFunction> compiled_function = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); -@@ -12117,7 +12144,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(); - - Handle<Object> arguments = GetArgumentsObject(isolate, -@@ -12198,7 +12226,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 = -- Compiler::CompileEval(source, context, is_global, kNonStrictMode); -+ Compiler::CompileEval(source, context, is_global, kNonStrictMode, false); - if (shared.is_null()) return Failure::Exception(); - Handle<JSFunction> compiled_function = - Handle<JSFunction>( -diff --git a/src/runtime.h b/src/runtime.h -index 67fc628..aada06d 100644 ---- a/src/runtime.h -+++ b/src/runtime.h -@@ -257,8 +257,8 @@ namespace internal { - \ - /* Eval */ \ - F(GlobalReceiver, 1, 1) \ -- F(ResolvePossiblyDirectEval, 4, 2) \ -- F(ResolvePossiblyDirectEvalNoLookup, 4, 2) \ -+ F(ResolvePossiblyDirectEval, 5, 2) \ -+ F(ResolvePossiblyDirectEvalNoLookup, 5, 2) \ - \ - F(SetProperty, -1 /* 4 or 5 */, 1) \ - F(DefineOrRedefineDataProperty, 4, 1) \ -@@ -336,8 +336,8 @@ namespace internal { - /* Declarations and initialization */ \ - F(DeclareGlobals, 3, 1) \ - F(DeclareContextSlot, 4, 1) \ -- F(InitializeVarGlobal, -1 /* 2 or 3 */, 1) \ -- F(InitializeConstGlobal, 2, 1) \ -+ F(InitializeVarGlobal, -1 /* 3 or 4 */, 1) \ -+ F(InitializeConstGlobal, 3, 1) \ - F(InitializeConstContextSlot, 3, 1) \ - F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - \ -diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc -index 8ea5f1e..a61b787 100644 ---- a/src/scopeinfo.cc -+++ b/src/scopeinfo.cc -@@ -51,6 +51,7 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope) - : function_name_(FACTORY->empty_symbol()), - calls_eval_(scope->calls_eval()), - is_strict_mode_(scope->is_strict_mode()), -+ is_qml_mode_(scope->is_qml_mode()), - type_(scope->type()), - parameters_(scope->num_parameters()), - stack_slots_(scope->num_stack_slots()), -@@ -153,6 +154,8 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope) - // - // - is strict mode scope - // -+// - is qml mode scope -+// - // - scope type - // - // - number of variables in the context object (smi) (= function context -@@ -252,6 +255,7 @@ ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) - p = ReadObject(p, &function_name_); - p = ReadBool(p, &calls_eval_); - p = ReadBool(p, &is_strict_mode_); -+ p = ReadBool(p, &is_qml_mode_); - p = ReadInt(p, &type_); - p = ReadList<Allocator>(p, &context_slots_, &context_modes_); - p = ReadList<Allocator>(p, ¶meters_); -@@ -307,9 +311,9 @@ static Object** WriteList(Object** p, - - template<class Allocator> - Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { -- // function name, calls eval, is_strict_mode, scope type, -+ // function name, calls eval, is_strict_mode, is_qml_mode, scope type, - // length for 3 tables: -- const int extra_slots = 1 + 1 + 1 + 1 + 3; -+ const int extra_slots = 1 + 1 + 1 + 1 + 1 + 3; - int length = extra_slots + - context_slots_.length() * 2 + - parameters_.length() + -@@ -324,6 +328,7 @@ Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { - p = WriteObject(p, function_name_); - p = WriteBool(p, calls_eval_); - p = WriteBool(p, is_strict_mode_); -+ p = WriteBool(p, is_qml_mode_); - p = WriteInt(p, type_); - p = WriteList(p, &context_slots_, &context_modes_); - p = WriteList(p, ¶meters_); -@@ -372,8 +377,8 @@ SerializedScopeInfo* SerializedScopeInfo::Empty() { - - Object** SerializedScopeInfo::ContextEntriesAddr() { - ASSERT(length() > 0); -- // +4 for function name, calls eval, strict mode, scope type. -- return data_start() + 4; -+ // +5 for function name, calls eval, strict mode, qml mode, scope type. -+ return data_start() + 5; - } - - -@@ -417,10 +422,21 @@ bool SerializedScopeInfo::IsStrictMode() { - } - - -+bool SerializedScopeInfo::IsQmlMode() { -+ if (length() > 0) { -+ Object** p = data_start() + 3; // +3 for function name, calls eval, strict mode. -+ bool qml_mode; -+ p = ReadBool(p, &qml_mode); -+ return qml_mode; -+ } -+ return false; -+} -+ -+ - ScopeType SerializedScopeInfo::Type() { - ASSERT(length() > 0); -- // +3 for function name, calls eval, strict mode. -- Object** p = data_start() + 3; -+ // +4 for function name, calls eval, strict mode, qml mode. -+ Object** p = data_start() + 4; - ScopeType type; - p = ReadInt(p, &type); - return type; -diff --git a/src/scopeinfo.h b/src/scopeinfo.h -index eeb3047..2ca4503 100644 ---- a/src/scopeinfo.h -+++ b/src/scopeinfo.h -@@ -88,6 +88,7 @@ class ScopeInfo BASE_EMBEDDED { - Handle<String> function_name_; - bool calls_eval_; - bool is_strict_mode_; -+ bool is_qml_mode_; - ScopeType type_; - List<Handle<String>, Allocator > parameters_; - List<Handle<String>, Allocator > stack_slots_; -diff --git a/src/scopes.cc b/src/scopes.cc -index 3167c4d..6503d07 100644 ---- a/src/scopes.cc -+++ b/src/scopes.cc -@@ -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_flag_ = (outer_scope != NULL) - ? outer_scope->strict_mode_flag_ : kNonStrictMode; -+ qml_mode_ = (outer_scope != NULL) && outer_scope->qml_mode_; - outer_scope_calls_non_strict_eval_ = false; - inner_scope_calls_eval_ = false; - 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_->global(); -+ -+#ifdef ENABLE_DEBUGGER_SUPPORT -+ 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); -+ } -+ } -+ - } 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_->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 (!global->HasProperty(*(proxy->name()))) { -+ var->set_is_qml_global(true); -+ } -+ } -+ - 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_->global(); -+ -+#ifdef ENABLE_DEBUGGER_SUPPORT -+ 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); -+ } -+ } -+ - break; - - case DYNAMIC_LOOKUP: -diff --git a/src/scopes.h b/src/scopes.h -index a141887..41e5f5c 100644 ---- a/src/scopes.h -+++ b/src/scopes.h -@@ -228,6 +228,11 @@ class Scope: public ZoneObject { - end_position_ = statement_pos; - } - -+ // Enable qml mode for this scope -+ void EnableQmlMode() { -+ qml_mode_ = true; -+ } -+ - // --------------------------------------------------------------------------- - // Predicates. - -@@ -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_; } - 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_non_strict_eval_; -diff --git a/src/variables.cc b/src/variables.cc -index d85e1b2..1887935 100644 ---- a/src/variables.cc -+++ b/src/variables.cc -@@ -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) { -+ is_used_(false), -+ is_qml_global_(false) { - // names must be canonicalized for fast equality checks - ASSERT(name->IsSymbol()); - } -diff --git a/src/variables.h b/src/variables.h -index 8b2d869..33561b0 100644 ---- a/src/variables.h -+++ b/src/variables.h -@@ -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_; -@@ -175,6 +177,9 @@ class Variable: public ZoneObject { - // Usage info. - bool is_accessed_from_inner_scope_; // set by variable resolver - bool is_used_; -+ -+ // QML info -+ bool is_qml_global_; - }; - - -diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc -index f62c517..f30221f 100644 ---- a/src/x64/code-stubs-x64.cc -+++ b/src/x64/code-stubs-x64.cc -@@ -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 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); -+ - // Initialize the rest of the slots to undefined. - __ 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 bf640db..b1e5d35 100644 ---- a/src/x64/full-codegen-x64.cc -+++ b/src/x64/full-codegen-x64.cc -@@ -173,12 +173,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) { - - // Possibly allocate a local context. - 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())) { - Comment cmnt(masm_, "[ Allocate local context"); - // Argument to NewContext is the function, which is still in rdi. - __ push(rdi); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ 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, 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 || var->is_qml_global()) - ? RelocInfo::CODE_TARGET - : RelocInfo::CODE_TARGET_CONTEXT; - __ 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(); -@@ -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())); -+ - __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP - ? Runtime::kResolvePossiblyDirectEvalNoLookup -- : Runtime::kResolvePossiblyDirectEval, 4); -+ : Runtime::kResolvePossiblyDirectEval, 5); - } - - -@@ -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, 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 38a8c18..2a95fee 100644 ---- a/src/x64/lithium-codegen-x64.cc -+++ b/src/x64/lithium-codegen-x64.cc -@@ -196,12 +196,13 @@ bool LCodeGen::GeneratePrologue() { - - // Possibly allocate a local context. - int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; -- if (heap_slots > 0) { -+ if (heap_slots > 0 || -+ (scope()->is_qml_mode() && scope()->is_global_scope())) { - Comment(";;; Allocate local context"); - // Argument to NewContext is the function, which is still in rdi. - __ push(rdi); - if (heap_slots <= FastNewContextStub::kMaximumSlots) { -- FastNewContextStub stub(heap_slots); -+ FastNewContextStub stub((heap_slots < 0)?0:heap_slots); - __ CallStub(&stub); - } else { - __ CallRuntime(Runtime::kNewFunctionContext, 1); -@@ -2610,7 +2611,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) { - - void LCodeGen::DoGlobalObject(LGlobalObject* instr) { - Register result = ToRegister(instr->result()); -- __ movq(result, GlobalObjectOperand()); -+ __ movq(result, instr->qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand()); - } - - -@@ -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 0af2ce4..9e2731f 100644 ---- a/src/x64/lithium-x64.cc -+++ b/src/x64/lithium-x64.cc -@@ -1123,7 +1123,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { - - - LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { -- return DefineAsRegister(new LGlobalObject); -+ return DefineAsRegister(new LGlobalObject(instr->qml_global())); - } - - -@@ -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 20a6937..8f1a3d8 100644 ---- a/src/x64/lithium-x64.h -+++ b/src/x64/lithium-x64.h -@@ -1303,7 +1303,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> { - - class LGlobalObject: public LTemplateInstruction<1, 0, 0> { - public: -+ explicit LGlobalObject(bool qml_global) : qml_global_(qml_global) {} -+ - DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object") -+ -+ bool qml_global() { return qml_global_; } -+ private: -+ bool qml_global_; - }; - - -@@ -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 f5f81b1..5caa6cf 100644 ---- a/src/x64/macro-assembler-x64.h -+++ b/src/x64/macro-assembler-x64.h -@@ -1418,6 +1418,11 @@ static inline Operand GlobalObjectOperand() { - } - - -+static inline Operand QmlGlobalObjectOperand() { -+ return ContextOperand(rsi, Context::QML_GLOBAL_INDEX); -+} -+ -+ - // Provides access to exit frame stack space (not GCed). - static inline Operand StackSpaceOperand(int index) { - #ifdef _WIN64 --- -1.7.4.1 - diff --git a/src/v8/0005-Allow-access-to-the-calling-script-data.patch b/src/v8/0005-Allow-access-to-the-calling-script-data.patch deleted file mode 100644 index 596e9573fc13fd9cd0c1bbdd46bab6536bf52562..0000000000000000000000000000000000000000 --- a/src/v8/0005-Allow-access-to-the-calling-script-data.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 2081f6baaab81d60564680de600b4dcf03de6cd4 Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Fri, 14 Oct 2011 17:03:06 +1000 -Subject: [PATCH 05/13] Allow access to the calling script data - ---- - include/v8.h | 1 + - src/api.cc | 12 ++++++++++++ - 2 files changed, 13 insertions(+), 0 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 193e2fe..c094d08 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -3517,6 +3517,7 @@ class V8EXPORT Context { - */ - static Local<Context> GetCalling(); - static Local<Object> GetCallingQmlGlobal(); -+ static Local<Value> GetCallingScriptData(); - - /** - * Sets the security token for the context. To access an object in -diff --git a/src/api.cc b/src/api.cc -index 2d3d97a..54df40d 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -4370,6 +4370,18 @@ v8::Local<v8::Object> Context::GetCallingQmlGlobal() { - } - } - -+v8::Local<v8::Value> Context::GetCallingScriptData() -+{ -+ i::Isolate* isolate = i::Isolate::Current(); -+ if (IsDeadCheck(isolate, "v8::Context::GetCallingScriptData()")) { -+ return Local<Object>(); -+ } -+ -+ i::JavaScriptFrameIterator it; -+ if (it.done()) return Local<Object>(); -+ i::Handle<i::Script> script(i::Script::cast(i::JSFunction::cast(it.frame()->function())->shared()->script())); -+ return Utils::ToLocal(i::Handle<i::Object>(script->data())); -+} - - v8::Local<v8::Object> Context::Global() { - if (IsDeadCheck(i::Isolate::Current(), "v8::Context::Global()")) { --- -1.7.4.1 - diff --git a/src/v8/0006-Add-custom-object-compare-callback.patch b/src/v8/0006-Add-custom-object-compare-callback.patch deleted file mode 100644 index 0ffe0b6dfc6a9445c6cb0b661ffc61bd305d6dfe..0000000000000000000000000000000000000000 --- a/src/v8/0006-Add-custom-object-compare-callback.patch +++ /dev/null @@ -1,548 +0,0 @@ -From d2d3c19a32e2f7a5586811bb10ea75a79a11f52f Mon Sep 17 00:00:00 2001 -From: Aaron Kennedy <aaron.kennedy@nokia.com> -Date: Thu, 27 Oct 2011 13:40:00 +0100 -Subject: [PATCH 06/13] Add custom object compare callback - -A global custom object comparison callback can be set with: - V8::SetUserObjectComparisonCallbackFunction() -When two JSObjects are compared (== or !=), if either one has -the MarkAsUseUserObjectComparison() bit set, the custom comparison -callback is invoked to do the actual comparison. - -This is useful when you have "value" objects that you want to -compare as equal, even though they are actually different JS object -instances. ---- - include/v8.h | 13 +++++++++++++ - src/api.cc | 22 ++++++++++++++++++++++ - src/arm/code-stubs-arm.cc | 43 +++++++++++++++++++++++++++++++++++++++++-- - src/factory.cc | 8 ++++++++ - src/ia32/code-stubs-ia32.cc | 39 +++++++++++++++++++++++++++++++++++++++ - src/isolate.cc | 7 +++++++ - src/isolate.h | 8 ++++++++ - src/objects-inl.h | 21 ++++++++++++++++++--- - src/objects.cc | 8 ++++---- - src/objects.h | 12 ++++++++++-- - src/runtime.cc | 23 +++++++++++++++++++++++ - src/runtime.h | 1 + - src/x64/code-stubs-x64.cc | 37 +++++++++++++++++++++++++++++++++++++ - 13 files changed, 231 insertions(+), 11 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index c094d08..6baf2b2 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -2501,6 +2501,12 @@ class V8EXPORT ObjectTemplate : public Template { - bool HasExternalResource(); - void SetHasExternalResource(bool value); - -+ /** -+ * Mark object instances of the template as using the user object -+ * comparison callback. -+ */ -+ void MarkAsUseUserObjectComparison(); -+ - private: - ObjectTemplate(); - static Local<ObjectTemplate> New(Handle<FunctionTemplate> constructor); -@@ -2720,6 +2726,10 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target, - AccessType type, - Local<Value> data); - -+// --- User Object Comparisoa nCallback --- -+typedef bool (*UserObjectComparisonCallback)(Local<Object> lhs, -+ Local<Object> rhs); -+ - // --- AllowCodeGenerationFromStrings callbacks --- - - /** -@@ -3046,6 +3056,9 @@ class V8EXPORT V8 { - /** Callback function for reporting failed access checks.*/ - static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback); - -+ /** Callback for user object comparisons */ -+ static void SetUserObjectComparisonCallbackFunction(UserObjectComparisonCallback); -+ - /** - * 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 54df40d..974d702 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -1464,6 +1464,17 @@ void ObjectTemplate::SetHasExternalResource(bool value) - } - - -+void ObjectTemplate::MarkAsUseUserObjectComparison() -+{ -+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); -+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::MarkAsUseUserObjectComparison()")) { -+ return; -+ } -+ ENTER_V8(isolate); -+ EnsureConstructor(this); -+ Utils::OpenHandle(this)->set_use_user_object_comparison(i::Smi::FromInt(1)); -+} -+ - // --- S c r i p t D a t a --- - - -@@ -5113,6 +5124,17 @@ void V8::SetFailedAccessCheckCallbackFunction( - isolate->SetFailedAccessCheckCallback(callback); - } - -+ -+void V8::SetUserObjectComparisonCallbackFunction( -+ UserObjectComparisonCallback callback) { -+ i::Isolate* isolate = i::Isolate::Current(); -+ if (IsDeadCheck(isolate, "v8::V8::SetUserObjectComparisonCallbackFunction()")) { -+ return; -+ } -+ 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 f5be938..1e1aebd 100644 ---- a/src/arm/code-stubs-arm.cc -+++ b/src/arm/code-stubs-arm.cc -@@ -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. - -+ { -+ Label not_user_equal, user_equal; -+ __ and_(r2, r1, Operand(r0)); -+ __ tst(r2, Operand(kSmiTagMask)); -+ __ b(eq, ¬_user_equal); -+ -+ __ CompareObjectType(r0, r2, r4, JS_OBJECT_TYPE); -+ __ b(ne, ¬_user_equal); -+ -+ __ CompareObjectType(r1, r3, r4, JS_OBJECT_TYPE); -+ __ b(ne, ¬_user_equal); -+ -+ __ 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::kBitField2Offset)); -+ __ and_(r3, r3, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r3, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(ne, ¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ Push(r0, r1); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_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_); -@@ -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::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::kBitField2Offset)); -+ __ and_(r2, r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ cmp(r2, Operand(1 << Map::kUseUserObjectComparison)); -+ __ b(eq, &miss); - - ASSERT(GetCondition() == eq); - __ sub(r0, r0, Operand(r1)); -diff --git a/src/factory.cc b/src/factory.cc -index 8c96944..76ca69d 100644 ---- a/src/factory.cc -+++ b/src/factory.cc -@@ -1153,6 +1153,7 @@ Handle<JSFunction> Factory::CreateApiFunction( - - int internal_field_count = 0; - bool has_external_resource = false; -+ bool use_user_object_comparison = false; - - if (!obj->instance_template()->IsUndefined()) { - Handle<ObjectTemplateInfo> instance_template = -@@ -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(); -+ use_user_object_comparison = -+ !instance_template->use_user_object_comparison()->IsUndefined(); - } - - int instance_size = kPointerSize * internal_field_count; -@@ -1206,6 +1209,11 @@ Handle<JSFunction> Factory::CreateApiFunction( - map->set_has_external_resource(true); - } - -+ // Mark as using user object comparison if needed -+ if (use_user_object_comparison) { -+ map->set_use_user_object_comparison(true); -+ } -+ - // Mark as undetectable if needed. - if (obj->undetectable()) { - map->set_is_undetectable(); -diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc -index 8a94a06..e73753e 100644 ---- a/src/ia32/code-stubs-ia32.cc -+++ b/src/ia32/code-stubs-ia32.cc -@@ -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. - -+ { -+ Label not_user_equal, user_equal; -+ __ test(eax, Immediate(kSmiTagMask)); -+ __ j(zero, ¬_user_equal); -+ __ test(edx, Immediate(kSmiTagMask)); -+ __ j(zero, ¬_user_equal); -+ -+ __ CmpObjectType(eax, JS_OBJECT_TYPE, ebx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ test_b(FieldOperand(ebx, Map::kBitField2Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &user_equal); -+ __ test_b(FieldOperand(ecx, Map::kBitField2Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &user_equal); -+ -+ __ jmp(¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ pop(ebx); // Return address. -+ __ push(eax); -+ __ push(edx); -+ __ push(ebx); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_user_equal); -+ } -+ - // 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, Label::kNear); -+ __ test_b(FieldOperand(ecx, Map::kBitField2Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &miss, Label::kNear); - __ CmpObjectType(edx, JS_OBJECT_TYPE, ecx); - __ j(not_equal, &miss, Label::kNear); -+ __ test_b(FieldOperand(ecx, Map::kBitField2Offset), -+ 1 << Map::kUseUserObjectComparison); -+ __ j(not_zero, &miss, Label::kNear); - - ASSERT(GetCondition() == equal); - __ 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 5453bf2..9919e83 100644 ---- a/src/isolate.h -+++ b/src/isolate.h -@@ -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_; -+ - // Whether out of memory exceptions should be ignored. - bool ignore_out_of_memory_; - -@@ -703,6 +706,11 @@ class Isolate { - void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback); - void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type); - -+ void SetUserObjectComparisonCallback(v8::UserObjectComparisonCallback callback); -+ inline v8::UserObjectComparisonCallback UserObjectComparisonCallback() { -+ return thread_local_top()->user_object_comparison_callback_; -+ } -+ - // Exception throwing support. The caller should use the result - // 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 2e83fb7..13d7591 100644 ---- a/src/objects-inl.h -+++ b/src/objects-inl.h -@@ -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_field2(bit_field2() | (1 << kUseUserObjectComparison)); -+ } else { -+ set_bit_field2(bit_field2() & ~(1 << kUseUserObjectComparison)); -+ } -+} -+ -+bool Map::use_user_object_comparison() { -+ return ((1 << kUseUserObjectComparison) & bit_field2()) != 0; -+} -+ -+ - void Map::set_named_interceptor_is_fallback(bool value) - { - if (value) { -@@ -3334,6 +3347,8 @@ ACCESSORS(ObjectTemplateInfo, internal_field_count, Object, - kInternalFieldCountOffset) - 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 b71eaac..3137437 100644 ---- a/src/objects.h -+++ b/src/objects.h -@@ -4258,6 +4258,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(); -+ - // [prototype]: implicit prototype object. - DECL_ACCESSORS(prototype, Object) - -@@ -4505,7 +4510,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; -@@ -4524,6 +4529,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; -@@ -7556,6 +7562,7 @@ class ObjectTemplateInfo: public TemplateInfo { - DECL_ACCESSORS(constructor, Object) - DECL_ACCESSORS(internal_field_count, Object) - DECL_ACCESSORS(has_external_resource, Object) -+ DECL_ACCESSORS(use_user_object_comparison, Object) - - static inline ObjectTemplateInfo* cast(Object* obj); - -@@ -7573,7 +7580,8 @@ class ObjectTemplateInfo: public TemplateInfo { - static const int kInternalFieldCountOffset = - kConstructorOffset + kPointerSize; - static const int kHasExternalResourceOffset = kInternalFieldCountOffset + kPointerSize; -- static const int kSize = kHasExternalResourceOffset + kPointerSize; -+ static const int kUseUserObjectComparisonOffset = kHasExternalResourceOffset + kPointerSize; -+ static const int kSize = kUseUserObjectComparisonOffset + kPointerSize; - }; - - -diff --git a/src/runtime.cc b/src/runtime.cc -index b64e66b..8010169 100644 ---- a/src/runtime.cc -+++ b/src/runtime.cc -@@ -7095,6 +7095,29 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringEquals) { - } - - -+RUNTIME_FUNCTION(MaybeObject*, Runtime_UserObjectEquals) { -+ NoHandleAllocation ha; -+ ASSERT(args.length() == 2); -+ -+ CONVERT_CHECKED(JSObject, lhs, args[1]); -+ CONVERT_CHECKED(JSObject, rhs, args[0]); -+ -+ bool result; -+ -+ v8::UserObjectComparisonCallback callback = isolate->UserObjectComparisonCallback(); -+ if (callback) { -+ HandleScope scope(isolate); -+ Handle<JSObject> lhs_handle(lhs); -+ Handle<JSObject> rhs_handle(rhs); -+ result = callback(v8::Utils::ToLocal(lhs_handle), v8::Utils::ToLocal(rhs_handle)); -+ } else { -+ result = (lhs == rhs); -+ } -+ -+ return Smi::FromInt(result?0:1); -+} -+ -+ - RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberCompare) { - NoHandleAllocation ha; - ASSERT(args.length() == 3); -diff --git a/src/runtime.h b/src/runtime.h -index aada06d..cd36da9 100644 ---- a/src/runtime.h -+++ b/src/runtime.h -@@ -157,6 +157,7 @@ namespace internal { - /* Comparisons */ \ - F(NumberEquals, 2, 1) \ - F(StringEquals, 2, 1) \ -+ F(UserObjectEquals, 2, 1) \ - \ - F(NumberCompare, 3, 1) \ - F(SmiLexicographicCompare, 2, 1) \ -diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc -index f30221f..ff8337f 100644 ---- a/src/x64/code-stubs-x64.cc -+++ b/src/x64/code-stubs-x64.cc -@@ -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. - -+ { -+ Label not_user_equal, user_equal; -+ __ JumpIfSmi(rax, ¬_user_equal); -+ __ JumpIfSmi(rdx, ¬_user_equal); -+ -+ __ CmpObjectType(rax, JS_OBJECT_TYPE, rbx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); -+ __ j(not_equal, ¬_user_equal); -+ -+ __ testb(FieldOperand(rbx, Map::kBitField2Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &user_equal); -+ __ testb(FieldOperand(rcx, Map::kBitField2Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &user_equal); -+ -+ __ jmp(¬_user_equal); -+ -+ __ bind(&user_equal); -+ -+ __ pop(rbx); // Return address. -+ __ push(rax); -+ __ push(rdx); -+ __ push(rbx); -+ __ TailCallRuntime(Runtime::kUserObjectEquals, 2, 1); -+ -+ __ bind(¬_user_equal); -+ } -+ - // 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, Label::kNear); -+ __ testb(FieldOperand(rcx, Map::kBitField2Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &miss, Label::kNear); - __ CmpObjectType(rdx, JS_OBJECT_TYPE, rcx); - __ j(not_equal, &miss, Label::kNear); -+ __ testb(FieldOperand(rcx, Map::kBitField2Offset), -+ Immediate(1 << Map::kUseUserObjectComparison)); -+ __ j(not_zero, &miss, Label::kNear); - - ASSERT(GetCondition() == equal); - __ subq(rax, rdx); --- -1.7.4.1 - diff --git a/src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch b/src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch deleted file mode 100644 index e3b65f5ee277f1b9f86396a583395c8272446af8..0000000000000000000000000000000000000000 --- a/src/v8/0007-Allow-a-script-to-be-flagged-as-native.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 1ecd533461383671ea465b37f2cad84a0aad3d52 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 07/13] 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 -useful to be able to write code in JavaScript instead of C++ and -still have it appear sensibly to the user. ---- - include/v8.h | 5 +++-- - src/compiler.cc | 2 +- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 6baf2b2..229ddbd 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -588,8 +588,9 @@ class ScriptOrigin { - class V8EXPORT Script { - public: - enum CompileFlags { -- Default = 0x00, -- QmlMode = 0x01 -+ Default = 0x00, -+ QmlMode = 0x01, -+ NativeMode = 0x02 - }; - - /** -diff --git a/src/compiler.cc b/src/compiler.cc -index 4902e72..cabca74 100644 ---- a/src/compiler.cc -+++ b/src/compiler.cc -@@ -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); -- if (natives == NATIVES_CODE) { -+ if (natives == NATIVES_CODE || compile_flags & v8::Script::NativeMode) { - script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); - } - if (!script_name.is_null()) { --- -1.7.4.1 - diff --git a/src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch b/src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch deleted file mode 100644 index 8c072d901e06832655ba28223aa1ebb95b01b06e..0000000000000000000000000000000000000000 --- a/src/v8/0008-QtScript-V8-Add-new-v8-api-to-check-if-a-value-is-an.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c7850561fcdf333a5b80a50623c7d4507757b315 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 08/13] QtScript/V8: Add new v8 api to check if a value is an error. - -New function v8::Value::IsError was created. - -This API is experimental and added only for the purposes of our -research. ---- - include/v8.h | 5 +++++ - src/api.cc | 6 ++++++ - src/heap.h | 1 + - 3 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index 229ddbd..d995e54 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -967,6 +967,11 @@ class Value : public Data { - */ - V8EXPORT bool IsRegExp() const; - -+ /** -+ * Returns true if this value is an Error. -+ */ -+ V8EXPORT bool IsError() const; -+ - V8EXPORT Local<Boolean> ToBoolean() const; - V8EXPORT Local<Number> ToNumber() const; - V8EXPORT Local<String> ToString() const; -diff --git a/src/api.cc b/src/api.cc -index 974d702..a16ef65 100644 ---- a/src/api.cc -+++ b/src/api.cc -@@ -2316,6 +2316,12 @@ bool Value::IsRegExp() const { - return obj->IsJSRegExp(); - } - -+bool Value::IsError() const { -+ if (IsDeadCheck(i::Isolate::Current(), "v8::Value::IsError()")) return false; -+ i::Handle<i::Object> obj = Utils::OpenHandle(this); -+ return obj->HasSpecificClassOf(HEAP->Error_symbol()); -+} -+ - - Local<String> Value::ToString() const { - i::Handle<i::Object> obj = Utils::OpenHandle(this); -diff --git a/src/heap.h b/src/heap.h -index 5e90964..6166cde 100644 ---- a/src/heap.h -+++ b/src/heap.h -@@ -190,6 +190,7 @@ inline Heap* _inline_get_heap_(); - V(string_symbol, "string") \ - V(String_symbol, "String") \ - V(Date_symbol, "Date") \ -+ V(Error_symbol, "Error") \ - V(this_symbol, "this") \ - V(to_string_symbol, "toString") \ - V(char_at_symbol, "CharAt") \ --- -1.7.4.1 - diff --git a/src/v8/0009-Fix-deprecated-Python-code.patch b/src/v8/0009-Fix-deprecated-Python-code.patch deleted file mode 100644 index 2c34e2032199a67f28f9466fe0cd3766db5aa0de..0000000000000000000000000000000000000000 --- a/src/v8/0009-Fix-deprecated-Python-code.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 4a9995fd141e40df2493dc2ef12d91f0a946629a 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 09/13] Fix deprecated Python code - -Needed to make the scripts run on Python 3, which is the -default python interpreter on some newer distros. - -Patch from http://code.google.com/p/v8/issues/detail?id=1391 ---- - tools/js2c.py | 4 ++-- - tools/jsmin.py | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tools/js2c.py b/tools/js2c.py -index a2ea8ea..fe6a72e 100644 ---- a/tools/js2c.py -+++ b/tools/js2c.py -@@ -194,14 +194,14 @@ def ReadMacros(lines): - macro_match = MACRO_PATTERN.match(line) - if macro_match: - name = macro_match.group(1) -- args = map(string.strip, macro_match.group(2).split(',')) -+ args = args = [match.strip() for match in macro_match.group(2).split(',')] - body = macro_match.group(3).strip() - macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body))) - else: - python_match = PYTHON_MACRO_PATTERN.match(line) - if python_match: - name = python_match.group(1) -- args = map(string.strip, python_match.group(2).split(',')) -+ args = [match.strip() for match in python_match.group(2).split(',')] - body = python_match.group(3).strip() - fun = eval("lambda " + ",".join(args) + ': ' + body) - macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) -diff --git a/tools/jsmin.py b/tools/jsmin.py -index 646bf14..395441b 100644 ---- a/tools/jsmin.py -+++ b/tools/jsmin.py -@@ -154,7 +154,7 @@ class JavaScriptMinifier(object): - return var_name - while True: - identifier_first_char = self.identifier_counter % 52 -- identifier_second_char = self.identifier_counter / 52 -+ identifier_second_char = self.identifier_counter // 52 - new_identifier = self.CharFromNumber(identifier_first_char) - if identifier_second_char != 0: - new_identifier = ( --- -1.7.4.1 - diff --git a/src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch b/src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch deleted file mode 100644 index 92ef7af9cd9a8446c6003913a55fcecc74d90a4d..0000000000000000000000000000000000000000 --- a/src/v8/0010-Remove-execute-flag-from-v8-debug.h.patch +++ /dev/null @@ -1,15 +0,0 @@ -From 8498e4b40d8355aa51dd8f4641dd1fdd4704e7bd 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 10/13] Remove execute flag from v8-debug.h - ---- - 0 files changed, 0 insertions(+), 0 deletions(-) - mode change 100755 => 100644 include/v8-debug.h - -diff --git a/include/v8-debug.h b/include/v8-debug.h -old mode 100755 -new mode 100644 --- -1.7.4.1 - diff --git a/src/v8/0011-Fix-warnings.patch b/src/v8/0011-Fix-warnings.patch deleted file mode 100644 index 40261df3583117c5bd71d901da4f19c2ebefec7e..0000000000000000000000000000000000000000 --- a/src/v8/0011-Fix-warnings.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 6643bd52181d51570bb1f9806dd06ff3b66c4251 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 11/13] Fix warnings - ---- - include/v8.h | 16 ++++++++-------- - 1 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/include/v8.h b/include/v8.h -index d995e54..a7b5c8a 100644 ---- a/include/v8.h -+++ b/include/v8.h -@@ -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) { -+ GetNativeFunction(v8::Handle<v8::String>) { - return v8::Handle<v8::FunctionTemplate>(); - } - -@@ -3946,13 +3946,13 @@ class Internals { - return *reinterpret_cast<T*>(addr); - } - -- static inline bool CanCastToHeapObject(void* o) { return false; } -- static inline bool CanCastToHeapObject(Context* o) { return true; } -- static inline bool CanCastToHeapObject(String* o) { return true; } -- static inline bool CanCastToHeapObject(Object* o) { return true; } -- static inline bool CanCastToHeapObject(Message* o) { return true; } -- static inline bool CanCastToHeapObject(StackTrace* o) { return true; } -- static inline bool CanCastToHeapObject(StackFrame* o) { return true; } -+ static inline bool CanCastToHeapObject(void*) { return false; } -+ static inline bool CanCastToHeapObject(Context*) { return true; } -+ static inline bool CanCastToHeapObject(String*) { return true; } -+ static inline bool CanCastToHeapObject(Object*) { return true; } -+ static inline bool CanCastToHeapObject(Message*) { return true; } -+ static inline bool CanCastToHeapObject(StackTrace*) { return true; } -+ static inline bool CanCastToHeapObject(StackFrame*) { return true; } - }; - - } // namespace internal --- -1.7.4.1 - diff --git a/src/v8/0012-Add-flag-to-avoid-breakpoint-relocation.patch b/src/v8/0012-Add-flag-to-avoid-breakpoint-relocation.patch deleted file mode 100644 index 0b6895657d59d6f28dfc696d33f9d02d190a763d..0000000000000000000000000000000000000000 --- a/src/v8/0012-Add-flag-to-avoid-breakpoint-relocation.patch +++ /dev/null @@ -1,147 +0,0 @@ -From f37d702159f3e606610b74fb2b56ece63d510a6e Mon Sep 17 00:00:00 2001 -From: Kai Koehne <kai.koehne@nokia.com> -Date: Thu, 10 Nov 2011 16:00:37 +0100 -Subject: [PATCH 12/13] Add flag to avoid breakpoint relocation - -Add a flag that prevents v8 from relocating breakpoints across -line boundaries. ---- - src/debug.cc | 29 +++++++++++++++++++--- - src/flag-definitions.h | 1 + - test/cctest/test-debug.cc | 59 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 85 insertions(+), 4 deletions(-) - -diff --git a/src/debug.cc b/src/debug.cc -index dc9f297..d32574b 100644 ---- a/src/debug.cc -+++ b/src/debug.cc -@@ -1131,6 +1131,17 @@ Handle<DebugInfo> Debug::GetDebugInfo(Handle<SharedFunctionInfo> shared) { - return Handle<DebugInfo>(DebugInfo::cast(shared->debug_info())); - } - -+static bool ContainsLineBreak(String *string, int from, int to) -+{ -+ ASSERT(from >= 0); -+ ASSERT(from <= to); -+ const int end = (string->length() < to) ? string->length() : to; -+ for (int pos = from; pos < end; ++pos) { -+ if (string->Get(pos) == '\n') -+ return true; -+ } -+ return false; -+} - - void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, - Handle<Object> break_point_object, -@@ -1151,12 +1162,22 @@ void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared, - // Find the break point and change it. - BreakLocationIterator it(debug_info, SOURCE_BREAK_LOCATIONS); - it.FindBreakLocationFromPosition(*source_position); -- it.SetBreakPoint(break_point_object); - -- *source_position = it.position(); -+ bool acceptBreak = true; -+ if (!FLAG_breakpoint_relocation) { -+ if (String *sourceStr = String::cast(shared->GetSourceCode())) { -+ acceptBreak = !ContainsLineBreak(sourceStr, *source_position, it.position()); -+ } -+ } -+ -+ if (acceptBreak) { -+ it.SetBreakPoint(break_point_object); - -- // At least one active break point now. -- ASSERT(debug_info->GetBreakPointCount() > 0); -+ *source_position = it.position(); -+ -+ // At least one active break point now. -+ ASSERT(debug_info->GetBreakPointCount() > 0); -+ } - } - - -diff --git a/src/flag-definitions.h b/src/flag-definitions.h -index ee6ef01..fe64a96 100644 ---- a/src/flag-definitions.h -+++ b/src/flag-definitions.h -@@ -233,6 +233,7 @@ DEFINE_bool(trace_debug_json, false, "trace debugging JSON request/response") - DEFINE_bool(debugger_auto_break, true, - "automatically set the debug break flag when debugger commands are " - "in the queue") -+DEFINE_bool(breakpoint_relocation, true, "relocate breakpoints to the next executable line") - DEFINE_bool(enable_liveedit, true, "enable liveedit experimental feature") - - // execution.cc -diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc -index cf723ba..7e51c34 100644 ---- a/test/cctest/test-debug.cc -+++ b/test/cctest/test-debug.cc -@@ -2305,6 +2305,65 @@ TEST(ScriptBreakPointTopLevelCrash) { - CheckDebuggerUnloaded(); - } - -+// Test that breakpoint_relocation flag is honored -+TEST(ScriptBreakPointNoRelocation) { -+ i::FLAG_breakpoint_relocation = false; -+ -+ v8::HandleScope scope; -+ DebugLocalContext env; -+ env.ExposeDebug(); -+ -+ // Create a function for checking the function when hitting a break point. -+ frame_function_name = CompileFunction(&env, -+ frame_function_name_source, -+ "frame_function_name"); -+ -+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount, -+ v8::Undefined()); -+ -+ v8::Local<v8::String> script1 = v8::String::New( -+ "a = 0 // line 0\n" -+ " // line 1\n" -+ " // line 2\n" -+ " // line 3\n" -+ "function f() { // line 4\n" -+ " return 0; // line 5\n" -+ "} // line 6"); -+ -+ // Set the script break point on the empty line -+ SetScriptBreakPointByNameFromJS("test.html", 2, -1); -+ -+ // Compile the script and call the function. -+ v8::ScriptOrigin origin(v8::String::New("test.html"), v8::Integer::New(0)); -+ v8::Script::Compile(script1, &origin)->Run(); -+ v8::Local<v8::Function> f -+ = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f"))); -+ f->Call(env->Global(), 0, NULL); -+ -+ // Check that a break point was not hit -+ CHECK_EQ(0, break_point_hit_count); -+ -+ v8::Local<v8::String> script2 = v8::String::New( -+ "a = 0 // line 0\n" -+ "function g() { // line 1\n" -+ " return 0; // line 2\n" -+ "} // line 3\n" -+ "function f() { // line 4\n" -+ " return 0; // line 5\n" -+ "} // line 6"); -+ -+ // Compile the script and call the new function -+ v8::Script::Compile(script2, &origin)->Run(); -+ v8::Local<v8::Function> g -+ = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("g"))); -+ g->Call(env->Global(), 0, NULL); -+ -+ // Check that a break point was not hit -+ CHECK_EQ(1, break_point_hit_count); -+ -+ v8::Debug::SetDebugEventListener(NULL); -+ CheckDebuggerUnloaded(); -+} - - // Test that it is possible to remove the last break point for a function - // inside the break handling of that break point. --- -1.7.4.1 - diff --git a/src/v8/0013-Update-ScriptBreakPoints-for-ScriptRegExp.patch b/src/v8/0013-Update-ScriptBreakPoints-for-ScriptRegExp.patch deleted file mode 100644 index 2945ff5f076e0bed96fd17a0af3e6d27979f0168..0000000000000000000000000000000000000000 --- a/src/v8/0013-Update-ScriptBreakPoints-for-ScriptRegExp.patch +++ /dev/null @@ -1,68 +0,0 @@ -From f02e75f4f2fdffcac78317dff38c6ca6e679cf5c Mon Sep 17 00:00:00 2001 -From: Aurindam Jana <aurindam.jana@nokia.com> -Date: Tue, 13 Dec 2011 13:43:23 +0100 -Subject: [PATCH 13/13] Update ScriptBreakPoints for ScriptRegExp - -Update breakpoints of type ScriptRegExpwhen a new script -is compiled. Solves Issue 1853 -(http://code.google.com/p/v8/issues/detail?id=1853) - -Reviewed-by: aaron.kennedy@nokia.com ---- - src/debug-debugger.js | 3 ++- - test/mjsunit/debug-setbreakpoint.js | 12 ++++++++++-- - 2 files changed, 12 insertions(+), 3 deletions(-) - -diff --git a/src/debug-debugger.js b/src/debug-debugger.js -index d254ee5..6f80a8b 100644 ---- a/src/debug-debugger.js -+++ b/src/debug-debugger.js -@@ -477,7 +477,8 @@ ScriptBreakPoint.prototype.clear = function () { - // break points set in this script. - function UpdateScriptBreakPoints(script) { - for (var i = 0; i < script_break_points.length; i++) { -- if (script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptName && -+ if ((script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptName || -+ script_break_points[i].type() == Debug.ScriptBreakPointType.ScriptRegExp) && - script_break_points[i].matchesScript(script)) { - script_break_points[i].set(script); - } -diff --git a/test/mjsunit/debug-setbreakpoint.js b/test/mjsunit/debug-setbreakpoint.js -index 90dfcd1..03ba28e 100644 ---- a/test/mjsunit/debug-setbreakpoint.js -+++ b/test/mjsunit/debug-setbreakpoint.js -@@ -49,14 +49,17 @@ function safeEval(code) { - } - } - --function testArguments(dcp, arguments, success, is_script) { -+function testArguments(dcp, arguments, success, is_script, is_script_reg_exp) { - var request = '{' + base_request + ',"arguments":' + arguments + '}' - var json_response = dcp.processDebugJSONRequest(request); - var response = safeEval(json_response); - if (success) { - assertTrue(response.success, request + ' -> ' + json_response); - if (is_script) { -- assertEquals('scriptName', response.body.type, request + ' -> ' + json_response); -+ if (is_script_reg_exp) -+ assertEquals('scriptRegExp', response.body.type, request + ' -> ' + json_response); -+ else -+ assertEquals('scriptName', response.body.type, request + ' -> ' + json_response); - } else { - assertEquals('scriptId', response.body.type, request + ' -> ' + json_response); - } -@@ -108,6 +111,11 @@ function listener(event, exec_state, event_data, data) { - testArguments(dcp, '{"type":"script","target":"test","line":1}', true, true); - testArguments(dcp, '{"type":"script","target":"test","column":1}', true, true); - -+ testArguments(dcp, '{"type":"scriptRegExp","target":"test"}', true, true, true); -+ testArguments(dcp, '{"type":"scriptRegExp","target":"test"}', true, true, true); -+ testArguments(dcp, '{"type":"scriptRegExp","target":"test","line":1}', true, true, true); -+ testArguments(dcp, '{"type":"scriptRegExp","target":"test","column":1}', true, true, true); -+ - testArguments(dcp, '{"type":"scriptId","target":' + f_script_id + ',"line":' + f_line + '}', true, false); - testArguments(dcp, '{"type":"scriptId","target":' + g_script_id + ',"line":' + g_line + '}', true, false); - testArguments(dcp, '{"type":"scriptId","target":' + h_script_id + ',"line":' + h_line + '}', true, false); --- -1.7.4.1 - diff --git a/src/v8/README b/src/v8/README deleted file mode 100644 index 850f70326e6cb5634f449a8545abc77689a58aee..0000000000000000000000000000000000000000 --- a/src/v8/README +++ /dev/null @@ -1 +0,0 @@ -These patches apply cleanly against v8 at e123c9dfe54146f8bfca38841255f63a95a00a19 diff --git a/src/v8/v8.pri b/src/v8/v8.pri deleted file mode 100644 index 530b2a729aaa66ce2d0ffe990e28736835119257..0000000000000000000000000000000000000000 --- a/src/v8/v8.pri +++ /dev/null @@ -1,307 +0,0 @@ -isEmpty(QT_ARCH) { - # We're most likely being parsed in a fromfile() call, in which case the - # QMake environment isn't complete. Load qt_config in an attempt to set - # the variables we need (QT_ARCH and CONFIG, in particular). - load(qt_config) -} - -isEmpty(V8_TARGET_ARCH) { - # Detect target - equals(QT_ARCH, x86_64)|contains(CONFIG, x86_64):V8_TARGET_ARCH = x64 - else:equals(QT_ARCH, "i386"): V8_TARGET_ARCH = ia32 - else:equals(QT_ARCH, "mips"): V8_TARGET_ARCH = mips - else:equals(QT_ARCH, "arm"): V8_TARGET_ARCH = arm - else:equals(QMAKE_HOST.arch, armv7l): V8_TARGET_ARCH = arm - else:equals(QMAKE_HOST.arch, armv5tel): V8_TARGET_ARCH = arm - else:equals(QMAKE_HOST.arch, x86_64): V8_TARGET_ARCH = x64 - else:equals(QMAKE_HOST.arch, x86): V8_TARGET_ARCH = ia32 - else:equals(QMAKE_HOST.arch, i386): V8_TARGET_ARCH = ia32 - else:equals(QMAKE_HOST.arch, i686): V8_TARGET_ARCH = ia32 - else:error("Couldn't detect supported v8 architecture ($$QMAKE_HOST.arch/$$QT_ARCH). Currently supported architectures are: x64, x86 and arm") -} - -include($$PWD/v8base.pri) - -# In debug-and-release builds, generated sources must not go to the same -# directory, or they could clobber each other in highly parallelized builds -CONFIG(debug, debug|release):V8_GENERATED_SOURCES_DIR = generated-debug -else: V8_GENERATED_SOURCES_DIR = generated-release - -# this maybe removed in future -DEFINES += ENABLE_DEBUGGER_SUPPORT - -# this is needed by crankshaft ( http://code.google.com/p/v8/issues/detail?id=1271 ) -DEFINES += ENABLE_VMSTATE_TRACKING ENABLE_LOGGING_AND_PROFILING - -CONFIG(debug, debug|release) { - DEFINES += DEBUG V8_ENABLE_CHECKS OBJECT_PRINT ENABLE_DISASSEMBLER -} else { - DEFINES += NDEBUG -} - -V8SRC = $$V8DIR/src - -INCLUDEPATH += \ - $$V8SRC - -SOURCES += \ - $$V8SRC/accessors.cc \ - $$V8SRC/allocation.cc \ - $$V8SRC/api.cc \ - $$V8SRC/assembler.cc \ - $$V8SRC/ast.cc \ - $$V8SRC/atomicops_internals_x86_gcc.cc \ - $$V8SRC/bignum.cc \ - $$V8SRC/bignum-dtoa.cc \ - $$V8SRC/bootstrapper.cc \ - $$V8SRC/builtins.cc \ - $$V8SRC/cached-powers.cc \ - $$V8SRC/checks.cc \ - $$V8SRC/circular-queue.cc \ - $$V8SRC/code-stubs.cc \ - $$V8SRC/codegen.cc \ - $$V8SRC/compilation-cache.cc \ - $$V8SRC/compiler.cc \ - $$V8SRC/contexts.cc \ - $$V8SRC/conversions.cc \ - $$V8SRC/counters.cc \ - $$V8SRC/cpu-profiler.cc \ - $$V8SRC/data-flow.cc \ - $$V8SRC/dateparser.cc \ - $$V8SRC/debug-agent.cc \ - $$V8SRC/debug.cc \ - $$V8SRC/deoptimizer.cc \ - $$V8SRC/disassembler.cc \ - $$V8SRC/diy-fp.cc \ - $$V8SRC/dtoa.cc \ - $$V8SRC/elements.cc \ - $$V8SRC/execution.cc \ - $$V8SRC/factory.cc \ - $$V8SRC/flags.cc \ - $$V8SRC/frames.cc \ - $$V8SRC/full-codegen.cc \ - $$V8SRC/func-name-inferrer.cc \ - $$V8SRC/gdb-jit.cc \ - $$V8SRC/global-handles.cc \ - $$V8SRC/fast-dtoa.cc \ - $$V8SRC/fixed-dtoa.cc \ - $$V8SRC/handles.cc \ - $$V8SRC/hashmap.cc \ - $$V8SRC/heap-profiler.cc \ - $$V8SRC/heap.cc \ - $$V8SRC/hydrogen.cc \ - $$V8SRC/hydrogen-instructions.cc \ - $$V8SRC/ic.cc \ - $$V8SRC/incremental-marking.cc \ - $$V8SRC/inspector.cc \ - $$V8SRC/interpreter-irregexp.cc \ - $$V8SRC/isolate.cc \ - $$V8SRC/jsregexp.cc \ - $$V8SRC/lithium-allocator.cc \ - $$V8SRC/lithium.cc \ - $$V8SRC/liveedit.cc \ - $$V8SRC/liveobjectlist.cc \ - $$V8SRC/log-utils.cc \ - $$V8SRC/log.cc \ - $$V8SRC/mark-compact.cc \ - $$V8SRC/messages.cc \ - $$V8SRC/objects.cc \ - $$V8SRC/objects-printer.cc \ - $$V8SRC/objects-visiting.cc \ - $$V8SRC/parser.cc \ - $$V8SRC/preparser.cc \ - $$V8SRC/preparse-data.cc \ - $$V8SRC/profile-generator.cc \ - $$V8SRC/property.cc \ - $$V8SRC/regexp-macro-assembler-irregexp.cc \ - $$V8SRC/regexp-macro-assembler.cc \ - $$V8SRC/regexp-stack.cc \ - $$V8SRC/rewriter.cc \ - $$V8SRC/runtime.cc \ - $$V8SRC/runtime-profiler.cc \ - $$V8SRC/safepoint-table.cc \ - $$V8SRC/scanner.cc \ - $$V8SRC/scanner-character-streams.cc \ - $$V8SRC/scopeinfo.cc \ - $$V8SRC/scopes.cc \ - $$V8SRC/serialize.cc \ - $$V8SRC/snapshot-common.cc \ - $$V8SRC/spaces.cc \ - $$V8SRC/string-search.cc \ - $$V8SRC/string-stream.cc \ - $$V8SRC/strtod.cc \ - $$V8SRC/stub-cache.cc \ - $$V8SRC/token.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 - -equals(V8_TARGET_ARCH, arm) { -DEFINES += V8_TARGET_ARCH_ARM -DEFINES += USE_EABI_HARDFLOAT=1 CAN_USE_VFP_INSTRUCTIONS -SOURCES += \ - $$V8SRC/arm/builtins-arm.cc \ - $$V8SRC/arm/code-stubs-arm.cc \ - $$V8SRC/arm/codegen-arm.cc \ - $$V8SRC/arm/constants-arm.cc \ - $$V8SRC/arm/cpu-arm.cc \ - $$V8SRC/arm/debug-arm.cc \ - $$V8SRC/arm/deoptimizer-arm.cc \ - $$V8SRC/arm/disasm-arm.cc \ - $$V8SRC/arm/frames-arm.cc \ - $$V8SRC/arm/full-codegen-arm.cc \ - $$V8SRC/arm/ic-arm.cc \ - $$V8SRC/arm/lithium-arm.cc \ - $$V8SRC/arm/lithium-codegen-arm.cc \ - $$V8SRC/arm/lithium-gap-resolver-arm.cc \ - $$V8SRC/arm/macro-assembler-arm.cc \ - $$V8SRC/arm/regexp-macro-assembler-arm.cc \ - $$V8SRC/arm/stub-cache-arm.cc \ - $$V8SRC/arm/assembler-arm.cc -} else:equals(V8_TARGET_ARCH, ia32) { -DEFINES += V8_TARGET_ARCH_IA32 -SOURCES += \ - $$V8SRC/ia32/assembler-ia32.cc \ - $$V8SRC/ia32/builtins-ia32.cc \ - $$V8SRC/ia32/code-stubs-ia32.cc \ - $$V8SRC/ia32/codegen-ia32.cc \ - $$V8SRC/ia32/cpu-ia32.cc \ - $$V8SRC/ia32/debug-ia32.cc \ - $$V8SRC/ia32/deoptimizer-ia32.cc \ - $$V8SRC/ia32/disasm-ia32.cc \ - $$V8SRC/ia32/frames-ia32.cc \ - $$V8SRC/ia32/full-codegen-ia32.cc \ - $$V8SRC/ia32/ic-ia32.cc \ - $$V8SRC/ia32/lithium-codegen-ia32.cc \ - $$V8SRC/ia32/lithium-gap-resolver-ia32.cc \ - $$V8SRC/ia32/lithium-ia32.cc \ - $$V8SRC/ia32/macro-assembler-ia32.cc \ - $$V8SRC/ia32/regexp-macro-assembler-ia32.cc \ - $$V8SRC/ia32/stub-cache-ia32.cc -} else:equals(V8_TARGET_ARCH, x64) { -# FIXME What about 32-bit Macs? -DEFINES += V8_TARGET_ARCH_X64 -SOURCES += \ - $$V8SRC/x64/assembler-x64.cc \ - $$V8SRC/x64/builtins-x64.cc \ - $$V8SRC/x64/code-stubs-x64.cc \ - $$V8SRC/x64/codegen-x64.cc \ - $$V8SRC/x64/cpu-x64.cc \ - $$V8SRC/x64/debug-x64.cc \ - $$V8SRC/x64/deoptimizer-x64.cc \ - $$V8SRC/x64/disasm-x64.cc \ - $$V8SRC/x64/frames-x64.cc \ - $$V8SRC/x64/full-codegen-x64.cc \ - $$V8SRC/x64/ic-x64.cc \ - $$V8SRC/x64/lithium-codegen-x64.cc \ - $$V8SRC/x64/lithium-gap-resolver-x64.cc \ - $$V8SRC/x64/lithium-x64.cc \ - $$V8SRC/x64/macro-assembler-x64.cc \ - $$V8SRC/x64/regexp-macro-assembler-x64.cc \ - $$V8SRC/x64/stub-cache-x64.cc -} else:equals(V8_TARGET_ARCH, mips) { -DEFINES += V8_TARGET_MIPS -SOURCES += \ - $$V8SRC/mips/assembler-mips.cc \ - $$V8SRC/mips/builtins-mips.cc \ - $$V8SRC/mips/codegen-mips.cc \ - $$V8SRC/mips/code-stubs-mips.cc \ - $$V8SRC/mips/constants-mips.cc \ - $$V8SRC/mips/cpu-mips.cc \ - $$V8SRC/mips/debug-mips.cc \ - $$V8SRC/mips/deoptimizer-mips.cc \ - $$V8SRC/mips/disasm-mips.cc \ - $$V8SRC/mips/frames-mips.cc \ - $$V8SRC/mips/full-codegen-mips.cc \ - $$V8SRC/mips/ic-mips.cc \ - $$V8SRC/mips/macro-assembler-mips.cc \ - $$V8SRC/mips/regexp-macro-assembler-mips.cc \ - $$V8SRC/mips/simulator-mips.cc \ - $$V8SRC/mips/stub-cache-mips.cc -} - -#os:macos -macx { -SOURCES += \ - $$V8SRC/platform-macos.cc \ - $$V8SRC/platform-posix.cc -} else:freebsd-* { -SOURCES += \ - $$V8SRC/platform-freebsd.cc \ - $$V8SRC/platform-posix.cc -LIBS += -lexecinfo -} else:unix:!symbian { -SOURCES += \ - $$V8SRC/platform-linux.cc \ - $$V8SRC/platform-posix.cc -} - -win32 { -SOURCES += \ - $$V8SRC/platform-win32.cc \ - $$V8SRC/win32-math.cc -LIBS += -lWs2_32 -lWinmm -win32-msvc*: QMAKE_CXXFLAGS += -wd4100 -wd 4291 -wd4351 -wd4355 -wd4800 -win32-msvc*:arch_i386: DEFINES += _USE_32BIT_TIME_T -} - -#mode:debug -CONFIG(debug) { - SOURCES += \ - $$V8SRC/objects-debug.cc \ - $$V8SRC/prettyprinter.cc \ - $$V8SRC/regexp-macro-assembler-tracer.cc -} - -V8_LIBRARY_FILES = \ - $$V8SRC/runtime.js \ - $$V8SRC/v8natives.js \ - $$V8SRC/array.js \ - $$V8SRC/string.js \ - $$V8SRC/uri.js \ - $$V8SRC/math.js \ - $$V8SRC/messages.js \ - $$V8SRC/apinatives.js \ - $$V8SRC/date.js \ - $$V8SRC/regexp.js \ - $$V8SRC/json.js \ - $$V8SRC/liveedit-debugger.js \ - $$V8SRC/mirror-debugger.js \ - $$V8SRC/debug-debugger.js - -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 -v8_js2c.variable_out = SOURCES -v8_js2c.dependency_type = TYPE_C -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 - -v8_js2c_experimental.commands = python $$V8DIR/tools/js2c.py $$V8_GENERATED_SOURCES_DIR/experimental-libraries.cpp EXPERIMENTAL off -v8_js2c_experimental.commands += $$V8SRC/macros.py ${QMAKE_FILE_IN} -v8_js2c_experimental.output = $$V8_GENERATED_SOURCES_DIR/experimental-libraries.cpp -v8_js2c_experimental.input = V8_EXPERIMENTAL_LIBRARY_FILES -v8_js2c_experimental.variable_out = SOURCES -v8_js2c_experimental.dependency_type = TYPE_C -v8_js2c_experimental.depends = $$V8DIR/tools/js2c.py $$V8SRC/macros.py -v8_js2c_experimental.CONFIG += combine -v8_js2c_experimental.name = generating[v8] ${QMAKE_FILE_IN} - -QMAKE_EXTRA_COMPILERS += v8_js2c v8_js2c_experimental diff --git a/src/v8/v8.pro b/src/v8/v8.pro deleted file mode 100644 index 6f8ed703aab35a4bce6aa998dc992b2de145894c..0000000000000000000000000000000000000000 --- a/src/v8/v8.pro +++ /dev/null @@ -1,41 +0,0 @@ -load(qt_module) - -TARGET = QtV8 -QPRO_PWD = $$PWD -QT = - -CONFIG += module -MODULE_PRI = ../modules/qt_v8.pri - -win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000 - -load(qt_module_config) -CONFIG += warn_off - -# Remove includepaths that were added by qt_module_config. -# These cause compilation of V8 to fail because they appear before -# 3rdparty/v8/src; 3rdparty/v8/src/v8.h will then be "shadowed" by -# the public v8.h API header (they are not the same!). -INCLUDEPATH -= $$MODULE_PRIVATE_INCLUDES -INCLUDEPATH -= $$MODULE_PRIVATE_INCLUDES/$$TARGET -INCLUDEPATH -= $$MODULE_INCLUDES $$MODULE_INCLUDES/.. - -HEADERS += $$QT_SOURCE_TREE/src/v8/qtv8version.h - -!contains(QT_CONFIG, static): DEFINES += V8_SHARED BUILDING_V8_SHARED - -include(v8.pri) - -contains(QT_CONFIG, v8snapshot) { - mkv8snapshot.commands = ../../bin/mkv8snapshot$$qtPlatformTargetSuffix() ${QMAKE_FILE_OUT} - DUMMY_FILE = v8.pro - mkv8snapshot.input = DUMMY_FILE - mkv8snapshot.output = $$V8_GENERATED_SOURCES_DIR/snapshot.cpp - mkv8snapshot.variable_out = SOURCES - mkv8snapshot.dependency_type = TYPE_C - mkv8snapshot.name = generating[v8] ${QMAKE_FILE_IN} - silent:mkv8snapshot.commands = @echo generating[v8] ${QMAKE_FILE_IN} && $$mkv8snapshot.commands - QMAKE_EXTRA_COMPILERS += mkv8snapshot -} else { - SOURCES += $$V8SRC/snapshot-empty.cc -} diff --git a/src/v8/v8base.pri b/src/v8/v8base.pri deleted file mode 100644 index 8a7d18cc49e58b6f022f80fb8046adcdc6b71561..0000000000000000000000000000000000000000 --- a/src/v8/v8base.pri +++ /dev/null @@ -1,24 +0,0 @@ -V8DIR = $$(V8DIR) -isEmpty(V8DIR) { - V8DIR = $$PWD/../3rdparty/v8 - !exists($$V8DIR/src):error("$$V8DIR/src does not exist! $$escape_expand(\\n)\ - If you are building from git, please ensure you have the v8 submodule available, e.g. $$escape_expand(\\n\\n)\ - git submodule update --init src/3rdparty/v8 $$escape_expand(\\n\\n)\ - Alternatively, Qt may be configured with -no-v8 to disable v8.\ - ") -} else { - message(using external V8 from $$V8DIR) -} - -*-g++*: { - QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter - QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter - - # mksnapshot hangs if gcc 4.5 is used - # for reference look at http://code.google.com/p/v8/issues/detail?id=884 - equals(QT_GCC_MAJOR_VERSION, 4): equals(QT_GCC_MINOR_VERSION, 5) { - message(because of a bug in gcc / v8 we need to add -fno-strict-aliasing) - QMAKE_CFLAGS += -fno-strict-aliasing - QMAKE_CXXFLAGS += -fno-strict-aliasing - } -} diff --git a/sync.profile b/sync.profile index 221086a5540bcab257df1afd784f39446ff31144..3a63517e15a6d85c858084b6dea400e747510de0 100644 --- a/sync.profile +++ b/sync.profile @@ -4,7 +4,6 @@ "QtPrintSupport" => "$basedir/src/printsupport", "QtOpenGL" => "$basedir/src/opengl", "QtCore" => "$basedir/src/corelib", - "QtV8" => "$basedir/src/v8", "QtXml" => "$basedir/src/xml", "QtSql" => "$basedir/src/sql", "QtNetwork" => "$basedir/src/network", @@ -13,10 +12,8 @@ "QtPlatformSupport" => "$basedir/src/platformsupport", ); %moduleheaders = ( # restrict the module headers to those found in relative path - "QtV8" => "../3rdparty/v8/include", ); @allmoduleheadersprivate = ( - "QtV8" ); %classnames = ( "qglobal.h" => "QtGlobal", @@ -41,7 +38,6 @@ "qtopenvgversion.h" => "QtOpenVGVersion", "qtsqlversion.h" => "QtSqlVersion", "qttestversion.h" => "QtTestVersion", - "qtv8version.h" => "QtV8Version", "qtxmlversion.h" => "QtXmlVersion", ); %mastercontent = ( @@ -63,7 +59,6 @@ "QtOpenGL" => "$basedir/src/modules/qt_opengl.pri", "QtSql" => "$basedir/src/modules/qt_sql.pri", "QtTest" => "$basedir/src/modules/qt_testlib.pri", - "QtV8" => "$basedir/src/modules/qt_v8.pri", "QtXml" => "$basedir/src/modules/qt_xml.pri", "QtPlatformSupport" => "$basedir/src/modules/qt_platformsupport.pri", ); diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 1fc1ba381cae1184a8313484d331cb4c04c79a0c..05b6f84fa912307ae7f5c7bd81b1286faf7ce801 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -9,7 +9,6 @@ SUBDIRS += \ sql \ testlib \ tools \ - v8 \ xml \ other \ widgets \ @@ -17,7 +16,6 @@ SUBDIRS += \ cross_compile: SUBDIRS -= tools !contains(QT_CONFIG, opengl): SUBDIRS -= opengl !unix|embedded|!contains(QT_CONFIG, dbus): SUBDIRS -= dbus -!contains(QT_CONFIG, v8): SUBDIRS -= v8 # disable 'make check' on Mac OS X for the following subdirs for the time being mac { diff --git a/tests/auto/v8/Makefile.nonqt b/tests/auto/v8/Makefile.nonqt deleted file mode 100644 index ded1ba3a7495249b20fe55962d1a8f426352d11b..0000000000000000000000000000000000000000 --- a/tests/auto/v8/Makefile.nonqt +++ /dev/null @@ -1,16 +0,0 @@ -V8PATH = ../../../src/3rdparty/v8 -V8LIBPATH = $(V8PATH) -V8INCPATH = $(V8PATH)/include -SOURCES = v8main.cpp v8test.cpp - -release-m32: - g++ -o v8test_release_m32 -m32 -O2 -I$(V8INCPATH) $(SOURCES) -lpthread -L$(V8LIBPATH) -lv8 - -debug-m32: - g++ -o v8test_debug_m32 -m32 -g -I$(V8INCPATH) $(SOURCES) -lpthread -L$(V8LIBPATH) -lv8_g - -release: - g++ -o v8test_release -O2 -I$(V8INCPATH) $(SOURCES) -lpthread -L$(V8LIBPATH) -lv8 - -debug: - g++ -o v8test_debug -g -I$(V8INCPATH) $(SOURCES) -lpthread -L$(V8LIBPATH) -lv8_g diff --git a/tests/auto/v8/README.txt b/tests/auto/v8/README.txt deleted file mode 100644 index 097c4590366f1f0c7eae28f3288fca09e768ea82..0000000000000000000000000000000000000000 --- a/tests/auto/v8/README.txt +++ /dev/null @@ -1,13 +0,0 @@ -The v8 tests are actually implemented in v8test.[h|cpp]. There are also QtTest -(tst_v8.cpp) and non-Qt (v8main.cpp) stubs provided to run these tests. This -is done to allow the tests to be run both in the Qt CI system, and manually -without a build of Qt. The latter is necessary to run them against more exotic -build of V8, like the ARM simulator. - -To build the non-Qt version of the tests, first build a debug or release V8 -library under src/3rdparty/v8 using scons, and then use the Makefile.nonqt -makefile selecting one of the following targets: - release: Build the tests with -O2 and link against libv8 - debug: Build the tests with -g and link against libv8_g - release-m32: Build the tests with -O2 -m32 and link against libv8 - debug-m32: Build the tests with -g -m32 and link against libv8_g diff --git a/tests/auto/v8/tst_v8.cpp b/tests/auto/v8/tst_v8.cpp deleted file mode 100644 index bb3184ca442a46fcdbe1148e09d4038e27218f70..0000000000000000000000000000000000000000 --- a/tests/auto/v8/tst_v8.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include <qtest.h> -#include <private/v8.h> -#include "v8test.h" - -using namespace v8; - -class tst_v8 : public QObject -{ - Q_OBJECT -public: - tst_v8() {} - -private slots: - void initTestCase() {} - void cleanupTestCase() {} - - void eval(); - void evalwithinwith(); - void userobjectcompare(); - void externalteardown(); - void globalcall(); -}; - -void tst_v8::eval() -{ - QVERIFY(v8test_eval()); -} - -void tst_v8::evalwithinwith() -{ - QVERIFY(v8test_evalwithinwith()); -} - -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); - - QCoreApplication app(argc, argv); - tst_v8 tc; - return QTest::qExec(&tc, argc, argv); -} - -#include "tst_v8.moc" diff --git a/tests/auto/v8/v8.pro b/tests/auto/v8/v8.pro deleted file mode 100644 index 493ea8e1cb07781588f8589cfd999e28bee31482..0000000000000000000000000000000000000000 --- a/tests/auto/v8/v8.pro +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG += testcase -TARGET = tst_v8 -macx:CONFIG -= app_bundle - -SOURCES += tst_v8.cpp v8test.cpp -HEADERS += v8test.h - -CONFIG += parallel_test - -QT = core v8-private testlib diff --git a/tests/auto/v8/v8main.cpp b/tests/auto/v8/v8main.cpp deleted file mode 100644 index f8ffea040305022c3ffe7e214b98041484334428..0000000000000000000000000000000000000000 --- a/tests/auto/v8/v8main.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "v8test.h" -#include <stdio.h> -#include <strings.h> - -#define RUN_TEST(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[]) -{ - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - - RUN_TEST(eval); - RUN_TEST(evalwithinwith); - RUN_TEST(userobjectcompare); - RUN_TEST(externalteardown); - RUN_TEST(globalcall); - - return -1; -} diff --git a/tests/auto/v8/v8test.cpp b/tests/auto/v8/v8test.cpp deleted file mode 100644 index 5576f4797165392a3998ec4be8f9a86541f06fef..0000000000000000000000000000000000000000 --- a/tests/auto/v8/v8test.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "v8test.h" - -using namespace v8; - -#define BEGINTEST() bool _testPassed = true; -#define ENDTEST() return _testPassed; - -#define VERIFY(expr) { \ - if (!(expr)) { \ - fprintf(stderr, "FAIL: %s:%d %s\n", __FILE__, __LINE__, # expr); \ - _testPassed = false; \ - goto cleanup; \ - } \ -} - -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); - - 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() -{ - BEGINTEST(); - - HandleScope handle_scope; - Persistent<Context> context = Context::New(); - Context::Scope context_scope(context); - - Local<Object> qmlglobal = Object::New(); - qmlglobal->Set(String::New("a"), Integer::New(1922)); - - Local<Script> script = Script::Compile(String::New("eval(\"a\")"), NULL, NULL, - Handle<String>(), Script::QmlMode); - - TryCatch tc; - Local<Value> result = script->Run(qmlglobal); - - VERIFY(!tc.HasCaught()); - VERIFY(result->Int32Value() == 1922); - -cleanup: - context.Dispose(); - - 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(); - - HandleScope handle_scope; - Persistent<Context> context = Context::New(); - Context::Scope context_scope(context); - - Local<Object> qmlglobal = Object::New(); - qmlglobal->Set(String::New("a"), Integer::New(1922)); - // There was a bug that the "eval" lookup would incorrectly resolve - // to the QML global object - qmlglobal->Set(String::New("eval"), Integer::New(1922)); - -#define SOURCE \ - "(function() { " \ - " var b = { c: 10 }; " \ - " with (b) { " \ - " return eval(\"a\"); " \ - " } " \ - "})" - Local<Script> script = Script::Compile(String::New(SOURCE), NULL, NULL, - Handle<String>(), Script::QmlMode); -#undef SOURCE - - TryCatch tc; - Local<Value> result = script->Run(qmlglobal); - - VERIFY(!tc.HasCaught()); - VERIFY(result->IsFunction()); - - { - Local<Value> fresult = Handle<Function>::Cast(result)->Call(context->Global(), 0, 0); - VERIFY(!tc.HasCaught()); - VERIFY(fresult->Int32Value() == 1922); - } - -cleanup: - context.Dispose(); - - ENDTEST(); -} - -static int userObjectComparisonCalled = 0; -static bool userObjectComparisonReturn = false; -static Local<Object> expectedLhs; -static Local<Object> expectedRhs; -static bool expectedObjectsCompared = false; - -#define SET_EXPECTED(lhs, rhs) { \ - expectedObjectsCompared = false; \ - expectedLhs = lhs; \ - expectedRhs = rhs; \ -} - -static bool UserObjectComparison(Local<Object> lhs, Local<Object> rhs) -{ - userObjectComparisonCalled++; - - expectedObjectsCompared = (lhs == expectedLhs && rhs == expectedRhs); - - return userObjectComparisonReturn; -} - -inline bool runscript(const char *source) { - Local<Script> script = Script::Compile(String::New(source)); - Local<Value> result = script->Run(); - return result->BooleanValue(); -} - -bool v8test_userobjectcompare() -{ - BEGINTEST(); - - HandleScope handle_scope; - Persistent<Context> context = Context::New(); - Context::Scope context_scope(context); - - V8::SetUserObjectComparisonCallbackFunction(UserObjectComparison); - - Local<ObjectTemplate> ot = ObjectTemplate::New(); - ot->MarkAsUseUserObjectComparison(); - - Local<Object> uoc1 = ot->NewInstance(); - Local<Object> uoc2 = ot->NewInstance(); - context->Global()->Set(String::New("uoc1a"), uoc1); - context->Global()->Set(String::New("uoc1b"), uoc1); - context->Global()->Set(String::New("uoc2"), uoc2); - Local<Object> obj1 = Object::New(); - context->Global()->Set(String::New("obj1a"), obj1); - context->Global()->Set(String::New("obj1b"), obj1); - context->Global()->Set(String::New("obj2"), Object::New()); - Local<String> string1 = String::New("Hello World"); - context->Global()->Set(String::New("string1a"), string1); - context->Global()->Set(String::New("string1b"), string1); - context->Global()->Set(String::New("string2"), v8::String::New("Goodbye World")); - - // XXX Opportunity for optimization - don't invoke user callback if objects are - // equal. -#if 0 - userObjectComparisonCalled = 0; userObjectComparisonReturn = false; - VERIFY(true == runscript("uoc1a == uoc1b")); - VERIFY(userObjectComparisonCalled == 0); -#endif - - // Comparing two uoc objects invokes uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(false == runscript("uoc1a == uoc2")); - VERIFY(userObjectComparisonCalled == 1); - - VERIFY(false == runscript("uoc2 == uoc1a")); - VERIFY(userObjectComparisonCalled == 2); - userObjectComparisonReturn = true; - VERIFY(true == runscript("uoc1a == uoc2")); - VERIFY(userObjectComparisonCalled == 3); - VERIFY(true == runscript("uoc2 == uoc1a")); - VERIFY(userObjectComparisonCalled == 4); - - // != on two uoc object invokes uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(true == runscript("uoc1a != uoc2")); - VERIFY(userObjectComparisonCalled == 1); - VERIFY(true == runscript("uoc2 != uoc1a")); - VERIFY(userObjectComparisonCalled == 2); - userObjectComparisonReturn = true; - VERIFY(false == runscript("uoc1a != uoc2")); - VERIFY(userObjectComparisonCalled == 3); - VERIFY(false == runscript("uoc2 != uoc1a")); - VERIFY(userObjectComparisonCalled == 4); - - // Comparison against a non-object doesn't invoke uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(false == runscript("uoc1a == string1a")); - VERIFY(userObjectComparisonCalled == 0); - VERIFY(false == runscript("string1a == uoc1a")); - VERIFY(userObjectComparisonCalled == 0); - VERIFY(false == runscript("2 == uoc1a")); - VERIFY(userObjectComparisonCalled == 0); - VERIFY(true == runscript("uoc1a != string1a")); - VERIFY(userObjectComparisonCalled == 0); - VERIFY(true == runscript("string1a != uoc1a")); - VERIFY(userObjectComparisonCalled == 0); - VERIFY(true == runscript("2 != uoc1a")); - VERIFY(userObjectComparisonCalled == 0); - - // Comparison against a non-uoc-object still invokes uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(false == runscript("uoc1a == obj1a")); - VERIFY(userObjectComparisonCalled == 1); - VERIFY(false == runscript("obj1a == uoc1a")); - VERIFY(userObjectComparisonCalled == 2); - userObjectComparisonReturn = true; - VERIFY(true == runscript("uoc1a == obj1a")); - VERIFY(userObjectComparisonCalled == 3); - VERIFY(true == runscript("obj1a == uoc1a")); - VERIFY(userObjectComparisonCalled == 4); - - // != comparison against a non-uoc-object still invokes uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(true == runscript("uoc1a != obj1a")); - VERIFY(userObjectComparisonCalled == 1); - VERIFY(true == runscript("obj1a != uoc1a")); - VERIFY(userObjectComparisonCalled == 2); - userObjectComparisonReturn = true; - VERIFY(false == runscript("uoc1a != obj1a")); - VERIFY(userObjectComparisonCalled == 3); - VERIFY(false == runscript("obj1a != uoc1a")); - VERIFY(userObjectComparisonCalled == 4); - - // Comparing two non-uoc objects does not invoke uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - VERIFY(true == runscript("obj1a == obj1a")); - VERIFY(true == runscript("obj1a == obj1b")); - VERIFY(false == runscript("obj1a == obj2")); - VERIFY(false == runscript("obj1a == string1a")); - VERIFY(true == runscript("string1a == string1a")); - VERIFY(true == runscript("string1a == string1b")); - VERIFY(false == runscript("string1a == string2")); - VERIFY(userObjectComparisonCalled == 0); - - // Correct lhs and rhs passed to uoc - userObjectComparisonCalled = 0; - userObjectComparisonReturn = false; - SET_EXPECTED(uoc1, uoc2); - VERIFY(false == runscript("uoc1a == uoc2")); - VERIFY(true == expectedObjectsCompared); - SET_EXPECTED(uoc2, uoc1); - VERIFY(false == runscript("uoc2 == uoc1a")); - VERIFY(true == expectedObjectsCompared); - SET_EXPECTED(uoc1, uoc2); - VERIFY(true == runscript("uoc1a != uoc2")); - VERIFY(true == expectedObjectsCompared); - SET_EXPECTED(uoc2, uoc1); - VERIFY(true == runscript("uoc2 != uoc1a")); - VERIFY(true == expectedObjectsCompared); - SET_EXPECTED(uoc1, obj1); - VERIFY(false == runscript("uoc1a == obj1a")); - VERIFY(true == expectedObjectsCompared); - SET_EXPECTED(obj1, uoc1); - VERIFY(false == runscript("obj1a == uoc1a")); - VERIFY(true == expectedObjectsCompared); - -cleanup: - V8::SetUserObjectComparisonCallbackFunction(0); - context.Dispose(); - - ENDTEST(); -} diff --git a/tests/auto/v8/v8test.h b/tests/auto/v8/v8test.h deleted file mode 100644 index 8aa358caff61d9310030306ad51c58f5ea153a4c..0000000000000000000000000000000000000000 --- a/tests/auto/v8/v8test.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef V8TEST_H -#define V8TEST_H - -#ifdef QT_CORE_LIB -#include <private/v8.h> -#else -#include <v8.h> -#endif - -bool v8test_eval(); -bool v8test_evalwithinwith(); -bool v8test_userobjectcompare(); -bool v8test_externalteardown(); -bool v8test_globalcall(); - -#endif // V8TEST_H -