aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-11-06 15:59:01 +0100
committerLars Knoll <lars.knoll@qt.io>2017-11-14 21:46:14 +0000
commit30ada3da8635f3e496ea6cb9483aa104d32e5a61 (patch)
tree5573b2a95dc25a5c8fa17de79179ef6bc10294f4
parentf0a412020f493f01205c302cf48927dd5e3b80b6 (diff)
Clean up ArgumentsObject handling
Introduce a proper strict arguments object. Change-Id: Ie4e7f904b3a0e03893b18b3c6709f4f25dbc1030 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp52
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h21
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
6 files changed, 55 insertions, 32 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 4d34099c73..075e7afd8a 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -46,38 +46,48 @@
using namespace QV4;
DEFINE_OBJECT_VTABLE(ArgumentsObject);
+DEFINE_OBJECT_VTABLE(StrictArgumentsObject);
-void Heap::ArgumentsObject::init(QV4::CallContext *context, int nFormals, bool strict)
+void Heap::ArgumentsObject::init(QV4::CppStackFrame *frame)
{
ExecutionEngine *v4 = internalClass->engine;
+ int nFormals = frame->v4Function->nFormals;
+ QV4::CallContext *context = static_cast<QV4::CallContext *>(frame->context());
+
Object::init();
fullyCreated = false;
- isStrict = strict;
this->nFormals = nFormals;
this->context.set(v4, context->d());
Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable());
+ Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()));
+ setProperty(v4, CalleePropertyIndex, context->d()->function);
+ Q_ASSERT(LengthPropertyIndex == internalClass->find(v4->id_length()));
+ setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(context->argc()));
+}
+
+void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame)
+{
+ Q_ASSERT(vtable() == QV4::StrictArgumentsObject::staticVTable());
+ ExecutionEngine *v4 = internalClass->engine;
+
+ Object::init();
+
+ Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()));
+ Q_ASSERT(CallerPropertyIndex == internalClass->find(v4->id_caller()));
+ setProperty(v4, CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
+ setProperty(v4, CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
+ setProperty(v4, CallerPropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
+ setProperty(v4, CallerPropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
+
Scope scope(v4);
- Scoped<QV4::ArgumentsObject> args(scope, this);
-
- if (isStrict) {
- Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(v4->id_callee()));
- Q_ASSERT(CallerPropertyIndex == args->internalClass()->find(v4->id_caller()));
- args->setProperty(CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
- args->setProperty(CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
- args->setProperty(CallerPropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
- args->setProperty(CallerPropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
-
- args->arrayReserve(context->argc());
- args->arrayPut(0, context->args(), context->argc());
- args->d()->fullyCreated = true;
- } else {
- Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(v4->id_callee()));
- args->setProperty(CalleePropertyIndex, context->d()->function);
- }
+ Scoped<QV4::StrictArgumentsObject> args(scope, this);
+ args->arrayReserve(frame->originalArgumentsCount);
+ args->arrayPut(0, frame->originalArguments, frame->originalArgumentsCount);
+
Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(v4->id_length()));
- args->setProperty(LengthPropertyIndex, Primitive::fromInt32(context->argc()));
+ setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(frame->originalArgumentsCount));
}
void ArgumentsObject::fullyCreate()
@@ -132,8 +142,6 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con
bool result = Object::defineOwnProperty2(scope.engine, index, desc, attrs);
if (!result) {
- if (d()->isStrict)
- return engine->throwTypeError();
return false;
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index cc7eada4b9..ac281f555a 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -79,17 +79,26 @@ DECLARE_HEAP_OBJECT(ArgumentsSetterFunction, FunctionObject) {
Member(class, Pointer, CallContext *, context) \
Member(class, Pointer, MemberData *, mappedArguments) \
Member(class, NoMark, bool, fullyCreated) \
- Member(class, NoMark, bool, isStrict) \
Member(class, NoMark, int, nFormals)
DECLARE_HEAP_OBJECT(ArgumentsObject, Object) {
DECLARE_MARKOBJECTS(ArgumentsObject);
enum {
LengthPropertyIndex = 0,
+ CalleePropertyIndex = 1
+ };
+ void init(CppStackFrame *frame);
+};
+
+#define StrictArgumentsObjectMembers(class, Member)
+
+DECLARE_HEAP_OBJECT(StrictArgumentsObject, Object) {
+ enum {
+ LengthPropertyIndex = 0,
CalleePropertyIndex = 1,
CallerPropertyIndex = 3
};
- void init(QV4::CallContext *context, int nFormals, bool strict);
+ void init(CppStackFrame *frame);
};
}
@@ -133,8 +142,7 @@ struct ArgumentsObject: Object {
bool fullyCreated() const { return d()->fullyCreated; }
static bool isNonStrictArgumentsObject(Managed *m) {
- return m->d()->vtable()->type == Type_ArgumentsObject &&
- !static_cast<ArgumentsObject *>(m)->d()->isStrict;
+ return m->d()->vtable() == staticVTable();
}
bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
@@ -148,6 +156,11 @@ struct ArgumentsObject: Object {
};
+struct StrictArgumentsObject : Object {
+ V4_OBJECT2(StrictArgumentsObject, Object)
+ Q_MANAGED_TYPE(ArgumentsObject)
+};
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 78c10eacc7..b92bd3992d 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -242,6 +242,8 @@ ExecutionEngine::ExecutionEngine()
InternalClass *argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
internalClasses[EngineBase::Class_ArgumentsObject] = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable);
+ argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
+ argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
argsClass = argsClass->addMember(id_callee(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
internalClasses[EngineBase::Class_StrictArgumentsObject] = argsClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index aaf69f6555..d165294a87 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -92,6 +92,8 @@ struct Q_QML_EXPORT CppStackFrame {
CppStackFrame *parent;
Function *v4Function;
CallData *jsFrame;
+ const Value *originalArguments;
+ int originalArgumentsCount;
const uchar *instructionPointer;
QString source() const;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 9728f5454c..8bbc021738 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1220,19 +1220,15 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::
QV4::ReturnedValue Runtime::method_createMappedArgumentsObject(ExecutionEngine *engine)
{
Q_ASSERT(engine->currentContext()->d()->type == Heap::ExecutionContext::Type_CallContext);
- QV4::CallContext *c = static_cast<QV4::CallContext *>(&engine->currentStackFrame->jsFrame->context);
QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_ArgumentsObject];
- int nFormals = engine->currentStackFrame->v4Function->nFormals;
- return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), c, nFormals, false)->asReturnedValue();
+ return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
}
QV4::ReturnedValue Runtime::method_createUnmappedArgumentsObject(ExecutionEngine *engine)
{
Q_ASSERT(engine->currentContext()->d()->type == Heap::ExecutionContext::Type_CallContext);
- QV4::CallContext *c = static_cast<QV4::CallContext *>(&engine->currentStackFrame->jsFrame->context);
QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_StrictArgumentsObject];
- int nFormals = engine->currentStackFrame->v4Function->nFormals;
- return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), c, nFormals, true)->asReturnedValue();
+ return engine->memoryManager->allocObject<StrictArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
}
ReturnedValue Runtime::method_loadQmlContext(NoThrowEngine *engine)
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 42c0abf3cb..a6cfa7cff1 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -503,6 +503,8 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
ExecutionEngine *engine;
Value *stack;
CppStackFrame frame;
+ frame.originalArguments = argv;
+ frame.originalArgumentsCount = argc;
Function *function;
{