Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4function.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
6
7#include <private/qqmlpropertycachecreator_p.h>
8#include <private/qqmltype_p_p.h>
9
10#include <private/qv4engine_p.h>
11#include <private/qv4functiontable_p.h>
12#include <private/qv4identifiertable_p.h>
13#include <private/qv4jscall_p.h>
14#include <private/qv4vme_moth_p.h>
15
16#include <assembler/MacroAssemblerCodeRef.h>
17
19
20namespace QV4 {
21
22bool Function::call(QObject *thisObject, void **a, const QMetaType *types, int argc,
24{
25 if (kind != AotCompiled) {
26 return QV4::convertAndCall(
28 [this, context](const Value *thisObject, const Value *argv, int argc) {
29 return call(thisObject, argv, argc, context);
30 });
31 }
32
40}
41
57
59 const Value *thisObject, const Value *argv, int argc, ExecutionContext *context) {
60 switch (kind) {
61 case AotCompiled:
62 return QV4::convertAndCall(
64 [this, context](
65 QObject *thisObject, void **a, const QMetaType *types, int argc) {
67 });
68 case JsTyped:
69 return QV4::coerceAndCall(
71 [this, context, thisObject](const Value *argv, int argc) {
72 return doCall(this, thisObject, argv, argc, context);
73 });
74 default:
75 break;
76 }
77
78 return doCall(this, thisObject, argv, argc, context);
79}
80
87
89{
90 delete this;
91}
92
98
99static bool isSpecificType(const CompiledData::ParameterType &type)
100{
101 return type.typeNameIndexOrCommonType()
102 != (type.indexIsCommonType() ? quint32(CompiledData::CommonType::Invalid) : 0);
103}
104
111{
114
115 // first locals
117 for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
119
122
123 for (quint32 i = 0; i < compiledFunction->nFormals; ++i) {
126 enforceJsTypes = false;
127 }
129
131
132 if (!enforceJsTypes)
133 return;
134
135 if (aotFunction) {
141 return;
142 }
143
144 // If a function has any typed arguments, but an untyped return value, the return value is void.
145 // If it doesn't have any arguments at all and the return value is untyped, the function is
146 // untyped. Users can specifically set the return type to "void" to have it enforced.
148 return;
149
151
152 const auto isEnumUsedAsType = [&](const QV4::ExecutableCompilationUnit *unit,
154 const quint16 *parameter = nullptr) {
156 const auto split = name.tokenize(u'.').toContainer<QVarLengthArray<QStringView, 4>>();
157 if (split.size() != 2)
158 return false;
159
160 const QStringView scopeName = split[0];
161 const QStringView enumName = split[1];
162
164 const auto warn = [&] {
166 auto where = parameter ? QStringLiteral("parameter ") + QString::number(*parameter)
167 : QStringLiteral("return type");
168 auto msg = QStringLiteral("Type annotation for %1 of function %2: Enumerations are "
169 "not types. Use underlying type (int or double) instead.")
170 .arg(where, this->name()->toQString());
177 };
178
179 bool ok;
180 if (scopeName == QStringLiteral("Qt")) {
182 for (int i = 0; i < mo->enumeratorCount(); ++i) {
183 if (mo->enumerator(i).name() == enumName.toLatin1()) {
184 warn();
185 return true;
186 }
187 }
188 return false;
189 }
190
193 if (!scope.isValid())
194 return false;
195
197 if (ok) {
198 warn();
199 return true;
200 }
202 if (ok) {
203 warn();
204 return true;
205 }
206
207 return false;
208 };
209
210 auto findQmlType = [&](const CompiledData::ParameterType &param,
211 const quint16 *parameter = nullptr) {
213 if (param.indexIsCommonType()) {
216 }
217
218 if (type == 0 || !typeLoader)
219 return QQmlType();
220
222 return QQmlType();
223
225 return qmltype.typeId().isValid() ? qmltype : QQmlType();
226 };
227
229 kind = JsTyped;
232 for (quint16 i = 0; i < nFormals; ++i)
234}
235
237{
238 if (codeRef) {
240 delete codeRef;
241 }
242
243 switch (kind) {
244 case JsTyped:
246 break;
247 case AotCompiled:
249 break;
250 case JsUntyped:
251 case Eval:
252 break;
253 }
254}
255
257{
259
260 // Resolve duplicate parameter names:
261 for (int i = 0, ei = parameters.size(); i != ei; ++i) {
262 const QByteArray &param = parameters.at(i);
263 int duplicate = -1;
264
265 for (int j = i - 1; j >= 0; --j) {
267 if (param == prevParam) {
268 duplicate = j;
269 break;
270 }
271 }
272
273 if (duplicate == -1) {
275 } else {
279 QString(QChar(0xfffe)) + QString::number(duplicate) + dup;
280 }
281
282 }
283
286
287 // first locals
289 for (quint32 i = 0; i < compiledFunction->nLocals; ++i) {
290 ic = ic->addMember(
293 }
294
296 for (const QString &parameterName : parameterNames) {
299 }
302}
303
305{
307 if (prettyName.isEmpty()) {
308 prettyName = QString::number(reinterpret_cast<quintptr>(code), 16);
309 prettyName.prepend(QLatin1String("QV4::Function(0x"));
311 }
312 return prettyName;
313}
314
320
325
326} // namespace QV4
327
328QT_END_NAMESPACE
Definition qjsvalue.h:23
static ReturnedValue doCall(QV4::Function *self, const QV4::Value *thisObject, const QV4::Value *argv, int argc, QV4::ExecutionContext *context)
static bool isSpecificType(const CompiledData::ParameterType &type)