| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/jsruntime/qv4functionobject.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /**************************************************************************** | - | ||||||||||||
| 2 | ** | - | ||||||||||||
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||
| 4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||
| 5 | ** | - | ||||||||||||
| 6 | ** This file is part of the QtQml module of the Qt Toolkit. | - | ||||||||||||
| 7 | ** | - | ||||||||||||
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||
| 9 | ** Commercial License Usage | - | ||||||||||||
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||
| 11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||
| 12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||
| 16 | ** | - | ||||||||||||
| 17 | ** GNU Lesser General Public License Usage | - | ||||||||||||
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||
| 19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||
| 21 | ** packaging of this file. Please review the following information to | - | ||||||||||||
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||
| 24 | ** | - | ||||||||||||
| 25 | ** GNU General Public License Usage | - | ||||||||||||
| 26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||
| 28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||
| 31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||
| 32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||
| 35 | ** | - | ||||||||||||
| 36 | ** $QT_END_LICENSE$ | - | ||||||||||||
| 37 | ** | - | ||||||||||||
| 38 | ****************************************************************************/ | - | ||||||||||||
| 39 | - | |||||||||||||
| 40 | #include "qv4object_p.h" | - | ||||||||||||
| 41 | #include "qv4objectproto_p.h" | - | ||||||||||||
| 42 | #include "qv4stringobject_p.h" | - | ||||||||||||
| 43 | #include "qv4function_p.h" | - | ||||||||||||
| 44 | #include "qv4symbol_p.h" | - | ||||||||||||
| 45 | #include <private/qv4mm_p.h> | - | ||||||||||||
| 46 | - | |||||||||||||
| 47 | #include "qv4arrayobject_p.h" | - | ||||||||||||
| 48 | #include "qv4scopedvalue_p.h" | - | ||||||||||||
| 49 | #include "qv4argumentsobject_p.h" | - | ||||||||||||
| 50 | - | |||||||||||||
| 51 | #include <private/qqmljsengine_p.h> | - | ||||||||||||
| 52 | #include <private/qqmljslexer_p.h> | - | ||||||||||||
| 53 | #include <private/qqmljsparser_p.h> | - | ||||||||||||
| 54 | #include <private/qqmljsast_p.h> | - | ||||||||||||
| 55 | #include <private/qqmljavascriptexpression_p.h> | - | ||||||||||||
| 56 | #include <private/qqmlengine_p.h> | - | ||||||||||||
| 57 | #include <qv4runtimecodegen_p.h> | - | ||||||||||||
| 58 | #include "private/qlocale_tools_p.h" | - | ||||||||||||
| 59 | #include "private/qqmlbuiltinfunctions_p.h" | - | ||||||||||||
| 60 | #include <private/qv4jscall_p.h> | - | ||||||||||||
| 61 | #include <private/qv4vme_moth_p.h> | - | ||||||||||||
| 62 | - | |||||||||||||
| 63 | #include <QtCore/QDebug> | - | ||||||||||||
| 64 | #include <algorithm> | - | ||||||||||||
| 65 | #include "qv4alloca_p.h" | - | ||||||||||||
| 66 | #include "qv4profiling_p.h" | - | ||||||||||||
| 67 | - | |||||||||||||
| 68 | using namespace QV4; | - | ||||||||||||
| 69 | - | |||||||||||||
| 70 | - | |||||||||||||
| 71 | DEFINE_OBJECT_VTABLE(FunctionObject); | - | ||||||||||||
| 72 | - | |||||||||||||
| 73 | void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, | - | ||||||||||||
| 74 | ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc)) | - | ||||||||||||
| 75 | { | - | ||||||||||||
| 76 | jsCall = code; | - | ||||||||||||
| 77 | jsConstruct = QV4::FunctionObject::virtualCallAsConstructor; | - | ||||||||||||
| 78 | - | |||||||||||||
| 79 | Object::init(); | - | ||||||||||||
| 80 | this->scope.set(scope->engine(), scope->d()); | - | ||||||||||||
| 81 | Scope s(scope->engine()); | - | ||||||||||||
| 82 | ScopedFunctionObject f(s, this); | - | ||||||||||||
| 83 | if (name)
| 99063-34321871 | ||||||||||||
| 84 | f->setName(name); executed 34317055 times by 153 tests: f->setName(name);Executed by:
| 34317055 | ||||||||||||
| 85 | } executed 34351957 times by 153 tests: end of blockExecuted by:
| 34351957 | ||||||||||||
| 86 | - | |||||||||||||
| 87 | void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, bool createProto) | - | ||||||||||||
| 88 | { | - | ||||||||||||
| 89 | jsCall = vtable()->call; | - | ||||||||||||
| 90 | jsConstruct = vtable()->callAsConstructor; | - | ||||||||||||
| 91 | - | |||||||||||||
| 92 | Object::init(); | - | ||||||||||||
| 93 | this->scope.set(scope->engine(), scope->d()); | - | ||||||||||||
| 94 | Scope s(scope->engine()); | - | ||||||||||||
| 95 | ScopedFunctionObject f(s, this); | - | ||||||||||||
| 96 | if (name)
| 180222-3180157 | ||||||||||||
| 97 | f->setName(name); executed 3178928 times by 153 tests: f->setName(name);Executed by:
| 3178928 | ||||||||||||
| 98 | - | |||||||||||||
| 99 | if (createProto)
| 0-3359402 | ||||||||||||
| 100 | f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); never executed: f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); | 0 | ||||||||||||
| 101 | } executed 3358433 times by 153 tests: end of blockExecuted by:
| 3358433 | ||||||||||||
| 102 | - | |||||||||||||
| 103 | - | |||||||||||||
| 104 | - | |||||||||||||
| 105 | void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function, bool createProto) | - | ||||||||||||
| 106 | { | - | ||||||||||||
| 107 | jsCall = vtable()->call; | - | ||||||||||||
| 108 | jsConstruct = vtable()->callAsConstructor; | - | ||||||||||||
| 109 | - | |||||||||||||
| 110 | Object::init(); | - | ||||||||||||
| 111 | setFunction(function); | - | ||||||||||||
| 112 | this->scope.set(scope->engine(), scope->d()); | - | ||||||||||||
| 113 | Scope s(scope->engine()); | - | ||||||||||||
| 114 | ScopedString name(s, function->name()); | - | ||||||||||||
| 115 | ScopedFunctionObject f(s, this); | - | ||||||||||||
| 116 | if (name)
| 0-90 | ||||||||||||
| 117 | f->setName(name); executed 90 times by 8 tests: f->setName(name);Executed by:
| 90 | ||||||||||||
| 118 | - | |||||||||||||
| 119 | if (createProto)
| 0-90 | ||||||||||||
| 120 | f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); never executed: f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); | 0 | ||||||||||||
| 121 | } executed 90 times by 8 tests: end of blockExecuted by:
| 90 | ||||||||||||
| 122 | - | |||||||||||||
| 123 | void Heap::FunctionObject::init(QV4::ExecutionContext *scope, const QString &name, bool createProto) | - | ||||||||||||
| 124 | { | - | ||||||||||||
| 125 | Scope valueScope(scope); | - | ||||||||||||
| 126 | ScopedString s(valueScope, valueScope.engine->newString(name)); | - | ||||||||||||
| 127 | init(scope, s, createProto); | - | ||||||||||||
| 128 | } executed 3083351 times by 153 tests: end of blockExecuted by:
| 3083351 | ||||||||||||
| 129 | - | |||||||||||||
| 130 | void Heap::FunctionObject::init() | - | ||||||||||||
| 131 | { | - | ||||||||||||
| 132 | jsCall = vtable()->call; | - | ||||||||||||
| 133 | jsConstruct = vtable()->callAsConstructor; | - | ||||||||||||
| 134 | - | |||||||||||||
| 135 | Object::init(); | - | ||||||||||||
| 136 | this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d()); | - | ||||||||||||
| 137 | Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()->propertyKey()) == Index_Prototype); | - | ||||||||||||
| 138 | setProperty(internalClass->engine, Index_Prototype, Primitive::undefinedValue()); | - | ||||||||||||
| 139 | } executed 1621011 times by 153 tests: end of blockExecuted by:
| 1621011 | ||||||||||||
| 140 | - | |||||||||||||
| 141 | void Heap::FunctionObject::setFunction(Function *f) | - | ||||||||||||
| 142 | { | - | ||||||||||||
| 143 | if (f) {
| 44-1522818 | ||||||||||||
| 144 | function = f; | - | ||||||||||||
| 145 | function->compilationUnit->addref(); | - | ||||||||||||
| 146 | } executed 1524066 times by 62 tests: end of blockExecuted by:
| 1524066 | ||||||||||||
| 147 | } executed 1524161 times by 62 tests: end of blockExecuted by:
| 1524161 | ||||||||||||
| 148 | void Heap::FunctionObject::destroy() | - | ||||||||||||
| 149 | { | - | ||||||||||||
| 150 | if (function)
| 1525791-37877975 | ||||||||||||
| 151 | function->compilationUnit->release(); executed 1525800 times by 62 tests: function->compilationUnit->release();Executed by:
| 1525800 | ||||||||||||
| 152 | Object::destroy(); | - | ||||||||||||
| 153 | } executed 39395632 times by 153 tests: end of blockExecuted by:
| 39395632 | ||||||||||||
| 154 | - | |||||||||||||
| 155 | void FunctionObject::createDefaultPrototypeProperty(uint protoSlot, uint protoConstructorSlot) | - | ||||||||||||
| 156 | { | - | ||||||||||||
| 157 | Scope s(this); | - | ||||||||||||
| 158 | - | |||||||||||||
| 159 | Q_ASSERT(internalClass() && internalClass()->find(s.engine->id_prototype()->propertyKey()) == protoSlot); | - | ||||||||||||
| 160 | Q_ASSERT(s.engine->internalClasses(EngineBase::Class_ObjectProto)->find(s.engine->id_constructor()->propertyKey()) == protoConstructorSlot); | - | ||||||||||||
| 161 | - | |||||||||||||
| 162 | ScopedObject proto(s, s.engine->newObject(s.engine->internalClasses(EngineBase::Class_ObjectProto))); | - | ||||||||||||
| 163 | proto->setProperty(protoConstructorSlot, d()); | - | ||||||||||||
| 164 | setProperty(protoSlot, proto); | - | ||||||||||||
| 165 | } executed 1523507 times by 62 tests: end of blockExecuted by:
| 1523507 | ||||||||||||
| 166 | - | |||||||||||||
| 167 | ReturnedValue FunctionObject::name() const | - | ||||||||||||
| 168 | { | - | ||||||||||||
| 169 | return get(scope()->internalClass->engine->id_name()); executed 891471 times by 153 tests: return get(scope()->internalClass->engine->id_name());Executed by:
| 891471 | ||||||||||||
| 170 | } | - | ||||||||||||
| 171 | - | |||||||||||||
| 172 | ReturnedValue FunctionObject::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) | - | ||||||||||||
| 173 | { | - | ||||||||||||
| 174 | return f->engine()->throwTypeError(); executed 302 times by 1 test: return f->engine()->throwTypeError();Executed by:
| 302 | ||||||||||||
| 175 | } | - | ||||||||||||
| 176 | - | |||||||||||||
| 177 | ReturnedValue FunctionObject::virtualCall(const FunctionObject *, const Value *, const Value *, int) | - | ||||||||||||
| 178 | { | - | ||||||||||||
| 179 | return Encode::undefined(); executed 16 times by 1 test: return Encode::undefined();Executed by:
| 16 | ||||||||||||
| 180 | } | - | ||||||||||||
| 181 | - | |||||||||||||
| 182 | Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function) | - | ||||||||||||
| 183 | { | - | ||||||||||||
| 184 | return scope->engine()->memoryManager->allocate<ScriptFunction>(scope, function); executed 1508812 times by 62 tests: return scope->engine()->memoryManager->allocate<ScriptFunction>(scope, function);Executed by:
| 1508812 | ||||||||||||
| 185 | } | - | ||||||||||||
| 186 | - | |||||||||||||
| 187 | Heap::FunctionObject *FunctionObject::createConstructorFunction(ExecutionContext *scope, Function *function, bool isDerivedConstructor) | - | ||||||||||||
| 188 | { | - | ||||||||||||
| 189 | if (!function) {
| 660-8353 | ||||||||||||
| 190 | Heap::DefaultClassConstructorFunction *c = scope->engine()->memoryManager->allocate<DefaultClassConstructorFunction>(scope); | - | ||||||||||||
| 191 | c->isDerivedConstructor = isDerivedConstructor; | - | ||||||||||||
| 192 | return c; executed 8358 times by 1 test: return c;Executed by:
| 8358 | ||||||||||||
| 193 | } | - | ||||||||||||
| 194 | Heap::ConstructorFunction *c = scope->engine()->memoryManager->allocate<ConstructorFunction>(scope, function); | - | ||||||||||||
| 195 | c->isDerivedConstructor = isDerivedConstructor; | - | ||||||||||||
| 196 | return c; executed 660 times by 1 test: return c;Executed by:
| 660 | ||||||||||||
| 197 | } | - | ||||||||||||
| 198 | - | |||||||||||||
| 199 | Heap::FunctionObject *FunctionObject::createMemberFunction(ExecutionContext *scope, Function *function) | - | ||||||||||||
| 200 | { | - | ||||||||||||
| 201 | return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function); executed 4735 times by 1 test: return scope->engine()->memoryManager->allocate<MemberFunction>(scope, function);Executed by:
| 4735 | ||||||||||||
| 202 | } | - | ||||||||||||
| 203 | - | |||||||||||||
| 204 | Heap::FunctionObject *FunctionObject::createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount) | - | ||||||||||||
| 205 | { | - | ||||||||||||
| 206 | Scope scope(engine); | - | ||||||||||||
| 207 | ScopedString name(scope, nameOrSymbol); | - | ||||||||||||
| 208 | if (!name)
| 494366-33854654 | ||||||||||||
| 209 | name = engine->newString(QChar::fromLatin1('[') + nameOrSymbol->toQString().midRef(1) + QChar::fromLatin1(']')); executed 493746 times by 153 tests: name = engine->newString(QChar::fromLatin1('[') + nameOrSymbol->toQString().midRef(1) + QChar::fromLatin1(']'));Executed by:
| 493746 | ||||||||||||
| 210 | - | |||||||||||||
| 211 | ScopedFunctionObject function(scope, engine->memoryManager->allocate<FunctionObject>(engine->rootContext(), name, code)); | - | ||||||||||||
| 212 | function->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(argumentCount)); | - | ||||||||||||
| 213 | return function->d(); executed 34288646 times by 153 tests: return function->d();Executed by:
| 34288646 | ||||||||||||
| 214 | } | - | ||||||||||||
| 215 | - | |||||||||||||
| 216 | bool FunctionObject::isBinding() const | - | ||||||||||||
| 217 | { | - | ||||||||||||
| 218 | return d()->vtable() == QQmlBindingFunction::staticVTable(); executed 742 times by 13 tests: return d()->vtable() == QQmlBindingFunction::staticVTable();Executed by:
| 742 | ||||||||||||
| 219 | } | - | ||||||||||||
| 220 | - | |||||||||||||
| 221 | bool FunctionObject::isBoundFunction() const | - | ||||||||||||
| 222 | { | - | ||||||||||||
| 223 | return d()->vtable() == BoundFunction::staticVTable(); executed 4289625 times by 17 tests: return d()->vtable() == BoundFunction::staticVTable();Executed by:
| 4289625 | ||||||||||||
| 224 | } | - | ||||||||||||
| 225 | - | |||||||||||||
| 226 | QQmlSourceLocation FunctionObject::sourceLocation() const | - | ||||||||||||
| 227 | { | - | ||||||||||||
| 228 | return d()->function->sourceLocation(); never executed: return d()->function->sourceLocation(); | 0 | ||||||||||||
| 229 | } | - | ||||||||||||
| 230 | - | |||||||||||||
| 231 | DEFINE_OBJECT_VTABLE(FunctionCtor); | - | ||||||||||||
| 232 | - | |||||||||||||
| 233 | void Heap::FunctionCtor::init(QV4::ExecutionContext *scope) | - | ||||||||||||
| 234 | { | - | ||||||||||||
| 235 | Heap::FunctionObject::init(scope, QStringLiteral("Function")); executed 98685 times by 153 tests: return qstring_literal_temp;Executed by:
| 98685 | ||||||||||||
| 236 | } executed 98961 times by 153 tests: end of blockExecuted by:
| 98961 | ||||||||||||
| 237 | - | |||||||||||||
| 238 | // 15.3.2 | - | ||||||||||||
| 239 | QQmlRefPointer<CompiledData::CompilationUnit> FunctionCtor::parse(ExecutionEngine *engine, const Value *argv, int argc, Type t) | - | ||||||||||||
| 240 | { | - | ||||||||||||
| 241 | QString arguments; | - | ||||||||||||
| 242 | QString body; | - | ||||||||||||
| 243 | if (argc > 0) {
| 180-818 | ||||||||||||
| 244 | for (int i = 0, ei = argc - 1; i < ei; ++i) {
| 548-820 | ||||||||||||
| 245 | if (i)
| 174-374 | ||||||||||||
| 246 | arguments += QLatin1String(", "); executed 176 times by 1 test: arguments += QLatin1String(", ");Executed by:
| 176 | ||||||||||||
| 247 | arguments += argv[i].toQString(); | - | ||||||||||||
| 248 | } executed 547 times by 2 tests: end of blockExecuted by:
| 547 | ||||||||||||
| 249 | body = argv[argc - 1].toQString(); | - | ||||||||||||
| 250 | } executed 825 times by 2 tests: end of blockExecuted by:
| 825 | ||||||||||||
| 251 | if (engine->hasException)
| 12-993 | ||||||||||||
| 252 | return nullptr; executed 12 times by 1 test: return nullptr;Executed by:
| 12 | ||||||||||||
| 253 | - | |||||||||||||
| 254 | QString function = (t == Type_Function ? QLatin1String("function anonymous(") : QLatin1String("function* anonymous(")) + arguments + QLatin1String("\n){") + body + QLatin1String("\n}");
| 120-867 | ||||||||||||
| 255 | - | |||||||||||||
| 256 | QQmlJS::Engine ee; | - | ||||||||||||
| 257 | QQmlJS::Lexer lexer(&ee); | - | ||||||||||||
| 258 | lexer.setCode(function, 1, false); | - | ||||||||||||
| 259 | QQmlJS::Parser parser(&ee); | - | ||||||||||||
| 260 | - | |||||||||||||
| 261 | const bool parsed = parser.parseExpression(); | - | ||||||||||||
| 262 | - | |||||||||||||
| 263 | if (!parsed) {
| 36-952 | ||||||||||||
| 264 | engine->throwSyntaxError(QLatin1String("Parse error")); | - | ||||||||||||
| 265 | return nullptr; executed 36 times by 1 test: return nullptr;Executed by:
| 36 | ||||||||||||
| 266 | } | - | ||||||||||||
| 267 | - | |||||||||||||
| 268 | QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(parser.rootNode()); | - | ||||||||||||
| 269 | if (!fe) {
| 0-951 | ||||||||||||
| 270 | engine->throwSyntaxError(QLatin1String("Parse error")); | - | ||||||||||||
| 271 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||
| 272 | } | - | ||||||||||||
| 273 | - | |||||||||||||
| 274 | Compiler::Module module(engine->debugger() != nullptr); | - | ||||||||||||
| 275 | - | |||||||||||||
| 276 | Compiler::JSUnitGenerator jsGenerator(&module); | - | ||||||||||||
| 277 | RuntimeCodegen cg(engine, &jsGenerator, false); | - | ||||||||||||
| 278 | cg.generateFromFunctionExpression(QString(), function, fe, &module); | - | ||||||||||||
| 279 | - | |||||||||||||
| 280 | if (engine->hasException)
| 16-935 | ||||||||||||
| 281 | return nullptr; executed 16 times by 1 test: return nullptr;Executed by:
| 16 | ||||||||||||
| 282 | - | |||||||||||||
| 283 | return cg.generateCompilationUnit(); executed 934 times by 2 tests: return cg.generateCompilationUnit();Executed by:
| 934 | ||||||||||||
| 284 | } | - | ||||||||||||
| 285 | - | |||||||||||||
| 286 | ReturnedValue FunctionCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) | - | ||||||||||||
| 287 | { | - | ||||||||||||
| 288 | ExecutionEngine *engine = f->engine(); | - | ||||||||||||
| 289 | - | |||||||||||||
| 290 | QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = parse(engine, argv, argc, Type_Function); | - | ||||||||||||
| 291 | if (engine->hasException)
| 56-823 | ||||||||||||
| 292 | return Encode::undefined(); executed 56 times by 1 test: return Encode::undefined();Executed by:
| 56 | ||||||||||||
| 293 | - | |||||||||||||
| 294 | Function *vmf = compilationUnit->linkToEngine(engine); | - | ||||||||||||
| 295 | ExecutionContext *global = engine->scriptContext(); | - | ||||||||||||
| 296 | return Encode(FunctionObject::createScriptFunction(global, vmf)); executed 821 times by 2 tests: return Encode(FunctionObject::createScriptFunction(global, vmf));Executed by:
| 821 | ||||||||||||
| 297 | } | - | ||||||||||||
| 298 | - | |||||||||||||
| 299 | // 15.3.1: This is equivalent to new Function(...) | - | ||||||||||||
| 300 | ReturnedValue FunctionCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc) | - | ||||||||||||
| 301 | { | - | ||||||||||||
| 302 | return virtualCallAsConstructor(f, argv, argc, f); executed 516 times by 1 test: return virtualCallAsConstructor(f, argv, argc, f);Executed by:
| 516 | ||||||||||||
| 303 | } | - | ||||||||||||
| 304 | - | |||||||||||||
| 305 | DEFINE_OBJECT_VTABLE(FunctionPrototype); | - | ||||||||||||
| 306 | - | |||||||||||||
| 307 | void Heap::FunctionPrototype::init() | - | ||||||||||||
| 308 | { | - | ||||||||||||
| 309 | Heap::FunctionObject::init(); | - | ||||||||||||
| 310 | } executed 98817 times by 153 tests: end of blockExecuted by:
| 98817 | ||||||||||||
| 311 | - | |||||||||||||
| 312 | void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor) | - | ||||||||||||
| 313 | { | - | ||||||||||||
| 314 | Scope scope(engine); | - | ||||||||||||
| 315 | ScopedObject o(scope); | - | ||||||||||||
| 316 | - | |||||||||||||
| 317 | ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(1)); | - | ||||||||||||
| 318 | ctor->defineReadonlyProperty(engine->id_prototype(), (o = this)); | - | ||||||||||||
| 319 | - | |||||||||||||
| 320 | defineReadonlyConfigurableProperty(engine->id_name(), *engine->id_empty()); | - | ||||||||||||
| 321 | defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0)); | - | ||||||||||||
| 322 | defineDefaultProperty(QStringLiteral("constructor"), (o = ctor)); executed 98860 times by 153 tests: return qstring_literal_temp;Executed by:
| 98860 | ||||||||||||
| 323 | defineDefaultProperty(engine->id_toString(), method_toString, 0); | - | ||||||||||||
| 324 | defineDefaultProperty(QStringLiteral("apply"), method_apply, 2); executed 99069 times by 153 tests: return qstring_literal_temp;Executed by:
| 99069 | ||||||||||||
| 325 | defineDefaultProperty(QStringLiteral("call"), method_call, 1); executed 99094 times by 153 tests: return qstring_literal_temp;Executed by:
| 99094 | ||||||||||||
| 326 | defineDefaultProperty(QStringLiteral("bind"), method_bind, 1); executed 99066 times by 153 tests: return qstring_literal_temp;Executed by:
| 99066 | ||||||||||||
| 327 | defineDefaultProperty(engine->symbol_hasInstance(), method_hasInstance, 1, Attr_ReadOnly); | - | ||||||||||||
| 328 | } executed 99035 times by 153 tests: end of blockExecuted by:
| 99035 | ||||||||||||
| 329 | - | |||||||||||||
| 330 | ReturnedValue FunctionPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||
| 331 | { | - | ||||||||||||
| 332 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||
| 333 | const FunctionObject *fun = thisObject->as<FunctionObject>(); | - | ||||||||||||
| 334 | if (!fun)
| 22-1306 | ||||||||||||
| 335 | return v4->throwTypeError(); executed 22 times by 2 tests: return v4->throwTypeError();Executed by:
| 22 | ||||||||||||
| 336 | - | |||||||||||||
| 337 | const Scope scope(fun->engine()); | - | ||||||||||||
| 338 | const ScopedString scopedFunctionName(scope, fun->name()); | - | ||||||||||||
| 339 | const QString functionName(scopedFunctionName ? scopedFunctionName->toQString() : QString()); | - | ||||||||||||
| 340 | QString functionAsString = QStringLiteral("function"); | - | ||||||||||||
| 341 | - | |||||||||||||
| 342 | // If fun->name() is empty, then there is no function name | - | ||||||||||||
| 343 | // to append because the function is anonymous. | - | ||||||||||||
| 344 | if (!functionName.isEmpty())
| 600-706 | ||||||||||||
| 345 | functionAsString.append(QLatin1Char(' ') + functionName); executed 600 times by 4 tests: functionAsString.append(QLatin1Char(' ') + functionName);Executed by:
| 600 | ||||||||||||
| 346 | - | |||||||||||||
| 347 | functionAsString.append(QStringLiteral("() { [code] }")); executed 1306 times by 4 tests: return qstring_literal_temp;Executed by:
| 1306 | ||||||||||||
| 348 | - | |||||||||||||
| 349 | return Encode(v4->newString(functionAsString)); executed 1306 times by 4 tests: return Encode(v4->newString(functionAsString));Executed by:
| 1306 | ||||||||||||
| 350 | } | - | ||||||||||||
| 351 | - | |||||||||||||
| 352 | ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
| 353 | { | - | ||||||||||||
| 354 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||
| 355 | const FunctionObject *f = thisObject->as<FunctionObject>(); | - | ||||||||||||
| 356 | if (!f)
| 19-259 | ||||||||||||
| 357 | return v4->throwTypeError(); executed 19 times by 1 test: return v4->throwTypeError();Executed by:
| 19 | ||||||||||||
| 358 | thisObject = argc ? argv : nullptr;
| 28-231 | ||||||||||||
| 359 | if (argc < 2 || argv[1].isNullOrUndefined())
| 0-142 | ||||||||||||
| 360 | return f->call(thisObject, argv, 0); executed 141 times by 1 test: return f->call(thisObject, argv, 0);Executed by:
| 141 | ||||||||||||
| 361 | - | |||||||||||||
| 362 | Object *arr = argv[1].objectValue(); | - | ||||||||||||
| 363 | if (!arr)
| 8-108 | ||||||||||||
| 364 | return v4->throwTypeError(); executed 8 times by 1 test: return v4->throwTypeError();Executed by:
| 8 | ||||||||||||
| 365 | - | |||||||||||||
| 366 | uint len = arr->getLength(); | - | ||||||||||||
| 367 | - | |||||||||||||
| 368 | Scope scope(v4); | - | ||||||||||||
| 369 | Value *arguments = scope.alloc(len); | - | ||||||||||||
| 370 | if (len) {
| 10-98 | ||||||||||||
| 371 | if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
| 0-84 | ||||||||||||
| 372 | QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>(); | - | ||||||||||||
| 373 | int l = qMin(len, (uint)a->d()->context->argc()); | - | ||||||||||||
| 374 | memcpy(arguments, a->d()->context->args(), l*sizeof(Value)); | - | ||||||||||||
| 375 | for (quint32 i = l; i < len; ++i)
| 0-14 | ||||||||||||
| 376 | arguments[i] = Primitive::undefinedValue(); never executed: arguments[i] = Primitive::undefinedValue(); | 0 | ||||||||||||
| 377 | } else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) { executed 14 times by 1 test: end of blockExecuted by:
| 0-84 | ||||||||||||
| 378 | auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData()); | - | ||||||||||||
| 379 | uint alen = sad ? sad->values.size : 0;
| 6-78 | ||||||||||||
| 380 | if (alen > len)
| 0-84 | ||||||||||||
| 381 | alen = len; never executed: alen = len; | 0 | ||||||||||||
| 382 | for (uint i = 0; i < alen; ++i)
| 84-226 | ||||||||||||
| 383 | arguments[i] = sad->data(i); executed 226 times by 1 test: arguments[i] = sad->data(i);Executed by:
| 226 | ||||||||||||
| 384 | for (quint32 i = alen; i < len; ++i)
| 84-406 | ||||||||||||
| 385 | arguments[i] = Primitive::undefinedValue(); executed 406 times by 1 test: arguments[i] = Primitive::undefinedValue();Executed by:
| 406 | ||||||||||||
| 386 | } else { executed 84 times by 1 test: end of blockExecuted by:
| 84 | ||||||||||||
| 387 | for (quint32 i = 0; i < len; ++i)
| 0 | ||||||||||||
| 388 | arguments[i] = arr->get(i); never executed: arguments[i] = arr->get(i); | 0 | ||||||||||||
| 389 | } never executed: end of block | 0 | ||||||||||||
| 390 | } | - | ||||||||||||
| 391 | - | |||||||||||||
| 392 | return f->call(thisObject, arguments, len); executed 108 times by 2 tests: return f->call(thisObject, arguments, len);Executed by:
| 108 | ||||||||||||
| 393 | } | - | ||||||||||||
| 394 | - | |||||||||||||
| 395 | ReturnedValue FunctionPrototype::method_call(const QV4::FunctionObject *b, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
| 396 | { | - | ||||||||||||
| 397 | if (!thisObject->isFunctionObject())
| 44-28216 | ||||||||||||
| 398 | return b->engine()->throwTypeError(); executed 44 times by 1 test: return b->engine()->throwTypeError();Executed by:
| 44 | ||||||||||||
| 399 | - | |||||||||||||
| 400 | const FunctionObject *f = static_cast<const FunctionObject *>(thisObject); | - | ||||||||||||
| 401 | - | |||||||||||||
| 402 | thisObject = argc ? argv : nullptr;
| 34-28183 | ||||||||||||
| 403 | if (argc) {
| 34-28207 | ||||||||||||
| 404 | ++argv; | - | ||||||||||||
| 405 | --argc; | - | ||||||||||||
| 406 | } executed 28196 times by 3 tests: end of blockExecuted by:
| 28196 | ||||||||||||
| 407 | return f->call(thisObject, argv, argc); executed 28237 times by 3 tests: return f->call(thisObject, argv, argc);Executed by:
| 28237 | ||||||||||||
| 408 | } | - | ||||||||||||
| 409 | - | |||||||||||||
| 410 | ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
| 411 | { | - | ||||||||||||
| 412 | QV4::Scope scope(b); | - | ||||||||||||
| 413 | ScopedFunctionObject target(scope, thisObject); | - | ||||||||||||
| 414 | if (!target || target->isBinding())
| 0-571 | ||||||||||||
| 415 | return scope.engine->throwTypeError(); executed 55 times by 1 test: return scope.engine->throwTypeError();Executed by:
| 55 | ||||||||||||
| 416 | - | |||||||||||||
| 417 | ScopedValue boundThis(scope, argc ? argv[0] : Primitive::undefinedValue()); | - | ||||||||||||
| 418 | Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)nullptr); | - | ||||||||||||
| 419 | - | |||||||||||||
| 420 | int nArgs = (argc - 1 >= 0) ? argc - 1 : 0;
| 114-451 | ||||||||||||
| 421 | if (target->isBoundFunction()) {
| 22-543 | ||||||||||||
| 422 | BoundFunction *bound = static_cast<BoundFunction *>(target.getPointer()); | - | ||||||||||||
| 423 | Scoped<MemberData> oldArgs(scope, bound->boundArgs()); | - | ||||||||||||
| 424 | boundThis = bound->boundThis(); | - | ||||||||||||
| 425 | int oldSize = !oldArgs ? 0 : oldArgs->size();
| 2-20 | ||||||||||||
| 426 | if (oldSize + nArgs) {
| 2-20 | ||||||||||||
| 427 | boundArgs = MemberData::allocate(scope.engine, oldSize + nArgs); | - | ||||||||||||
| 428 | boundArgs->d()->values.size = oldSize + nArgs; | - | ||||||||||||
| 429 | for (uint i = 0; i < static_cast<uint>(oldSize); ++i)
| 2 | ||||||||||||
| 430 | boundArgs->set(scope.engine, i, oldArgs->data()[i]); executed 2 times by 1 test: boundArgs->set(scope.engine, i, oldArgs->data()[i]);Executed by:
| 2 | ||||||||||||
| 431 | for (uint i = 0; i < static_cast<uint>(nArgs); ++i)
| 2 | ||||||||||||
| 432 | boundArgs->set(scope.engine, oldSize + i, argv[i + 1]); executed 2 times by 1 test: boundArgs->set(scope.engine, oldSize + i, argv[i + 1]);Executed by:
| 2 | ||||||||||||
| 433 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||
| 434 | target = bound->target(); | - | ||||||||||||
| 435 | } else if (nArgs) { executed 22 times by 2 tests: end of blockExecuted by:
| 22-461 | ||||||||||||
| 436 | boundArgs = MemberData::allocate(scope.engine, nArgs); | - | ||||||||||||
| 437 | boundArgs->d()->values.size = nArgs; | - | ||||||||||||
| 438 | for (uint i = 0, ei = static_cast<uint>(nArgs); i < ei; ++i)
| 90-136 | ||||||||||||
| 439 | boundArgs->set(scope.engine, i, argv[i + 1]); executed 136 times by 3 tests: boundArgs->set(scope.engine, i, argv[i + 1]);Executed by:
| 136 | ||||||||||||
| 440 | } executed 90 times by 3 tests: end of blockExecuted by:
| 90 | ||||||||||||
| 441 | - | |||||||||||||
| 442 | ScopedContext ctx(scope, target->scope()); | - | ||||||||||||
| 443 | Heap::BoundFunction *bound = BoundFunction::create(ctx, target, boundThis, boundArgs); | - | ||||||||||||
| 444 | bound->setFunction(target->function()); | - | ||||||||||||
| 445 | return bound->asReturnedValue(); executed 574 times by 3 tests: return bound->asReturnedValue();Executed by:
| 574 | ||||||||||||
| 446 | } | - | ||||||||||||
| 447 | - | |||||||||||||
| 448 | ReturnedValue FunctionPrototype::method_hasInstance(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
| 449 | { | - | ||||||||||||
| 450 | if (!argc)
| 8-4235391 | ||||||||||||
| 451 | return false; executed 8 times by 1 test: return false;Executed by:
| 8 | ||||||||||||
| 452 | const Object *o = thisObject->as<Object>(); | - | ||||||||||||
| 453 | if (!o)
| 0-4250958 | ||||||||||||
| 454 | return f->engine()->throwTypeError(); never executed: return f->engine()->throwTypeError(); | 0 | ||||||||||||
| 455 | - | |||||||||||||
| 456 | return Object::virtualInstanceOf(o, argv[0]); executed 4247077 times by 11 tests: return Object::virtualInstanceOf(o, argv[0]);Executed by:
| 4247077 | ||||||||||||
| 457 | } | - | ||||||||||||
| 458 | - | |||||||||||||
| 459 | DEFINE_OBJECT_VTABLE(ScriptFunction); | - | ||||||||||||
| 460 | - | |||||||||||||
| 461 | ReturnedValue ScriptFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *newTarget) | - | ||||||||||||
| 462 | { | - | ||||||||||||
| 463 | ExecutionEngine *v4 = fo->engine(); | - | ||||||||||||
| 464 | const ScriptFunction *f = static_cast<const ScriptFunction *>(fo); | - | ||||||||||||
| 465 | Q_ASSERT(newTarget->isFunctionObject()); | - | ||||||||||||
| 466 | const FunctionObject *nt = static_cast<const FunctionObject *>(newTarget); | - | ||||||||||||
| 467 | - | |||||||||||||
| 468 | Scope scope(v4); | - | ||||||||||||
| 469 | Scoped<InternalClass> ic(scope); | - | ||||||||||||
| 470 | if (nt->d() == f->d()) {
| 208-14395 | ||||||||||||
| 471 | ic = f->classForConstructor(); | - | ||||||||||||
| 472 | } else { executed 14414 times by 3 tests: end of blockExecuted by:
| 14414 | ||||||||||||
| 473 | const Object *o = nt->d()->protoProperty(); | - | ||||||||||||
| 474 | ic = scope.engine->internalClasses(EngineBase::Class_Object); | - | ||||||||||||
| 475 | if (o)
| 0-208 | ||||||||||||
| 476 | ic = ic->changePrototype(o->d()); executed 208 times by 1 test: ic = ic->changePrototype(o->d());Executed by:
| 208 | ||||||||||||
| 477 | } executed 208 times by 1 test: end of blockExecuted by:
| 208 | ||||||||||||
| 478 | ScopedValue thisObject(scope, v4->memoryManager->allocObject<Object>(ic)); | - | ||||||||||||
| 479 | - | |||||||||||||
| 480 | CppStackFrame frame; | - | ||||||||||||
| 481 | frame.init(v4, f->function(), argv, argc); | - | ||||||||||||
| 482 | frame.setupJSFrame(v4->jsStackTop, *f, f->scope(), | - | ||||||||||||
| 483 | thisObject, | - | ||||||||||||
| 484 | newTarget ? *newTarget : Primitive::undefinedValue()); | - | ||||||||||||
| 485 | - | |||||||||||||
| 486 | frame.push(); | - | ||||||||||||
| 487 | v4->jsStackTop += frame.requiredJSStackFrameSize(); | - | ||||||||||||
| 488 | - | |||||||||||||
| 489 | ReturnedValue result = Moth::VME::exec(&frame, v4); | - | ||||||||||||
| 490 | - | |||||||||||||
| 491 | frame.pop(); | - | ||||||||||||
| 492 | - | |||||||||||||
| 493 | if (Q_UNLIKELY(v4->hasException))
| 66-14561 | ||||||||||||
| 494 | return Encode::undefined(); executed 66 times by 2 tests: return Encode::undefined();Executed by:
| 66 | ||||||||||||
| 495 | else if (!Value::fromReturnedValue(result).isObject())
| 184-14372 | ||||||||||||
| 496 | return thisObject->asReturnedValue(); executed 14376 times by 3 tests: return thisObject->asReturnedValue();Executed by:
| 14376 | ||||||||||||
| 497 | return result; executed 184 times by 2 tests: return result;Executed by:
| 184 | ||||||||||||
| 498 | } | - | ||||||||||||
| 499 | - | |||||||||||||
| 500 | ReturnedValue ScriptFunction::virtualCall(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
| 501 | { | - | ||||||||||||
| 502 | ExecutionEngine *engine = fo->engine(); | - | ||||||||||||
| 503 | CppStackFrame frame; | - | ||||||||||||
| 504 | frame.init(engine, fo->function(), argv, argc); | - | ||||||||||||
| 505 | frame.setupJSFrame(engine->jsStackTop, *fo, fo->scope(), | - | ||||||||||||
| 506 | thisObject ? *thisObject : Primitive::undefinedValue(), | - | ||||||||||||
| 507 | Primitive::undefinedValue()); | - | ||||||||||||
| 508 | - | |||||||||||||
| 509 | frame.push(); | - | ||||||||||||
| 510 | engine->jsStackTop += frame.requiredJSStackFrameSize(); | - | ||||||||||||
| 511 | - | |||||||||||||
| 512 | ReturnedValue result = Moth::VME::exec(&frame, engine); | - | ||||||||||||
| 513 | - | |||||||||||||
| 514 | frame.pop(); | - | ||||||||||||
| 515 | - | |||||||||||||
| 516 | return result; executed 14908599 times by 59 tests: return result;Executed by:
| 14908599 | ||||||||||||
| 517 | } | - | ||||||||||||
| 518 | - | |||||||||||||
| 519 | void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) | - | ||||||||||||
| 520 | { | - | ||||||||||||
| 521 | FunctionObject::init(); | - | ||||||||||||
| 522 | this->scope.set(scope->engine(), scope->d()); | - | ||||||||||||
| 523 | - | |||||||||||||
| 524 | setFunction(function); | - | ||||||||||||
| 525 | Q_ASSERT(function); | - | ||||||||||||
| 526 | - | |||||||||||||
| 527 | Scope s(scope); | - | ||||||||||||
| 528 | ScopedFunctionObject f(s, this); | - | ||||||||||||
| 529 | - | |||||||||||||
| 530 | ScopedString name(s, function->name()); | - | ||||||||||||
| 531 | if (name)
| 0-1522497 | ||||||||||||
| 532 | f->setName(name); executed 1522416 times by 62 tests: f->setName(name);Executed by:
| 1522416 | ||||||||||||
| 533 | f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_Prototype, Heap::FunctionObject::Index_ProtoConstructor); | - | ||||||||||||
| 534 | - | |||||||||||||
| 535 | Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()->propertyKey()) == Index_Length); | - | ||||||||||||
| 536 | setProperty(s.engine, Index_Length, Primitive::fromInt32(int(function->compiledFunction->length))); | - | ||||||||||||
| 537 | } executed 1523569 times by 62 tests: end of blockExecuted by:
| 1523569 | ||||||||||||
| 538 | - | |||||||||||||
| 539 | Heap::InternalClass *ScriptFunction::classForConstructor() const | - | ||||||||||||
| 540 | { | - | ||||||||||||
| 541 | const Object *o = d()->protoProperty(); | - | ||||||||||||
| 542 | if (d()->cachedClassForConstructor && d()->cachedClassForConstructor->prototype == o->d())
| 4-3208 | ||||||||||||
| 543 | return d()->cachedClassForConstructor; executed 3208 times by 2 tests: return d()->cachedClassForConstructor;Executed by:
| 3208 | ||||||||||||
| 544 | - | |||||||||||||
| 545 | Scope scope(engine()); | - | ||||||||||||
| 546 | Scoped<InternalClass> ic(scope, engine()->internalClasses(EngineBase::Class_Object)); | - | ||||||||||||
| 547 | if (o)
| 8-11200 | ||||||||||||
| 548 | ic = ic->changePrototype(o->d()); executed 11200 times by 3 tests: ic = ic->changePrototype(o->d());Executed by:
| 11200 | ||||||||||||
| 549 | d()->cachedClassForConstructor.set(scope.engine, ic->d()); | - | ||||||||||||
| 550 | - | |||||||||||||
| 551 | return ic->d(); executed 11227 times by 3 tests: return ic->d();Executed by:
| 11227 | ||||||||||||
| 552 | } | - | ||||||||||||
| 553 | - | |||||||||||||
| 554 | DEFINE_OBJECT_VTABLE(ConstructorFunction); | - | ||||||||||||
| 555 | - | |||||||||||||
| 556 | ReturnedValue ConstructorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) | - | ||||||||||||
| 557 | { | - | ||||||||||||
| 558 | const ConstructorFunction *c = static_cast<const ConstructorFunction *>(f); | - | ||||||||||||
| 559 | if (!c->d()->isDerivedConstructor)
| 224-376 | ||||||||||||
| 560 | return ScriptFunction::virtualCallAsConstructor(f, argv, argc, newTarget); executed 224 times by 1 test: return ScriptFunction::virtualCallAsConstructor(f, argv, argc, newTarget);Executed by:
| 224 | ||||||||||||
| 561 | - | |||||||||||||
| 562 | ExecutionEngine *v4 = f->engine(); | - | ||||||||||||
| 563 | - | |||||||||||||
| 564 | CppStackFrame frame; | - | ||||||||||||
| 565 | frame.init(v4, f->function(), argv, argc); | - | ||||||||||||
| 566 | frame.setupJSFrame(v4->jsStackTop, *f, f->scope(), | - | ||||||||||||
| 567 | Primitive::undefinedValue(), | - | ||||||||||||
| 568 | newTarget ? *newTarget : Primitive::undefinedValue()); | - | ||||||||||||
| 569 | - | |||||||||||||
| 570 | frame.push(); | - | ||||||||||||
| 571 | v4->jsStackTop += frame.requiredJSStackFrameSize(); | - | ||||||||||||
| 572 | - | |||||||||||||
| 573 | ReturnedValue result = Moth::VME::exec(&frame, v4); | - | ||||||||||||
| 574 | - | |||||||||||||
| 575 | frame.pop(); | - | ||||||||||||
| 576 | - | |||||||||||||
| 577 | if (Q_UNLIKELY(v4->hasException))
| 88-287 | ||||||||||||
| 578 | return Encode::undefined(); executed 88 times by 1 test: return Encode::undefined();Executed by:
| 88 | ||||||||||||
| 579 | else if (Value::fromReturnedValue(result).isObject())
| 12-275 | ||||||||||||
| 580 | return result; executed 12 times by 1 test: return result;Executed by:
| 12 | ||||||||||||
| 581 | else if (!Value::fromReturnedValue(result).isUndefined())
| 28-248 | ||||||||||||
| 582 | return v4->throwTypeError(); executed 28 times by 1 test: return v4->throwTypeError();Executed by:
| 28 | ||||||||||||
| 583 | return frame.jsFrame->thisObject.asReturnedValue(); executed 248 times by 1 test: return frame.jsFrame->thisObject.asReturnedValue();Executed by:
| 248 | ||||||||||||
| 584 | } | - | ||||||||||||
| 585 | - | |||||||||||||
| 586 | ReturnedValue ConstructorFunction::virtualCall(const FunctionObject *f, const Value *, const Value *, int) | - | ||||||||||||
| 587 | { | - | ||||||||||||
| 588 | return f->engine()->throwTypeError(QStringLiteral("Cannot call a class constructor without |new|")); executed 16 times by 1 test: return f->engine()->throwTypeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "Cannot call a class constructor without |new|")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Cannot call a class constructor without |new|" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()));Executed by:
executed 16 times by 1 test: return qstring_literal_temp;Executed by:
| 16 | ||||||||||||
| 589 | } | - | ||||||||||||
| 590 | - | |||||||||||||
| 591 | DEFINE_OBJECT_VTABLE(MemberFunction); | - | ||||||||||||
| 592 | - | |||||||||||||
| 593 | ReturnedValue MemberFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) | - | ||||||||||||
| 594 | { | - | ||||||||||||
| 595 | return f->engine()->throwTypeError(QStringLiteral("Function is not a constructor.")); never executed: return f->engine()->throwTypeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "Function is not a constructor.")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Function is not a constructor." }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()));never executed: return qstring_literal_temp; | 0 | ||||||||||||
| 596 | } | - | ||||||||||||
| 597 | - | |||||||||||||
| 598 | DEFINE_OBJECT_VTABLE(DefaultClassConstructorFunction); | - | ||||||||||||
| 599 | - | |||||||||||||
| 600 | ReturnedValue DefaultClassConstructorFunction::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget) | - | ||||||||||||
| 601 | { | - | ||||||||||||
| 602 | const DefaultClassConstructorFunction *c = static_cast<const DefaultClassConstructorFunction *>(f); | - | ||||||||||||
| 603 | ExecutionEngine *v4 = f->engine(); | - | ||||||||||||
| 604 | - | |||||||||||||
| 605 | Scope scope(v4); | - | ||||||||||||
| 606 | - | |||||||||||||
| 607 | if (!c->d()->isDerivedConstructor) {
| 359-2739 | ||||||||||||
| 608 | ScopedObject proto(scope, static_cast<const Object *>(newTarget) ->get(scope.engine->id_prototype())); | - | ||||||||||||
| 609 | ScopedObject c(scope, scope.engine->newObject()); | - | ||||||||||||
| 610 | c->setPrototypeUnchecked(proto); | - | ||||||||||||
| 611 | return c->asReturnedValue(); executed 2762 times by 1 test: return c->asReturnedValue();Executed by:
| 2762 | ||||||||||||
| 612 | } | - | ||||||||||||
| 613 | - | |||||||||||||
| 614 | ScopedFunctionObject super(scope, f->getPrototypeOf()); | - | ||||||||||||
| 615 | Q_ASSERT(super->isFunctionObject()); | - | ||||||||||||
| 616 | - | |||||||||||||
| 617 | CppStackFrame frame; | - | ||||||||||||
| 618 | frame.init(v4, nullptr, argv, argc); | - | ||||||||||||
| 619 | frame.setupJSFrame(v4->jsStackTop, *f, f->scope(), | - | ||||||||||||
| 620 | Primitive::undefinedValue(), | - | ||||||||||||
| 621 | newTarget ? *newTarget : Primitive::undefinedValue(), argc, argc); | - | ||||||||||||
| 622 | - | |||||||||||||
| 623 | frame.push(); | - | ||||||||||||
| 624 | v4->jsStackTop += frame.requiredJSStackFrameSize(argc); | - | ||||||||||||
| 625 | - | |||||||||||||
| 626 | // Do a super call | - | ||||||||||||
| 627 | ReturnedValue result = super->callAsConstructor(argv, argc, newTarget); | - | ||||||||||||
| 628 | - | |||||||||||||
| 629 | frame.pop(); | - | ||||||||||||
| 630 | - | |||||||||||||
| 631 | if (Q_UNLIKELY(v4->hasException))
| 12-347 | ||||||||||||
| 632 | return Encode::undefined(); executed 12 times by 1 test: return Encode::undefined();Executed by:
| 12 | ||||||||||||
| 633 | else if (Value::fromReturnedValue(result).isObject())
| 0-348 | ||||||||||||
| 634 | return result; executed 348 times by 1 test: return result;Executed by:
| 348 | ||||||||||||
| 635 | else if (!Value::fromReturnedValue(result).isUndefined())
| 0 | ||||||||||||
| 636 | return v4->throwTypeError(); never executed: return v4->throwTypeError(); | 0 | ||||||||||||
| 637 | return frame.jsFrame->thisObject.asReturnedValue(); never executed: return frame.jsFrame->thisObject.asReturnedValue(); | 0 | ||||||||||||
| 638 | } | - | ||||||||||||
| 639 | - | |||||||||||||
| 640 | ReturnedValue DefaultClassConstructorFunction::virtualCall(const FunctionObject *f, const Value *, const Value *, int) | - | ||||||||||||
| 641 | { | - | ||||||||||||
| 642 | return f->engine()->throwTypeError(QStringLiteral("Cannot call a class constructor without |new|")); executed 20 times by 1 test: return f->engine()->throwTypeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "Cannot call a class constructor without |new|")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Cannot call a class constructor without |new|" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()));Executed by:
executed 20 times by 1 test: return qstring_literal_temp;Executed by:
| 20 | ||||||||||||
| 643 | } | - | ||||||||||||
| 644 | - | |||||||||||||
| 645 | DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction); | - | ||||||||||||
| 646 | - | |||||||||||||
| 647 | DEFINE_OBJECT_VTABLE(BoundFunction); | - | ||||||||||||
| 648 | - | |||||||||||||
| 649 | void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject *target, | - | ||||||||||||
| 650 | const Value &boundThis, QV4::MemberData *boundArgs) | - | ||||||||||||
| 651 | { | - | ||||||||||||
| 652 | Scope s(scope); | - | ||||||||||||
| 653 | Heap::FunctionObject::init(scope, QStringLiteral("__bound function__")); executed 567 times by 3 tests: return qstring_literal_temp;Executed by:
| 567 | ||||||||||||
| 654 | this->target.set(s.engine, target->d()); | - | ||||||||||||
| 655 | this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : nullptr); | - | ||||||||||||
| 656 | this->boundThis.set(scope->engine(), boundThis); | - | ||||||||||||
| 657 | - | |||||||||||||
| 658 | ScopedObject f(s, this); | - | ||||||||||||
| 659 | - | |||||||||||||
| 660 | ScopedValue l(s, target->get(s.engine->id_length())); | - | ||||||||||||
| 661 | int len = l->toUInt32(); | - | ||||||||||||
| 662 | if (boundArgs)
| 90-480 | ||||||||||||
| 663 | len -= boundArgs->size(); executed 90 times by 3 tests: len -= boundArgs->size();Executed by:
| 90 | ||||||||||||
| 664 | if (len < 0)
| 32-538 | ||||||||||||
| 665 | len = 0; executed 32 times by 1 test: len = 0;Executed by:
| 32 | ||||||||||||
| 666 | f->defineReadonlyConfigurableProperty(s.engine->id_length(), Primitive::fromInt32(len)); | - | ||||||||||||
| 667 | - | |||||||||||||
| 668 | ScopedProperty pd(s); | - | ||||||||||||
| 669 | pd->value = s.engine->thrower(); | - | ||||||||||||
| 670 | pd->set = s.engine->thrower(); | - | ||||||||||||
| 671 | f->insertMember(s.engine->id_arguments(), pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); | - | ||||||||||||
| 672 | f->insertMember(s.engine->id_caller(), pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); | - | ||||||||||||
| 673 | } executed 576 times by 3 tests: end of blockExecuted by:
| 576 | ||||||||||||
| 674 | - | |||||||||||||
| 675 | ReturnedValue BoundFunction::virtualCall(const FunctionObject *fo, const Value *, const Value *argv, int argc) | - | ||||||||||||
| 676 | { | - | ||||||||||||
| 677 | const BoundFunction *f = static_cast<const BoundFunction *>(fo); | - | ||||||||||||
| 678 | Scope scope(f->engine()); | - | ||||||||||||
| 679 | - | |||||||||||||
| 680 | if (scope.hasException())
| 0-186 | ||||||||||||
| 681 | return Encode::undefined(); never executed: return Encode::undefined(); | 0 | ||||||||||||
| 682 | - | |||||||||||||
| 683 | Scoped<MemberData> boundArgs(scope, f->boundArgs()); | - | ||||||||||||
| 684 | ScopedFunctionObject target(scope, f->target()); | - | ||||||||||||
| 685 | JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); | - | ||||||||||||
| 686 | *jsCallData->thisObject = f->boundThis(); | - | ||||||||||||
| 687 | Value *argp = jsCallData->args; | - | ||||||||||||
| 688 | if (boundArgs) {
| 42-143 | ||||||||||||
| 689 | memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value)); | - | ||||||||||||
| 690 | argp += boundArgs->size(); | - | ||||||||||||
| 691 | } executed 41 times by 2 tests: end of blockExecuted by:
| 41 | ||||||||||||
| 692 | memcpy(argp, argv, argc*sizeof(Value)); | - | ||||||||||||
| 693 | return target->call(jsCallData); executed 184 times by 2 tests: return target->call(jsCallData);Executed by:
| 184 | ||||||||||||
| 694 | } | - | ||||||||||||
| 695 | - | |||||||||||||
| 696 | ReturnedValue BoundFunction::virtualCallAsConstructor(const FunctionObject *fo, const Value *argv, int argc, const Value *) | - | ||||||||||||
| 697 | { | - | ||||||||||||
| 698 | const BoundFunction *f = static_cast<const BoundFunction *>(fo); | - | ||||||||||||
| 699 | Scope scope(f->engine()); | - | ||||||||||||
| 700 | - | |||||||||||||
| 701 | if (scope.hasException())
| 0-100 | ||||||||||||
| 702 | return Encode::undefined(); never executed: return Encode::undefined(); | 0 | ||||||||||||
| 703 | - | |||||||||||||
| 704 | Scoped<MemberData> boundArgs(scope, f->boundArgs()); | - | ||||||||||||
| 705 | ScopedFunctionObject target(scope, f->target()); | - | ||||||||||||
| 706 | JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc); | - | ||||||||||||
| 707 | Value *argp = jsCallData->args; | - | ||||||||||||
| 708 | if (boundArgs) {
| 36-64 | ||||||||||||
| 709 | memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value)); | - | ||||||||||||
| 710 | argp += boundArgs->size(); | - | ||||||||||||
| 711 | } executed 36 times by 1 test: end of blockExecuted by:
| 36 | ||||||||||||
| 712 | memcpy(argp, argv, argc*sizeof(Value)); | - | ||||||||||||
| 713 | return target->callAsConstructor(jsCallData); executed 100 times by 1 test: return target->callAsConstructor(jsCallData);Executed by:
| 100 | ||||||||||||
| 714 | } | - | ||||||||||||
| Source code | Switch to Preprocessed file |