7#include <private/qv4mm_p.h>
12#include <private/qqmljsengine_p.h>
13#include <private/qqmljslexer_p.h>
14#include <private/qqmljsparser_p.h>
15#include <private/qqmljsast_p.h>
16#include <private/qqmljavascriptexpression_p.h>
17#include <private/qqmlengine_p.h>
19#include "private/qlocale_tools_p.h"
20#include "private/qqmlbuiltinfunctions_p.h"
21#include <private/qv4jscall_p.h>
22#include <private/qv4vme_moth_p.h>
23#include <private/qv4alloca_p.h>
25#include <QtCore/QDebug>
37 jsCallWithMetaTypes = callWithMetaTypes;
38 jsConstruct =
nullptr;
41 this->scope.set(scope->
engine(), scope->d());
52 jsCall = vtable()->call;
53 jsCallWithMetaTypes = vtable()->callWithMetaTypes;
54 jsConstruct = vtable()->callAsConstructor;
57 this->scope.set(scope->
engine(), scope->d());
68 jsCall = vtable()->call;
69 jsCallWithMetaTypes = vtable()->callWithMetaTypes;
70 jsConstruct = vtable()->callAsConstructor;
74 this->scope.set(scope->
engine(), scope->d());
84 Scope valueScope(scope);
89void Heap::FunctionObject::init()
91 jsCall = vtable()->call;
92 jsCallWithMetaTypes = vtable()->callWithMetaTypes;
93 jsConstruct = vtable()->callAsConstructor;
96 this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d());
99void Heap::FunctionObject::setFunction(
Function *
f)
103 function->executableCompilationUnit()->addref();
106void Heap::FunctionObject::destroy()
109 function->executableCompilationUnit()->release();
120 proto->setProperty(protoConstructorSlot,
d());
126 if (
const auto callWithMetaTypes =
d()->jsCallWithMetaTypes) {
127 callWithMetaTypes(
this, thisObject,
a,
types, argc);
132 [
this](
const Value *thisObject,
const Value *argv,
int argc) {
133 return call(thisObject, argv, argc);
163 c->isDerivedConstructor = isDerivedConstructor;
167 c->homeObject.
set(
scope->engine(), homeObject->d());
168 c->isDerivedConstructor = isDerivedConstructor;
175 m->homeObject.
set(
scope->engine(), homeObject->d());
195 return m->d()->homeObject->asReturnedValue();
198 return c->d()->homeObject->asReturnedValue();
204 return d()->function->sourceLocation();
220 for (
int i = 0, ei = argc - 1;
i < ei; ++
i) {
235 QQmlJS::Parser parser(&ee);
237 const bool parsed = parser.parseExpression();
267 = parse(
engine, argv, argc, Type_Function);
279 obj->setProtoFromNewTarget(newTarget);
280 return obj->asReturnedValue();
293 Heap::FunctionObject::init();
323 const QString functionName(scopedFunctionName ? scopedFunctionName->toQString() :
QString());
328 if (!functionName.isEmpty())
329 functionAsString.append(
QLatin1Char(
' ') + functionName);
342 thisObject = argc ? argv :
nullptr;
358 int l =
qMin(
len,
a->d()->context->argc());
360 for (
int i = l;
i <
len; ++
i)
364 int alen = sad ? sad->values.size : 0;
367 for (
int i = 0;
i < alen; ++
i)
369 for (
int i = alen;
i <
len; ++
i)
374 for (
int i = 0;
i <
len; ++
i)
390 thisObject = argc ? argv :
nullptr;
403 return scope.engine->throwTypeError();
408 int nArgs = (argc - 1 >= 0) ? argc - 1 : 0;
409 if (
target->isBoundFunction()) {
413 int oldSize = !oldArgs ? 0 : oldArgs->size();
414 if (oldSize + nArgs) {
416 boundArgs->d()->values.size = oldSize + nArgs;
417 for (
uint i = 0; i < static_cast<uint>(oldSize); ++
i)
418 boundArgs->set(
scope.engine,
i, oldArgs->data()[
i]);
419 for (
uint i = 0; i < static_cast<uint>(nArgs); ++
i)
420 boundArgs->set(
scope.engine, oldSize +
i, argv[
i + 1]);
425 boundArgs->d()->values.size = nArgs;
426 for (
uint i = 0, ei =
static_cast<uint>(nArgs);
i < ei; ++
i)
427 boundArgs->set(
scope.engine,
i, argv[
i + 1]);
432 bound->setFunction(
target->function());
433 return bound->asReturnedValue();
458 if (nt->d() ==
f->d()) {
459 ic =
f->classForConstructor();
464 ic = ic->changePrototype(
o->d());
469 frame.init(
f->function(), argv, argc);
495 [fo](
const Value *thisObject,
const Value *argv,
int argc) {
496 return ArrowFunction::virtualCall(fo, thisObject, argv, argc);
520 engine->jsStackTop +=
frame.requiredJSStackFrameSize();
525 frame.setPendingTailCall(
false);
527 frame.setTailCalling(
true);
528 }
while (
frame.pendingTailCall());
544 ArrowFunction::virtualCallWithMetaTypes(fo, thisObject, a, types, argc);
549 thisObject, argv, argc,
550 [fo](
const Value *thisObject,
const Value *argv,
int argc) {
551 return qfoDoCall(fo, thisObject, argv, argc);
557 return qfoDoCall(fo, thisObject, argv, argc);
562 FunctionObject::init();
563 this->scope.set(scope->
engine(), scope->d());
575 Q_ASSERT(internalClass && internalClass->verifyIndex(
s.engine->id_length()->propertyKey(), Index_Length));
577 canBeTailCalled =
true;
587 f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_ProtoConstructor);
594 if (
d()->cachedClassForConstructor &&
d()->cachedClassForConstructor->prototype ==
o->heapObject())
595 return d()->cachedClassForConstructor;
600 ic = ic->changePrototype(
p->d());
601 d()->cachedClassForConstructor.set(scope.
engine, ic->d());
611 if (!
c->d()->isDerivedConstructor)
617 frame.init(
f->function(), argv, argc);
646 return f->engine()->throwTypeError(
QStringLiteral(
"Cannot call a class constructor without |new|"));
660 if (!
c->d()->isDerivedConstructor) {
663 c->setPrototypeUnchecked(proto);
664 return c->asReturnedValue();
668 Q_ASSERT(super->isFunctionObject());
671 frame.init(
nullptr, argv, argc);
702 return f->engine()->throwTypeError(
QStringLiteral(
"Cannot call a class constructor without |new|"));
713 Heap::FunctionObject::init(scope,
QStringLiteral(
"__bound function__"));
715 this->boundArgs.
set(
s.engine, boundArgs ? boundArgs->d() :
nullptr);
716 this->boundThis.set(scope->
engine(), boundThis);
718 if (!
target->isConstructor())
719 jsConstruct =
nullptr;
724 int len = l->toUInt32();
732 pd->value =
s.engine->thrower();
733 pd->set =
s.engine->thrower();
748 JSCallArguments jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
752 memcpy(argp, boundArgs->data(), boundArgs->size()*
sizeof(
Value));
753 argp += boundArgs->size();
755 memcpy(argp, argv, argc*
sizeof(
Value));
769 JSCallArguments jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
772 memcpy(argp, boundArgs->data(), boundArgs->size()*
sizeof(
Value));
773 argp += boundArgs->size();
775 memcpy(argp, argv, argc*
sizeof(
Value));
776 return target->callAsConstructor(jsCallData);
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
void setCode(const QString &code, int lineno, bool qmlMode=true, CodeContinuation codeContinuation=CodeContinuation::Reset)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData=true)
static QQmlRefPointer< ExecutableCompilationUnit > create()
ObjectType::Data * allocate(Args &&... args)
ObjectType::Data * allocObject(Heap::InternalClass *ic, Args &&... args)
static void exec(MetaTypesStackFrame *frame, ExecutionEngine *engine)
void generateFromFunctionExpression(const QString &fileName, const QString &sourceCode, QQmlJS::AST::FunctionExpression *ast, Compiler::Module *module)
object setProperty("down", true)
type name READ getFunction WRITE setFunction
[0]
QList< QVariant > arguments
\qmltype Particle \inqmlmodule QtQuick.Particles
ReturnedValue convertAndCall(ExecutionEngine *engine, const QQmlPrivate::AOTCompiledFunction *aotFunction, const Value *thisObject, const Value *argv, int argc, Callable call)
ReturnedValue coerceAndCall(ExecutionEngine *engine, const Function::JSTypedFunction *typedFunction, const CompiledData::Function *compiledFunction, const Value *thisObject, const Value *argv, int argc, Callable call)
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
constexpr const T & qMin(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLsizei GLenum GLenum * types
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
static ReturnedValue qfoDoCall(const QV4::FunctionObject *fo, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
#define CHECK_EXCEPTION()
#define DEFINE_OBJECT_VTABLE(classname)
\inmodule QtCore \reentrant
static bool isNonStrictArgumentsObject(Managed *m)
Heap::FunctionObject * target() const
static Heap::BoundFunction * create(ExecutionContext *scope, FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs)
Heap::MemberData * boundArgs() const
static constexpr ReturnedValue undefined()
Heap::InternalClass * internalClasses(InternalClassType icType)
MemoryManager * memoryManager
ExecutionContext * rootContext() const
Heap::String * newString(const QString &s=QString())
QV4::Debugging::Debugger * debugger() const
String * id_length() const
ReturnedValue throwReferenceError(const Value &value)
String * id_toString() const
String * id_prototype() const
int safeForAllocLength(qint64 len64)
ExecutionContext * scriptContext() const
String * id_empty() const
Symbol * symbol_hasInstance() const
ReturnedValue throwSyntaxError(const QString &message)
ReturnedValue throwTypeError()
static QQmlRefPointer< ExecutableCompilationUnit > parse(ExecutionEngine *engine, const Value *argv, int argc, Type t=Type_Function)
static Heap::FunctionObject * createMemberFunction(ExecutionContext *scope, Function *function, Object *homeObject, String *name)
static Heap::FunctionObject * createScriptFunction(ExecutionContext *scope, Function *function)
ReturnedValue getHomeObject() const
static Heap::FunctionObject * createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
ReturnedValue protoProperty() const
ReturnedValue name() const
static Heap::FunctionObject * createConstructorFunction(ExecutionContext *scope, Function *function, Object *homeObject, bool isDerivedConstructor)
QQmlSourceLocation sourceLocation() const
void createDefaultPrototypeProperty(uint protoConstructorSlot)
ReturnedValue call(const JSCallData &data) const
Function * function() const
Heap::ExecutionContext * scope() const
static ReturnedValue method_bind(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_hasInstance(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_apply(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
const JSTypedFunction * jsTypedFunction
bool isArrowFunction() const
const CompiledData::Function * compiledFunction
const QQmlPrivate::AOTCompiledFunction * aotCompiledFunction
void init(QV4::ExecutionContext *scope, Function *function, QV4::String *name=nullptr)
void init(QV4::ExecutionContext *scope)
Heap::InternalClass * internalClass() const
ExecutionEngine * engine() const
static Heap::MemberData * allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old=nullptr)
void set(EngineBase *e, uint index, Value v)
void defineDefaultProperty(StringOrSymbol *name, const Value &value, PropertyAttributes attributes=Attr_Data|Attr_NotEnumerable)
Heap::ArrayData * arrayData() const
ArrayData::Type arrayType() const
bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
void defineReadonlyConfigurableProperty(const QString &name, const Value &value)
void defineReadonlyProperty(const QString &name, const Value &value)
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
bool hasException() const
Heap::InternalClass * classForConstructor() const
constexpr ReturnedValue asReturnedValue() const
bool isNullOrUndefined() const
QString toQString() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr VTable::CallWithMetaTypes virtualCallWithMetaTypes
static constexpr VTable::InstanceOf virtualInstanceOf
ReturnedValue(* Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
void(* CallWithMetaTypes)(const FunctionObject *, QObject *, void **, const QMetaType *, int)
static constexpr Value fromInt32(int i)
bool isFunctionObject() const
static constexpr Value undefinedValue()
QML_NEARLY_ALWAYS_INLINE Object * objectValue() const
static constexpr Value fromReturnedValue(ReturnedValue val)
QString toQString() const
static constexpr Value emptyValue()