summaryrefslogtreecommitdiff
path: root/src/3rdparty/v8
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-10-27 13:34:16 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-05 12:18:10 +0100
commit2fe857938c3d1683df88133582bc3e7736264b10 (patch)
tree1ec9903bd86ffe2d264dcc52a658ebdb0474714e /src/3rdparty/v8
parente5ba7458fc5418e688de9cf294f5eb96cd6c4510 (diff)
downloadqtjsbackend-2fe857938c3d1683df88133582bc3e7736264b10.tar.gz
[V8] 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. Change-Id: I4950562d455074578c372d8e0e3089887b06e0a1
Diffstat (limited to 'src/3rdparty/v8')
-rw-r--r--src/3rdparty/v8/include/v8.h19
-rw-r--r--src/3rdparty/v8/src/api.cc52
-rw-r--r--src/3rdparty/v8/src/arm/code-stubs-arm.cc4
-rw-r--r--src/3rdparty/v8/src/arm/full-codegen-arm.cc28
-rw-r--r--src/3rdparty/v8/src/arm/lithium-arm.cc4
-rw-r--r--src/3rdparty/v8/src/arm/lithium-arm.h12
-rw-r--r--src/3rdparty/v8/src/arm/lithium-codegen-arm.cc9
-rw-r--r--src/3rdparty/v8/src/arm/macro-assembler-arm.h5
-rw-r--r--src/3rdparty/v8/src/ast-inl.h5
-rw-r--r--src/3rdparty/v8/src/ast.cc5
-rw-r--r--src/3rdparty/v8/src/ast.h1
-rw-r--r--src/3rdparty/v8/src/code-stubs.h2
-rw-r--r--src/3rdparty/v8/src/compiler.cc15
-rw-r--r--src/3rdparty/v8/src/compiler.h16
-rw-r--r--src/3rdparty/v8/src/contexts.cc35
-rw-r--r--src/3rdparty/v8/src/contexts.h4
-rw-r--r--src/3rdparty/v8/src/execution.cc31
-rw-r--r--src/3rdparty/v8/src/execution.h8
-rw-r--r--src/3rdparty/v8/src/full-codegen.cc3
-rw-r--r--src/3rdparty/v8/src/full-codegen.h1
-rw-r--r--src/3rdparty/v8/src/heap.cc4
-rw-r--r--src/3rdparty/v8/src/hydrogen-instructions.cc5
-rw-r--r--src/3rdparty/v8/src/hydrogen-instructions.h21
-rw-r--r--src/3rdparty/v8/src/hydrogen.cc4
-rw-r--r--src/3rdparty/v8/src/ia32/code-stubs-ia32.cc5
-rw-r--r--src/3rdparty/v8/src/ia32/full-codegen-ia32.cc28
-rw-r--r--src/3rdparty/v8/src/ia32/lithium-codegen-ia32.cc9
-rw-r--r--src/3rdparty/v8/src/ia32/lithium-ia32.cc4
-rw-r--r--src/3rdparty/v8/src/ia32/lithium-ia32.h12
-rw-r--r--src/3rdparty/v8/src/ia32/macro-assembler-ia32.h3
-rw-r--r--src/3rdparty/v8/src/mips/code-stubs-mips.cc5
-rw-r--r--src/3rdparty/v8/src/mips/full-codegen-mips.cc30
-rw-r--r--src/3rdparty/v8/src/mips/macro-assembler-mips.h5
-rw-r--r--src/3rdparty/v8/src/objects-inl.h2
-rw-r--r--src/3rdparty/v8/src/objects.h7
-rw-r--r--src/3rdparty/v8/src/parser.cc28
-rw-r--r--src/3rdparty/v8/src/parser.h4
-rw-r--r--src/3rdparty/v8/src/prettyprinter.cc3
-rw-r--r--src/3rdparty/v8/src/runtime.cc84
-rw-r--r--src/3rdparty/v8/src/runtime.h8
-rw-r--r--src/3rdparty/v8/src/scopeinfo.cc28
-rw-r--r--src/3rdparty/v8/src/scopeinfo.h1
-rw-r--r--src/3rdparty/v8/src/scopes.cc63
-rw-r--r--src/3rdparty/v8/src/scopes.h8
-rw-r--r--src/3rdparty/v8/src/variables.cc3
-rw-r--r--src/3rdparty/v8/src/variables.h5
-rw-r--r--src/3rdparty/v8/src/x64/code-stubs-x64.cc4
-rw-r--r--src/3rdparty/v8/src/x64/full-codegen-x64.cc28
-rw-r--r--src/3rdparty/v8/src/x64/lithium-codegen-x64.cc9
-rw-r--r--src/3rdparty/v8/src/x64/lithium-x64.cc4
-rw-r--r--src/3rdparty/v8/src/x64/lithium-x64.h12
-rw-r--r--src/3rdparty/v8/src/x64/macro-assembler-x64.h5
52 files changed, 559 insertions, 141 deletions
diff --git a/src/3rdparty/v8/include/v8.h b/src/3rdparty/v8/include/v8.h
index 3ef4dd6..193e2fe 100644
--- a/src/3rdparty/v8/include/v8.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/api.cc b/src/3rdparty/v8/src/api.cc
index 7d54252..2d3d97a 100644
--- a/src/3rdparty/v8/src/api.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/code-stubs-arm.cc b/src/3rdparty/v8/src/arm/code-stubs-arm.cc
index cb3bc88..f5be938 100644
--- a/src/3rdparty/v8/src/arm/code-stubs-arm.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/full-codegen-arm.cc b/src/3rdparty/v8/src/arm/full-codegen-arm.cc
index 497a295..b8e3f30 100644
--- a/src/3rdparty/v8/src/arm/full-codegen-arm.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/lithium-arm.cc b/src/3rdparty/v8/src/arm/lithium-arm.cc
index 5197842..943bc82 100644
--- a/src/3rdparty/v8/src/arm/lithium-arm.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/lithium-arm.h b/src/3rdparty/v8/src/arm/lithium-arm.h
index 5733bd0..a7e1704 100644
--- a/src/3rdparty/v8/src/arm/lithium-arm.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/lithium-codegen-arm.cc b/src/3rdparty/v8/src/arm/lithium-codegen-arm.cc
index 4cf7df4..2e1e6fa 100644
--- a/src/3rdparty/v8/src/arm/lithium-codegen-arm.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/arm/macro-assembler-arm.h b/src/3rdparty/v8/src/arm/macro-assembler-arm.h
index 90c4b37..5947e6a 100644
--- a/src/3rdparty/v8/src/arm/macro-assembler-arm.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ast-inl.h b/src/3rdparty/v8/src/ast-inl.h
index f8b460d..217c71f 100644
--- a/src/3rdparty/v8/src/ast-inl.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ast.cc b/src/3rdparty/v8/src/ast.cc
index 9e34bc0..0dc3c1c 100644
--- a/src/3rdparty/v8/src/ast.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ast.h b/src/3rdparty/v8/src/ast.h
index 3de00ef..8920b50 100644
--- a/src/3rdparty/v8/src/ast.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/code-stubs.h b/src/3rdparty/v8/src/code-stubs.h
index fc7000b..4380764 100644
--- a/src/3rdparty/v8/src/code-stubs.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/compiler.cc b/src/3rdparty/v8/src/compiler.cc
index 88db467..4902e72 100644
--- a/src/3rdparty/v8/src/compiler.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/compiler.h b/src/3rdparty/v8/src/compiler.h
index bedf5ee..054e3b9 100644
--- a/src/3rdparty/v8/src/compiler.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/contexts.cc b/src/3rdparty/v8/src/contexts.cc
index b25ffac..3129af0 100644
--- a/src/3rdparty/v8/src/contexts.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/contexts.h b/src/3rdparty/v8/src/contexts.h
index 7021ff8..c3cfeee 100644
--- a/src/3rdparty/v8/src/contexts.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/execution.cc b/src/3rdparty/v8/src/execution.cc
index 29955fa..4261ac2 100644
--- a/src/3rdparty/v8/src/execution.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/execution.h b/src/3rdparty/v8/src/execution.h
index f2d17d0..532e5d8 100644
--- a/src/3rdparty/v8/src/execution.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/full-codegen.cc b/src/3rdparty/v8/src/full-codegen.cc
index 27c509f..f099d25 100644
--- a/src/3rdparty/v8/src/full-codegen.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/full-codegen.h b/src/3rdparty/v8/src/full-codegen.h
index 9132502..78e6089 100644
--- a/src/3rdparty/v8/src/full-codegen.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/heap.cc b/src/3rdparty/v8/src/heap.cc
index 53a0f27..881a876 100644
--- a/src/3rdparty/v8/src/heap.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/hydrogen-instructions.cc b/src/3rdparty/v8/src/hydrogen-instructions.cc
index 6f46509..ac9728c 100644
--- a/src/3rdparty/v8/src/hydrogen-instructions.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/hydrogen-instructions.h b/src/3rdparty/v8/src/hydrogen-instructions.h
index 65fc4df..ebf0030 100644
--- a/src/3rdparty/v8/src/hydrogen-instructions.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/hydrogen.cc b/src/3rdparty/v8/src/hydrogen.cc
index 3a4d172..0a7fad1 100644
--- a/src/3rdparty/v8/src/hydrogen.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/code-stubs-ia32.cc b/src/3rdparty/v8/src/ia32/code-stubs-ia32.cc
index 37b519a..8a94a06 100644
--- a/src/3rdparty/v8/src/ia32/code-stubs-ia32.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/full-codegen-ia32.cc b/src/3rdparty/v8/src/ia32/full-codegen-ia32.cc
index 25588c8..9cee4a3 100644
--- a/src/3rdparty/v8/src/ia32/full-codegen-ia32.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/lithium-codegen-ia32.cc b/src/3rdparty/v8/src/ia32/lithium-codegen-ia32.cc
index d4cbbce..b381227 100644
--- a/src/3rdparty/v8/src/ia32/lithium-codegen-ia32.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/lithium-ia32.cc b/src/3rdparty/v8/src/ia32/lithium-ia32.cc
index 626f899..d09d55f 100644
--- a/src/3rdparty/v8/src/ia32/lithium-ia32.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/lithium-ia32.h b/src/3rdparty/v8/src/ia32/lithium-ia32.h
index 5f23afa..22541c8 100644
--- a/src/3rdparty/v8/src/ia32/lithium-ia32.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/ia32/macro-assembler-ia32.h b/src/3rdparty/v8/src/ia32/macro-assembler-ia32.h
index 8528c55..de3c3a0 100644
--- a/src/3rdparty/v8/src/ia32/macro-assembler-ia32.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/mips/code-stubs-mips.cc b/src/3rdparty/v8/src/mips/code-stubs-mips.cc
index 85e929d..a534b78 100644
--- a/src/3rdparty/v8/src/mips/code-stubs-mips.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/mips/full-codegen-mips.cc b/src/3rdparty/v8/src/mips/full-codegen-mips.cc
index 2f989bc..b6bd407 100644
--- a/src/3rdparty/v8/src/mips/full-codegen-mips.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/mips/macro-assembler-mips.h b/src/3rdparty/v8/src/mips/macro-assembler-mips.h
index 84c55f7..5224db9 100644
--- a/src/3rdparty/v8/src/mips/macro-assembler-mips.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/objects-inl.h b/src/3rdparty/v8/src/objects-inl.h
index 6a80c9c..2e83fb7 100644
--- a/src/3rdparty/v8/src/objects-inl.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/objects.h b/src/3rdparty/v8/src/objects.h
index c38d461..b71eaac 100644
--- a/src/3rdparty/v8/src/objects.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/parser.cc b/src/3rdparty/v8/src/parser.cc
index 37204c9..357d340 100644
--- a/src/3rdparty/v8/src/parser.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/parser.h b/src/3rdparty/v8/src/parser.h
index eaae6f7..a60951d 100644
--- a/src/3rdparty/v8/src/parser.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/prettyprinter.cc b/src/3rdparty/v8/src/prettyprinter.cc
index 37c76ce..73812fd 100644
--- a/src/3rdparty/v8/src/prettyprinter.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/runtime.cc b/src/3rdparty/v8/src/runtime.cc
index 0e256c1..b64e66b 100644
--- a/src/3rdparty/v8/src/runtime.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/runtime.h b/src/3rdparty/v8/src/runtime.h
index 67fc628..aada06d 100644
--- a/src/3rdparty/v8/src/runtime.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/scopeinfo.cc b/src/3rdparty/v8/src/scopeinfo.cc
index 8ea5f1e..a61b787 100644
--- a/src/3rdparty/v8/src/scopeinfo.cc
+++ b/src/3rdparty/v8/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, &parameters_);
@@ -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, &parameters_);
@@ -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/3rdparty/v8/src/scopeinfo.h b/src/3rdparty/v8/src/scopeinfo.h
index eeb3047..2ca4503 100644
--- a/src/3rdparty/v8/src/scopeinfo.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/scopes.cc b/src/3rdparty/v8/src/scopes.cc
index 3167c4d..6503d07 100644
--- a/src/3rdparty/v8/src/scopes.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/scopes.h b/src/3rdparty/v8/src/scopes.h
index a141887..41e5f5c 100644
--- a/src/3rdparty/v8/src/scopes.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/variables.cc b/src/3rdparty/v8/src/variables.cc
index d85e1b2..1887935 100644
--- a/src/3rdparty/v8/src/variables.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/variables.h b/src/3rdparty/v8/src/variables.h
index 8b2d869..33561b0 100644
--- a/src/3rdparty/v8/src/variables.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/code-stubs-x64.cc b/src/3rdparty/v8/src/x64/code-stubs-x64.cc
index f62c517..f30221f 100644
--- a/src/3rdparty/v8/src/x64/code-stubs-x64.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/full-codegen-x64.cc b/src/3rdparty/v8/src/x64/full-codegen-x64.cc
index bf640db..b1e5d35 100644
--- a/src/3rdparty/v8/src/x64/full-codegen-x64.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/lithium-codegen-x64.cc b/src/3rdparty/v8/src/x64/lithium-codegen-x64.cc
index 38a8c18..2a95fee 100644
--- a/src/3rdparty/v8/src/x64/lithium-codegen-x64.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/lithium-x64.cc b/src/3rdparty/v8/src/x64/lithium-x64.cc
index 0af2ce4..9e2731f 100644
--- a/src/3rdparty/v8/src/x64/lithium-x64.cc
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/lithium-x64.h b/src/3rdparty/v8/src/x64/lithium-x64.h
index 20a6937..8f1a3d8 100644
--- a/src/3rdparty/v8/src/x64/lithium-x64.h
+++ b/src/3rdparty/v8/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/3rdparty/v8/src/x64/macro-assembler-x64.h b/src/3rdparty/v8/src/x64/macro-assembler-x64.h
index f5f81b1..5caa6cf 100644
--- a/src/3rdparty/v8/src/x64/macro-assembler-x64.h
+++ b/src/3rdparty/v8/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