diff options
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4generatorobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 14 |
9 files changed, 42 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index c81af767fa..8a6f1044b9 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -57,17 +57,17 @@ DEFINE_MANAGED_VTABLE(CallContext); Heap::CallContext *ExecutionContext::newBlockContext(CppStackFrame *frame, int blockIndex) { Function *function = frame->v4Function; - Heap::ExecutionContext *outer = static_cast<Heap::ExecutionContext *>(frame->context()->m()); Heap::InternalClass *ic = function->compilationUnit->runtimeBlocks.at(blockIndex); int nLocals = ic->size; size_t requiredMemory = sizeof(CallContext::Data) - sizeof(Value) + sizeof(Value) * nLocals; - ExecutionEngine *v4 = outer->internalClass->engine; + ExecutionEngine *v4 = function->internalClass->engine; Heap::CallContext *c = v4->memoryManager->allocManaged<CallContext>(requiredMemory, ic); c->init(); c->type = Heap::ExecutionContext::Type_BlockContext; + Heap::ExecutionContext *outer = static_cast<Heap::ExecutionContext *>(frame->context()->m()); c->outer.set(v4, outer); c->function.set(v4, static_cast<Heap::FunctionObject *>(frame->jsFrame->function.m())); @@ -137,7 +137,6 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) ScopedContext ctx(scope, this); while (ctx) { switch (ctx->d()->type) { - case Heap::ExecutionContext::Type_BlockContext: case Heap::ExecutionContext::Type_CallContext: if (!activation) { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d()); @@ -158,6 +157,8 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) activation = ctx->d()->activation; break; } + case Heap::ExecutionContext::Type_BlockContext: + // never create activation records on block contexts default: break; } @@ -169,7 +170,8 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) ScopedProperty desc(scope); PropertyAttributes attrs(Attr_Data); attrs.setConfigurable(deletable); - activation->__defineOwnProperty__(scope.engine, name, desc, attrs); + if (!activation->__defineOwnProperty__(scope.engine, name, desc, attrs)) + scope.engine->throwTypeError(); } bool ExecutionContext::deleteProperty(String *name) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 2a37f3ee47..b703f6e4f3 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -585,6 +585,7 @@ void ExecutionEngine::initRootContext() r->d_unchecked()->init(Heap::ExecutionContext::Type_GlobalContext); r->d()->activation.set(this, globalObject->d()); jsObjects[RootContext] = r; + jsObjects[ScriptContext] = r; jsObjects[IntegerNull] = Encode((int)0); } diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index e1b1ba38ca..e8218d0d1c 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -161,6 +161,7 @@ public: enum JSObjects { RootContext, + ScriptContext, IntegerNull, // Has to come after the RootContext to make the context stack safe ObjectProto, SymbolProto, @@ -223,6 +224,8 @@ public: enum { NTypedArrayTypes = 9 }; // == TypedArray::NValues, avoid header dependency ExecutionContext *rootContext() const { return reinterpret_cast<ExecutionContext *>(jsObjects + RootContext); } + ExecutionContext *scriptContext() const { return reinterpret_cast<ExecutionContext *>(jsObjects + ScriptContext); } + void setScriptContext(ReturnedValue c) { jsObjects[ScriptContext] = c; } FunctionObject *objectCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Object_Ctor); } FunctionObject *stringCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + String_Ctor); } FunctionObject *symbolCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Symbol_Ctor); } diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index c556bdb008..8a70715728 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -270,7 +270,7 @@ ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Val return Encode::undefined(); Function *vmf = compilationUnit->linkToEngine(engine); - ExecutionContext *global = engine->rootContext(); + ExecutionContext *global = engine->scriptContext(); return Encode(FunctionObject::createScriptFunction(global, vmf)); } diff --git a/src/qml/jsruntime/qv4generatorobject.cpp b/src/qml/jsruntime/qv4generatorobject.cpp index 4339a95f45..c91e182b54 100644 --- a/src/qml/jsruntime/qv4generatorobject.cpp +++ b/src/qml/jsruntime/qv4generatorobject.cpp @@ -63,7 +63,7 @@ ReturnedValue GeneratorFunctionCtor::callAsConstructor(const FunctionObject *f, return Encode::undefined(); Function *vmf = compilationUnit->linkToEngine(engine); - ExecutionContext *global = engine->rootContext(); + ExecutionContext *global = engine->scriptContext(); return Encode(GeneratorFunction::create(global, vmf)); } diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index b68f3db3cf..47a6734eda 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -351,7 +351,7 @@ ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc, if (!directCall) { // the context for eval should be the global scope - ctx = v4->rootContext(); + ctx = v4->scriptContext(); } String *scode = argv[0].stringValue(); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 05b0ddf753..8bf6d6b73f 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1230,6 +1230,22 @@ ReturnedValue Runtime::method_createBlockContext(ExecutionContext *parent, int i return parent->newBlockContext(e->currentStackFrame, index)->asReturnedValue(); } +ReturnedValue Runtime::method_createScriptContext(ExecutionEngine *engine, int index) +{ + Q_ASSERT(engine->currentStackFrame->context()->d()->type == Heap::ExecutionContext::Type_GlobalContext || + engine->currentStackFrame->context()->d()->type == Heap::ExecutionContext::Type_QmlContext); + ReturnedValue c = ExecutionContext::newBlockContext(engine->currentStackFrame, index)->asReturnedValue(); + engine->setScriptContext(c); + return c; +} + +ReturnedValue Runtime::method_popScriptContext(ExecutionEngine *engine) +{ + ReturnedValue root = engine->rootContext()->asReturnedValue(); + engine->setScriptContext(root); + return root; +} + void Runtime::method_declareVar(ExecutionEngine *engine, bool deletable, int nameIndex) { diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 4d4112bf0c..f707de00f8 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -127,6 +127,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { F(ReturnedValue, createWithContext, (ExecutionContext *parent, const Value &o)) \ F(ReturnedValue, createCatchContext, (ExecutionContext *parent, int blockIndex, int exceptionVarNameIndex)) \ F(ReturnedValue, createBlockContext, (ExecutionContext *parent, int index)) \ + F(ReturnedValue, createScriptContext, (ExecutionEngine *engine, int index)) \ + F(ReturnedValue, popScriptContext, (ExecutionEngine *engine)) \ \ /* closures */ \ F(ReturnedValue, closure, (ExecutionEngine *engine, int functionId)) \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 7f27619d08..3fadb6e670 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -929,11 +929,19 @@ QV4::ReturnedValue VME::interpret(CppStackFrame &frame, const uchar *code) MOTH_END_INSTR(PushWithContext) MOTH_BEGIN_INSTR(PushBlockContext) - STACK_VALUE(reg) = STACK_VALUE(CallData::Context); - ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context); - STACK_VALUE(CallData::Context) = Runtime::method_createBlockContext(c, index); + STACK_VALUE(reg) = STACK_VALUE(CallData::Context); + ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context); + STACK_VALUE(CallData::Context) = Runtime::method_createBlockContext(c, index); MOTH_END_INSTR(PushBlockContext) + MOTH_BEGIN_INSTR(PushScriptContext) + STACK_VALUE(CallData::Context) = Runtime::method_createScriptContext(engine, index); + MOTH_END_INSTR(PushScriptContext) + + MOTH_BEGIN_INSTR(PopScriptContext) + STACK_VALUE(CallData::Context) = Runtime::method_popScriptContext(engine); + MOTH_END_INSTR(PopScriptContext) + MOTH_BEGIN_INSTR(PopContext) STACK_VALUE(CallData::Context) = STACK_VALUE(reg); MOTH_END_INSTR(PopContext) |