6#include <private/qqmlengine_p.h>
7#include <private/qqmljavascriptexpression_p.h>
8#include <private/qqmljsast_p.h>
9#include <private/qqmltypewrapper_p.h>
10#include <private/qqmlvaluetypewrapper_p.h>
11#include <private/qv4argumentsobject_p.h>
12#include <private/qv4engine_p.h>
13#include <private/qv4function_p.h>
14#include <private/qv4generatorobject_p.h>
15#include <private/qv4global_p.h>
16#include <private/qv4globalobject_p.h>
17#include <private/qv4jscall_p.h>
18#include <private/qv4lookup_p.h>
19#include <private/qv4math_p.h>
20#include <private/qv4object_p.h>
21#include <private/qv4qmlcontext_p.h>
22#include <private/qv4qobjectwrapper_p.h>
23#include <private/qv4regexp_p.h>
24#include <private/qv4regexpobject_p.h>
25#include <private/qv4scopedvalue_p.h>
26#include <private/qv4stackframe_p.h>
27#include <private/qv4symbol_p.h>
29#include <wtf/MathExtras.h>
31#include <QtCore/private/qlocale_tools_p.h>
32#include <QtCore/qdebug.h>
34#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
35# include <QtCore/qbuffer.h>
46#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
47struct RuntimeCounters::Data {
58 static const char *pretty(
Type t) {
62 case Null:
return "Null";
65 case Managed:
return "Managed";
66 case Double:
return "Double";
67 default:
return "Unknown";
71 static unsigned mangle(
unsigned tag) {
73 case Value::Undefined_Type:
return Undefined;
74 case Value::Null_Type:
return Null;
75 case Value::Boolean_Type:
return Boolean;
76 case Value::Integer_Type:
return Integer;
77 case Value::Managed_Type:
return Managed;
82 static unsigned mangle(
unsigned tag1,
unsigned tag2) {
83 return (mangle(tag1) << 3) | mangle(tag2);
86 static void unmangle(
unsigned signature,
Type &tag1,
Type &tag2) {
87 tag1 =
Type((signature >> 3) & 7);
88 tag2 =
Type(signature & 7);
105 cnt[mangle(
tag)] += 1;
108 inline void count(
const char *
func,
unsigned tag1,
unsigned tag2) {
112 cnt[mangle(tag1, tag2)] += 1;
120 static bool less(
const Line &line1,
const Line &line2) {
121 return line1.count > line2.count;
131 const Counters &fCount =
it.value();
132 for (
int i = 0, ei = fCount.size();
i != ei; ++
i) {
143 std::sort(lines.
begin(), lines.
end(), Line::less);
144 outs << lines.
size() <<
" counters:" <<
endl;
148 <<
" | " << pretty(
line.tag1)
149 <<
" | " << pretty(
line.tag2)
155RuntimeCounters *RuntimeCounters::instance = 0;
156static RuntimeCounters runtimeCountersInstance;
157RuntimeCounters::RuntimeCounters()
164RuntimeCounters::~RuntimeCounters()
170void RuntimeCounters::count(
const char *
func)
175void RuntimeCounters::count(
const char *
func,
uint tag)
180void RuntimeCounters::count(
const char *
func,
uint tag1,
uint tag2)
182 d->count(
func, tag1, tag2);
189 return f->executableCompilationUnit()->runtimeLookups +
i;
196 if (std::isnan(
num)) {
207 const int ecma_shortest_low = -6;
208 const int ecma_shortest_high = 21;
217 if (decpt <= ecma_shortest_low || decpt > ecma_shortest_high) {
224 }
else if (decpt <= 0) {
226 }
else if (decpt < result->
size()) {
239 bool negative =
false;
246 double frac =
num - ::floor(
num);
247 num = Value::toInteger(
num);
250 char c = (char)::fmod(
num, radix);
251 c = (
c < 10) ? (
c +
'0') : (
c - 10 +
'a');
253 num = ::floor(
num / radix);
258 double magnitude = 1;
262 const int floored = ::floor(
next);
263 char c = char(floored);
264 c = (
c < 10) ? (
c +
'0') : (
c - 10 +
'a');
267 frac -= double(floored) * magnitude;
268 next -= double(floored);
273 }
while (frac > 0 && frac - magnitude != frac);
283 ->runtimeFunctions[functionId];
287 return GeneratorFunction::create(current, clos)->asReturnedValue();
288 return FunctionObject::createScriptFunction(current, clos)->asReturnedValue();
296 return Encode::undefined();
302 return o->deleteProperty(
key);
319 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
320 return engine->currentContext()->deleteProperty(
name);
325 if (!Runtime::DeleteName_NoThrow::call(
engine,
name)) {
339 return engine->throwTypeError();
344 if (
f &&
f->d()->prototype() ==
engine->functionPrototype()->d() && !
f->hasHasInstanceProperty())
345 return Object::checkedInstanceOf(
engine,
f, lval);
354 return engine->throwTypeError();
356 return Encode(fHasInstance->
call(&rval, &lval, 1));
375 return Encode::null();
380 else if (
result->isBoolean())
381 return Encode::null();
387 return Encode::undefined();
394 return engine->throwTypeError();
398 return Encode::undefined();
403double RuntimeHelpers::stringToNumber(
const QString &
string)
410 const int excessiveLength = 16 * 1024;
411 if (
string.
size() > excessiveLength)
435 const char *
end =
nullptr;
438 if (
ba ==
"Infinity" ||
ba ==
"+Infinity")
440 else if (
ba ==
"-Infinity")
443 d = std::numeric_limits<double>::quiet_NaN();
451 RuntimeHelpers::numberToString(&qstr,
number, 10);
452 return engine->newString(qstr);
459 return Encode::undefined();
477 return Encode::undefined();
481 return Encode::undefined();
482 if (!
result->isPrimitive())
483 return engine->throwTypeError();
484 return result->asReturnedValue();
489 return ordinaryToPrimitive(
engine,
object,
hint);
511 result =
o->call(
object,
nullptr, 0);
513 return Encode::undefined();
514 if (
result->isPrimitive())
515 return result->asReturnedValue();
519 return Encode::undefined();
521 conv =
object->get(meth2);
523 result =
o->call(
object,
nullptr, 0);
525 return Encode::undefined();
526 if (
result->isPrimitive())
527 return result->asReturnedValue();
530 return engine->throwTypeError();
537 switch (
value.type()) {
538 case Value::Undefined_Type:
539 engine->throwTypeError(
QLatin1String(
"Value is undefined and could not be converted to an object"));
541 case Value::Null_Type:
542 engine->throwTypeError(
QLatin1String(
"Value is null and could not be converted to an object"));
544 case Value::Boolean_Type:
545 return engine->newBooleanObject(
value.booleanValue());
546 case Value::Managed_Type:
548 if (!
value.isString())
549 return engine->newSymbolObject(
value.symbolValue());
550 return engine->newStringObject(
value.stringValue());
551 case Value::Integer_Type:
560 switch (
value.type()) {
561 case Value::Empty_Type:
562 Q_ASSERT(!
"empty Value encountered");
564 case Value::Undefined_Type:
565 return engine->id_undefined()->d();
566 case Value::Null_Type:
567 return engine->id_null()->d();
568 case Value::Boolean_Type:
569 if (
value.booleanValue())
570 return engine->id_true()->d();
572 return engine->id_false()->d();
573 case Value::Managed_Type: {
574 if (
value.isString())
576 if (
value.isSymbol()) {
580 value = Value::fromReturnedValue(RuntimeHelpers::toPrimitive(
value,
hint));
582 if (
value.isString())
586 case Value::Integer_Type:
587 return RuntimeHelpers::stringFromNumber(
engine,
value.int_32());
589 return RuntimeHelpers::stringFromNumber(
engine,
value.doubleValue());
608 if (sleft || sright) {
611 sleft =
static_cast<String *
>(pleft.
ptr);
615 sright =
static_cast<String *
>(pright.
ptr);
618 return Encode::undefined();
619 if (!sleft->d()->length())
621 if (!sright->d()->length())
626 double x = RuntimeHelpers::toNumber(pleft);
627 double y = RuntimeHelpers::toNumber(pright);
633 return function->executableCompilationUnit()->templateObjectAt(
index)->asReturnedValue();
660 if (
const String *
str =
object.as<String>()) {
662 return Encode::undefined();
668 if (
object.isNullOrUndefined()) {
673 o = RuntimeHelpers::convertToObject(scope.
engine,
object);
677 if (
o->arrayData() && !
o->arrayData()->attrs) {
680 return v->asReturnedValue();
694 if (
object.isNullOrUndefined()) {
699 o = RuntimeHelpers::convertToObject(scope.
engine,
object);
705 return Encode::undefined();
711 if (
index.isPositiveInt()) {
714 if (
b->internalClass->vtable->isObject) {
715 Heap::Object *
o =
static_cast<Heap::Object *
>(
b);
716 if (
o->arrayData &&
o->arrayData->type == Heap::ArrayData::Simple) {
719 if (!
s->data(idx).isEmpty())
735 if (
engine->currentStackFrame->v4Function->isStrict()) {
745 if (
index.isPositiveInt()) {
747 if (
o->d()->arrayData &&
o->d()->arrayData->type == Heap::ArrayData::Simple) {
749 if (idx < s->
values.size) {
754 return o->put(idx,
value);
765 if (
index.isPositiveInt()) {
768 if (
b->internalClass->vtable->isObject) {
769 Heap::Object *
o =
static_cast<Heap::Object *
>(
b);
770 if (
o->arrayData &&
o->arrayData->type == Heap::ArrayData::Simple) {
772 if (idx < s->
values.size) {
789 if (!
in.isNullOrUndefined())
792 return Encode::undefined();
795 return engine->throwTypeError();
798 return engine->throwTypeError();
802 return Encode::undefined();
804 return engine->throwTypeError();
805 return it->asReturnedValue();
807 return engine->newForInIteratorObject(
o)->asReturnedValue();
834 bool done =
d->toBoolean();
836 *
value = Encode::undefined();
856 bool returnCalled =
false;
858 if (
engine->hasException) {
859 if (
engine->exceptionValue->isEmpty()) {
861 *
engine->exceptionValue = Encode::undefined();
862 engine->hasException =
false;
865 if (
ret->isUndefined()) {
867 return Encode::undefined();
874 *
engine->exceptionValue = Encode::undefined();
875 engine->hasException =
false;
879 return Encode::undefined();
880 if (
t->isUndefined()) {
885 return Encode::undefined();
886 return engine->throwTypeError();
889 arg = exceptionValue;
898 return engine->throwTypeError();
904 return engine->throwTypeError();
909 bool done =
d->toBoolean();
911 *
object =
o->get(
engine->id_value());
912 return returnCalled ? Encode::undefined() :
Encode(
true);
922 if (
done.booleanValue())
923 return Encode::undefined();
927 bool hadException =
engine->hasException;
930 engine->hasException =
false;
933 auto originalCompletion = [=]() {
936 engine->hasException = hadException;
938 return Encode::undefined();
943 if (!
ret->isUndefined()) {
945 o =
f->call(&iterator,
nullptr, 0);
946 if (
engine->hasException && !hadException)
947 return Encode::undefined();
949 if (hadException ||
ret->isUndefined())
950 return originalCompletion();
953 return engine->throwTypeError();
955 return originalCompletion();
964 array->arrayCreate();
970 return Encode::undefined();
972 if (
done->booleanValue())
977 return array->asReturnedValue();
983 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
986 if (
e == ExecutionContext::RangeError)
993 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
995 if (
e == ExecutionContext::TypeError)
997 else if (
e == ExecutionContext::RangeError)
1004 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1008 return o->get(
name);
1010 if (
object.isNullOrUndefined()) {
1015 o = RuntimeHelpers::convertToObject(scope.
engine,
object);
1017 return Encode::undefined();
1018 return o->get(
name);
1024 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1025 return engine->currentContext()->getProperty(
name);
1036 if (
frame->jsFrame->thisObject.isEmpty()) {
1042 f = Value::fromStaticValue(
frame->jsFrame->function);
1043 homeObject =
f->getHomeObject();
1048 if (
frame->thisObject() ==
nullptr) {
1060 f =
c->d()->function;
1068 homeObject =
f->getHomeObject();
1075 ScopedObject proto(scope, homeObject->getPrototypeOf());
1088 return Encode::undefined();
1090 if (
engine->hasException)
1091 return Encode::undefined();
1113 if (
engine->hasException)
1129 if (!
result &&
engine->currentStackFrame->v4Function->isStrict())
1130 engine->throwTypeError();
1163 engine->throwTypeError();
1168 if (
engine->currentStackFrame->isJSTypesFrame()) {
1170 if (
frame->thisObject() != Value::emptyValue().asReturnedValue()) {
1172 return engine->throwReferenceError(
1178 if (
frame->thisObject() !=
nullptr) {
1180 return engine->throwReferenceError(
1187 return engine->throwTypeError();
1188 Heap::Object *
c =
static_cast<const Object &
>(
t).getPrototypeOf();
1189 if (!
c->vtable()->isFunctionObject || !
static_cast<Heap::FunctionObject *
>(
c)->isConstructor())
1190 return engine->throwTypeError();
1191 return c->asReturnedValue();
1196 Q_ASSERT(
x.type() !=
y.type() || (
x.isManaged() && (
x.isString() !=
y.isString())));
1198 if (
x.isNumber() &&
y.isNumber())
1199 return x.asDouble() ==
y.asDouble();
1200 if (
x.isNull() &&
y.isUndefined()) {
1202 }
else if (
x.isUndefined() &&
y.isNull()) {
1204 }
else if (
x.isNumber() &&
y.isString()) {
1205 double dy = RuntimeHelpers::toNumber(
y);
1206 return x.asDouble() == dy;
1207 }
else if (
x.isString() &&
y.isNumber()) {
1208 double dx = RuntimeHelpers::toNumber(
x);
1209 return dx ==
y.asDouble();
1210 }
else if (
x.isBoolean()) {
1211 return Runtime::CompareEqual::call(Value::fromDouble((
double)
x.booleanValue()),
y);
1212 }
else if (
y.isBoolean()) {
1213 return Runtime::CompareEqual::call(
x, Value::fromDouble((
double)
y.booleanValue()));
1217 if (yo && (
x.isNumber() ||
x.isString())) {
1220 return Runtime::CompareEqual::call(
x, py);
1221 }
else if (xo && (
y.isNumber() ||
y.isString())) {
1224 return Runtime::CompareEqual::call(px,
y);
1235 if (
x.rawValue() ==
y.rawValue())
1240 return y.isNumber() &&
x.asDouble() ==
y.asDouble();
1241 if (
x.isManaged()) {
1267 return Runtime::CompareGreaterThan::call(pl, pr);
1270 double dl = RuntimeHelpers::toNumber(l);
1271 double dr = RuntimeHelpers::toNumber(
r);
1295 return Runtime::CompareLessThan::call(pl, pr);
1298 double dl = RuntimeHelpers::toNumber(l);
1299 double dr = RuntimeHelpers::toNumber(
r);
1323 return Runtime::CompareGreaterEqual::call(pl, pr);
1326 double dl = RuntimeHelpers::toNumber(l);
1327 double dr = RuntimeHelpers::toNumber(
r);
1351 return Runtime::CompareLessEqual::call(pl, pr);
1354 double dl = RuntimeHelpers::toNumber(l);
1355 double dr = RuntimeHelpers::toNumber(
r);
1365 return v->booleanValue();
1374 return v->booleanValue();
1383 .arg(propertyName, objectAsString);
1384 return engine->throwTypeError(msg);
1392 Value thisObject = Value::undefinedValue();
1393 if (!
function.isFunctionObject()) {
1395 engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->
nameIndex]->toQString());
1399 &thisObject, argv, argc));
1403 Value *argv,
int argc)
1409 if (!
function.isFunctionObject()) {
1411 engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->
nameIndex]->toQString());
1415 thisObject, argv, argc));
1424 scope,
engine->currentContext()->getPropertyAndBase(
engine->id_eval(), thisObject));
1425 if (
engine->hasException)
1426 return Encode::undefined();
1432 return static_cast<EvalFunction *
>(
function.getPointer())->evalCall(thisObject, argv, argc,
true);
1441 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1444 if (
engine->hasException)
1445 return Encode::undefined();
1449 engine, thisObject,
engine->currentStackFrame->v4Function->compilationUnit
1450 ->runtimeStrings[nameIndex]->toQString());
1462 engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1465 if (!lookupObject) {
1467 if (
base->isNullOrUndefined()) {
1469 .arg(
name->toQString(),
base->toQStringNoThrow());
1473 if (
base->isManaged()) {
1475 lookupObject =
m->internalClass()->prototype;
1476 Q_ASSERT(
m->internalClass()->prototype);
1478 lookupObject = RuntimeHelpers::convertToObject(
engine, *
base);
1479 if (
engine->hasException)
1480 return Encode::undefined();
1481 if (!
engine->currentStackFrame->v4Function->isStrict())
1482 base = lookupObject;
1490 .arg(
name->toQString(),
1491 base->toQStringNoThrow());
1504 if (!
f.isFunctionObject())
1505 return engine->throwTypeError();
1512 if (!
func.isFunctionObject())
1514 Value undef = Value::undefinedValue();
1516 &undef, argv, argc));
1520 const Value &thisObject,
Value argv[],
int argc)
1522 if (!
func.isFunctionObject())
1525 &thisObject, argv, argc));
1542 for (
int i = 0;
i < argc; ++
i) {
1543 if (!argv[
i].isEmpty()) {
1546 v = scope.
alloc<Scope::Uninitialized>();
1551 it = Runtime::GetIterator::call(scope.
engine, argv[
i], 1);
1553 return {
nullptr, 0 };
1557 return {
nullptr, 0 };
1559 if (
done->booleanValue())
1562 constexpr auto safetyMargin = 100;
1565 return {
nullptr, 0 };
1567 v = scope.
alloc<Scope::Uninitialized>();
1577 return engine->throwTypeError();
1581 if (
engine->hasException)
1582 return Encode::undefined();
1591 return engine->throwTypeError();
1599 return engine->throwTypeError();
1603 if (
engine->hasException)
1604 return Encode::undefined();
1615 const Value &
function = tos[StackOffsets::tailCall_function];
1616 const Value &thisObject = tos[StackOffsets::tailCall_thisObject];
1617 Value *argv =
reinterpret_cast<Value *
>(
frame->jsFrame) + tos[StackOffsets::tailCall_argv].int_32();
1618 int argc = tos[StackOffsets::tailCall_argc].
int_32();
1622 return engine->throwTypeError();
1631 memcpy(
frame->jsFrame->args, argv, argc *
sizeof(
Value));
1633 frame->callerCanHandleTailCall());
1634 frame->setupJSFrame(
frame->framePointer(), fo, fo.
scope(), thisObject,
1635 Primitive::undefinedValue());
1636 engine->jsStackTop =
frame->framePointer() +
frame->requiredJSStackFrameSize();
1637 frame->setPendingTailCall(
true);
1638 return Encode::undefined();
1643 if (!
value.isEmpty())
1651 switch (
value.type()) {
1652 case Value::Undefined_Type:
1655 case Value::Null_Type:
1658 case Value::Boolean_Type:
1661 case Value::Managed_Type:
1662 if (
value.isString())
1664 else if (
value.isSymbol())
1675 return res.asReturnedValue();
1681 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1685 return TypeofValue::call(
engine, prop);
1690 frame->jsFrame->context = ExecutionContext::newCallContext(
frame)->asReturnedValue();
1699 if (!
engine->hasException) {
1704 context = ec->newWithContext(
obj.d())->asReturnedValue();
1712 auto name =
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex];
1728 auto context =
static_cast<Heap::CallContext *
>(
1729 Value::fromStaticValue(
frame->jsFrame->context).m());
1730 frame->jsFrame->context =
1731 ExecutionContext::cloneBlockContext(
engine,
context)->asReturnedValue();
1737 Q_ASSERT(
engine->currentContext()->d()->type == Heap::ExecutionContext::Type_GlobalContext ||
1738 engine->currentContext()->d()->type == Heap::ExecutionContext::Type_QmlContext);
1748 engine->setScriptContext(root);
1755 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1761 if (
v.isNullOrUndefined())
1762 engine->throwTypeError();
1767 if (!
t.isObject()) {
1768 if (
t.isNullOrUndefined()) {
1771 return t.toObject(
engine)->asReturnedValue();
1774 return t.asReturnedValue();
1780 ScopedString name(scope,
engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
1781 engine->currentContext()->createMutableBinding(
name, deletable);
1798 o->setProperty(
i, *
args++);
1800 Q_ASSERT((argc - klass->d()->size) % 3 == 0);
1801 int additionalArgs = (argc - int(klass->d()->size))/3;
1803 if (!additionalArgs)
1804 return o->asReturnedValue();
1811 for (
int i = 0;
i < additionalArgs; ++
i) {
1816 if (
engine->hasException)
1817 return Encode::undefined();
1818 if (
arg != ObjectLiteralArgument::Value) {
1820 int functionId =
args[2].integerValue();
1822 ->runtimeFunctions[functionId];
1826 if (
arg == ObjectLiteralArgument::Getter)
1827 prefix = PropertyKey::Getter;
1828 else if (
arg == ObjectLiteralArgument::Setter)
1829 prefix = PropertyKey::Setter;
1831 arg = ObjectLiteralArgument::Value;
1832 fnName =
name->asFunctionName(
engine, prefix);
1836 value = MemberGeneratorFunction::create(current, clos,
o, fnName)->asReturnedValue();
1838 value = FunctionObject::createMemberFunction(current, clos,
o, fnName)->asReturnedValue();
1839 }
else if (
args[2].isFunctionObject()) {
1842 fnName =
name->asFunctionName(
engine, PropertyKey::None);
1843 fn->setName(fnName);
1846 Q_ASSERT(
arg == ObjectLiteralArgument::Value ||
value->isFunctionObject());
1847 if (
arg == ObjectLiteralArgument::Value ||
arg == ObjectLiteralArgument::Getter) {
1849 pd->
set = Value::emptyValue();
1851 pd->
value = Value::emptyValue();
1856 return engine->throwTypeError();
1860 return o.asReturnedValue();
1864 const Value &superClass,
Value computedNames[])
1867 =
engine->currentStackFrame->v4Function->executableCompilationUnit();
1874 if (superClass.
isNull()) {
1875 protoParent = Encode::null();
1884 return engine->throwTypeError(
QStringLiteral(
"The value of the superclass's prototype property is not an object."));
1886 constructorParent = superClass;
1891 proto->setPrototypeUnchecked(protoParent);
1896 constructor = FunctionObject::createConstructorFunction(current,
f, proto, !superClass.
isEmpty())->
asReturnedValue();
1897 constructor->setPrototypeUnchecked(constructorParent);
1898 Value argCount = Value::fromInt32(
f ?
f->nFormals : 0);
1899 constructor->defineReadonlyConfigurableProperty(scope.
engine->
id_length(), argCount);
1900 constructor->defineReadonlyConfigurableProperty(
engine->id_prototype(), proto);
1901 proto->defineDefaultProperty(
engine->id_constructor(), constructor);
1906 constructor->defineReadonlyConfigurableProperty(
engine->id_name(),
name);
1920 return engine->throwTypeError(
QStringLiteral(
"Cannot declare a static method named 'prototype'."));
1921 if (
engine->hasException)
1922 return Encode::undefined();
1926 propertyName =
name->toPropertyKey();
1932 prefix = PropertyKey::Getter;
1933 else if (
methods[
i].
type == CompiledData::Method::Setter)
1934 prefix = PropertyKey::Setter;
1938 if (
f->isGenerator())
1939 function = MemberGeneratorFunction::create(current,
f, receiver,
name);
1941 function = FunctionObject::createMemberFunction(current,
f, receiver,
name);
1945 case CompiledData::Method::Getter:
1947 property->set = Value::emptyValue();
1950 case CompiledData::Method::Setter:
1951 property->value = Value::emptyValue();
1957 property->set = Value::emptyValue();
1961 receiver->defineOwnProperty(propertyName,
property, attributes);
1969 Q_ASSERT(
engine->currentContext()->d()->type == Heap::ExecutionContext::Type_CallContext);
1987 int nValues =
frame->argc() - argIndex;
1989 return engine->newArrayObject(0)->asReturnedValue();
1990 return engine->newArrayObject(
values, nValues)->asReturnedValue();
1996 =
engine->currentStackFrame->v4Function->compilationUnit->runtimeRegularExpressions[
id];
1997 Heap::RegExpObject *ro =
engine->newRegExpObject(Value::fromStaticValue(
val).as<RegExp>());
1998 return ro->asReturnedValue();
2004 return obj.asReturnedValue();
2006 return obj.toObject(
engine)->asReturnedValue();
2011 return obj.toBoolean();
2024 if (
value.isInteger() &&
value.integerValue() &&
2025 value.integerValue() != std::numeric_limits<int>::min())
2028 double n = RuntimeHelpers::toNumber(
value);
2040 return add_int32(
left.integerValue(),
right.integerValue());
2041 if (
left.isNumber() &&
right.isNumber())
2042 return Value::fromDouble(
left.asDouble() +
right.asDouble()).asReturnedValue();
2052 return sub_int32(
left.integerValue(),
right.integerValue());
2054 double lval =
left.isNumber() ?
left.asDouble() :
left.toNumberImpl();
2055 double rval =
right.isNumber() ?
right.asDouble() :
right.toNumberImpl();
2057 return Value::fromDouble(lval - rval).asReturnedValue();
2065 return mul_int32(
left.integerValue(),
right.integerValue());
2067 double lval =
left.isNumber() ?
left.asDouble() :
left.toNumberImpl();
2068 double rval =
right.isNumber() ?
right.asDouble() :
right.toNumberImpl();
2070 return Value::fromDouble(lval * rval).asReturnedValue();
2077 if (Value::integerCompatible(
left,
right)) {
2078 int lval =
left.integerValue();
2079 int rval =
right.integerValue();
2081 && !(lval == std::numeric_limits<int>::min() && rval == -1)
2082 && (lval % rval == 0)
2083 && !(lval == 0 && rval < 0))
2084 return Encode(
int(lval / rval));
2086 return Encode(
double(lval) / rval);
2089 double lval =
left.toNumber();
2090 double rval =
right.toNumber();
2091 return Value::fromDouble(lval / rval).asReturnedValue();
2098 if (Value::integerCompatible(
left,
right) &&
left.integerValue() >= 0 &&
right.integerValue() > 0) {
2107 double lval = RuntimeHelpers::toNumber(
left);
2108 double rval = RuntimeHelpers::toNumber(
right);
2112 return Value::fromDouble(std::fmod(lval, rval)).asReturnedValue();
2117 double b =
base.toNumber();
2126 int lval =
left.toInt32();
2127 int rval =
right.toInt32();
2128 return Encode((
int)(lval & rval));
2135 int lval =
left.toInt32();
2136 int rval =
right.toInt32();
2137 return Encode((
int)(lval | rval));
2144 int lval =
left.toInt32();
2145 int rval =
right.toInt32();
2146 return Encode((
int)(lval ^ rval));
2153 int lval =
left.toInt32();
2154 int rval =
right.toInt32() & 0x1f;
2155 return Encode((
int)(lval << rval));
2162 int lval =
left.toInt32();
2163 unsigned rval =
right.toUInt32() & 0x1f;
2164 return Encode((
int)(lval >> rval));
2171 unsigned lval =
left.toUInt32();
2172 unsigned rval =
right.toUInt32() & 0x1f;
2182 bool r = CompareGreaterThan::call(
left,
right);
2198 bool r = CompareGreaterEqual::call(
left,
right);
2206 bool r = CompareLessEqual::call(
left,
right);
2216 engine->jsStackTop = stackMark;
2218 template <
typename T>
2222 stackMark =
engine->jsStackTop;
2225 *scopedValue =
e->jsAlloca(1);
2226 **scopedValue =
value;
2238 Value *lhsGuard =
nullptr;
2239 Value *rhsGuard =
nullptr;
2243 return !lhs.
isNaN();
2249 if ((lt & (Value::ManagedMask >> Value::Tag_Shift)) == 0) {
2254 if ((rt & (Value::ManagedMask >> Value::Tag_Shift)) == 0) {
2262 if (l->
internalClass->vtable->isStringOrSymbol ==
r->internalClass->vtable->isStringOrSymbol)
2269 Q_ASSERT(
r->internalClass->vtable->isStringOrSymbol);
2277lhs_managed_and_rhs_not:
2285 rhs = Value::fromDouble(rhs.
int_32());
2289 return lhs.m()->internalClass->vtable->
isString ? (RuntimeHelpers::toNumber(lhs) == rhs.
doubleValue()) :
false;
2296 }
else if ((rt & (Value::ManagedMask >> Value::Tag_Shift)) == 0) {
2301 goto lhs_managed_and_rhs_not;
2357 bool r = RuntimeHelpers::strictEqual(
left,
right);
2365 bool r = ! RuntimeHelpers::strictEqual(
left,
right);
2373 return !Runtime::CompareEqual::call(
left,
right);
2380 return RuntimeHelpers::strictEqual(
left,
right);
2387 return ! RuntimeHelpers::strictEqual(
left,
right);
2390template<
typename Operation>
2393 return reinterpret_cast<void *
>(&Operation::call);
2400 {symbol<CallGlobalLookup>(),
"CallGlobalLookup" },
2401 {symbol<CallQmlContextPropertyLookup>(),
"CallQmlContextPropertyLookup" },
2402 {symbol<CallName>(),
"CallName" },
2403 {symbol<CallProperty>(),
"CallProperty" },
2404 {symbol<CallPropertyLookup>(),
"CallPropertyLookup" },
2405 {symbol<CallValue>(),
"CallValue" },
2406 {symbol<CallWithReceiver>(),
"CallWithReceiver" },
2407 {symbol<CallPossiblyDirectEval>(),
"CallPossiblyDirectEval" },
2408 {symbol<CallWithSpread>(),
"CallWithSpread" },
2409 {symbol<TailCall>(),
"TailCall" },
2411 {symbol<Construct>(),
"Construct" },
2412 {symbol<ConstructWithSpread>(),
"ConstructWithSpread" },
2414 {symbol<StoreNameStrict>(),
"StoreNameStrict" },
2415 {symbol<StoreNameSloppy>(),
"StoreNameSloppy" },
2416 {symbol<StoreProperty>(),
"StoreProperty" },
2417 {symbol<StoreElement>(),
"StoreElement" },
2418 {symbol<LoadProperty>(),
"LoadProperty" },
2419 {symbol<LoadName>(),
"LoadName" },
2420 {symbol<LoadElement>(),
"LoadElement" },
2421 {symbol<LoadSuperProperty>(),
"LoadSuperProperty" },
2422 {symbol<StoreSuperProperty>(),
"StoreSuperProperty" },
2423 {symbol<LoadSuperConstructor>(),
"LoadSuperConstructor" },
2424 {symbol<LoadGlobalLookup>(),
"LoadGlobalLookup" },
2425 {symbol<LoadQmlContextPropertyLookup>(),
"LoadQmlContextPropertyLookup" },
2426 {symbol<GetLookup>(),
"GetLookup" },
2427 {symbol<SetLookupStrict>(),
"SetLookupStrict" },
2428 {symbol<SetLookupSloppy>(),
"SetLookupSloppy" },
2430 {symbol<TypeofValue>(),
"TypeofValue" },
2431 {symbol<TypeofName>(),
"TypeofName" },
2433 {symbol<DeleteProperty_NoThrow>(),
"DeleteProperty_NoThrow" },
2434 {symbol<DeleteProperty>(),
"DeleteProperty" },
2435 {symbol<DeleteName_NoThrow>(),
"DeleteName_NoThrow" },
2436 {symbol<DeleteName>(),
"DeleteName" },
2438 {symbol<ThrowException>(),
"ThrowException" },
2439 {symbol<PushCallContext>(),
"PushCallContext" },
2440 {symbol<PushWithContext>(),
"PushWithContext" },
2441 {symbol<PushCatchContext>(),
"PushCatchContext" },
2442 {symbol<PushBlockContext>(),
"PushBlockContext" },
2443 {symbol<CloneBlockContext>(),
"CloneBlockContext" },
2444 {symbol<PushScriptContext>(),
"PushScriptContext" },
2445 {symbol<PopScriptContext>(),
"PopScriptContext" },
2446 {symbol<ThrowReferenceError>(),
"ThrowReferenceError" },
2447 {symbol<ThrowOnNullOrUndefined>(),
"ThrowOnNullOrUndefined" },
2449 {symbol<Closure>(),
"Closure" },
2451 {symbol<ConvertThisToObject>(),
"ConvertThisToObject" },
2452 {symbol<DeclareVar>(),
"DeclareVar" },
2453 {symbol<CreateMappedArgumentsObject>(),
"CreateMappedArgumentsObject" },
2454 {symbol<CreateUnmappedArgumentsObject>(),
"CreateUnmappedArgumentsObject" },
2455 {symbol<CreateRestParameter>(),
"CreateRestParameter" },
2457 {symbol<ArrayLiteral>(),
"ArrayLiteral" },
2458 {symbol<ObjectLiteral>(),
"ObjectLiteral" },
2459 {symbol<CreateClass>(),
"CreateClass" },
2461 {symbol<GetIterator>(),
"GetIterator" },
2462 {symbol<IteratorNext>(),
"IteratorNext" },
2463 {symbol<IteratorNextForYieldStar>(),
"IteratorNextForYieldStar" },
2464 {symbol<IteratorClose>(),
"IteratorClose" },
2465 {symbol<DestructureRestElement>(),
"DestructureRestElement" },
2467 {symbol<ToObject>(),
"ToObject" },
2468 {symbol<ToBoolean>(),
"ToBoolean" },
2469 {symbol<ToNumber>(),
"ToNumber" },
2471 {symbol<UMinus>(),
"UMinus" },
2473 {symbol<Instanceof>(),
"Instanceof" },
2474 {symbol<As>(),
"As" },
2475 {symbol<In>(),
"In" },
2476 {symbol<Add>(),
"Add" },
2477 {symbol<Sub>(),
"Sub" },
2478 {symbol<Mul>(),
"Mul" },
2479 {symbol<Div>(),
"Div" },
2480 {symbol<Mod>(),
"Mod" },
2481 {symbol<Exp>(),
"Exp" },
2482 {symbol<BitAnd>(),
"BitAnd" },
2483 {symbol<BitOr>(),
"BitOr" },
2484 {symbol<BitXor>(),
"BitXor" },
2485 {symbol<Shl>(),
"Shl" },
2486 {symbol<Shr>(),
"Shr" },
2487 {symbol<UShr>(),
"UShr" },
2488 {symbol<GreaterThan>(),
"GreaterThan" },
2489 {symbol<LessThan>(),
"LessThan" },
2490 {symbol<GreaterEqual>(),
"GreaterEqual" },
2491 {symbol<LessEqual>(),
"LessEqual" },
2492 {symbol<Equal>(),
"Equal" },
2493 {symbol<NotEqual>(),
"NotEqual" },
2494 {symbol<StrictEqual>(),
"StrictEqual" },
2495 {symbol<StrictNotEqual>(),
"StrictNotEqual" },
2497 {symbol<CompareGreaterThan>(),
"CompareGreaterThan" },
2498 {symbol<CompareLessThan>(),
"CompareLessThan" },
2499 {symbol<CompareGreaterEqual>(),
"CompareGreaterEqual" },
2500 {symbol<CompareLessEqual>(),
"CompareLessEqual" },
2501 {symbol<CompareEqual>(),
"CompareEqual" },
2502 {symbol<CompareNotEqual>(),
"CompareNotEqual" },
2503 {symbol<CompareStrictEqual>(),
"CompareStrictEqual" },
2504 {symbol<CompareStrictNotEqual>(),
"CompareStrictNotEqual" },
2506 {symbol<CompareInstanceof>(),
"CompareInstanceOf" },
2507 {symbol<CompareIn>(),
"CompareIn" },
2509 {symbol<RegexpLiteral>(),
"RegexpLiteral" },
2510 {symbol<GetTemplateObject>(),
"GetTemplateObject" }
static JNINativeMethod methods[]
\inmodule QtCore \reentrant
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
void throwError(const QString &message)
Throws a run-time error (exception) with the given message.
QJSValue globalObject() const
Returns this engine's Global Object.
QJSValue newObject()
Creates a JavaScript object of class Object.
qsizetype size() const noexcept
bool isEmpty() const noexcept
void resize(qsizetype size)
void append(parameter_type t)
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
const_iterator cbegin() const noexcept
QStringView trimmed() const noexcept
Strips leading and trailing whitespace and returns the result.
\macro QT_RESTRICTED_CAST_FROM_ASCII
qsizetype size() const
Returns the number of characters in this string.
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
qsizetype count(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QVector< QV4::Function * > runtimeFunctions
ManagedType::Data * alloc(Args &&... args)
QSet< QString >::iterator it
QList< QVariant > arguments
double jsExponentiate(double base, double exponent)
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
static QV4::ReturnedValue doInstanceof(ExecutionEngine *engine, const Value &lval, const Value &rval)
static Q_NEVER_INLINE ReturnedValue getElementIntFallback(ExecutionEngine *engine, const Value &object, uint idx)
static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine, const Value &object, const Value &index)
ReturnedValue coerce(ExecutionEngine *engine, const Value &value, const QQmlType &qmlType, bool isList)
static Heap::String * convert_to_string_add(ExecutionEngine *engine, Value value)
static ReturnedValue throwPropertyIsNotAFunctionTypeError(ExecutionEngine *engine, Value *thisObject, const QString &propertyName)
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
static QV4::Lookup * runtimeLookup(Function *f, uint i)
static Q_NEVER_INLINE bool setElementFallback(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
static Object * getSuperBase(Scope &scope)
static CallArgs createSpreadArguments(Scope &scope, Value *argv, int argc)
static const void * symbol()
QTextStream & endl(QTextStream &stream)
Writes '\n' to the stream and flushes the stream.
AudioChannelLayoutTag tag
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
static QDBusError::ErrorType get(const char *name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
static Q_DECL_CONST_FUNCTION bool qt_is_inf(double d)
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLint GLint GLsizei GLuint * counters
GLenum GLuint GLenum GLsizei const GLchar * buf
GLuint GLsizei const GLchar * message
static qreal dot(const QPointF &a, const QPointF &b)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static QString dump(const QByteArray &)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
QTextStreamManipulator qSetFieldWidth(int width)
unsigned long long quint64
\inmodule QtCore \reentrant
const Method * methodTable() const
quint32_le nStaticMethods
quint32_le constructorFunction
Heap::String ** runtimeStrings
const Unit * unitData() const
const Class * classAt(int idx) const
bool isJSTypesFrame() const
bool isMetaTypesFrame() const
CppStackFrame * currentStackFrame
CallContext * asCallContext()
Heap::String * newString(const QString &s=QString())
ReturnedValue throwRangeError(const Value &value)
String * id_length() const
ReturnedValue throwReferenceError(const Value &value)
String * id_prototype() const
ReturnedValue throwTypeError()
ExecutionContext * currentContext() const
CompiledData::CompilationUnitBase * compilationUnit
bool isConstructor() const
unsigned int formalParameterCount() const
ReturnedValue call(const JSCallData &data) const
Function * function() const
bool canBeTailCalled() const
Heap::ExecutionContext * scope() const
bool isArrowFunction() const
ReturnedValue asReturnedValue() const
Pointer< InternalClass *, 0 > internalClass
void setData(EngineBase *e, uint index, Value newVal)
const Value & data(uint index) const
ExecutionContext * context() const
void set(Value **scopedValue, T value, ExecutionEngine *e)
ReturnedValue(* globalGetter)(Lookup *l, ExecutionEngine *engine)
ReturnedValue(* qmlContextPropertyGetter)(Lookup *l, ExecutionEngine *engine, Value *thisObject)
ReturnedValue(* getter)(Lookup *l, ExecutionEngine *engine, const Value &object)
bool(* setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v)
ExecutionEngine * engine() const
bool hasProperty(PropertyKey id) const
ReturnedValue instanceOf(const Value &var) const
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
Heap::String * asFunctionName(ExecutionEngine *e, FunctionNamePrefix prefix) const
Value * alloc(qint64 nValues) const =delete
bool hasException() const
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
quint64 quickType() const
const Value & asValue() const
constexpr ReturnedValue asReturnedValue() const
QV4_NEARLY_ALWAYS_INLINE double doubleValue() const
bool isNullOrUndefined() const
QV4_NEARLY_ALWAYS_INLINE constexpr int int_32() const
PropertyKey propertyKey() const
bool lessThan(const String *other)
bool isStringOrSymbol() const
QV4::PropertyKey toPropertyKey(ExecutionEngine *e) const
QML_NEARLY_ALWAYS_INLINE String * stringValue() const
QML_NEARLY_ALWAYS_INLINE Object * objectValue() const
QString toQStringNoThrow() const
Heap::Object * toObject(ExecutionEngine *e) const