6#include <private/qv4argumentsobject_p.h>
7#include <private/qv4identifiertable_p.h>
8#include <private/qv4jscall_p.h>
9#include <private/qv4lookup_p.h>
10#include <private/qv4memberdata_p.h>
11#include <private/qv4mm_p.h>
12#include <private/qv4proxy_p.h>
13#include <private/qv4scopedvalue_p.h>
14#include <private/qv4stackframe_p.h>
15#include <private/qv4stringobject_p.h>
16#include <private/qv4symbol_p.h>
18#include <QtCore/qloggingcategory.h>
31 Heap::Object *
p =
d();
33 if (ic->numRedundantTransitions <
p->internalClass.get()->numRedundantTransitions) {
44 for (
uint i = 0;
i < ic->size; ++
i)
45 newMembers->set(scope.
engine,
i,
get(ic->nameMap.at(
i)));
47 p->internalClass.set(scope.
engine, ic);
48 const uint nInline =
p->vtable()->nInlineProperties;
50 if (ic->size > nInline)
53 p->memberData.set(scope.
engine,
nullptr);
55 const auto &memberValues = newMembers->d()->values;
56 for (
uint i = 0;
i < ic->size; ++
i)
62 p->internalClass.set(ic->engine, ic);
63 const uint nInline =
p->vtable()->nInlineProperties;
64 if (ic->size > nInline) {
65 const uint requiredSize = ic->size - nInline;
66 if ((
p->memberData ?
p->memberData->values.size : 0) < requiredSize) {
68 ic->engine, requiredSize,
p->memberData));
75 if (ic->engine->isInitialized && ic->isUsedAsProto())
76 ic->updateProtoUsage(
p);
82 p->value = *propertyData(
entry.index);
83 if (
entry.attributes.isAccessor())
84 p->set = *propertyData(
entry.setterIndex);
90 if (
entry.attributes.isAccessor())
94void Heap::Object::setUsedAsProto()
96 internalClass.set(internalClass->engine, internalClass->asProtoClass());
101 if (!
attrs.isAccessor())
102 return v.asReturnedValue();
120 if (
attrs.isAccessor()) {
128 setter->call(jsCallData);
134 if (!
attrs.isWritable())
146 defineDefaultProperty(
s,
value, attributes);
156 defineDefaultProperty(
s,
function, attributes);
165 defineDefaultProperty(nameOrSymbol, function, attributes);
173 defineAccessorProperty(
s, getter, setter);
188 p->setGetter(
nullptr);
194 p->setSetter(
nullptr);
206 defineReadonlyProperty(
s,
value);
219 defineReadonlyConfigurableProperty(
s,
value);
227void Object::addSymbolSpecies()
232 p->setSetter(
nullptr);
238 Base::markObjects(
b, stack);
241 o->memberData->mark(stack);
243 o->arrayData->mark(stack);
244 uint nInline =
o->vtable()->nInlineProperties;
245 Value *
v =
reinterpret_cast<Value *
>(
o) +
o->vtable()->inlinePropertyOffset;
264void Object::setPrototypeUnchecked(
const Object *
p)
266 setInternalClass(internalClass()->changePrototype(
p ?
p->d() :
nullptr));
272 if (
id.isArrayIndex()) {
274 Heap::Object *
o =
d();
278 if (idx != UINT_MAX) {
280 return {
o->arrayData ,
o->arrayData->values.values + (
attrs->isAccessor() ? idx + SetterOffset : idx) };
283 if (
o->vtable()->type == Type_StringObject) {
284 if (
index <
static_cast<const Heap::StringObject *
>(
o)->length()) {
288 return {
reinterpret_cast<Heap::ArrayData *
>(0x1),
nullptr };
294 Heap::Object *
o =
d();
296 auto idx =
o->internalClass->findValueOrSetter(
id);
299 return o->writablePropertyData(idx.index);
306 return {
nullptr,
nullptr };
311 return static_cast<const Object *
>(
m)->internalGet(
id, receiver, hasProperty);
316 return static_cast<Object *
>(
m)->internalPut(
id,
value, receiver);
321 return static_cast<Object *
>(
m)->internalDeleteProperty(
id);
328 if (
o->arrayType() == Heap::ArrayData::Sparse) {
335 while (arrayNode !=
o->sparseEnd()) {
339 const Property *
p =
reinterpret_cast<const Property *
>(sa->values.data() + pidx);
352 while (arrayIndex < o->
d()->arrayData->values.size) {
358 if (!
val.isEmpty()) {
370 while (memberIndex < o->internalClass()->
size) {
373 if (!
n.isStringOrSymbol())
385 pd->
value = *
o->propertyData(
e.index);
386 if (
e.attributes.isAccessor())
387 pd->
set = *
o->propertyData(
e.setterIndex);
411 Heap::Object *
o =
d();
413 if (
id.isArrayIndex()) {
419 if (
o->arrayData &&
o->arrayData->getProperty(
index, pd, &
attrs)) {
430 return str.asReturnedValue();
439 auto idx =
o->internalClass->findValueOrGetter(
id);
466 if (scope.hasException())
470 if (
r &&
r->d() ==
d()) {
479 if (
id.isArrayIndex()) {
481 propertyIndex =
arrayData()->getValueOrSetter(
id.asArrayIndex(), &
attrs);
484 if (member.isValid()) {
485 attrs = member.attrs;
486 propertyIndex =
d()->writablePropertyData(member.index);
490 if (!propertyIndex.isNull() && !
attrs.isAccessor()) {
491 if (!
attrs.isWritable())
493 else if (
isArrayObject() &&
id == scope.engine->id_length()->propertyKey()) {
497 scope.engine->throwRangeError(
value);
504 propertyIndex.set(scope.engine,
value);
517 return p->put(
id,
value, receiver);
521 if (
attrs.isAccessor()) {
526 jsCallData.args[0] =
value;
527 *jsCallData.thisObject = *receiver;
529 return !scope.hasException();
533 if (!
attrs.isWritable())
537 attrs =
r->getOwnProperty(
id,
p);
540 if (
attrs.isAccessor() || !
attrs.isWritable())
543 if (!
r->isExtensible())
550 if (
id.isArrayIndex()) {
551 r->arraySet(
id.asArrayIndex(),
value);
560 return r->defineOwnProperty(
id,
p,
attrs);
569 if (
id.isArrayIndex()) {
572 if (scope.hasException())
576 if (!ad || ad->vtable()->del(
this,
index))
583 if (memberIdx.isValid()) {
584 if (memberIdx.attrs.isConfigurable()) {
612 if (
p->isSubset(
attrs, current, cattrs))
617 if (
attrs.isConfigurable())
624 if (
attrs.isGeneric() || current->value.isEmpty())
642 current->setGetter(
nullptr);
643 current->setSetter(
nullptr);
656 if (
attrs.isWritable() || !current->value.sameValue(
p->value))
662 if (!
p->value.isEmpty() && current->value.rawValue() !=
p->value.rawValue())
664 if (!
p->set.isEmpty() && current->set.rawValue() !=
p->set.rawValue())
671 current->merge(cattrs,
p,
attrs);
690 (
other->arrayType() == Heap::ArrayData::Sparse &&
other->arrayData()->attrs)) {
698 }
else if (!
other->arrayData()) {
703 other->d()->arrayData->values.alloc,
false);
704 if (
other->arrayType() == Heap::ArrayData::Sparse) {
705 Heap::ArrayData *od =
other->d()->arrayData;
706 Heap::ArrayData *dd =
d()->arrayData;
709 Heap::ArrayData *dd =
d()->arrayData;
710 dd->values.size =
other->d()->arrayData->values.size;
711 dd->offset =
other->d()->arrayData->offset;
714 memcpy(
d()->
arrayData->values.values,
other->d()->arrayData->values.values,
other->d()->arrayData->values.alloc*
sizeof(
Value));
723 return v->toLength();
744 Heap::Object *
obj =
object->d();
746 if (
name.isArrayIndex()) {
752 auto index =
obj->internalClass->findValueOrGetter(
name);
753 if (
index.isValid()) {
755 uint nInline =
obj->vtable()->nInlineProperties;
756 if (
attrs.isData()) {
757 if (
index.index <
obj->vtable()->nInlineProperties) {
758 index.index +=
obj->vtable()->inlinePropertyOffset;
761 index.index -= nInline;
787 auto idx =
c->findValueOrSetter(
key);
793 }
else if (idx.attrs.isData() && idx.attrs.isWritable()) {
796 const auto nInline =
object->d()->vtable()->nInlineProperties;
797 if (idx.index < nInline) {
799 lookup->
objectLookup.
offset = idx.index +
object->d()->vtable()->inlinePropertyOffset;
818 if (
object->internalClass() ==
c) {
823 idx =
object->internalClass()->findValueOrSetter(
key);
824 if (!idx.isValid() || idx.attrs.isAccessor()) {
862 if (
f->isBoundFunction()) {
876 return f->engine()->throwTypeError();
878 Heap::Object *
v = lhs->d();
890 else if (
o->d() ==
v)
906 o =
o->getPrototypeOf();
908 return o->hasProperty(
id);
917 if (
id.isArrayIndex()) {
919 if (
o->arrayData()) {
926 auto member =
o->internalClass()->find(
id);
927 if (member.isValid()) {
928 attrs = member.attributes;
930 p->value = *
o->propertyData(member.index);
931 if (
attrs.isAccessor())
932 p->set = *
o->propertyData(member.setterIndex);
946 if (
id.isArrayIndex()) {
951 if (
o->arrayData()) {
954 hasProperty = (index < static_cast<StringObject *>(
o)->length());
958 if (!
o->isExtensible())
977 auto memberIndex = ic->d()->find(
id);
979 if (!memberIndex.isValid()) {
980 if (!
o->isExtensible())
984 if (ic->d()->isLocked()) {
985 while (Heap::Object *prototype = ic->d()->prototype) {
986 ic = prototype->internalClass;
987 const auto entry = ic->d()->find(
id);
988 if (
entry.isValid()) {
989 if (
entry.attributes.isConfigurable())
1007 return o->internalDefineOwnProperty(scope.
engine, UINT_MAX, &memberIndex,
p,
attrs);
1012 return m->d()->internalClass->isExtensible();
1019 o->setInternalClass(
o->internalClass()->nonExtensible());
1025 return m->internalClass()->prototype;
1034 Heap::Object *protod = proto ? proto->d() :
nullptr;
1035 if (current == protod)
1039 Heap::Object *
p = protod;
1043 if (
p->vtable()->getPrototypeOf != Object::staticVTable()->getPrototypeOf)
1058 if (newLen < oldLen) {
1066 if (newLen >= 0x100000)
1077 if (
arrayType() == Heap::ArrayData::Sparse)
1096 if (
vtable() == ProxyObject::staticVTable()) {
1099 if (!
p->d()->handler) {
1104 return o->isArray();
1113 return defaultConstructor;
1120 if (S->isNullOrUndefined())
1121 return defaultConstructor;
1123 if (!
f || !
f->isConstructor()) {
1161 a->arrayReserve(
len);
1163 for (
int ii = 0; ii <
len; ++ii)
1165 a->setArrayLengthUnchecked(
len);
1186 result.append(
v->toQStringNoThrow());
1196 if (
id.isArrayIndex()) {
1207 a->setArrayLengthUnchecked(
index + 1);
1218 a->getProperty(
e, lp);
1219 if (
attrs.isEmpty() ||
p->isSubset(
attrs, lp,
e.attributes))
1223 bool succeeded =
true;
1226 uint l =
p->value.asArrayLength(&
ok);
1232 succeeded =
a->setArrayLength(l);
1234 if (
attrs.hasWritable() && !
attrs.isWritable()) {
1235 e.attributes.setWritable(
false);
static constexpr QChar fromLatin1(char c) noexcept
Converts the Latin-1 character c to its equivalent QChar.
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
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
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
object setProperty("down", true)
employee setName("Richard Schmit")
\qmltype Particle \inqmlmodule QtQuick.Particles
Scoped< FunctionObject > ScopedFunctionObject
ReturnedValue checkedResult(QV4::ExecutionEngine *v4, ReturnedValue result)
@ Attr_ReadOnly_ButConfigurable
void setter(QUntypedPropertyData *d, const void *value)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
static QDBusError::ErrorType get(const char *name)
static struct AttrInfo attrs[]
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
#define QStringLiteral(str)
#define DEFINE_OBJECT_VTABLE(classname)
QFuture< QSet< QChar > > set
[10]
\inmodule QtCore \reentrant
static bool isNonStrictArgumentsObject(Managed *m)
static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes)
PropertyAttributes * attrs() const
Heap::ArrayData::Type Type
QStringList toQStringList() const
Heap::String ** runtimeStrings
static constexpr ReturnedValue undefined()
IdentifierTable * identifierTable
CppStackFrame * currentStackFrame
Symbol * symbol_isConcatSpreadable() const
FunctionObject * getSymbolSpecies() const
Heap::String * newString(const QString &s=QString())
ReturnedValue throwRangeError(const Value &value)
String * id_length() const
String * id_constructor() const
Symbol * symbol_species() const
ReturnedValue throwTypeError()
CompiledData::CompilationUnitBase * compilationUnit
static Heap::FunctionObject * createBuiltinFunction(ExecutionEngine *engine, StringOrSymbol *nameOrSymbol, VTable::Call code, int argumentCount)
Pointer< InternalClass *, 0 > internalClass
IndexAndAttribute findValueOrSetter(const PropertyKey id)
static void addMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry)
SharedInternalClassData< PropertyKey > nameMap
IndexAndAttribute findValueOrGetter(const PropertyKey id)
Q_REQUIRED_RESULT InternalClass * changePrototype(Heap::Object *proto)
bool isExtensible() const
Q_REQUIRED_RESULT InternalClass * changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry=nullptr)
static void removeMember(QV4::Object *object, PropertyKey identifier)
const Value & data(uint index) const
PropertyKey asPropertyKey(const Heap::String *str)
PropertyAttributes attributes
struct QV4::Lookup::@576::@592 objectLookup
void resolveProtoGetter(PropertyKey name, const Heap::Object *proto)
static bool setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
ReturnedValue(* getter)(Lookup *l, ExecutionEngine *engine, const Value &object)
static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
struct QV4::Lookup::@576::@600 indexedLookup
static bool setter0MemberData(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
struct QV4::Lookup::@576::@593 protoLookup
Heap::InternalClass * newClass
static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
bool(* setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v)
static ReturnedValue getterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
struct QV4::Lookup::@576::@599 insertionLookup
static ReturnedValue getter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object)
static bool setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
static ReturnedValue getter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object)
static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object)
Heap::InternalClass * internalClass() const
bool isArrayObject() const
ExecutionEngine * engine() const
static Heap::MemberData * allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old=nullptr)
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
const Value * propertyData(uint index) const
void arraySet(uint index, const Property *p, PropertyAttributes attributes=Attr_Data)
bool setArrayLength(uint newLen)
static ReturnedValue getValue(const Value *thisObject, const Value &v, PropertyAttributes attrs)
void copyArrayData(Object *other)
bool hasProperty(PropertyKey id) const
PropertyAttributes getOwnProperty(PropertyKey id, Property *p=nullptr) const
bool setProtoFromNewTarget(const Value *newTarget)
Heap::ArrayData * arrayData() const
ArrayData::Type arrayType() const
const FunctionObject * speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const
void getProperty(const InternalClassEntry &entry, Property *p) const
const VTable * vtable() const
void setArrayAttributes(uint i, PropertyAttributes a)
void setProperty(const InternalClassEntry &entry, const Property *p)
bool isConcatSpreadable() const
bool setPrototypeOf(const Object *p)
void setArrayLengthUnchecked(uint l)
Heap::Object * getPrototypeOf() const
ReturnedValue get(StringOrSymbol *name, bool *hasProperty=nullptr, const Value *receiver=nullptr) const
static ReturnedValue checkedInstanceOf(ExecutionEngine *engine, const FunctionObject *typeObject, const Value &var)
bool isEnumerable() const
bool isConfigurable() const
static PropertyKey invalid()
static PropertyKey fromArrayIndex(uint idx)
void fullyPopulated(PropertyAttributes *attrs)
void copy(const Property *other, PropertyAttributes attrs)
const SparseArrayNode * nextNode() const
SparseArrayNode * lowerBound(uint key)
const SparseArrayNode * begin() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const
PropertyKey propertyKey() const
static constexpr VTable::SetPrototypeOf virtualSetPrototypeOf
static constexpr VTable::DefineOwnProperty virtualDefineOwnProperty
static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys
static constexpr VTable::GetOwnProperty virtualGetOwnProperty
static constexpr VTable::PreventExtensions virtualPreventExtensions
static constexpr VTable::GetPrototypeOf virtualGetPrototypeOf
static constexpr VTable::Get virtualGet
static constexpr VTable::Metacall virtualMetacall
static constexpr VTable::GetLength virtualGetLength
static constexpr VTable::InstanceOf virtualInstanceOf
static constexpr VTable::HasProperty virtualHasProperty
static constexpr VTable::ResolveLookupGetter virtualResolveLookupGetter
static constexpr VTable::ResolveLookupSetter virtualResolveLookupSetter
static constexpr VTable::IsExtensible virtualIsExtensible
ReturnedValue(* Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
GetOwnProperty getOwnProperty
void mark(MarkStack *markStack)
bool isFunctionObject() const
static constexpr Value undefinedValue()
QML_NEARLY_ALWAYS_INLINE Object * objectValue() const
static Value fromHeapObject(HeapBasePtr m)
static constexpr Value fromReturnedValue(ReturnedValue val)
QString toQString() const