Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4qmlcontext.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
4#include "qv4qmlcontext_p.h"
5
6#include <private/qjsvalue_p.h>
7#include <private/qqmlcontext_p.h>
8#include <private/qqmlengine_p.h>
9#include <private/qqmlglobal_p.h>
10#include <private/qqmljavascriptexpression_p.h>
11#include <private/qqmllistwrapper_p.h>
12#include <private/qqmltypewrapper_p.h>
13#include <private/qv4compileddata_p.h>
14#include <private/qv4engine_p.h>
15#include <private/qv4function_p.h>
16#include <private/qv4identifiertable_p.h>
17#include <private/qv4lookup_p.h>
18#include <private/qv4mm_p.h>
19#include <private/qv4module_p.h>
20#include <private/qv4objectproto_p.h>
21#include <private/qv4qobjectwrapper_p.h>
22#include <private/qv4stackframe_p.h>
23#include <private/qv4value_p.h>
24
25#include <QtCore/qloggingcategory.h>
26
28
29Q_LOGGING_CATEGORY(lcQmlContext, "qt.qml.context");
30
31using namespace QV4;
32
35
36void Heap::QQmlContextWrapper::init(QQmlRefPointer<QQmlContextData> context, QObject *scopeObject)
37{
38 Object::init();
39 this->context = context.take();
40 this->scopeObject.init(scopeObject);
41}
42
43void Heap::QQmlContextWrapper::destroy()
44{
45 context->release();
46 context = nullptr;
47 scopeObject.destroy();
48 Object::destroy();
49}
50
52 QV4::ExecutionEngine *v4, const QQmlRefPointer<QQmlContextData> &context, String *name,
53 bool *hasProperty, Value *base, QV4::Lookup *lookup, QV4::Lookup *originalLookup,
55{
56 const int propertyIdx = context->propertyIndex(name);
57
58 if (propertyIdx == -1)
59 return OptionalReturnedValue();
60
61 if (propertyIdx < context->numIdValues()) {
62 if (hasProperty)
63 *hasProperty = true;
64
65 if (lookup) {
66 lookup->qmlContextIdObjectLookup.objectId = propertyIdx;
68 return OptionalReturnedValue(lookup->qmlContextPropertyGetter(lookup, v4, base));
69 } else if (originalLookup) {
70 originalLookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupInParentContextHierarchy;
71 }
72
73 if (ep->propertyCapture)
74 ep->propertyCapture->captureProperty(context->idValueBindings(propertyIdx));
75 return OptionalReturnedValue(QV4::QObjectWrapper::wrap(v4, context->idValue(propertyIdx)));
76 }
77
78 QQmlContextPrivate *cp = context->asQQmlContextPrivate();
79
80 if (ep->propertyCapture)
81 ep->propertyCapture->captureProperty(context->asQQmlContext(), -1, propertyIdx + cp->notifyIndex());
82
83 const QVariant &value = cp->propertyValue(propertyIdx);
84 if (hasProperty)
85 *hasProperty = true;
86 if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
87 QQmlListProperty<QObject> prop(context->asQQmlContext(), (void*) qintptr(propertyIdx),
90 return OptionalReturnedValue(QmlListWrapper::create(v4, prop, QMetaType::fromType<QQmlListProperty<QObject> >()));
91 }
92 return OptionalReturnedValue(v4->fromVariant(cp->propertyValue(propertyIdx)));
93}
94
95template<typename Lookup>
96bool performLookup(ScopedValue *result, bool *hasProperty, const Lookup &lookup) {
97 bool hasProp = false;
98 *result = lookup(&hasProp);
99 if (hasProp) {
100 if (hasProperty)
101 *hasProperty = hasProp;
102 return true;
103 }
104 return false;
105}
106
107static QV4::QObjectWrapper::Flags getQmlPropertyFlags(const Lookup *l)
108{
109 return (l && l->forCall)
112}
113
114ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *resource, PropertyKey id, const Value *receiver, bool *hasProperty, Value *base, Lookup *lookup)
115{
116 if (!id.isString())
117 return Object::virtualGet(resource, id, receiver, hasProperty);
118
119 QV4::ExecutionEngine *v4 = resource->engine();
120 QV4::Scope scope(v4);
121
122 if (v4->callingQmlContext().data() != resource->d()->context) {
123 if (resource->d()->module) {
124 Scoped<Module> module(scope, resource->d()->module);
125 bool hasProp = false;
126 ScopedValue value(scope, module->get(id, receiver, &hasProp));
127 if (hasProp) {
128 if (hasProperty)
129 *hasProperty = hasProp;
130 return value->asReturnedValue();
131 }
132 }
133
134 return Object::virtualGet(resource, id, receiver, hasProperty);
135 }
136
137 ScopedValue result(scope);
138
139 // It's possible we could delay the calculation of the "actual" context (in the case
140 // of sub contexts) until it is definitely needed.
141 QQmlRefPointer<QQmlContextData> context = resource->getContext();
142 QQmlRefPointer<QQmlContextData> expressionContext = context;
143
144 if (!context) {
145 if (hasProperty)
146 *hasProperty = true;
147 return result->asReturnedValue();
148 }
149
150 // Search type (attached property/enum/imported scripts) names
151 // while (context) {
152 // Search context properties
153 // Search scope object
154 // Search context object
155 // context = context->parent
156 // }
157
158 QObject *scopeObject = resource->getScopeObject();
159
160 ScopedString name(scope, id.asStringOrSymbol());
161
162 const auto globalLookup = [v4, &name](bool *hasProp) {
163 return v4->globalObject->get(name, hasProp);
164 };
165
166 const auto jsLookup = [resource, &id, receiver](bool *hasProp) {
167 return Object::virtualGet(resource, id, receiver, hasProp);
168 };
169
170 const bool isJSContext = context->isJSContext();
171
172 // Do the generic JS lookup early in case of a JavaScript context.
173 if (isJSContext && performLookup(&result, hasProperty, jsLookup))
174 return result->asReturnedValue();
175
176 // If the scope object is a QAbstractDynamicMetaObject, then QMetaObject::indexOfProperty
177 // will call createProperty() on the QADMO and implicitly create the property. While that
178 // is questionable behavior, there are two use-cases that we support in the light of this:
179 //
180 // (1) The implicit creation of properties is necessary because it will also result in
181 // a recorded capture, which will allow a re-evaluation of bindings when the value
182 // is populated later. See QTBUG-35233 and the test-case in tst_qqmlpropertymap.
183 //
184 // (1) Looking up "console" in order to place a console.log() call for example must
185 // find the console instead of creating a new property. Therefore we prioritize the
186 // lookup in the global object here.
187 //
188 // Note: The scope object is only a QADMO for example when somebody registers a QQmlPropertyMap
189 // sub-class as QML type and then instantiates it in .qml.
190 const QMetaObjectPrivate *metaObjectPrivate = scopeObject
191 ? reinterpret_cast<const QMetaObjectPrivate *>(scopeObject->metaObject()->d.data)
192 : nullptr;
193 if (metaObjectPrivate && metaObjectPrivate->flags & DynamicMetaObject) {
194 // all bets are off, so don't try to optimize any lookups
195 lookup = nullptr;
196 if (performLookup(&result, hasProperty, globalLookup))
197 return result->asReturnedValue();
198 }
199
201 if (context->imports() && (name->startsWithUpper() || context->valueTypesAreAddressable())) {
202 // Search for attached properties, enums and imported scripts
205
206 if (r.isValid()) {
207 if (hasProperty)
208 *hasProperty = true;
209 if (r.scriptIndex != -1) {
210 if (lookup) {
211 lookup->qmlContextScriptLookup.scriptIndex = r.scriptIndex;
213 return lookup->qmlContextPropertyGetter(lookup, v4, base);
214 }
215 QV4::ScopedObject scripts(scope, context->importedScripts().valueRef());
216 if (scripts)
217 return scripts->get(r.scriptIndex);
218 return QV4::Encode::null();
219 } else if (r.type.isValid()) {
220 if (lookup) {
221 bool isValueSingleton = false;
222 if (r.type.isSingleton()) {
224 if (r.type.isQObjectSingleton() || r.type.isCompositeSingleton()) {
225 e->singletonInstance<QObject*>(r.type);
226 lookup->qmlContextSingletonLookup.singletonObject.set(v4,
228 QQmlTypeWrapper::create(v4, nullptr, r.type)
229 ).heapObject());
230 } else {
231 QJSValue singleton = e->singletonInstance<QJSValue>(r.type);
232
233 // QSrting values should already have been put on the engine heap at this point
234 // to manage their memory. We later assume this has already happened.
236
237 if (QV4::Value *val = QJSValuePrivate::takeManagedValue(&singleton)) {
238 lookup->qmlContextSingletonLookup.singletonObject.set(v4, val->heapObject());
239 } else {
240 lookup->qmlContextSingletonLookup.singletonValue = QJSValuePrivate::asReturnedValue(&singleton);
241 isValueSingleton = true;
242 }
243 }
246 return lookup->qmlContextPropertyGetter(lookup, v4, base);
247 }
248 }
249 result = QQmlTypeWrapper::create(v4, scopeObject, r.type);
250 } else if (r.importNamespace) {
251 result = QQmlTypeWrapper::create(v4, scopeObject, context->imports(), r.importNamespace);
252 }
253 if (lookup) {
254 lookup->qmlTypeLookup.qmlTypeWrapper.set(v4, result->heapObject());
256 }
257 return result->asReturnedValue();
258 }
259
260 // Fall through
261 }
262
263 Lookup * const originalLookup = lookup;
264
265 decltype(lookup->qmlContextPropertyGetter) contextGetterFunction = QQmlContextWrapper::lookupContextObjectProperty;
266
267 // minor optimization so we don't potentially try two property lookups on the same object
268 if (scopeObject == context->contextObject()) {
269 scopeObject = nullptr;
270 contextGetterFunction = QQmlContextWrapper::lookupScopeObjectProperty;
271 }
272
273 QQmlRefPointer<QQmlContextData> outer = context;
274 while (context) {
275 if (outer == context) {
277 v4, context, name, hasProperty, base, lookup, originalLookup, ep)) {
278 return *property;
279 }
280
281 outer = outer->parent();
282
283 if (const auto cu = context->typeCompilationUnit(); cu && cu->componentsAreBound()) {
284 // If components are bound in this CU, we can search the whole context hierarchy
285 // of the file. Bound components' contexts override their local properties.
286 // You also can't instantiate bound components outside of their creation
287 // context. Therefore this is safe.
288
289 for (;
290 outer && outer->typeCompilationUnit() == cu;
291 outer = outer->parent()) {
293 v4, outer, name, hasProperty, base,
294 nullptr, originalLookup, ep)) {
295 return *property;
296 }
297 }
298 }
299 }
300
301 // Search scope object
302 if (scopeObject) {
303 bool hasProp = false;
304
305 const QQmlPropertyData *propertyData = nullptr;
306
307 QV4::ScopedObject wrapper(scope, QV4::QObjectWrapper::wrap(v4, scopeObject));
309 v4, context, wrapper->d(), scopeObject, name,
310 getQmlPropertyFlags(lookup), &hasProp, &propertyData));
311 if (hasProp) {
312 if (hasProperty)
313 *hasProperty = true;
314 if (base)
315 *base = wrapper;
316
317 if (lookup && propertyData) {
318 QQmlData *ddata = QQmlData::get(scopeObject, false);
319 if (ddata && ddata->propertyCache) {
321 scope,
323 QV4::QObjectWrapper::wrap(v4, scopeObject)));
326 lookup, ddata, propertyData, val->objectValue(),
327 method->d());
330 } else {
332 lookup, ddata, propertyData, val->objectValue());
335 }
336 }
337 }
338
339 return result->asReturnedValue();
340 }
341 }
342 scopeObject = nullptr;
343
344
345 // Search context object
346 if (QObject *contextObject = context->contextObject()) {
347 bool hasProp = false;
348 const QQmlPropertyData *propertyData = nullptr;
349 QV4::ScopedObject wrapper(scope, QV4::QObjectWrapper::wrap(v4, contextObject));
351 v4, context, wrapper->d(), contextObject, name, getQmlPropertyFlags(lookup),
352 &hasProp, &propertyData);
353 if (hasProp) {
354 if (hasProperty)
355 *hasProperty = true;
356 if (base)
357 *base = wrapper;
358
359 if (propertyData) {
360 if (lookup) {
361 QQmlData *ddata = QQmlData::get(contextObject, false);
362 if (ddata && ddata->propertyCache
363 && lookup->qmlContextPropertyGetter != contextGetterFunction) {
365 scope,
367 QV4::QObjectWrapper::wrap(v4, contextObject)));
370 lookup, ddata, propertyData, val->objectValue(),
371 method->d());
372 if (contextGetterFunction == lookupScopeObjectProperty)
374 else
376 } else {
378 lookup, ddata, propertyData, val->objectValue());
379 lookup->qmlContextPropertyGetter = contextGetterFunction;
380 }
381 }
382 } else if (originalLookup) {
383 originalLookup->qmlContextPropertyGetter = lookupInParentContextHierarchy;
384 }
385 }
386
387 return result->asReturnedValue();
388 }
389 }
390
391 context = context->parent();
392
393 // As the hierarchy of contexts is not stable, we can't do accelerated lookups beyond
394 // the immediate QML context (of the .qml file).
395 lookup = nullptr;
396 }
397
398 // Do the generic JS lookup late in case of a non-JavaScript context.
399 // The scope, context, types etc should be able to override it.
400 if (!isJSContext && performLookup(&result, hasProperty, jsLookup))
401 return result->asReturnedValue();
402
403 // Do a lookup in the global object here to avoid expressionContext->unresolvedNames becoming
404 // true if we access properties of the global object.
405 if (originalLookup) {
406 // Try a lookup in the global object. It's theoretically possible to first find a property
407 // in the global object and then later a context property with the same name is added, but that
408 // never really worked as we used to detect access to global properties at type compile time anyway.
409 lookup = originalLookup;
410 result = lookup->resolveGlobalGetter(v4);
412 if (hasProperty)
413 *hasProperty = true;
414 lookup->qmlContextGlobalLookup.getterTrampoline = lookup->globalGetter;
416 return result->asReturnedValue();
417 }
419 } else {
420 if (performLookup(&result, hasProperty, globalLookup))
421 return result->asReturnedValue();
422 }
423
424 expressionContext->setUnresolvedNames(true);
425
426 return Encode::undefined();
427}
428
429ReturnedValue QQmlContextWrapper::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
430{
432 const QQmlContextWrapper *This = static_cast<const QQmlContextWrapper *>(m);
433 return getPropertyAndBase(This, id, receiver, hasProperty, /*base*/nullptr);
434}
435
437{
439
440 if (id.isSymbol() || id.isArrayIndex())
441 return Object::virtualPut(m, id, value, receiver);
442
443 QQmlContextWrapper *resource = static_cast<QQmlContextWrapper *>(m);
444 ExecutionEngine *v4 = resource->engine();
445 QV4::Scope scope(v4);
446 if (scope.hasException())
447 return false;
449
450 auto member = wrapper->internalClass()->findValueOrSetter(id);
451 if (member.index < UINT_MAX)
452 return wrapper->putValue(member.index, member.attrs, value);
453
454 // It's possible we could delay the calculation of the "actual" context (in the case
455 // of sub contexts) until it is definitely needed.
456 QQmlRefPointer<QQmlContextData> context = wrapper->getContext();
457 QQmlRefPointer<QQmlContextData> expressionContext = context;
458
459 if (!context)
460 return false;
461
462 // See QV8ContextWrapper::Getter for resolution order
463
464 QObject *scopeObject = wrapper->getScopeObject();
465 ScopedString name(scope, id.asStringOrSymbol());
466
467 while (context) {
468 // Search context properties
469 if (const int propertyIndex = context->propertyIndex(name); propertyIndex != -1) {
470 if (propertyIndex < context->numIdValues()) {
471 v4->throwError(QLatin1String("left-hand side of assignment operator is not an lvalue"));
472 return false;
473 }
474 return false;
475 }
476
477 // Search scope object
478 if (scopeObject &&
480 return true;
481 scopeObject = nullptr;
482
483 // Search context object
484 if (context->contextObject() &&
487 return true;
488
489 context = context->parent();
490 }
491
492 expressionContext->setUnresolvedNames(true);
493
494 QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
495 QLatin1Char('"');
496 v4->throwError(error);
497 return false;
498}
499
501{
502 Scope scope(engine);
505 func->compilationUnit->runtimeStrings[l->nameIndex]));
506
507 // Special hack for bounded signal expressions, where the parameters of signals are injected
508 // into the handler expression through the locals of the call context. So for onClicked: { ... }
509 // the parameters of the clicked signal are injected and we must allow for them to be found here
510 // before any other property from the QML context.
511 for (Heap::ExecutionContext *ctx = engine->currentContext()->d(); ctx; ctx = ctx->outer) {
512 if (ctx->type == Heap::ExecutionContext::Type_CallContext) {
513 const uint index = ctx->internalClass->indexOfValueOrGetter(name);
514 if (index < std::numeric_limits<uint>::max()) {
515 if (!func->detectedInjectedParameters) {
516 const auto location = func->sourceLocation();
517 qCWarning(lcQmlContext).nospace().noquote()
518 << location.sourceFile << ":" << location.line << ":" << location.column
519 << " Parameter \"" << name->toQString() << "\" is not declared."
520 << " Injection of parameters into signal handlers is deprecated."
521 << " Use JavaScript functions with formal parameters instead.";
522
523 // Don't warn over and over for the same function
524 func->detectedInjectedParameters = true;
525 }
526
527 return static_cast<Heap::CallContext *>(ctx)->locals[index].asReturnedValue();
528 }
529 }
530
531 // Skip only block and call contexts.
532 // Other contexts need a regular QML property lookup. See below.
533 if (ctx->type != Heap::ExecutionContext::Type_BlockContext && ctx->type != Heap::ExecutionContext::Type_CallContext)
534 break;
535 }
536
537 bool hasProperty = false;
538 ScopedValue result(scope);
539
540 Scoped<QmlContext> callingQmlContext(scope, engine->qmlContext());
541 if (callingQmlContext) {
542 Scoped<QQmlContextWrapper> qmlContextWrapper(scope, callingQmlContext->d()->qml());
544 qmlContextWrapper, name, /*receiver*/nullptr, &hasProperty, base, l);
545 } else {
546 // Code path typical to worker scripts, compiled with lookups but no qml context.
549 hasProperty = true;
550 l->qmlContextGlobalLookup.getterTrampoline = l->globalGetter;
552 }
553 }
554 if (!hasProperty)
555 return engine->throwReferenceError(name->toQString());
556 return result->asReturnedValue();
557}
558
560{
561 Q_UNUSED(base);
562 Scope scope(engine);
563 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
564 if (!qmlContext)
565 return QV4::Encode::null();
566
567 QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
568 if (!context)
569 return QV4::Encode::null();
570
571 QV4::ScopedObject scripts(scope, context->importedScripts().valueRef());
572 if (!scripts)
573 return QV4::Encode::null();
574 return scripts->get(l->qmlContextScriptLookup.scriptIndex);
575}
576
578{
580 Q_UNUSED(base);
581
582 return l->qmlContextSingletonLookup.singletonObject->asReturnedValue();
583}
584
593
595{
596 Q_UNUSED(base);
597 Scope scope(engine);
598 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
599 if (!qmlContext)
600 return QV4::Encode::null();
601
602 QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
603 if (!context)
604 return QV4::Encode::null();
605
607 const int objectId = l->qmlContextIdObjectLookup.objectId;
608
609 if (qmlEngine->propertyCapture)
610 qmlEngine->propertyCapture->captureProperty(context->idValueBindings(objectId));
611
612 return QV4::QObjectWrapper::wrap(engine, context->idValue(objectId));
613}
614
620
628
636
637template<typename Call>
639{
640 Scope scope(engine);
641 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
642 if (!qmlContext)
643 return QV4::Encode::undefined();
644
645 QObject *scopeObject = qmlContext->qmlScope();
646 if (!scopeObject)
647 return QV4::Encode::undefined();
648
649 if (QQmlData::wasDeleted(scopeObject))
650 return QV4::Encode::undefined();
651
652 ScopedValue obj(scope, QV4::QObjectWrapper::wrap(engine, scopeObject));
653
654 if (base)
655 *base = obj;
656
657 return c(obj);
658}
659
671
683
684template<typename Call>
686{
687 Scope scope(engine);
688 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
689 if (!qmlContext)
690 return QV4::Encode::undefined();
691
692 QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
693 if (!context)
694 return QV4::Encode::undefined();
695
696 QObject *contextObject = context->contextObject();
697 if (!contextObject)
698 return QV4::Encode::undefined();
699
700 if (QQmlData::wasDeleted(contextObject))
701 return QV4::Encode::undefined();
702
703 ScopedValue obj(scope, QV4::QObjectWrapper::wrap(engine, contextObject));
704
705 if (base)
706 *base = obj;
707
708 return c(obj);
709}
710
723
736
741
743{
744 Q_UNUSED(base);
745 ReturnedValue result = l->qmlContextGlobalLookup.getterTrampoline(l, engine);
746 // In the unlikely event of mutation of the global object, update the trampoline.
748 l->qmlContextGlobalLookup.getterTrampoline = l->globalGetter;
750 }
751 return result;
752}
753
755{
756 Scope scope(engine);
757 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
758 if (!qmlContext)
759 return QV4::Encode::undefined();
760
761 QQmlRefPointer<QQmlContextData> context = qmlContext->qmlContext();
762 if (!context)
763 return QV4::Encode::undefined();
764
765 QQmlRefPointer<QQmlContextData> expressionContext = context;
766
768
770 runtimeStrings[l->nameIndex]);
771 ScopedString name(scope, id.asStringOrSymbol());
772
773 ScopedValue result(scope);
774
775 for (context = context->parent(); context; context = context->parent()) {
776 if (auto property = searchContextProperties(engine, context, name, nullptr, base, nullptr, nullptr, ep))
777 return *property;
778
779 // Search context object
780 if (QObject *contextObject = context->contextObject()) {
781 bool hasProp = false;
784 engine, context, wrapper->d(), contextObject, name, getQmlPropertyFlags(l),
785 &hasProp);
786 if (hasProp) {
787 if (base)
788 *base = wrapper;
789
790 return result->asReturnedValue();
791 }
792 }
793 }
794
795 bool hasProp = false;
796 result = engine->globalObject->get(name, &hasProp);
797 if (hasProp)
798 return result->asReturnedValue();
799
800 expressionContext->setUnresolvedNames(true);
801
802 return Encode::undefined();
803}
804
806{
807 Scope scope(engine);
808 Scoped<QmlContext> qmlContext(scope, engine->qmlContext());
809 if (!qmlContext)
810 return QV4::Encode::undefined();
811
812 QObject *scopeObject = qmlContext->qmlScope();
813 if (scopeObject && QQmlData::wasDeleted(scopeObject))
814 return QV4::Encode::undefined();
815
816 Heap::Base *heapObject = l->qmlTypeLookup.qmlTypeWrapper;
817 if (static_cast<Heap::QQmlTypeWrapper *>(heapObject)->object != scopeObject) {
818 l->qmlTypeLookup.qmlTypeWrapper.clear();
821 }
822
823 return Value::fromHeapObject(heapObject).asReturnedValue();
824}
825
826void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml)
827{
828 Heap::ExecutionContext::init(Heap::ExecutionContext::Type_QmlContext);
829 outer.set(internalClass->engine, outerContext->d());
830
831 this->activation.set(internalClass->engine, qml->d());
832}
833
834Heap::QmlContext *QmlContext::create(
835 ExecutionContext *parent, QQmlRefPointer<QQmlContextData> context,
836 QObject *scopeObject)
837{
838 Scope scope(parent);
839
840 Scoped<QQmlContextWrapper> qml(
842 std::move(context), scopeObject));
843 Heap::QmlContext *c = scope.engine->memoryManager->alloc<QmlContext>(parent, qml);
844 Q_ASSERT(c->vtable() == staticVTable());
845 return c;
846}
847
static QV4::Value * takeManagedValue(QJSValue *jsval)
Definition qjsvalue_p.h:215
static QV4::ReturnedValue asReturnedValue(const QJSValue *jsval)
Definition qjsvalue_p.h:257
static const QString * asQString(const QJSValue *jsval)
Definition qjsvalue_p.h:248
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
static constexpr QMetaType fromType()
Definition qmetatype.h:2642
\inmodule QtCore
Definition qobject.h:103
static qsizetype context_count(QQmlListProperty< QObject > *)
int notifyIndex() const
QVariant propertyValue(int index) const
static QObject * context_at(QQmlListProperty< QObject > *, qsizetype)
static bool wasDeleted(const QObject *)
Definition qqmldata_p.h:312
static QQmlData * get(QObjectPrivate *priv, bool create)
Definition qqmldata_p.h:199
QQmlPropertyCapture * propertyCapture
static QQmlEnginePrivate * get(QQmlEngine *e)
T singletonInstance(const QQmlType &type)
void captureProperty(QObject *object, const QMetaProperty &property) const
void captureProperty(QQmlNotifier *)
T * data() const
static QQmlTypeLoader * get(Engine *engine)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
ObjectType::Data * allocate(Args &&... args)
Definition qv4mm_p.h:298
ManagedType::Data * alloc(Args &&... args)
Definition qv4mm_p.h:307
\inmodule QtCore
Definition qvariant.h:65
EGLContext ctx
Combined button and popup list for selecting options.
void setupQObjectMethodLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
quint64 ReturnedValue
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
Scoped< String > ScopedString
static void * context
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
@ DynamicMetaObject
constexpr int qMetaTypeId()
Definition qmetatype.h:1405
GLint location
const GLfloat * m
GLuint index
[2]
GLboolean r
[2]
GLenum GLuint id
[7]
GLbitfield flags
GLuint name
GLhandleARB obj
[2]
GLenum func
Definition qopenglext.h:663
const GLubyte * c
GLuint GLfloat * val
GLuint64EXT * result
[6]
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
ptrdiff_t qintptr
Definition qtypes.h:166
static const uint base
Definition qurlidna.cpp:20
static ReturnedValue revertObjectMethodLookup(Lookup *l, ExecutionEngine *engine, Value *base)
static QV4::QObjectWrapper::Flags getQmlPropertyFlags(const Lookup *l)
static ReturnedValue revertObjectPropertyLookup(Lookup *l, ExecutionEngine *engine, Value *base)
static OptionalReturnedValue searchContextProperties(QV4::ExecutionEngine *v4, const QQmlRefPointer< QQmlContextData > &context, String *name, bool *hasProperty, Value *base, QV4::Lookup *lookup, QV4::Lookup *originalLookup, QQmlEnginePrivate *ep)
ReturnedValue callWithScopeObject(ExecutionEngine *engine, Value *base, Call c)
ReturnedValue callWithContextObject(ExecutionEngine *engine, Value *base, Call c)
bool performLookup(ScopedValue *result, bool *hasProperty, const Lookup &lookup)
#define DEFINE_OBJECT_VTABLE(classname)
#define DEFINE_MANAGED_VTABLE(classname)
const char property[13]
Definition qwizard.cpp:101
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
static constexpr ReturnedValue undefined()
static constexpr ReturnedValue null()
IdentifierTable * identifierTable
MemoryManager * memoryManager
CppStackFrame * currentStackFrame
QQmlRefPointer< QQmlContextData > callingQmlContext() const
ReturnedValue throwError(const Value &value)
ReturnedValue throwReferenceError(const Value &value)
QV4::ReturnedValue fromVariant(const QVariant &)
QQmlEngine * qmlEngine() const
static Heap::ExecutionContext * qmlContext(Heap::ExecutionContext *ctx)
ExecutionContext * currentContext() const
WriteBarrier::HeapObjectWrapper< CompilationUnitRuntimeData, 1 > compilationUnit
PropertyKey asPropertyKey(const Heap::String *str)
ReturnedValue(* globalGetter)(Lookup *l, ExecutionEngine *engine)
Definition qv4lookup_p.h:41
ReturnedValue resolveGlobalGetter(ExecutionEngine *engine)
Definition qv4lookup.cpp:89
ReturnedValue(* qmlContextPropertyGetter)(Lookup *l, ExecutionEngine *engine, Value *thisObject)
Definition qv4lookup_p.h:42
struct QV4::Lookup::@583::@604 qmlContextIdObjectLookup
struct QV4::Lookup::@583::@599 qobjectMethodLookup
static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
struct QV4::Lookup::@583::@606 qmlTypeLookup
struct QV4::Lookup::@583::@598 qobjectLookup
struct QV4::Lookup::@583::@605 qmlContextGlobalLookup
struct QV4::Lookup::@583::@602 qmlContextScriptLookup
struct QV4::Lookup::@583::@603 qmlContextSingletonLookup
Q_ALWAYS_INLINE Heap::Base * heapObject() const
ExecutionEngine * engine() const
const Value * propertyData(uint index) const
bool hasProperty(PropertyKey id) const
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
static bool setQmlProperty(ExecutionEngine *engine, const QQmlRefPointer< QQmlContextData > &qmlContext, QObject *object, String *name, Flags flags, const Value &value)
ReturnedValue getQmlProperty(const QQmlRefPointer< QQmlContextData > &qmlContext, String *name, Flags flags, bool *hasProperty=nullptr) const
static ReturnedValue lookupPropertyGetterImpl(Lookup *l, ExecutionEngine *engine, const Value &object, Flags flags, ReversalFunctor revert)
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object)
static ReturnedValue lookupMethodGetterImpl(Lookup *l, ExecutionEngine *engine, const Value &object, Flags flags, ReversalFunctor revert)
static ReturnedValue lookupScopeObjectMethod(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupSingleton(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupInParentContextHierarchy(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupContextObjectMethod(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue getPropertyAndBase(const QQmlContextWrapper *resource, PropertyKey id, const Value *receiver, bool *hasProperty, Value *base, Lookup *lookup=nullptr)
QQmlRefPointer< QQmlContextData > getContext() const
static ReturnedValue lookupContextObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base)
V4_NEEDS_DESTROY QObject * getScopeObject() const
static ReturnedValue lookupIdObjectInParentContext(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupIdObject(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue resolveQmlContextPropertyLookupGetter(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupScopeObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupValueSingleton(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupScopeFallbackProperty(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupType(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue lookupScript(Lookup *l, ExecutionEngine *engine, Value *base)
static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlType &, Heap::QQmlTypeWrapper::TypeNameMode=Heap::QQmlTypeWrapper::IncludeEnums)
static Heap::QmlContext * create(QV4::ExecutionContext *parent, QQmlRefPointer< QQmlContextData > context, QObject *scopeObject)
static V4_NEEDS_DESTROY ReturnedValue create(ExecutionEngine *engine, QObject *object, int propId, QMetaType propType)
bool hasException() const
ExecutionEngine * engine
constexpr ReturnedValue asReturnedValue() const
static constexpr VTable::Get virtualGet
static constexpr VTable::Put virtualPut
bool isString() const
Definition qv4value_p.h:284
QML_NEARLY_ALWAYS_INLINE Object * objectValue() const
Definition qv4value_p.h:70
static Value fromHeapObject(HeapBasePtr m)
Definition qv4value_p.h:84
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
bool isSymbol() const
Definition qv4value_p.h:296
void wrapper()