diff options
Diffstat (limited to 'src/v8/0004-Introduce-a-QML-compilation-mode.patch')
-rw-r--r-- | src/v8/0004-Introduce-a-QML-compilation-mode.patch | 2355 |
1 files changed, 0 insertions, 2355 deletions
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 712c710df2..0000000000 --- a/src/v8/0004-Introduce-a-QML-compilation-mode.patch +++ /dev/null @@ -1,2355 +0,0 @@ -From ae1c497cf2235df9d73d3c5d3c2b40bcde7e534f 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/12] 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 a1418874..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.7.3 - |