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>
49void Heap::FunctionObject::init()
54void Heap::JavaScriptFunctionObject::init(
60 FunctionObject::init(
s.engine,
name);
61 this->scope.set(
s.engine, scope->d());
65void Heap::JavaScriptFunctionObject::setFunction(
Function *
f)
69 function->executableCompilationUnit()->addref();
72void Heap::JavaScriptFunctionObject::destroy()
75 function->executableCompilationUnit()->release();
76 FunctionObject::destroy();
79void Heap::DynamicFunctionObject::init(
117 [
f](
const Value *thisObject,
const Value *argv,
int argc) {
118 return f->call(thisObject, argv, argc);
124 if (function->isArrowFunction())
134 Heap::DefaultClassConstructorFunction *
c
136 c->isDerivedConstructor = isDerivedConstructor;
140 Heap::ConstructorFunction *
c
143 c->isDerivedConstructor = isDerivedConstructor;
150 m->homeObject.
set(scope->
engine(), homeObject->d());
164 return function->d();
171 return m->d()->homeObject->asReturnedValue();
174 return c->d()->homeObject->asReturnedValue();
182 return d()->function->sourceLocation();
191 return d->jsCall(
f, thisObject, argv, argc);
209 for (
int i = 0, ei = argc - 1;
i < ei; ++
i) {
223 lexer.
setCode(function, 1,
false);
224 QQmlJS::Parser parser(&ee);
226 const bool parsed = parser.parseExpression();
255 QQmlRefPointer<ExecutableCompilationUnit> compilationUnit
256 = parse(
engine, argv, argc, Type_Function);
260 Function *vmf = compilationUnit->rootFunction();
268 obj->setProtoFromNewTarget(newTarget);
269 return obj->asReturnedValue();
282 Heap::FunctionObject::init();
318 const QString functionName(scopedFunctionName ? scopedFunctionName->toQString() :
QString());
323 if (!functionName.isEmpty())
324 functionAsString.append(
QLatin1Char(
' ') + functionName);
337 thisObject = argc ? argv :
nullptr;
353 int l =
qMin(
len,
a->d()->context->argc());
355 for (
int i = l;
i <
len; ++
i)
357 }
else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
359 int alen = sad ? sad->values.size : 0;
362 for (
int i = 0;
i < alen; ++
i)
364 for (
int i = alen;
i <
len; ++
i)
369 for (
int i = 0;
i <
len; ++
i)
385 thisObject = argc ? argv :
nullptr;
401 Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)
nullptr);
403 int nArgs = (argc - 1 >= 0) ? argc - 1 : 0;
404 if (
target->isBoundFunction()) {
406 Scoped<MemberData> oldArgs(scope, bound->
boundArgs());
408 int oldSize = !oldArgs ? 0 : oldArgs->size();
409 if (oldSize + nArgs) {
411 boundArgs->d()->values.size = oldSize + nArgs;
412 for (
uint i = 0; i < static_cast<uint>(oldSize); ++
i)
413 boundArgs->set(scope.
engine,
i, oldArgs->data()[
i]);
414 for (
uint i = 0; i < static_cast<uint>(nArgs); ++
i)
415 boundArgs->set(scope.
engine, oldSize +
i, argv[
i + 1]);
420 boundArgs->d()->values.size = nArgs;
421 for (
uint i = 0, ei =
static_cast<uint>(nArgs);
i < ei; ++
i)
422 boundArgs->set(scope.
engine,
i, argv[
i + 1]);
425 if (
target->isConstructor()) {
455 Scoped<InternalClass> ic(scope);
456 if (nt->d() ==
f->d()) {
457 ic =
f->classForConstructor();
462 ic = ic->changePrototype(
o->d());
467 frame.init(
f->function(), argv, argc);
492 Function *function = self->function();
495 [fo](
const Value *thisObject,
const Value *argv,
int argc) {
496 return ArrowFunction::virtualCall(fo, thisObject, argv, argc);
516 frame.init(fo->function(), argv, argc,
true);
517 frame.setupJSFrame(
engine->jsStackTop, *fo, fo->scope(),
521 engine->jsStackTop +=
frame.requiredJSStackFrameSize();
526 frame.setPendingTailCall(
false);
528 frame.setTailCalling(
true);
529 }
while (
frame.pendingTailCall());
540 Function *function = self->function();
541 switch (function->kind) {
544 fo->engine(), &function->aotCompiledFunction, thisObject, argv, argc,
546 ArrowFunction::virtualCallWithMetaTypes(fo, thisObject, a, types, argc);
550 fo->engine(), &function->jsTypedFunction, function->compiledFunction, argv, argc,
551 [self, thisObject](
const Value *argv,
int argc) {
552 return qfoDoCall(self, thisObject, argv, argc);
558 return qfoDoCall(self, thisObject, argv, argc);
564 JavaScriptFunctionObject::init(scope, function,
n);
567 Q_ASSERT(internalClass && internalClass->verifyIndex(
s.engine->id_length()->propertyKey(), Index_Length));
574 Q_ASSERT(!function->isArrowFunction());
578 f->createDefaultPrototypeProperty(Heap::FunctionObject::Index_ProtoConstructor);
584 FunctionObject::init(
s.engine,
nullptr);
585 this->scope.set(
s.engine, scope->d());
592 if (
d()->cachedClassForConstructor &&
d()->cachedClassForConstructor->prototype ==
o->heapObject())
593 return d()->cachedClassForConstructor;
598 ic = ic->changePrototype(
p->d());
599 d()->cachedClassForConstructor.set(scope.
engine, ic->d());
609 if (!
c->d()->isDerivedConstructor)
615 frame.init(
c->function(), argv, argc);
644 return f->engine()->throwTypeError(
QStringLiteral(
"Cannot call a class constructor without |new|"));
658 if (!
c->d()->isDerivedConstructor) {
661 c->setPrototypeUnchecked(proto);
662 return c->asReturnedValue();
666 Q_ASSERT(super->isFunctionObject());
669 frame.init(
nullptr, argv, argc);
700 return f->engine()->throwTypeError(
QStringLiteral(
"Cannot call a class constructor without |new|"));
707void Heap::BoundFunction::init(
715 JavaScriptFunctionObject::init(
ctx, js->function(),
name);
718 JavaScriptFunctionObject::init(
engine->rootContext(),
nullptr,
name);
722 this->boundArgs.
set(
s.engine, boundArgs ? boundArgs->d() :
nullptr);
723 this->boundThis.set(
s.engine, boundThis);
728 int len = l->toUInt32();
736 pd->value =
engine->thrower();
737 pd->set =
engine->thrower();
750 Scoped<MemberData> boundArgs(scope,
f->boundArgs());
752 JSCallArguments jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
753 *jsCallData.thisObject =
f->boundThis();
754 Value *argp = jsCallData.args;
756 memcpy(argp, boundArgs->data(), boundArgs->size()*
sizeof(
Value));
757 argp += boundArgs->size();
759 memcpy(argp, argv, argc*
sizeof(
Value));
771 if (
scope.hasException())
777 Value *argp = jsCallData.args;
782 memcpy(argp, argv, argc*
sizeof(
Value));
783 return target->callAsConstructor(jsCallData);
void setCode(const QString &code, int lineno, bool qmlMode=true, CodeContinuation codeContinuation=CodeContinuation::Reset)
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QQmlRefPointer< QV4::CompiledData::CompilationUnit > generateCompilationUnit(bool generateUnitData=true)
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)
type name READ getFunction WRITE setFunction
[0]
QList< QVariant > arguments
Scoped< FunctionObject > ScopedFunctionObject
ReturnedValue convertAndCall(ExecutionEngine *engine, const Function::AOTCompiledFunction *aotFunction, const Value *thisObject, const Value *argv, int argc, Callable call)
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
Scoped< String > ScopedString
ReturnedValue coerceAndCall(ExecutionEngine *engine, const Function::JSTypedFunction *typedFunction, const CompiledData::Function *compiledFunction, const Value *argv, int argc, Callable call)
Scoped< ExecutionContext > ScopedContext
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
static QDBusError::ErrorType get(const char *name)
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::JavaScriptFunctionObject *fo, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
#define CHECK_EXCEPTION()
#define DEFINE_OBJECT_VTABLE(classname)
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)
\inmodule QtCore \reentrant
static bool isNonStrictArgumentsObject(Managed *m)
Heap::FunctionObject * target() const
Heap::MemberData * boundArgs() const
static constexpr ReturnedValue undefined()
Heap::InternalClass * internalClasses(InternalClassType icType)
MemoryManager * memoryManager
QQmlRefPointer< ExecutableCompilationUnit > insertCompilationUnit(QQmlRefPointer< QV4::CompiledData::CompilationUnit > &&unit)
QV4::Debugging::Debugger * debugger() const
String * id_length() const
ReturnedValue throwReferenceError(const Value &value)
String * id_toString() const
String * id_prototype() const
Heap::Object * newObject()
int safeForAllocLength(qint64 len64)
Heap::String * newString(char16_t c)
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
ReturnedValue failCall() 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)
ReturnedValue failCallAsConstructor() const
void createDefaultPrototypeProperty(uint protoConstructorSlot)
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)
void init(QV4::ExecutionContext *scope, Function *function, QV4::String *name=nullptr)
void init(QV4::ExecutionEngine *engine)
QQmlSourceLocation sourceLocation() const
V4_NEEDS_DESTROY Heap::ExecutionContext * scope() const
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)
bool set(StringOrSymbol *name, const Value &v, ThrowOnFailure shouldThrow)
void setProperty(const InternalClassEntry &entry, const Property *p)
void defineReadonlyConfigurableProperty(const QString &name, const Value &value)
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
Value * alloc(qint64 nValues) const =delete
Heap::InternalClass * classForConstructor() const
constexpr ReturnedValue asReturnedValue() const
bool isNullOrUndefined() const
static constexpr VTable::CallAsConstructor virtualCallAsConstructor
static constexpr VTable::Call virtualCall
static constexpr VTable::CallWithMetaTypes virtualCallWithMetaTypes
static constexpr VTable::InstanceOf virtualInstanceOf
static constexpr VTable::CallWithMetaTypes virtualConvertAndCall
ReturnedValue(* Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
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()