diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-16 21:24:33 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-08-25 12:05:45 +0000 |
commit | 3c201dd0d95020c4cb4c8ceaf779673d411664e7 (patch) | |
tree | 97d4316e6d2ce54c0fa20600dcd1429f1b8ab789 /src/qml/jsruntime/qv4runtime.cpp | |
parent | 34280d266fe4bed0274b260c0091d50908acd087 (diff) |
Specialize possible direct calls to eval
To avoid additional overhead on most function calls
Change-Id: I2477b91fda6216b508c8331884a02b601f65590c
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4runtime.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a1d480160f..9c5ddece2a 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1023,13 +1023,36 @@ ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint ind if (!o) return engine->throwTypeError(); - 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); - return o->call(callData); } +ReturnedValue Runtime::method_callPossiblyDirectEval(ExecutionEngine *engine, CallData *callData) +{ + Q_ASSERT(callData->thisObject.isUndefined()); + Scope scope(engine); + ScopedObject base(scope); + ExecutionContext &ctx = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context); + ScopedValue func(scope, ctx.getPropertyAndBase(engine->id_eval(), base.getRef())); + if (scope.engine->hasException) + return Encode::undefined(); + + if (base) + callData->thisObject = base; + + FunctionObject *o = func->as<FunctionObject>(); + if (!o) { + QString objectAsString = QStringLiteral("[null]"); + if (base) + objectAsString = ScopedValue(scope, base.asReturnedValue())->toQStringNoThrow(); + QString msg = QStringLiteral("Property 'eval' of object %2 is not a function").arg(objectAsString); + return engine->throwTypeError(msg); + } + + if (o->d() == scope.engine->evalFunction()->d()) + return static_cast<EvalFunction *>(o)->evalCall(callData, true); + + return o->call(callData); +} ReturnedValue Runtime::method_callName(ExecutionEngine *engine, int nameIndex, CallData *callData) { @@ -1038,7 +1061,8 @@ ReturnedValue Runtime::method_callName(ExecutionEngine *engine, int nameIndex, C ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); ScopedObject base(scope); - ScopedValue func(scope, static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).getPropertyAndBase(name, base.getRef())); + ExecutionContext &ctx = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context); + ScopedValue func(scope, ctx.getPropertyAndBase(name, base.getRef())); if (scope.engine->hasException) return Encode::undefined(); @@ -1054,9 +1078,6 @@ ReturnedValue Runtime::method_callName(ExecutionEngine *engine, int nameIndex, C return engine->throwTypeError(msg); } - if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) - return static_cast<EvalFunction *>(o)->evalCall(callData, true); - return o->call(callData); } |