diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-11-06 15:59:01 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-11-14 21:46:14 +0000 |
commit | 30ada3da8635f3e496ea6cb9483aa104d32e5a61 (patch) | |
tree | 5573b2a95dc25a5c8fa17de79179ef6bc10294f4 /src/qml/jsruntime | |
parent | f0a412020f493f01205c302cf48927dd5e3b80b6 (diff) |
Clean up ArgumentsObject handling
Introduce a proper strict arguments object.
Change-Id: Ie4e7f904b3a0e03893b18b3c6709f4f25dbc1030
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 52 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject_p.h | 21 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 2 |
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; { |