7#include <private/qv4alloca_p.h>
8#include <private/qv4arrayobject_p.h>
9#include <private/qv4function_p.h>
10#include <private/qv4jscall_p.h>
11#include <private/qv4scopedvalue_p.h>
12#include <private/qv4stackframe_p.h>
13#include <private/qv4string_p.h>
14#include <private/qv4symbol_p.h>
21void Heap::StrictArgumentsObject::init(QV4::JSTypesStackFrame *frame)
24 Q_ASSERT(vtable() == QV4::StrictArgumentsObject::staticVTable());
25 ExecutionEngine *v4 = internalClass->engine;
29 Q_ASSERT(internalClass->verifyIndex(v4->id_callee()->propertyKey(), CalleePropertyIndex));
30 Q_ASSERT(internalClass->findValueOrSetter(v4->id_callee()->propertyKey()).index == CalleeSetterPropertyIndex);
31 Q_ASSERT(internalClass->verifyIndex(v4->symbol_iterator()->propertyKey(), SymbolIteratorPropertyIndex));
32 setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues());
33 setProperty(v4, CalleePropertyIndex, *v4->thrower());
34 setProperty(v4, CalleeSetterPropertyIndex, *v4->thrower());
37 Scoped<QV4::StrictArgumentsObject> args(scope,
this);
38 args->arrayReserve(frame->argc());
39 args->arrayPut(0, frame->argv(), frame->argc());
41 Q_ASSERT(args->internalClass()->verifyIndex(v4->id_length()->propertyKey(), LengthPropertyIndex));
42 setProperty(v4, LengthPropertyIndex, Value::fromInt32(frame->argc()));
45void Heap::ArgumentsObject::init(QV4::CppStackFrame *frame)
47 ExecutionEngine *v4 = internalClass->engine;
49 QV4::CallContext *context =
static_cast<QV4::CallContext *>(frame->context());
52 this->context.set(v4, context->d());
53 Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable());
55 Q_ASSERT(internalClass->verifyIndex(v4->id_callee()->propertyKey(), CalleePropertyIndex));
56 setProperty(v4, CalleePropertyIndex, context->d()->function);
57 Q_ASSERT(internalClass->verifyIndex(v4->id_length()->propertyKey(), LengthPropertyIndex));
58 setProperty(v4, LengthPropertyIndex, Value::fromInt32(context->argc()));
59 Q_ASSERT(internalClass->verifyIndex(v4->symbol_iterator()->propertyKey(), SymbolIteratorPropertyIndex));
60 setProperty(v4, SymbolIteratorPropertyIndex, *v4->arrayProtoValues());
63 argCount = frame->argc();
64 uint nFormals = frame->v4Function->nFormals;
65 mapped = nFormals > 63 ? std::numeric_limits<quint64>::max() : (1ull << nFormals) - 1;
68void ArgumentsObject::fullyCreate()
70 if (d()->fullyCreated)
73 Scope scope(engine());
75 arrayReserve(d()->argCount);
76 arrayPut(0, context()->args(), d()->argCount);
80 d()->fullyCreated =
true;
83bool ArgumentsObject::virtualDefineOwnProperty(Managed *m, PropertyKey id,
const Property *desc, PropertyAttributes attrs)
85 ArgumentsObject *args =
static_cast<ArgumentsObject *>(m);
87 if (!id.isArrayIndex())
88 return Object::virtualDefineOwnProperty(m, id, desc, attrs);
90 uint index = id.asArrayIndex();
92 if (!args->isMapped(index))
93 return Object::virtualDefineOwnProperty(m, id, desc, attrs);
96 PropertyAttributes cAttrs = attrs;
97 ScopedProperty cDesc(scope);
98 cDesc->copy(desc, attrs);
100 if (attrs.isData() && desc->value.isEmpty() && attrs.hasWritable() && !attrs.isWritable()) {
101 cDesc->value = args->context()->args()[index];
102 cAttrs.setType(PropertyAttributes::Data);
105 bool allowed = Object::virtualDefineOwnProperty(m, id, cDesc, cAttrs);
109 if (attrs.isAccessor()) {
110 args->removeMapping(index);
112 if (!desc->value.isEmpty())
113 args->context()->setArg(index, desc->value);
114 if (attrs.hasWritable() && !attrs.isWritable())
115 args->removeMapping(index);
120ReturnedValue ArgumentsObject::virtualGet(
const Managed *m, PropertyKey id,
const Value *receiver,
bool *hasProperty)
122 if (id.isArrayIndex()) {
123 const ArgumentsObject *args =
static_cast<
const ArgumentsObject *>(m);
124 uint index = id.asArrayIndex();
125 if (index < args->d()->argCount && !args->d()->fullyCreated) {
128 return args->context()->args()[index].asReturnedValue();
131 if (args->isMapped(index)) {
132 Q_ASSERT(index <
static_cast<uint>(args->context()->function->formalParameterCount()));
135 return args->context()->args()[index].asReturnedValue();
139 return Object::virtualGet(m, id, receiver, hasProperty);
142bool ArgumentsObject::virtualPut(Managed *m, PropertyKey id,
const Value &value, Value *receiver)
144 if (id.isArrayIndex()) {
145 ArgumentsObject *args =
static_cast<ArgumentsObject *>(m);
146 uint index = id.asArrayIndex();
148 if (args == receiver && index < args->d()->argCount && !args->d()->fullyCreated) {
149 args->context()->setArg(index, value);
153 bool isMapped = (args == receiver && args->isMapped(index));
155 args->context()->setArg(index, value);
158 return Object::virtualPut(m, id, value, receiver);
161bool ArgumentsObject::virtualDeleteProperty(Managed *m, PropertyKey id)
163 ArgumentsObject *args =
static_cast<ArgumentsObject *>(m);
165 bool result = Object::virtualDeleteProperty(m, id);
166 if (result && id.isArrayIndex())
167 args->removeMapping(id.asArrayIndex());
171PropertyAttributes ArgumentsObject::virtualGetOwnProperty(
const Managed *m, PropertyKey id, Property *p)
173 if (!id.isArrayIndex())
174 return Object::virtualGetOwnProperty(m, id, p);
176 const ArgumentsObject *args =
static_cast<
const ArgumentsObject *>(m);
177 uint index = id.asArrayIndex();
178 if (index < args->d()->argCount && !args->d()->fullyCreated) {
179 p->value = args->context()->args()[index];
183 PropertyAttributes attrs = Object::virtualGetOwnProperty(m, id, p);
184 if (attrs.isEmpty() || !args->isMapped(index))
187 Q_ASSERT(index <
static_cast<uint>(args->context()->function->formalParameterCount()));
189 p->value = args->context()->args()[index];
193qint64 ArgumentsObject::virtualGetLength(
const Managed *m)
195 const ArgumentsObject *a =
static_cast<
const ArgumentsObject *>(m);
196 return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->toLength();
199OwnPropertyKeyIterator *ArgumentsObject::virtualOwnPropertyKeys(
const Object *m, Value *target)
201 static_cast<ArgumentsObject *>(
const_cast<Object *>(m))->fullyCreate();
202 return Object::virtualOwnPropertyKeys(m, target);
DEFINE_OBJECT_VTABLE(StrictArgumentsObject)
DEFINE_OBJECT_VTABLE(ArgumentsObject)