Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/jsruntime/qv4argumentsobject.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 | #include <qv4argumentsobject_p.h> | - | ||||||||||||
40 | #include <qv4arrayobject_p.h> | - | ||||||||||||
41 | #include <qv4alloca_p.h> | - | ||||||||||||
42 | #include <qv4scopedvalue_p.h> | - | ||||||||||||
43 | #include <qv4string_p.h> | - | ||||||||||||
44 | #include <qv4function_p.h> | - | ||||||||||||
45 | #include <qv4jscall_p.h> | - | ||||||||||||
46 | #include <qv4symbol_p.h> | - | ||||||||||||
47 | - | |||||||||||||
48 | using namespace QV4; | - | ||||||||||||
49 | - | |||||||||||||
50 | DEFINE_OBJECT_VTABLE(ArgumentsObject); | - | ||||||||||||
51 | DEFINE_OBJECT_VTABLE(StrictArgumentsObject); | - | ||||||||||||
52 | - | |||||||||||||
53 | void Heap::ArgumentsObject::init(QV4::CppStackFrame *frame) | - | ||||||||||||
54 | { | - | ||||||||||||
55 | ExecutionEngine *v4 = internalClass->engine; | - | ||||||||||||
56 | - | |||||||||||||
57 | int nFormals = frame->v4Function->nFormals; | - | ||||||||||||
58 | QV4::CallContext *context = static_cast<QV4::CallContext *>(frame->context()); | - | ||||||||||||
59 | - | |||||||||||||
60 | Object::init(); | - | ||||||||||||
61 | fullyCreated = false; | - | ||||||||||||
62 | this->nFormals = nFormals; | - | ||||||||||||
63 | this->context.set(v4, context->d()); | - | ||||||||||||
64 | Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable()); | - | ||||||||||||
65 | - | |||||||||||||
66 | Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->propertyKey())); | - | ||||||||||||
67 | setProperty(v4, CalleePropertyIndex, context->d()->function); | - | ||||||||||||
68 | Q_ASSERT(LengthPropertyIndex == internalClass->find(v4->id_length()->propertyKey())); | - | ||||||||||||
69 | setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(context->argc())); | - | ||||||||||||
70 | Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->propertyKey())); | - | ||||||||||||
71 | setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues()); | - | ||||||||||||
72 | } executed 4487 times by 11 tests: end of block Executed by:
| 4487 | ||||||||||||
73 | - | |||||||||||||
74 | void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame) | - | ||||||||||||
75 | { | - | ||||||||||||
76 | Q_ASSERT(vtable() == QV4::StrictArgumentsObject::staticVTable()); | - | ||||||||||||
77 | ExecutionEngine *v4 = internalClass->engine; | - | ||||||||||||
78 | - | |||||||||||||
79 | Object::init(); | - | ||||||||||||
80 | - | |||||||||||||
81 | Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()->propertyKey())); | - | ||||||||||||
82 | Q_ASSERT(SymbolIteratorPropertyIndex == internalClass->find(v4->symbol_iterator()->propertyKey())); | - | ||||||||||||
83 | setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues()); | - | ||||||||||||
84 | setProperty(v4, CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower()); | - | ||||||||||||
85 | setProperty(v4, CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower()); | - | ||||||||||||
86 | - | |||||||||||||
87 | Scope scope(v4); | - | ||||||||||||
88 | Scoped<QV4::StrictArgumentsObject> args(scope, this); | - | ||||||||||||
89 | args->arrayReserve(frame->originalArgumentsCount); | - | ||||||||||||
90 | args->arrayPut(0, frame->originalArguments, frame->originalArgumentsCount); | - | ||||||||||||
91 | - | |||||||||||||
92 | Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(v4->id_length()->propertyKey())); | - | ||||||||||||
93 | setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(frame->originalArgumentsCount)); | - | ||||||||||||
94 | } executed 3836 times by 2 tests: end of block Executed by:
| 3836 | ||||||||||||
95 | - | |||||||||||||
96 | void ArgumentsObject::fullyCreate() | - | ||||||||||||
97 | { | - | ||||||||||||
98 | if (fullyCreated())
| 446-1101 | ||||||||||||
99 | return; executed 1101 times by 1 test: return; Executed by:
| 1101 | ||||||||||||
100 | - | |||||||||||||
101 | Scope scope(engine()); | - | ||||||||||||
102 | - | |||||||||||||
103 | int argCount = context()->argc(); | - | ||||||||||||
104 | uint numAccessors = qMin(d()->nFormals, argCount); | - | ||||||||||||
105 | ArrayData::realloc(this, Heap::ArrayData::Sparse, argCount, true); | - | ||||||||||||
106 | scope.engine->requireArgumentsAccessors(numAccessors); | - | ||||||||||||
107 | - | |||||||||||||
108 | Scoped<MemberData> md(scope, d()->mappedArguments); | - | ||||||||||||
109 | if (numAccessors) {
| 200-252 | ||||||||||||
110 | d()->mappedArguments.set(scope.engine, md->allocate(scope.engine, numAccessors)); | - | ||||||||||||
111 | for (uint i = 0; i < numAccessors; ++i) {
| 198-403 | ||||||||||||
112 | d()->mappedArguments->values.set(scope.engine, i, context()->args()[i]); | - | ||||||||||||
113 | arraySet(i, scope.engine->argumentsAccessors + i, Attr_Accessor); | - | ||||||||||||
114 | } executed 403 times by 1 test: end of block Executed by:
| 403 | ||||||||||||
115 | } executed 199 times by 1 test: end of block Executed by:
| 199 | ||||||||||||
116 | arrayPut(numAccessors, context()->args() + numAccessors, argCount - numAccessors); | - | ||||||||||||
117 | for (int i = int(numAccessors); i < argCount; ++i)
| 334-451 | ||||||||||||
118 | setArrayAttributes(i, Attr_Data); executed 334 times by 1 test: setArrayAttributes(i, Attr_Data); Executed by:
| 334 | ||||||||||||
119 | - | |||||||||||||
120 | d()->fullyCreated = true; | - | ||||||||||||
121 | } executed 450 times by 1 test: end of block Executed by:
| 450 | ||||||||||||
122 | - | |||||||||||||
123 | bool ArgumentsObject::virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property *desc, PropertyAttributes attrs) | - | ||||||||||||
124 | { | - | ||||||||||||
125 | if (!id.isArrayIndex())
| 188-399 | ||||||||||||
126 | return Object::virtualDefineOwnProperty(m, id, desc, attrs); executed 188 times by 1 test: return Object::virtualDefineOwnProperty(m, id, desc, attrs); Executed by:
| 188 | ||||||||||||
127 | - | |||||||||||||
128 | ArgumentsObject *a = static_cast<ArgumentsObject *>(m); | - | ||||||||||||
129 | a->fullyCreate(); | - | ||||||||||||
130 | - | |||||||||||||
131 | uint index = id.asArrayIndex(); | - | ||||||||||||
132 | Scope scope(m); | - | ||||||||||||
133 | ScopedProperty map(scope); | - | ||||||||||||
134 | PropertyAttributes mapAttrs; | - | ||||||||||||
135 | uint numAccessors = qMin(a->d()->nFormals, a->context()->argc()); | - | ||||||||||||
136 | bool isMapped = false; | - | ||||||||||||
137 | if (a->arrayData() && index < numAccessors &&
| 0-401 | ||||||||||||
138 | a->arrayData()->attributes(index).isAccessor() &&
| 80-144 | ||||||||||||
139 | a->arrayData()->get(index) == scope.engine->argumentsAccessors[index].getter()->asReturnedValue())
| 20-124 | ||||||||||||
140 | isMapped = true; executed 124 times by 1 test: isMapped = true; Executed by:
| 124 | ||||||||||||
141 | - | |||||||||||||
142 | if (isMapped) {
| 124-276 | ||||||||||||
143 | Q_ASSERT(a->arrayData()); | - | ||||||||||||
144 | mapAttrs = a->arrayData()->attributes(index); | - | ||||||||||||
145 | a->arrayData()->getProperty(index, map, &mapAttrs); | - | ||||||||||||
146 | a->setArrayAttributes(index, Attr_Data); | - | ||||||||||||
147 | PropertyIndex arrayIndex{ a->arrayData(), a->arrayData()->values.values + a->arrayData()->mappedIndex(index) }; | - | ||||||||||||
148 | arrayIndex.set(scope.engine, a->d()->mappedArguments->values[index]); | - | ||||||||||||
149 | } executed 126 times by 1 test: end of block Executed by:
| 126 | ||||||||||||
150 | - | |||||||||||||
151 | bool result = Object::virtualDefineOwnProperty(m, id, desc, attrs); | - | ||||||||||||
152 | if (!result)
| 88-312 | ||||||||||||
153 | return false; executed 88 times by 1 test: return false; Executed by:
| 88 | ||||||||||||
154 | - | |||||||||||||
155 | if (isMapped && attrs.isData()) {
| 52-188 | ||||||||||||
156 | Q_ASSERT(a->arrayData()); | - | ||||||||||||
157 | ScopedFunctionObject setter(scope, map->setter()); | - | ||||||||||||
158 | JSCallData jsCallData(scope, 1); | - | ||||||||||||
159 | *jsCallData->thisObject = a->asReturnedValue(); | - | ||||||||||||
160 | jsCallData->args[0] = desc->value; | - | ||||||||||||
161 | setter->call(jsCallData); | - | ||||||||||||
162 | - | |||||||||||||
163 | if (attrs.isWritable()) {
| 2-49 | ||||||||||||
164 | a->setArrayAttributes(index, mapAttrs); | - | ||||||||||||
165 | a->arrayData()->setProperty(m->engine(), index, map); | - | ||||||||||||
166 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||
167 | } executed 51 times by 1 test: end of block Executed by:
| 51 | ||||||||||||
168 | - | |||||||||||||
169 | return result; executed 313 times by 1 test: return result; Executed by:
| 313 | ||||||||||||
170 | } | - | ||||||||||||
171 | - | |||||||||||||
172 | ReturnedValue ArgumentsObject::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty) | - | ||||||||||||
173 | { | - | ||||||||||||
174 | const ArgumentsObject *args = static_cast<const ArgumentsObject *>(m); | - | ||||||||||||
175 | if (id.isArrayIndex() && !args->fullyCreated()) {
| 525-1601 | ||||||||||||
176 | uint index = id.asArrayIndex(); | - | ||||||||||||
177 | if (index < static_cast<uint>(args->context()->argc())) {
| 28-1047 | ||||||||||||
178 | if (hasProperty)
| 222-825 | ||||||||||||
179 | *hasProperty = true; executed 222 times by 1 test: *hasProperty = true; Executed by:
| 222 | ||||||||||||
180 | return args->context()->args()[index].asReturnedValue(); executed 1046 times by 4 tests: return args->context()->args()[index].asReturnedValue(); Executed by:
| 1046 | ||||||||||||
181 | } | - | ||||||||||||
182 | } executed 28 times by 2 tests: end of block Executed by:
| 28 | ||||||||||||
183 | return Object::virtualGet(m, id, receiver, hasProperty); executed 1844 times by 6 tests: return Object::virtualGet(m, id, receiver, hasProperty); Executed by:
| 1844 | ||||||||||||
184 | } | - | ||||||||||||
185 | - | |||||||||||||
186 | bool ArgumentsObject::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver) | - | ||||||||||||
187 | { | - | ||||||||||||
188 | ArgumentsObject *args = static_cast<ArgumentsObject *>(m); | - | ||||||||||||
189 | if (id.isArrayIndex()) {
| 237-327 | ||||||||||||
190 | uint index = id.asArrayIndex(); | - | ||||||||||||
191 | if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->argc()))
| 16-191 | ||||||||||||
192 | args->fullyCreate(); executed 30 times by 1 test: args->fullyCreate(); Executed by:
| 30 | ||||||||||||
193 | - | |||||||||||||
194 | if (!args->fullyCreated()) {
| 16-221 | ||||||||||||
195 | args->context()->setArg(index, value); | - | ||||||||||||
196 | return true; executed 16 times by 1 test: return true; Executed by:
| 16 | ||||||||||||
197 | } | - | ||||||||||||
198 | } executed 221 times by 1 test: end of block Executed by:
| 221 | ||||||||||||
199 | return Object::virtualPut(m, id, value, receiver); executed 549 times by 1 test: return Object::virtualPut(m, id, value, receiver); Executed by:
| 549 | ||||||||||||
200 | } | - | ||||||||||||
201 | - | |||||||||||||
202 | bool ArgumentsObject::virtualDeleteProperty(Managed *m, PropertyKey id) | - | ||||||||||||
203 | { | - | ||||||||||||
204 | ArgumentsObject *args = static_cast<ArgumentsObject *>(m); | - | ||||||||||||
205 | if (!args->fullyCreated())
| 54-287 | ||||||||||||
206 | args->fullyCreate(); executed 53 times by 1 test: args->fullyCreate(); Executed by:
| 53 | ||||||||||||
207 | return Object::virtualDeleteProperty(m, id); executed 342 times by 1 test: return Object::virtualDeleteProperty(m, id); Executed by:
| 342 | ||||||||||||
208 | } | - | ||||||||||||
209 | - | |||||||||||||
210 | PropertyAttributes ArgumentsObject::virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p) | - | ||||||||||||
211 | { | - | ||||||||||||
212 | const ArgumentsObject *args = static_cast<const ArgumentsObject *>(m); | - | ||||||||||||
213 | if (!id.isArrayIndex() || args->fullyCreated())
| 2-978 | ||||||||||||
214 | return Object::virtualGetOwnProperty(m, id, p); executed 1778 times by 1 test: return Object::virtualGetOwnProperty(m, id, p); Executed by:
| 1778 | ||||||||||||
215 | - | |||||||||||||
216 | uint index = id.asArrayIndex(); | - | ||||||||||||
217 | uint argCount = args->context()->argc(); | - | ||||||||||||
218 | if (index >= argCount)
| 0-2 | ||||||||||||
219 | return PropertyAttributes(); executed 2 times by 1 test: return PropertyAttributes(); Executed by:
| 2 | ||||||||||||
220 | if (p)
| 0 | ||||||||||||
221 | p->value = args->context()->args()[index]; never executed: p->value = args->context()->args()[index]; | 0 | ||||||||||||
222 | return Attr_Data; never executed: return Attr_Data; | 0 | ||||||||||||
223 | } | - | ||||||||||||
224 | - | |||||||||||||
225 | DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction); | - | ||||||||||||
226 | - | |||||||||||||
227 | ReturnedValue ArgumentsGetterFunction::virtualCall(const FunctionObject *getter, const Value *thisObject, const Value *, int) | - | ||||||||||||
228 | { | - | ||||||||||||
229 | ExecutionEngine *v4 = getter->engine(); | - | ||||||||||||
230 | Scope scope(v4); | - | ||||||||||||
231 | const ArgumentsGetterFunction *g = static_cast<const ArgumentsGetterFunction *>(getter); | - | ||||||||||||
232 | Scoped<ArgumentsObject> o(scope, thisObject->as<ArgumentsObject>()); | - | ||||||||||||
233 | if (!o)
| 0-48 | ||||||||||||
234 | return v4->throwTypeError(); never executed: return v4->throwTypeError(); | 0 | ||||||||||||
235 | - | |||||||||||||
236 | Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->argc())); | - | ||||||||||||
237 | return o->context()->args()[g->index()].asReturnedValue(); executed 48 times by 1 test: return o->context()->args()[g->index()].asReturnedValue(); Executed by:
| 48 | ||||||||||||
238 | } | - | ||||||||||||
239 | - | |||||||||||||
240 | DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction); | - | ||||||||||||
241 | - | |||||||||||||
242 | ReturnedValue ArgumentsSetterFunction::virtualCall(const FunctionObject *setter, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||
243 | { | - | ||||||||||||
244 | ExecutionEngine *v4 = setter->engine(); | - | ||||||||||||
245 | Scope scope(v4); | - | ||||||||||||
246 | const ArgumentsSetterFunction *s = static_cast<const ArgumentsSetterFunction *>(setter); | - | ||||||||||||
247 | Scoped<ArgumentsObject> o(scope, thisObject->as<ArgumentsObject>()); | - | ||||||||||||
248 | if (!o)
| 0-51 | ||||||||||||
249 | return v4->throwTypeError(); never executed: return v4->throwTypeError(); | 0 | ||||||||||||
250 | - | |||||||||||||
251 | Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->argc())); | - | ||||||||||||
252 | o->context()->setArg(s->index(), argc ? argv[0] : Primitive::undefinedValue()); | - | ||||||||||||
253 | return Encode::undefined(); executed 51 times by 1 test: return Encode::undefined(); Executed by:
| 51 | ||||||||||||
254 | } | - | ||||||||||||
255 | - | |||||||||||||
256 | qint64 ArgumentsObject::virtualGetLength(const Managed *m) | - | ||||||||||||
257 | { | - | ||||||||||||
258 | const ArgumentsObject *a = static_cast<const ArgumentsObject *>(m); | - | ||||||||||||
259 | return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->toLength(); executed 208 times by 1 test: return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->toLength(); Executed by:
| 208 | ||||||||||||
260 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |