summaryrefslogtreecommitdiffstats
path: root/src/v8/0005-Introduce-a-QML-compilation-mode.patch
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-09-07 10:51:39 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-07 04:50:45 +0200
commitbc2eac1ef3e6902f8fed65f72b70b582f93bcb19 (patch)
tree6af22cb1316b194268981bee884d17ba40dbce3a /src/v8/0005-Introduce-a-QML-compilation-mode.patch
parent846c5c9459331cde33ef92b665fab1457eaf1252 (diff)
Update V8
This fixes a few bugs in QML mode name resolution and simplifies our V8 patchset a little by folding some patches together. Change-Id: Ia528a43ac8ccad95ac81bcdff5d05aaeab4b48b2 Reviewed-on: http://codereview.qt.nokia.com/4294 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src/v8/0005-Introduce-a-QML-compilation-mode.patch')
-rw-r--r--src/v8/0005-Introduce-a-QML-compilation-mode.patch509
1 files changed, 294 insertions, 215 deletions
diff --git a/src/v8/0005-Introduce-a-QML-compilation-mode.patch b/src/v8/0005-Introduce-a-QML-compilation-mode.patch
index 3c1cab2497..d1b4d4d510 100644
--- a/src/v8/0005-Introduce-a-QML-compilation-mode.patch
+++ b/src/v8/0005-Introduce-a-QML-compilation-mode.patch
@@ -1,7 +1,7 @@
-From fd7d475e298e5b63cd6383c78cc900635c82aa38 Mon Sep 17 00:00:00 2001
+From 60c1a26bf89d3b06bcdd8408fcee89a018120f32 Mon Sep 17 00:00:00 2001
From: Aaron Kennedy <aaron.kennedy@nokia.com>
Date: Mon, 23 May 2011 18:26:19 +1000
-Subject: [PATCH 05/16] Introduce a QML compilation mode
+Subject: [PATCH 05/14] Introduce a QML compilation mode
In QML mode, there is a second global object - known as the QML
global object. During property resolution, if a property is not
@@ -15,8 +15,8 @@ closures etc. created during the run will retain a reference to this
object, so different objects can be passed in different script
runs.
---
- include/v8.h | 18 ++++++++--
- src/api.cc | 52 ++++++++++++++++++++++++-----
+ include/v8.h | 18 +++++++--
+ src/api.cc | 52 ++++++++++++++++++++++-----
src/arm/code-stubs-arm.cc | 4 ++
src/arm/full-codegen-arm.cc | 26 ++++++++------
src/arm/lithium-arm.cc | 2 +-
@@ -27,10 +27,10 @@ runs.
src/ast.h | 1 +
src/code-stubs.h | 2 +-
src/compiler.cc | 15 +++++++-
- src/compiler.h | 22 ++++++++++--
- src/contexts.cc | 23 +++++++++++++
+ src/compiler.h | 22 +++++++++--
+ src/contexts.cc | 35 ++++++++++++++++++
src/contexts.h | 4 ++
- src/execution.cc | 28 +++++++++++++--
+ src/execution.cc | 28 ++++++++++++--
src/execution.h | 6 +++
src/full-codegen.cc | 3 +-
src/full-codegen.h | 1 +
@@ -43,14 +43,14 @@ runs.
src/ia32/lithium-ia32.cc | 2 +-
src/ia32/lithium-ia32.h | 6 +++-
src/ia32/macro-assembler-ia32.h | 5 +++
- src/objects-inl.h | 12 +++++++
+ src/objects-inl.h | 12 ++++++
src/objects.h | 5 +++
- src/parser.cc | 27 +++++++++++++--
+ src/parser.cc | 27 ++++++++++++--
src/parser.h | 4 ++-
src/prettyprinter.cc | 3 ++
- src/runtime.cc | 68 ++++++++++++++++++++++++-------------
+ src/runtime.cc | 72 ++++++++++++++++++++++++-------------
src/runtime.h | 8 ++--
- src/scopes.cc | 10 +++++
+ src/scopes.cc | 59 +++++++++++++++++++++++++++++++
src/scopes.h | 7 ++++
src/variables.cc | 3 +-
src/variables.h | 5 +++
@@ -60,10 +60,10 @@ runs.
src/x64/lithium-x64.cc | 2 +-
src/x64/lithium-x64.h | 6 +++
src/x64/macro-assembler-x64.h | 5 +++
- 45 files changed, 391 insertions(+), 108 deletions(-)
+ 45 files changed, 455 insertions(+), 109 deletions(-)
diff --git a/include/v8.h b/include/v8.h
-index 7f06ae7..a858eae 100644
+index 205e856..d78ab1f 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -577,6 +577,10 @@ class ScriptOrigin {
@@ -74,7 +74,7 @@ index 7f06ae7..a858eae 100644
+ Default = 0x00,
+ QmlMode = 0x01
+ };
-
+
/**
* Compiles the specified script (context-independent).
@@ -596,7 +600,8 @@ class V8EXPORT Script {
@@ -84,7 +84,7 @@ index 7f06ae7..a858eae 100644
- Handle<String> script_data = Handle<String>());
+ Handle<String> script_data = Handle<String>(),
+ CompileFlags = Default);
-
+
/**
* Compiles the specified script using the specified file name
@@ -609,7 +614,8 @@ class V8EXPORT Script {
@@ -94,7 +94,7 @@ index 7f06ae7..a858eae 100644
- Handle<Value> file_name);
+ Handle<Value> file_name,
+ CompileFlags = Default);
-
+
/**
* Compiles the specified script (bound to current context).
@@ -630,7 +636,8 @@ class V8EXPORT Script {
@@ -104,7 +104,7 @@ index 7f06ae7..a858eae 100644
- Handle<String> script_data = Handle<String>());
+ Handle<String> script_data = Handle<String>(),
+ CompileFlags = Default);
-
+
/**
* Compiles the specified script using the specified file name
@@ -647,7 +654,8 @@ class V8EXPORT Script {
@@ -114,7 +114,7 @@ index 7f06ae7..a858eae 100644
- Handle<String> script_data = Handle<String>());
+ Handle<String> script_data = Handle<String>(),
+ CompileFlags = Default);
-
+
/**
* Runs the script returning the resulting value. If the script is
@@ -657,6 +665,7 @@ class V8EXPORT Script {
@@ -122,15 +122,15 @@ index 7f06ae7..a858eae 100644
*/
Local<Value> Run();
+ Local<Value> Run(Handle<Object> qml);
-
+
/**
* Returns the script id value.
-@@ -3326,6 +3335,7 @@ class V8EXPORT Context {
+@@ -3327,6 +3336,7 @@ class V8EXPORT Context {
* JavaScript frames an empty handle is returned.
*/
static Local<Context> GetCalling();
+ static Local<Object> GetCallingQmlGlobal();
-
+
/**
* Sets the security token for the context. To access an object in
diff --git a/src/api.cc b/src/api.cc
@@ -158,18 +158,18 @@ index 1a6fbbb..39767f4 100644
EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
return Local<Script>(ToApi<Script>(result));
@@ -1417,21 +1419,23 @@ Local<Script> Script::New(v8::Handle<String> source,
-
-
+
+
Local<Script> Script::New(v8::Handle<String> source,
- v8::Handle<Value> file_name) {
-+ v8::Handle<Value> file_name,
++ v8::Handle<Value> file_name,
+ v8::Script::CompileFlags compile_flags) {
ScriptOrigin origin(file_name);
- return New(source, &origin);
+ return New(source, &origin, 0, Handle<String>(), compile_flags);
}
-
-
+
+
Local<Script> Script::Compile(v8::Handle<String> source,
v8::ScriptOrigin* origin,
v8::ScriptData* pre_data,
@@ -186,7 +186,7 @@ index 1a6fbbb..39767f4 100644
return generic;
i::Handle<i::Object> obj = Utils::OpenHandle(*generic);
@@ -1447,13 +1451,18 @@ Local<Script> Script::Compile(v8::Handle<String> source,
-
+
Local<Script> Script::Compile(v8::Handle<String> source,
v8::Handle<Value> file_name,
- v8::Handle<String> script_data) {
@@ -196,8 +196,8 @@ index 1a6fbbb..39767f4 100644
- return Compile(source, &origin, 0, script_data);
+ return Compile(source, &origin, 0, script_data, compile_flags);
}
-
-
+
+
Local<Value> Script::Run() {
+ return Run(Handle<Object>());
+}
@@ -221,8 +221,8 @@ index 1a6fbbb..39767f4 100644
}
@@ -3943,6 +3953,30 @@ v8::Local<v8::Context> Context::GetCalling() {
}
-
-
+
+
+v8::Local<v8::Object> Context::GetCallingQmlGlobal() {
+ i::Isolate* isolate = i::Isolate::Current();
+ if (IsDeadCheck(isolate, "v8::Context::GetCallingQmlGlobal()")) {
@@ -257,7 +257,7 @@ index 8c147f9..a2626bf 100644
@@ -166,6 +166,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
-
+
+ // Copy the qml global object from the surrounding context.
+ __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
+ __ str(r1, MemOperand(r0, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
@@ -270,7 +270,7 @@ index 871b453..a69f10d 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -154,12 +154,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
@@ -288,7 +288,7 @@ index 871b453..a69f10d 100644
@@ -1247,9 +1248,9 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
__ bind(&fast);
}
-
+
- __ ldr(r0, GlobalObjectOperand());
+ __ ldr(r0, slot->var()->is_qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
__ mov(r2, Operand(slot->var()->name()));
@@ -308,7 +308,7 @@ index 871b453..a69f10d 100644
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(r0);
-
+
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
@@ -1893,11 +1894,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// assignment. Right-hand-side value is passed in r0, variable name in
@@ -321,7 +321,7 @@ index 871b453..a69f10d 100644
: isolate()->builtins()->StoreIC_Initialize();
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
-
+
} else if (op == Token::INIT_CONST) {
// Like var declarations, const declarations are hoisted to function
@@ -2184,10 +2185,13 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
@@ -331,14 +331,14 @@ index 871b453..a69f10d 100644
+ // Push the qml mode flag.
+ __ mov(r1, Operand(Smi::FromInt(is_qml_mode())));
+ __ push(r1);
-
+
__ CallRuntime(flag == SKIP_CONTEXT_LOOKUP
? Runtime::kResolvePossiblyDirectEvalNoLookup
- : Runtime::kResolvePossiblyDirectEval, 4);
+ : Runtime::kResolvePossiblyDirectEval, 5);
}
-
-
+
+
@@ -2263,9 +2267,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
context()->DropAndPlug(1, r0);
} else if (var != NULL && !var->is_this() && var->is_global()) {
@@ -356,20 +356,20 @@ index 3f1d15b..8406a96 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
+
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LGlobalObject(context));
+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global()));
}
-
-
+
+
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 6da7c86..10b901f 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -1378,13 +1378,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
+
class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LGlobalObject(LOperand* context) {
@@ -377,22 +377,22 @@ index 6da7c86..10b901f 100644
inputs_[0] = context;
+ qml_global_ = qml_global;
}
-
+
DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-
+
LOperand* context() { return InputAt(0); }
+ bool qml_global() { return qml_global_; }
+ private:
+ bool qml_global_;
};
-
-
+
+
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 4912449..db114ea 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -166,12 +166,13 @@ bool LCodeGen::GeneratePrologue() {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
@@ -414,16 +414,16 @@ index 4912449..db114ea 100644
- __ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX));
+ __ ldr(result, ContextOperand(cp, instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX));
}
-
-
+
+
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index ab5efb0..d40cdbc 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1056,6 +1056,11 @@ static inline MemOperand GlobalObjectOperand() {
}
-
-
+
+
+static inline MemOperand QmlGlobalObjectOperand() {
+ return ContextOperand(cp, Context::QML_GLOBAL_INDEX);
+}
@@ -438,15 +438,15 @@ index d80684a..adc5a1f 100644
+++ b/src/ast-inl.h
@@ -106,6 +106,11 @@ bool FunctionLiteral::strict_mode() const {
}
-
-
+
+
+bool FunctionLiteral::qml_mode() const {
+ return scope()->is_qml_mode();
+}
+
+
} } // namespace v8::internal
-
+
#endif // V8_AST_INL_H_
diff --git a/src/ast.h b/src/ast.h
index 65a25a9..f790dc0 100644
@@ -457,7 +457,7 @@ index 65a25a9..f790dc0 100644
bool is_expression() const { return is_expression_; }
bool strict_mode() const;
+ bool qml_mode() const;
-
+
int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; }
diff --git a/src/code-stubs.h b/src/code-stubs.h
@@ -466,12 +466,12 @@ index 56ef072..37e5383 100644
+++ b/src/code-stubs.h
@@ -303,7 +303,7 @@ class FastNewContextStub : public CodeStub {
static const int kMaximumSlots = 64;
-
+
explicit FastNewContextStub(int slots) : slots_(slots) {
- ASSERT(slots_ > 0 && slots <= kMaximumSlots);
+ ASSERT(slots_ >= 0 && slots <= kMaximumSlots);
}
-
+
void Generate(MacroAssembler* masm);
diff --git a/src/compiler.cc b/src/compiler.cc
index 86d5de3..d2191b9 100755
@@ -516,7 +516,7 @@ index 86d5de3..d2191b9 100755
@@ -610,6 +614,12 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
info->MarkAsStrictMode();
}
-
+
+ // After parsing we know function's qml mode. Remember it.
+ if (info->function()->qml_mode()) {
+ shared->set_qml_mode(true);
@@ -532,8 +532,8 @@ index 86d5de3..d2191b9 100755
function_info->set_strict_mode(lit->strict_mode());
+ function_info->set_qml_mode(lit->qml_mode());
}
-
-
+
+
diff --git a/src/compiler.h b/src/compiler.h
index e75e869..17cd369 100644
--- a/src/compiler.h
@@ -557,15 +557,15 @@ index e75e869..17cd369 100644
flags_ |= IsNativesSyntaxAllowed::encode(true);
}
@@ -141,6 +145,7 @@ class CompilationInfo BASE_EMBEDDED {
-
+
// Determine whether or not we can adaptively optimize.
bool AllowOptimize() {
+ // XXX - fix qml mode optimizations
return V8::UseCrankshaft() && !closure_.is_null();
}
-
+
@@ -163,8 +168,13 @@ class CompilationInfo BASE_EMBEDDED {
-
+
void Initialize(Mode mode) {
mode_ = V8::UseCrankshaft() ? mode : NONOPT;
- if (!shared_info_.is_null() && shared_info_->strict_mode()) {
@@ -579,16 +579,16 @@ index e75e869..17cd369 100644
+ }
}
}
-
+
@@ -187,6 +197,8 @@ class CompilationInfo BASE_EMBEDDED {
class IsStrictMode: public BitField<bool, 4, 1> {};
// Native syntax (%-stuff) allowed?
class IsNativesSyntaxAllowed: public BitField<bool, 5, 1> {};
+ // Qml mode
+ class IsQmlMode: public BitField<bool, 6, 1> {};
-
+
unsigned flags_;
-
+
@@ -252,13 +264,15 @@ class Compiler : public AllStatic {
v8::Extension* extension,
ScriptDataImpl* pre_data,
@@ -596,7 +596,7 @@ index e75e869..17cd369 100644
- NativesFlag is_natives_code);
+ NativesFlag is_natives_code,
+ v8::Script::CompileFlags compile_flags = v8::Script::Default);
-
+
// Compile a String source within a context for Eval.
static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
Handle<Context> context,
@@ -604,51 +604,63 @@ index e75e869..17cd369 100644
- StrictModeFlag strict_mode);
+ StrictModeFlag strict_mode,
+ bool qml_mode);
-
+
// Compile from function info (used for lazy compilation). Returns true on
// success and false if the compilation resulted in a stack overflow.
diff --git a/src/contexts.cc b/src/contexts.cc
-index 520f3dd..da5cacb 100644
+index 520f3dd..035ac3b 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
-@@ -89,6 +89,8 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
+@@ -89,6 +89,9 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
PrintF(")\n");
}
-
+
+ Handle<JSObject> qml_global;
++ Handle<JSObject> qml_global_global;
+
do {
if (FLAG_trace_contexts) {
PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
-@@ -119,6 +121,10 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
+@@ -119,6 +122,11 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
}
}
-
+
+ if (qml_global.is_null() && !context->qml_global()->IsUndefined()) {
+ qml_global = Handle<JSObject>(context->qml_global(), isolate);
++ qml_global_global = Handle<JSObject>(context->global(), isolate);
+ }
+
if (context->is_function_context()) {
// we have context-local slots
-
-@@ -198,6 +204,23 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
+
+@@ -198,6 +206,33 @@ Handle<Object> Context::Lookup(Handle<String> name, ContextLookupFlags flags,
}
} while (follow_context_chain);
-
+
+ if (!qml_global.is_null()) {
+ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) {
-+ *attributes = qml_global->GetLocalPropertyAttribute(*name);
++ *attributes = qml_global_global->GetLocalPropertyAttribute(*name);
+ } else {
-+ *attributes = qml_global->GetPropertyAttribute(*name);
++ *attributes = qml_global_global->GetPropertyAttribute(*name);
+ }
+
+ if (*attributes != ABSENT) {
-+ // property found
-+ if (FLAG_trace_contexts) {
-+ PrintF("=> found property in qml global object %p\n",
-+ reinterpret_cast<void*>(*qml_global));
++ *attributes = ABSENT;
++ } else {
++ if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0) {
++ *attributes = qml_global->GetLocalPropertyAttribute(*name);
++ } else {
++ *attributes = qml_global->GetPropertyAttribute(*name);
++ }
++
++ if (*attributes != ABSENT) {
++ // property found
++ if (FLAG_trace_contexts) {
++ PrintF("=> found property in qml global object %p\n",
++ reinterpret_cast<void*>(*qml_global));
++ }
++ return qml_global;
+ }
-+ return qml_global;
+ }
+ }
+
@@ -666,11 +678,11 @@ index e46619e..57d8e7b 100644
+ QML_GLOBAL_INDEX,
GLOBAL_INDEX,
MIN_CONTEXT_SLOTS,
-
+
@@ -273,6 +274,9 @@ class Context: public FixedArray {
}
void set_global(GlobalObject* global) { set(GLOBAL_INDEX, global); }
-
+
+ JSObject *qml_global() { return reinterpret_cast<JSObject *>(get(QML_GLOBAL_INDEX)); }
+ void set_qml_global(JSObject *qml_global) { set(QML_GLOBAL_INDEX, qml_global); }
+
@@ -689,12 +701,12 @@ index eb26438..1632076 100644
+ bool* has_pending_exception,
+ Handle<Object> qml) {
Isolate* isolate = func->GetIsolate();
-
+
// Entering JavaScript.
@@ -107,6 +108,12 @@ static Handle<Object> Invoke(bool construct,
// make the current one is indeed a global object.
ASSERT(func->context()->global()->IsGlobalObject());
-
+
+ Handle<JSObject> oldqml;
+ if (!qml.is_null()) {
+ oldqml = Handle<JSObject>(func->context()->qml_global());
@@ -707,8 +719,8 @@ index eb26438..1632076 100644
@@ -122,6 +129,9 @@ static Handle<Object> Invoke(bool construct,
receiver_pointer, argc, args);
}
-
-+ if (!qml.is_null())
+
++ if (!qml.is_null())
+ func->context()->set_qml_global(*oldqml);
+
#ifdef DEBUG
@@ -731,23 +743,23 @@ index eb26438..1632076 100644
+ Handle<Object> qml) {
+ return Invoke(false, func, receiver, argc, args, pending_exception, qml);
}
-
-
+
+
Handle<Object> Execution::New(Handle<JSFunction> func, int argc,
Object*** args, bool* pending_exception) {
return Invoke(true, func, Isolate::Current()->global(), argc, args,
- pending_exception);
+ pending_exception, Handle<Object>());
}
-
-
+
+
@@ -175,7 +195,7 @@ Handle<Object> Execution::TryCall(Handle<JSFunction> func,
catcher.SetCaptureMessage(false);
-
+
Handle<Object> result = Invoke(false, func, receiver, argc, args,
- caught_exception);
+ caught_exception, Handle<Object>());
-
+
if (*caught_exception) {
ASSERT(catcher.HasCaught());
diff --git a/src/execution.h b/src/execution.h
@@ -764,7 +776,7 @@ index d4b80d2..a476eb4 100644
+ Object*** args,
+ bool* pending_exception,
+ Handle<Object> qml);
-
+
// Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns,
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
@@ -799,7 +811,7 @@ index d6ed1b9..e3241aa 100644
+ bool is_qml_mode() { return function()->qml_mode(); }
FunctionLiteral* function() { return info_->function(); }
Scope* scope() { return info_->scope(); }
-
+
diff --git a/src/heap.cc b/src/heap.cc
index bf2940e..da958c2 100644
--- a/src/heap.cc
@@ -825,7 +837,7 @@ index a623775..52455bc 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -1148,7 +1148,7 @@ class HOuterContext: public HUnaryOperation {
-
+
class HGlobalObject: public HUnaryOperation {
public:
- explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
@@ -836,7 +848,7 @@ index a623775..52455bc 100644
@@ -1159,8 +1159,14 @@ class HGlobalObject: public HUnaryOperation {
return Representation::Tagged();
}
-
+
+ bool qml_global() { return qml_global_; }
+ void set_qml_global(bool v) { qml_global_ = v; }
+
@@ -846,14 +858,14 @@ index a623775..52455bc 100644
+ private:
+ bool qml_global_;
};
-
-
+
+
@@ -1177,7 +1183,7 @@ class HGlobalReceiver: public HUnaryOperation {
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
-
-+
++
protected:
virtual bool DataEquals(HValue* other) { return true; }
};
@@ -884,7 +896,7 @@ index 5d32095..afa599e 100644
@@ -147,6 +147,13 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ mov(ebx, Operand(ebx, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ mov(Operand(eax, Context::SlotOffset(Context::GLOBAL_INDEX)), ebx);
-
+
+ // Copy the qml global object from the surrounding context. We go through the
+ // context in the function (ecx) to match the allocation behavior we have
+ // in the runtime system (see Heap::AllocateFunctionContext).
@@ -900,7 +912,7 @@ index 5d153a8..0ddcde2 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -142,12 +142,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
@@ -916,7 +928,7 @@ index 5d153a8..0ddcde2 100644
} else {
__ CallRuntime(Runtime::kNewContext, 1);
@@ -1107,10 +1108,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
-
+
// All extension objects were empty and it is safe to use a global
// load IC call.
- __ mov(eax, GlobalObjectOperand());
@@ -939,7 +951,7 @@ index 5d153a8..0ddcde2 100644
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(eax);
-
+
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
@@ -1837,11 +1838,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// assignment. Right-hand-side value is passed in eax, variable name in
@@ -952,13 +964,13 @@ index 5d153a8..0ddcde2 100644
: isolate()->builtins()->StoreIC_Initialize();
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global()?RelocInfo::CODE_TARGET:RelocInfo::CODE_TARGET_CONTEXT);
-
+
} else if (op == Token::INIT_CONST) {
// Like var declarations, const declarations are hoisted to function
@@ -2113,9 +2114,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
// Push the strict mode flag.
__ push(Immediate(Smi::FromInt(strict_mode_flag())));
-
+
+ // Push the qml mode flag
+ __ push(Immediate(Smi::FromInt(is_qml_mode())));
+
@@ -967,8 +979,8 @@ index 5d153a8..0ddcde2 100644
- : Runtime::kResolvePossiblyDirectEval, 4);
+ : Runtime::kResolvePossiblyDirectEval, 5);
}
-
-
+
+
@@ -2188,8 +2192,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
context()->DropAndPlug(1, eax);
} else if (var != NULL && !var->is_this() && var->is_global()) {
@@ -985,7 +997,7 @@ index 0f96f78..c1da075 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -159,12 +159,13 @@ bool LCodeGen::GeneratePrologue() {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
@@ -1007,27 +1019,27 @@ index 0f96f78..c1da075 100644
- __ mov(result, Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ __ mov(result, Operand(context, Context::SlotOffset(instr->qml_global()?Context::QML_GLOBAL_INDEX:Context::GLOBAL_INDEX)));
}
-
-
+
+
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 9ccd189..8e98b73 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1205,7 +1205,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
+
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
LOperand* context = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LGlobalObject(context));
+ return DefineAsRegister(new LGlobalObject(context, instr->qml_global()));
}
-
-
+
+
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 9ace8f8..95ed001 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -1416,13 +1416,17 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
+
class LGlobalObject: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LGlobalObject(LOperand* context) {
@@ -1035,24 +1047,24 @@ index 9ace8f8..95ed001 100644
inputs_[0] = context;
+ qml_global_ = qml_global;
}
-
+
DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-
+
LOperand* context() { return InputAt(0); }
+ bool qml_global() { return qml_global_; }
+ private:
+ bool qml_global_;
};
-
-
+
+
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index b986264..f8479ae 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -778,6 +778,11 @@ static inline Operand GlobalObjectOperand() {
}
-
-
+
+
+static inline Operand QmlGlobalObjectOperand() {
+ return ContextOperand(esi, Context::QML_GLOBAL_INDEX);
+}
@@ -1060,15 +1072,15 @@ index b986264..f8479ae 100644
+
// Generates an Operand for saving parameters after PrepareCallApiFunction.
Operand ApiParameterOperand(int index);
-
+
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 231b835..1c7f83e 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -3242,6 +3242,18 @@ void SharedFunctionInfo::set_strict_mode(bool value) {
}
-
-
+
+
+bool SharedFunctionInfo::qml_mode() {
+ return BooleanBit::get(compiler_hints(), kQmlModeFunction);
+}
@@ -1083,7 +1095,7 @@ index 231b835..1c7f83e 100644
+
ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
-
+
diff --git a/src/objects.h b/src/objects.h
index 1bdb5c7..edbc47a 100644
--- a/src/objects.h
@@ -1091,7 +1103,7 @@ index 1bdb5c7..edbc47a 100644
@@ -4331,6 +4331,10 @@ class SharedFunctionInfo: public HeapObject {
inline bool strict_mode();
inline void set_strict_mode(bool value);
-
+
+ // Indicates whether the function is a qml mode function
+ inline bool qml_mode();
+ inline void set_qml_mode(bool value);
@@ -1104,7 +1116,7 @@ index 1bdb5c7..edbc47a 100644
static const int kOptimizationDisabled = 6;
static const int kStrictModeFunction = 7;
+ static const int kQmlModeFunction = 8;
-
+
private:
#if V8_HOST_ARCH_32_BIT
diff --git a/src/parser.cc b/src/parser.cc
@@ -1112,14 +1124,14 @@ index a84ec6f..7f5c361 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -593,7 +593,8 @@ Parser::Parser(Handle<Script> script,
-
+
FunctionLiteral* Parser::ParseProgram(Handle<String> source,
bool in_global_context,
- StrictModeFlag strict_mode) {
+ StrictModeFlag strict_mode,
+ bool qml_mode) {
CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
-
+
HistogramTimerScope timer(isolate()->counters()->parse());
@@ -609,11 +610,11 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
ExternalTwoByteStringUC16CharacterStream stream(
@@ -1134,7 +1146,7 @@ index a84ec6f..7f5c361 100644
+ return DoParseProgram(source, in_global_context, strict_mode, qml_mode, &zone_scope);
}
}
-
+
@@ -621,6 +622,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
bool in_global_context,
@@ -1160,15 +1172,15 @@ index a84ec6f..7f5c361 100644
+ if (shared_info->qml_mode()) {
+ top_scope_->EnableQmlMode();
+ }
-
+
FunctionLiteralType type =
shared_info->is_expression() ? EXPRESSION : DECLARATION;
@@ -1661,6 +1669,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
arguments->Add(value);
value = NULL; // zap the value to avoid the unnecessary assignment
-
+
+ int qml_mode = 0;
-+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
++ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
+ qml_mode = 1;
+ arguments->Add(NewNumberLiteral(qml_mode));
+
@@ -1178,9 +1190,9 @@ index a84ec6f..7f5c361 100644
@@ -1676,6 +1689,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
arguments->Add(NewNumberLiteral(
top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
-
+
+ int qml_mode = 0;
-+ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
++ if (top_scope_->is_qml_mode() && !Isolate::Current()->global()->HasProperty(*name))
+ qml_mode = 1;
+ arguments->Add(NewNumberLiteral(qml_mode));
+
@@ -1196,7 +1208,7 @@ index a84ec6f..7f5c361 100644
+ info->is_qml_mode());
}
}
-
+
diff --git a/src/parser.h b/src/parser.h
index 64f1303..4d45e45 100644
--- a/src/parser.h
@@ -1208,16 +1220,16 @@ index 64f1303..4d45e45 100644
- StrictModeFlag strict_mode);
+ StrictModeFlag strict_mode,
+ bool qml_mode);
-
+
FunctionLiteral* ParseLazy(CompilationInfo* info);
-
+
@@ -464,6 +465,7 @@ class Parser {
FunctionLiteral* DoParseProgram(Handle<String> source,
bool in_global_context,
StrictModeFlag strict_mode,
+ bool qml_mode,
ZoneScope* zone_scope);
-
+
// Report syntax error
diff --git a/src/prettyprinter.cc b/src/prettyprinter.cc
index c777ab4..1964e02 100644
@@ -1234,7 +1246,7 @@ index c777ab4..1964e02 100644
PrintLiteralIndented(buf.start(), value, true);
}
diff --git a/src/runtime.cc b/src/runtime.cc
-index 660352c..827d954 100644
+index 660352c..c13f92d 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1065,8 +1065,6 @@ static Failure* ThrowRedeclarationError(Isolate* isolate,
@@ -1243,13 +1255,13 @@ index 660352c..827d954 100644
HandleScope scope(isolate);
- Handle<GlobalObject> global = Handle<GlobalObject>(
- isolate->context()->global());
-
+
Handle<Context> context = args.at<Context>(0);
CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
@@ -1075,6 +1073,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
-
+
+ Handle<JSObject> js_global = Handle<JSObject>(isolate->context()->global());
+ Handle<JSObject> qml_global = Handle<JSObject>(isolate->context()->qml_global());
+
@@ -1257,7 +1269,7 @@ index 660352c..827d954 100644
// 13, page 71, the property must be read-only and
// non-deletable. However, neither SpiderMonkey nor KJS creates the
@@ -1083,10 +1084,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
-
+
// Traverse the name/value pairs and set the properties.
int length = pairs->length();
- for (int i = 0; i < length; i += 2) {
@@ -1268,7 +1280,7 @@ index 660352c..827d954 100644
+ Handle<Smi> is_qml_global(Smi::cast(pairs->get(i + 2)));
+
+ Handle<JSObject> global = is_qml_global->value()?qml_global:js_global;
-
+
// We have to declare a global const property. To capture we only
// assign to it when evaluating the assignment for "const x =
@@ -1316,20 +1320,25 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
@@ -1278,21 +1290,21 @@ index 660352c..827d954 100644
- // args[2] == value (optional)
+ // args[2] == qml_mode
+ // args[3] == value (optional)
-
+
// Determine if we need to assign to the variable if it already
// exists (based on the number of arguments).
- RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
- bool assign = args.length() == 3;
+ RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
+ bool assign = args.length() == 4;
-
+
CONVERT_ARG_CHECKED(String, name, 0);
- GlobalObject* global = isolate->context()->global();
RUNTIME_ASSERT(args[1]->IsSmi());
StrictModeFlag strict_mode =
static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
-
+
+ RUNTIME_ASSERT(args[2]->IsSmi());
+ int qml_mode = Smi::cast(args[2])->value();
+
@@ -1309,7 +1321,7 @@ index 660352c..827d954 100644
+ if (real_holder != global) break;
return ThrowRedeclarationError(isolate, "const", name);
}
-
+
@@ -1372,7 +1381,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
// overwrite it with a variable declaration we must throw a
// re-declaration error. However if we found readonly property
@@ -1321,7 +1333,7 @@ index 660352c..827d954 100644
}
@@ -1384,7 +1393,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
}
-
+
// Assign the value (or undefined) to the property.
- Object* value = (assign) ? args[2] : isolate->heap()->undefined_value();
+ Object* value = (assign) ? args[3] : isolate->heap()->undefined_value();
@@ -1331,7 +1343,7 @@ index 660352c..827d954 100644
@@ -1399,9 +1408,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
real_holder = JSObject::cast(proto);
}
-
+
- global = isolate->context()->global();
+ global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
if (assign) {
@@ -1348,14 +1360,14 @@ index 660352c..827d954 100644
+ RUNTIME_ASSERT(args.length() == 3);
CONVERT_ARG_CHECKED(String, name, 0);
Handle<Object> value = args.at<Object>(1);
-
+
+ RUNTIME_ASSERT(args[2]->IsSmi());
+ int qml_mode = Smi::cast(args[2])->value();
+
// Get the current global object from top.
- GlobalObject* global = isolate->context()->global();
+ JSObject* global = qml_mode?isolate->context()->qml_global():isolate->context()->global();
-
+
// According to ECMA-262, section 12.2, page 62, the property must
// not be deletable. Since it's a const, it must be READ_ONLY too.
@@ -1456,7 +1468,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
@@ -1364,7 +1376,7 @@ index 660352c..827d954 100644
HandleScope handle_scope(isolate);
- Handle<GlobalObject> global(isolate->context()->global());
+ Handle<JSObject> global(qml_mode?isolate->context()->qml_global():isolate->context()->global());
-
+
// BUG 1213575: Handle the case where we have to set a read-only
// property through an interceptor and only do it if it's
@@ -8160,7 +8172,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
@@ -1392,22 +1404,22 @@ index 660352c..827d954 100644
isolate->context()->IsGlobalContext(),
- strict_mode);
+ strict_mode,
-+ qml_mode);
++ qml_mode);
if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
Handle<JSFunction> compiled =
isolate->factory()->NewFunctionFromSharedFunctionInfo(
@@ -8190,7 +8205,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
-
-
+
+
RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
- ASSERT(args.length() == 4);
+ ASSERT(args.length() == 5);
-
+
HandleScope scope(isolate);
Handle<Object> callee = args.at<Object>(0);
@@ -8257,16 +8272,18 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
}
-
+
ASSERT(args[3]->IsSmi());
+ ASSERT(args[4]->IsSmi());
return CompileGlobalEval(isolate,
@@ -1418,17 +1430,17 @@ index 660352c..827d954 100644
+ Smi::cast(args[3])->value()),
+ Smi::cast(args[4])->value());
}
-
-
+
+
RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
- ASSERT(args.length() == 4);
+ ASSERT(args.length() == 5);
-
+
HandleScope scope(isolate);
Handle<Object> callee = args.at<Object>(0);
@@ -8280,11 +8297,13 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEvalNoLookup) {
}
-
+
ASSERT(args[3]->IsSmi());
+ ASSERT(args[4]->IsSmi());
return CompileGlobalEval(isolate,
@@ -1439,19 +1451,37 @@ index 660352c..827d954 100644
+ Smi::cast(args[3])->value()),
+ Smi::cast(args[4])->value());
}
-
-
-@@ -10633,7 +10652,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+
+
+@@ -10570,6 +10589,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+ Handle<JSFunction> function(JSFunction::cast(frame->function()));
+ Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
+ ScopeInfo<> sinfo(*scope_info);
++ bool qml_mode = function->shared()->qml_mode();
+
+ // Traverse the saved contexts chain to find the active context for the
+ // selected frame.
+@@ -10633,7 +10653,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Compiler::CompileEval(function_source,
context,
context->IsGlobalContext(),
- kNonStrictMode);
+ kNonStrictMode,
-+ false);
++ qml_mode);
if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
-@@ -10722,7 +10742,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
+@@ -10656,7 +10677,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
+ Handle<Object>::cast(source).location() };
+ Handle<Object> result =
+ Execution::Call(Handle<JSFunction>::cast(evaluation_function), receiver,
+- argc, argv, &has_pending_exception);
++ argc, argv, &has_pending_exception,
++ Handle<Object>(function->context()->qml_global()));
+ if (has_pending_exception) return Failure::Exception();
+
+ // Skip the global proxy as it has no properties and always delegates to the
+@@ -10722,7 +10744,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// Currently, the eval code will be executed in non-strict mode,
// even in the strict code context.
Handle<SharedFunctionInfo> shared =
@@ -1487,7 +1517,7 @@ index bf1ba68..5e97173 100644
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
\
diff --git a/src/scopes.cc b/src/scopes.cc
-index 8df93c5..734a217 100644
+index 8df93c5..b5d7ff3 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -198,6 +198,7 @@ void Scope::SetDefaults(Type type,
@@ -1498,33 +1528,82 @@ index 8df93c5..734a217 100644
outer_scope_calls_eval_ = false;
inner_scope_calls_eval_ = false;
outer_scope_is_eval_scope_ = false;
-@@ -796,6 +797,10 @@ void Scope::ResolveVariable(Scope* global_scope,
+@@ -796,6 +797,25 @@ void Scope::ResolveVariable(Scope* global_scope,
ASSERT(global_scope != NULL);
var = global_scope->DeclareGlobal(proxy->name());
-
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name()))) {
-+ var->set_is_qml_global(true);
+
++ if (qml_mode_) {
++ Handle<GlobalObject> global = Isolate::Current()->global();
++
++#ifdef ENABLE_DEBUGGER_SUPPORT
++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
++ //Get the context before the debugger was entered.
++ SaveContext *save = Isolate::Current()->save_context();
++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
++ save = save->prev();
++
++ global = Handle<GlobalObject>(save->context()->global());
++ }
++#endif
++
++ if (!global->HasProperty(*(proxy->name()))) {
++ var->set_is_qml_global(true);
++ }
+ }
+
} else if (scope_inside_with_) {
// If we are inside a with statement we give up and look up
// the variable at runtime.
-@@ -816,6 +821,8 @@ void Scope::ResolveVariable(Scope* global_scope,
- // variables.
+@@ -817,6 +837,25 @@ void Scope::ResolveVariable(Scope* global_scope,
if (context->GlobalIfNotShadowedByEval(proxy->name())) {
var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name())))
-+ var->set_is_qml_global(true);
-
+
++ if (qml_mode_) {
++ Handle<GlobalObject> global = Isolate::Current()->global();
++
++#ifdef ENABLE_DEBUGGER_SUPPORT
++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
++ //Get the context before the debugger was entered.
++ SaveContext *save = Isolate::Current()->save_context();
++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
++ save = save->prev();
++
++ global = Handle<GlobalObject>(save->context()->global());
++ }
++#endif
++
++ if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
++ var->set_is_qml_global(true);
++ }
++ }
++
} else {
var = NonLocal(proxy->name(), Variable::DYNAMIC);
-@@ -827,6 +834,9 @@ void Scope::ResolveVariable(Scope* global_scope,
+ }
+@@ -827,6 +866,26 @@ void Scope::ResolveVariable(Scope* global_scope,
// variable is global unless it is shadowed by eval-introduced
// variables.
var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
+
-+ if (qml_mode_ && !Isolate::Current()->global()->HasProperty(*(proxy->name())))
-+ var->set_is_qml_global(true);
++ if (qml_mode_) {
++ Handle<GlobalObject> global = Isolate::Current()->global();
++
++#ifdef ENABLE_DEBUGGER_SUPPORT
++ if (Isolate::Current()->debug()->IsLoaded() && Isolate::Current()->debug()->InDebugger()) {
++ //Get the context before the debugger was entered.
++ SaveContext *save = Isolate::Current()->save_context();
++ while (save != NULL && *save->context() == *Isolate::Current()->debug()->debug_context())
++ save = save->prev();
++
++ global = Handle<GlobalObject>(save->context()->global());
++ }
++#endif
++
++ if (qml_mode_ && !global->HasProperty(*(proxy->name()))) {
++ var->set_is_qml_global(true);
++ }
++ }
++
}
}
}
@@ -1535,7 +1614,7 @@ index a0e56a4..6dd3f65 100644
@@ -210,6 +210,11 @@ class Scope: public ZoneObject {
strict_mode_ = FLAG_strict_mode;
}
-
+
+ // Enable qml mode for this scope
+ void EnableQmlMode() {
+ qml_mode_ = true;
@@ -1543,13 +1622,13 @@ index a0e56a4..6dd3f65 100644
+
// ---------------------------------------------------------------------------
// Predicates.
-
+
@@ -218,6 +223,7 @@ class Scope: public ZoneObject {
bool is_function_scope() const { return type_ == FUNCTION_SCOPE; }
bool is_global_scope() const { return type_ == GLOBAL_SCOPE; }
bool is_strict_mode() const { return strict_mode_; }
+ bool is_qml_mode() const { return qml_mode_; }
-
+
// Information about which scopes calls eval.
bool calls_eval() const { return scope_calls_eval_; }
@@ -376,6 +382,7 @@ class Scope: public ZoneObject {
@@ -1557,7 +1636,7 @@ index a0e56a4..6dd3f65 100644
bool scope_calls_eval_; // this scope contains an 'eval' call
bool strict_mode_; // this scope is a strict mode scope
+ bool qml_mode_; // this scope is a qml mode scope
-
+
// Computed via PropagateScopeInfo.
bool outer_scope_calls_eval_;
diff --git a/src/variables.cc b/src/variables.cc
@@ -1581,7 +1660,7 @@ index b1ff0db..0b31d1a 100644
@@ -141,6 +141,8 @@ class Variable: public ZoneObject {
Expression* rewrite() const { return rewrite_; }
void set_rewrite(Expression* expr) { rewrite_ = expr; }
-
+
+ bool is_qml_global() const { return is_qml_global_; }
+ void set_is_qml_global(bool is_qml_global) { is_qml_global_ = is_qml_global; }
private:
@@ -1595,8 +1674,8 @@ index b1ff0db..0b31d1a 100644
+ // QML info
+ bool is_qml_global_;
};
-
-
+
+
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index c365385..d923494 100644
--- a/src/x64/code-stubs-x64.cc
@@ -1604,7 +1683,7 @@ index c365385..d923494 100644
@@ -140,6 +140,10 @@ void FastNewContextStub::Generate(MacroAssembler* masm) {
__ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ movq(Operand(rax, Context::SlotOffset(Context::GLOBAL_INDEX)), rbx);
-
+
+ // Copy the qml global object from the surrounding context.
+ __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::QML_GLOBAL_INDEX)));
+ __ movq(Operand(rax, Context::SlotOffset(Context::QML_GLOBAL_INDEX)), rbx);
@@ -1617,11 +1696,11 @@ index 97168cd..c45cdb6 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -141,12 +141,13 @@ void FullCodeGenerator::Generate(CompilationInfo* info) {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
-+ if (heap_slots > 0 ||
++ if (heap_slots > 0 ||
+ (scope()->is_qml_mode() && scope()->is_global_scope())) {
Comment cmnt(masm_, "[ Allocate local context");
// Argument to NewContext is the function, which is still in rdi.
@@ -1633,7 +1712,7 @@ index 97168cd..c45cdb6 100644
} else {
__ CallRuntime(Runtime::kNewContext, 1);
@@ -1119,10 +1120,10 @@ void FullCodeGenerator::EmitLoadGlobalSlotCheckExtensions(
-
+
// All extension objects were empty and it is safe to use a global
// load IC call.
- __ movq(rax, GlobalObjectOperand());
@@ -1655,7 +1734,7 @@ index 97168cd..c45cdb6 100644
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
context()->Plug(rax);
-
+
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
@@ -1806,11 +1807,11 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var,
// assignment. Right-hand-side value is passed in rax, variable name in
@@ -1668,13 +1747,13 @@ index 97168cd..c45cdb6 100644
: isolate()->builtins()->StoreIC_Initialize();
- EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
+ EmitCallIC(ic, var->is_qml_global() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT);
-
+
} else if (op == Token::INIT_CONST) {
// Like var declarations, const declarations are hoisted to function
@@ -2085,9 +2086,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag,
// Push the strict mode flag.
__ Push(Smi::FromInt(strict_mode_flag()));
-
+
+ // Push the qml mode flag
+ __ Push(Smi::FromInt(is_qml_mode()));
+
@@ -1683,8 +1762,8 @@ index 97168cd..c45cdb6 100644
- : Runtime::kResolvePossiblyDirectEval, 4);
+ : Runtime::kResolvePossiblyDirectEval, 5);
}
-
-
+
+
@@ -2160,8 +2164,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else if (var != NULL && !var->is_this() && var->is_global()) {
// Call to a global variable.
@@ -1701,7 +1780,7 @@ index 202e7a2..45acbdf 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -174,12 +174,13 @@ bool LCodeGen::GeneratePrologue() {
-
+
// Possibly allocate a local context.
int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
- if (heap_slots > 0) {
@@ -1717,53 +1796,53 @@ index 202e7a2..45acbdf 100644
} else {
__ CallRuntime(Runtime::kNewContext, 1);
@@ -2540,7 +2541,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
-
+
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
Register result = ToRegister(instr->result());
- __ movq(result, GlobalObjectOperand());
+ __ movq(result, instr->qml_global()?QmlGlobalObjectOperand():GlobalObjectOperand());
}
-
-
+
+
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 07ca3a5..00feeac 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -1194,7 +1194,7 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
-
-
+
+
LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
- return DefineAsRegister(new LGlobalObject);
+ return DefineAsRegister(new LGlobalObject(instr->qml_global()));
}
-
-
+
+
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 15bb894..16f754c 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -1365,7 +1365,13 @@ class LOuterContext: public LTemplateInstruction<1, 1, 0> {
-
+
class LGlobalObject: public LTemplateInstruction<1, 0, 0> {
public:
+ explicit LGlobalObject(bool qml_global) : qml_global_(qml_global) {}
+
DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global-object")
-+
++
+ bool qml_global() { return qml_global_; }
+ private:
+ bool qml_global_;
};
-
-
+
+
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 4c17720..aa284ed 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1233,6 +1233,11 @@ static inline Operand GlobalObjectOperand() {
}
-
-
+
+
+static inline Operand QmlGlobalObjectOperand() {
+ return ContextOperand(rsi, Context::QML_GLOBAL_INDEX);
+}
@@ -1772,6 +1851,6 @@ index 4c17720..aa284ed 100644
// Provides access to exit frame stack space (not GCed).
static inline Operand StackSpaceOperand(int index) {
#ifdef _WIN64
---
-1.7.6
+--
+1.7.4.4