aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-07 08:37:45 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-10 08:18:56 +0000
commit30e3664bf3668bda9a211fe7d1404f8f806dbf7b (patch)
treebd119839af7db0f6f9119401d478b37b44051c8b /src
parenteb2c08f57493aa12850e6cddff2cc3527e7cbfd7 (diff)
Avoid creating a CallContext for simple functions
This cuts out quite a bit of overhead when entering and leaving functions. Change-Id: I32670c98a4087ea3b2d45853d9cabff9066399e8 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4codegen.cpp27
-rw-r--r--src/qml/jsapi/qjsengine.cpp6
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp3
-rw-r--r--src/qml/jsruntime/qv4context.cpp20
-rw-r--r--src/qml/jsruntime/qv4engine.cpp11
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h5
-rw-r--r--src/qml/jsruntime/qv4function_p.h3
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp20
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp14
-rw-r--r--src/qml/jsruntime/qv4object.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp44
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp16
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp3
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp8
15 files changed, 109 insertions, 77 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 52e908d4f3..2a474eaad5 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1263,6 +1263,29 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs)
int scope = 0;
Context *c = _context;
+ // skip the innermost context if it's simple (as the runtime won't
+ // create a context for it
+ if (c->canUseSimpleCall()) {
+ Context::Member m = c->findMember(name);
+ if (m.type != Context::UndefinedMember) {
+ Q_ASSERT((!m.canEscape));
+ Reference r = Reference::fromStackSlot(this, m.index, true /*isLocal*/);
+ if (name == QLatin1String("arguments") || name == QLatin1String("eval")) {
+ r.isArgOrEval = true;
+ if (isLhs && c->isStrict)
+ // ### add correct source location
+ throwSyntaxError(SourceLocation(), QStringLiteral("Variable name may not be eval or arguments in strict mode"));
+ }
+ return r;
+ }
+ const int argIdx = c->findArgument(name);
+ if (argIdx != -1) {
+ Q_ASSERT(!c->argumentsCanEscape && c->usesArgumentsObject != Context::ArgumentsObjectUsed);
+ return Reference::fromArgument(this, argIdx);
+ }
+ c = c->parent;
+ }
+
while (c->parent) {
if (c->forceLookupByName() || (c->isNamedFunctionExpression && c->name == name))
goto loadByName;
@@ -1771,8 +1794,8 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
savedBytecodeGenerator = bytecodeGenerator;
bytecodeGenerator = &bytecode;
- // allocate the js stack frame (Context & js Function)
- bytecodeGenerator->newRegisterArray(2);
+ // allocate the js stack frame (Context & js Function & accumulator)
+ bytecodeGenerator->newRegisterArray(sizeof(EngineBase::JSStackFrame)/sizeof(Value));
int returnAddress = bytecodeGenerator->newRegister();
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 61cc0294e2..5027975d84 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -446,7 +446,11 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
QV4::ScopedValue result(scope);
QV4::Script script(ctx, program, fileName, lineNumber);
- script.strictMode = ctx->d()->v4Function ? ctx->d()->v4Function->isStrict() : false;
+ script.strictMode = false;
+ if (v4->currentStackFrame)
+ script.strictMode = v4->currentStackFrame->v4Function->isStrict();
+ else if (v4->globalCode)
+ script.strictMode = v4->globalCode->isStrict();
script.inheritContext = true;
script.parse();
if (!scope.engine->hasException)
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 5201924bcc..b269b39ff3 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -929,12 +929,11 @@ ReturnedValue ArrayPrototype::method_filter(const BuiltinFunction *b, CallData *
a->arrayReserve(len);
ScopedValue selected(scope);
+ ScopedValue v(scope);
ScopedCallData cData(scope, 3);
cData->thisObject = callData->argument(1);
cData->args[2] = instance;
- ScopedValue v(scope);
-
uint to = 0;
for (uint k = 0; k < len; ++k) {
bool exists;
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index e18d8bce83..ddb5dc4ea5 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -253,24 +253,24 @@ ReturnedValue QV4::ExecutionContext::simpleCall(ExecutionEngine *engine, CallDat
{
Q_ASSERT(function->canUseSimpleFunction());
- ExecutionContextSaver ctxSaver(engine);
-
- CallContext::Data *ctx = engine->memoryManager->allocSimpleCallContext();
-
- ctx->callData = callData;
- ctx->v4Function = function;
- ctx->outer.set(engine, this->d());
+ Value *jsStackTop = engine->jsStackTop;
+ engine->jsStackTop = reinterpret_cast<QV4::Value *>(callData) + 2 + (int)function->nFormals;
for (int i = callData->argc; i < (int)function->nFormals; ++i)
callData->args[i] = Encode::undefined();
- engine->pushContext(ctx);
- Q_ASSERT(engine->current == ctx);
+ ExecutionContext *old = engine->currentContext;
+ engine->currentContext = this;
+ engine->current = d();
ReturnedValue res = Q_V4_PROFILE(engine, function, 0);
if (function->hasQmlDependencies)
QQmlPropertyCapture::registerQmlDependencies(engine, function->compiledFunction);
- engine->memoryManager->freeSimpleCallContext();
+
+ engine->currentContext = old;
+ engine->current = old->d();
+
+ engine->jsStackTop = jsStackTop;
return res;
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index ad090682cc..08f4f29763 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -875,14 +875,13 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
return src;
QUrl base;
- ExecutionContext *c = currentContext;
- while (c) {
- CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->d()->v4Function) {
- base.setUrl(callCtx->d()->v4Function->sourceFile());
+ StackFrame *f = currentStackFrame;
+ while (f) {
+ if (f->v4Function) {
+ base.setUrl(f->v4Function->sourceFile());
break;
}
- c = parentContext(c);
+ f = f->parent;
}
if (base.isEmpty() && globalCode)
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index a713e8eab4..2aa6910a1c 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -65,8 +65,9 @@ namespace QV4 {
struct EngineBase {
struct JSStackFrame {
// callData is directly before this
- QV4::Value jsFunction;
- QV4::Value context;
+ Value jsFunction;
+ Value context;
+ Value accumulator; // ###
// registers follow
};
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 17311ca3c1..a6b2c0c5d0 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -100,7 +100,8 @@ struct Q_QML_EXPORT Function {
inline unsigned int Heap::CallContext::formalParameterCount() const
{
- return v4Function ? v4Function->nFormals : 0;
+ Q_ASSERT(v4Function);
+ return v4Function->nFormals;
}
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index f314d02912..f175e2cd5d 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -359,28 +359,28 @@ ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData)
return Encode::undefined();
CHECK_STACK_LIMITS(v4);
- Scope scope(v4);
- Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that));
+ const ScriptFunction *f = static_cast<const ScriptFunction *>(that);
InternalClass *ic = f->classForConstructor();
- ScopedObject proto(scope, ic->prototype);
- callData->thisObject = v4->newObject(ic, proto);
+ Scope scope(v4);
+ callData->thisObject = v4->memoryManager->allocObject<Object>(ic);
QV4::Function *v4Function = f->function();
Q_ASSERT(v4Function);
- ScopedContext c(scope, f->scope());
- ScopedValue result(scope);
+ Value s = Value::fromHeapObject(f->scope());
+ ExecutionContext *outer = static_cast<ExecutionContext *>(&s);
+ ReturnedValue result;
if (v4Function->canUseSimpleCall)
- result = c->simpleCall(scope.engine, callData, v4Function);
+ result = outer->simpleCall(scope.engine, callData, v4Function);
else
- result = c->call(scope.engine, callData, v4Function, f);
+ result = outer->call(scope.engine, callData, v4Function, f);
if (Q_UNLIKELY(v4->hasException))
return Encode::undefined();
- else if (!result->isObject())
+ else if (!Value::fromReturnedValue(result).isObject())
return callData->thisObject.asReturnedValue();
- return result->asReturnedValue();
+ return result;
}
ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData)
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 8d2d18fa2a..0fa8e1fc3d 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -49,7 +49,7 @@ using namespace QV4;
ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttributes *attrs)
{
ExecutionEngine *engine = o->engine();
- Identifier *name = engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]->identifier;
+ Identifier *name = engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]->identifier;
int i = 0;
Heap::Object *obj = o->d();
while (i < Size && obj) {
@@ -85,7 +85,7 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs
{
Heap::Object *obj = thisObject->d();
ExecutionEngine *engine = thisObject->engine();
- Identifier *name = engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]->identifier;
+ Identifier *name = engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]->identifier;
int i = 0;
while (i < Size && obj) {
classList[i] = obj->internalClass;
@@ -133,7 +133,7 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va
Q_ASSERT(object.isString());
proto = engine->stringPrototype();
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
if (name->equals(engine->id_length())) {
// special case, as the property is on the object itself
l->getter = stringLengthGetter;
@@ -234,7 +234,7 @@ ReturnedValue Lookup::getterFallback(Lookup *l, ExecutionEngine *engine, const V
QV4::ScopedObject o(scope, object.toObject(scope.engine));
if (!o)
return Encode::undefined();
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
return o->get(name);
}
@@ -580,7 +580,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
}
}
Scope scope(engine);
- ScopedString n(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString n(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
return engine->throwReferenceError(n);
}
@@ -697,7 +697,7 @@ bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, co
o = RuntimeHelpers::convertToObject(scope.engine, object);
if (!o) // type error
return false;
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
return o->put(name, value);
}
return o->setLookup(l, value);
@@ -730,7 +730,7 @@ bool Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, c
if (!o)
return false;
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
return o->put(name, value);
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 20d640bb6b..c701e981b7 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -508,7 +508,7 @@ bool Object::setLookup(Managed *m, Lookup *l, const Value &value)
{
Scope scope(static_cast<Object *>(m)->engine());
ScopedObject o(scope, static_cast<Object *>(m));
- ScopedString name(scope, scope.engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
InternalClass *c = o->internalClass();
uint idx = c->find(name);
@@ -1219,7 +1219,7 @@ void Heap::ArrayObject::init(const QStringList &list)
ReturnedValue ArrayObject::getLookup(const Managed *m, Lookup *l)
{
Scope scope(static_cast<const Object *>(m)->engine());
- ScopedString name(scope, scope.engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
if (name->equals(scope.engine->id_length())) {
// special case, as the property is on the object itself
l->getter = Lookup::arrayLengthGetter;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index e81ab783cf..81f1efbff0 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -308,7 +308,7 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
ReturnedValue Runtime::method_closure(ExecutionEngine *engine, int functionId)
{
- QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->current->v4Function->compilationUnit)->runtimeFunctions[functionId];
+ QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeFunctions[functionId];
Q_ASSERT(clos);
return FunctionObject::createScriptFunction(engine->currentContext, clos)->asReturnedValue();
}
@@ -330,7 +330,7 @@ bool Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, c
bool Runtime::method_deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return method_deleteMemberString(engine, base, name);
}
@@ -346,7 +346,7 @@ bool Runtime::method_deleteMemberString(ExecutionEngine *engine, const Value &ba
bool Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return engine->currentContext->deleteProperty(name);
}
@@ -591,7 +591,7 @@ QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Valu
bool Runtime::method_setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject o(scope, object.toObject(engine));
if (!o)
return false;
@@ -741,14 +741,14 @@ ReturnedValue Runtime::method_foreachNextPropertyName(const Value &foreach_itera
bool Runtime::method_setActivationProperty(ExecutionEngine *engine, int nameIndex, const Value &value)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return engine->currentContext->setProperty(name, value);
}
ReturnedValue Runtime::method_getProperty(ExecutionEngine *engine, const Value &object, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject o(scope, object);
if (o)
@@ -768,7 +768,7 @@ ReturnedValue Runtime::method_getProperty(ExecutionEngine *engine, const Value &
ReturnedValue Runtime::method_getActivationProperty(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return engine->currentContext->getProperty(name);
}
@@ -1003,12 +1003,12 @@ ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint ind
Scope scope(engine);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = engine->current->v4Function->compilationUnit->runtimeLookups + index;
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
ScopedFunctionObject o(scope, l->globalGetter(l, engine));
if (!o)
return engine->throwTypeError();
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval()))
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
@@ -1020,7 +1020,7 @@ ReturnedValue Runtime::method_callActivationProperty(ExecutionEngine *engine, in
{
Q_ASSERT(callData->thisObject.isUndefined());
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject base(scope);
ScopedValue func(scope, engine->currentContext->getPropertyAndBase(name, base.getRef()));
@@ -1048,7 +1048,7 @@ ReturnedValue Runtime::method_callActivationProperty(ExecutionEngine *engine, in
ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject baseObject(scope, callData->thisObject);
if (!baseObject) {
Q_ASSERT(!callData->thisObject.isEmpty());
@@ -1075,7 +1075,7 @@ ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameInde
ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
- Lookup *l = engine->current->v4Function->compilationUnit->runtimeLookups + index;
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
Value v;
v = l->getter(l, engine, callData->thisObject);
Object *o = v.objectValue();
@@ -1116,7 +1116,7 @@ ReturnedValue Runtime::method_constructGlobalLookup(ExecutionEngine *engine, uin
Scope scope(engine);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = engine->current->v4Function->compilationUnit->runtimeLookups + index;
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
ScopedObject f(scope, l->globalGetter(l, engine));
if (f)
return f->construct(callData);
@@ -1128,7 +1128,7 @@ ReturnedValue Runtime::method_constructGlobalLookup(ExecutionEngine *engine, uin
ReturnedValue Runtime::method_constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedValue func(scope, engine->currentContext->getProperty(name));
if (scope.engine->hasException)
return Encode::undefined();
@@ -1153,7 +1153,7 @@ ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nam
{
Scope scope(engine);
ScopedObject thisObject(scope, callData->thisObject.toObject(engine));
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
if (scope.engine->hasException)
return Encode::undefined();
@@ -1166,7 +1166,7 @@ ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nam
ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
- Lookup *l = engine->current->v4Function->compilationUnit->runtimeLookups + index;
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
Value v;
v = l->getter(l, engine, callData->thisObject);
Object *o = v.objectValue();
@@ -1215,7 +1215,7 @@ ReturnedValue Runtime::method_typeofValue(ExecutionEngine *engine, const Value &
QV4::ReturnedValue Runtime::method_typeofName(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedValue prop(scope, engine->currentContext->getProperty(name));
// typeof doesn't throw. clear any possible exception
scope.engine->hasException = false;
@@ -1247,7 +1247,7 @@ void Runtime::method_pushCatchScope(NoThrowEngine *engine, int exceptionVarNameI
{
engine->jsAlloca(1); // keep this symmetric with pushWithScope
ExecutionContext *c = engine->currentContext;
- engine->pushContext(c->newCatchContext(engine->current->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0)));
+ engine->pushContext(c->newCatchContext(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0)));
Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
}
@@ -1261,7 +1261,7 @@ void Runtime::method_popScope(NoThrowEngine *engine)
void Runtime::method_declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
engine->currentContext->createMutableBinding(name, deletable);
}
@@ -1273,7 +1273,7 @@ ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *value
ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
Scope scope(engine);
- QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->current->v4Function->compilationUnit)->runtimeClasses[classId];
+ QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeClasses[classId];
ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
{
@@ -1369,7 +1369,7 @@ ReturnedValue Runtime::method_getQmlContext(NoThrowEngine *engine)
ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id)
{
- return static_cast<CompiledData::CompilationUnit*>(engine->current->v4Function->compilationUnit)->runtimeRegularExpressions[id].asReturnedValue();
+ return static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeRegularExpressions[id].asReturnedValue();
}
ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
@@ -1421,7 +1421,7 @@ ReturnedValue Runtime::method_getQmlImportedScripts(NoThrowEngine *engine)
QV4::ReturnedValue Runtime::method_getQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return engine->qmlSingletonWrapper(name);
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index f6cb6fda5d..5e3e71a30f 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -109,7 +109,7 @@ struct Scope {
~Scope() {
#ifndef QT_NO_DEBUG
Q_ASSERT(engine->jsStackTop >= mark);
- Q_ASSERT(engine->currentContext < mark);
+// Q_ASSERT(engine->currentContext < mark);
memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
#endif
#ifdef V4_USE_VALGRIND
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 6297f42c81..97e9a90b5a 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -455,17 +455,21 @@ QV4::ReturnedValue VME::exec(Function *function, const FunctionObject *jsFunctio
const uchar *exceptionHandler = 0;
QV4::Scope scope(engine);
- int nFormals = function->nFormals;
- stack = scope.alloc(function->compiledFunction->nRegisters + nFormals + 2 + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value));
- QV4::Value &accumulator = *stack;
- ++stack;
- memcpy(stack, &engine->current->callData->thisObject, (nFormals + 1)*sizeof(Value));
- stack += nFormals + 1;
+ if (!function->canUseSimpleFunction()) {
+ int nFormals = function->nFormals;
+ stack = scope.alloc(nFormals + 1 + function->compiledFunction->nRegisters + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value));
+ memcpy(stack, &engine->current->callData->thisObject, (nFormals + 1)*sizeof(Value));
+ stack += nFormals + 1;
+ } else {
+ stack = scope.alloc(function->compiledFunction->nRegisters + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value));
+ }
frame.jsFrame = reinterpret_cast<EngineBase::JSStackFrame *>(stack);
frame.jsFrame->context = engine->current;
if (jsFunction)
frame.jsFrame->jsFunction = *jsFunction;
+ QV4::Value &accumulator = frame.jsFrame->accumulator;
+
if (QV4::Debugging::Debugger *debugger = engine->debugger())
debugger->enteringFunction();
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index e00c8d30be..231708da70 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -217,10 +217,11 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b
QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
QV4::Scope scope(v4);
+ QV4::ScopedValue value(scope);
QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue());
callData->thisObject = v4->globalObject;
if (scopeObject()) {
- QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(v4, scopeObject()));
+ value = QV4::QObjectWrapper::wrap(v4, scopeObject());
if (value->isObject())
callData->thisObject = value;
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index ebf8918d31..a3874e4e65 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1908,10 +1908,10 @@ ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *
int length = lastDot - (lastSlash + 1);
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
} else {
- ExecutionContext *parentCtx = scope.engine->currentContext;
+ ExecutionEngine::StackFrame *frame = scope.engine->currentStackFrame;
// The first non-empty source URL in the call stack determines the translation context.
- while (!!parentCtx && context.isEmpty()) {
- if (CompiledData::CompilationUnit *unit = parentCtx->d()->v4Function->compilationUnit) {
+ while (frame && context.isEmpty()) {
+ if (CompiledData::CompilationUnit *unit = frame->v4Function->compilationUnit) {
QString fileName = unit->fileName();
QUrl url(unit->fileName());
if (url.isValid() && url.isRelative()) {
@@ -1923,7 +1923,7 @@ ReturnedValue GlobalExtensions::method_qsTr(const BuiltinFunction *b, CallData *
}
context = QFileInfo(context).baseName();
}
- parentCtx = scope.engine->parentContext(parentCtx);
+ frame = frame->parent;
}
}