From e9a8252305fa5e3b3cd4a18261990820975a79da Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 7 Aug 2017 14:26:42 +0200 Subject: Don't throw exceptions in Object::delete(indexed) anymore Change-Id: I8613ab21eb1435903e2a8514c21fe51f4a305a2f Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4arrayobject.cpp | 14 ++++++++------ src/qml/jsruntime/qv4context.cpp | 4 +--- src/qml/jsruntime/qv4object.cpp | 4 ---- src/qml/jsruntime/qv4runtime.cpp | 17 ++++++++--------- src/qml/jsruntime/qv4runtimeapi_p.h | 9 ++++----- src/qml/jsruntime/qv4stringobject.cpp | 5 +---- src/qml/jsruntime/qv4vme_moth.cpp | 31 ++++++++++++++++++++++++++++--- 7 files changed, 50 insertions(+), 34 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index 67781bcbb1..5201924bcc 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -334,13 +334,15 @@ ReturnedValue ArrayPrototype::method_pop(const BuiltinFunction *b, CallData *cal ScopedValue result(scope, instance->getIndexed(len - 1)); CHECK_EXCEPTION(); - instance->deleteIndexedProperty(len - 1); - CHECK_EXCEPTION(); + if (!instance->deleteIndexedProperty(len - 1)) + return scope.engine->throwTypeError(); if (instance->isArrayObject()) instance->setArrayLength(len - 1); - else - instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1))); + else { + if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)))) + return scope.engine->throwTypeError(); + } return result->asReturnedValue(); } @@ -589,8 +591,8 @@ ReturnedValue ArrayPrototype::method_splice(const BuiltinFunction *b, CallData * return scope.engine->throwTypeError(); } for (uint k = len; k > len - deleteCount + itemCount; --k) { - instance->deleteIndexedProperty(k - 1); - CHECK_EXCEPTION(); + if (!instance->deleteIndexedProperty(k - 1)) + return scope.engine->throwTypeError(); } } else if (itemCount > deleteCount) { uint k = len - deleteCount; diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index add007fdfb..6a6f80827f 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -228,9 +228,7 @@ bool ExecutionContext::deleteProperty(String *name) } } - if (d()->strictMode) - engine()->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString())); - return true; + return !d()->v4Function->isStrict(); } // Do a standard call with this execution context as the outer scope diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 718f6278d0..20d640bb6b 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -857,8 +857,6 @@ bool Object::internalDeleteProperty(String *name) InternalClass::removeMember(this, name->identifier()); return true; } - if (engine()->current->strictMode) - engine()->throwTypeError(); return false; } @@ -875,8 +873,6 @@ bool Object::internalDeleteIndexedProperty(uint index) if (!ad || ad->vtable()->del(this, index)) return true; - if (engine()->current->strictMode) - engine()->throwTypeError(); return false; } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index cbcf585f94..e81ab783cf 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -313,42 +313,41 @@ ReturnedValue Runtime::method_closure(ExecutionEngine *engine, int functionId) return FunctionObject::createScriptFunction(engine->currentContext, clos)->asReturnedValue(); } -ReturnedValue Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, const Value &index) +bool Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, const Value &index) { Scope scope(engine); ScopedObject o(scope, base); if (o) { uint n = index.asArrayIndex(); - if (n < UINT_MAX) { - return Encode((bool)o->deleteIndexedProperty(n)); - } + if (n < UINT_MAX) + return o->deleteIndexedProperty(n); } ScopedString name(scope, index.toString(engine)); return method_deleteMemberString(engine, base, name); } -ReturnedValue Runtime::method_deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex) +bool Runtime::method_deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex) { Scope scope(engine); ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]); return method_deleteMemberString(engine, base, name); } -ReturnedValue Runtime::method_deleteMemberString(ExecutionEngine *engine, const Value &base, String *name) +bool Runtime::method_deleteMemberString(ExecutionEngine *engine, const Value &base, String *name) { Scope scope(engine); ScopedObject obj(scope, base.toObject(engine)); if (scope.engine->hasException) return Encode::undefined(); - return Encode(obj->deleteProperty(name)); + return obj->deleteProperty(name); } -ReturnedValue Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex) +bool Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex) { Scope scope(engine); ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[nameIndex]); - return Encode(engine->currentContext->deleteProperty(name)); + return engine->currentContext->deleteProperty(name); } QV4::ReturnedValue Runtime::method_instanceof(ExecutionEngine *engine, const Value &lval, const Value &rval) diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index ba4a55f864..d67761ccfc 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -58,7 +58,6 @@ namespace QV4 { typedef uint Bool; struct NoThrowEngine; - namespace { template struct ExceptionCheck { @@ -120,10 +119,10 @@ struct ExceptionCheck { F(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex)) \ \ /* delete */ \ - F(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \ - F(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \ - F(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \ - F(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex)) \ + F(bool, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \ + F(bool, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \ + F(bool, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \ + F(bool, deleteName, (ExecutionEngine *engine, int nameIndex)) \ \ /* exceptions & scopes */ \ F(void, throwException, (ExecutionEngine *engine, const Value &value)) \ diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index d21dd4808f..a3d272469b 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -106,11 +106,8 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index) Scoped o(scope, m->as()); Q_ASSERT(!!o); - if (index < static_cast(o->d()->string->toQString().length())) { - if (v4->current->strictMode) - v4->throwTypeError(); + if (index < static_cast(o->d()->string->toQString().length())) return false; - } return true; } diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 17c2b07105..6297f42c81 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -693,15 +693,40 @@ QV4::ReturnedValue VME::exec(Function *function, const FunctionObject *jsFunctio MOTH_END_INSTR(CallBuiltinForeachNextPropertyName) MOTH_BEGIN_INSTR(CallBuiltinDeleteMember) - STORE_ACCUMULATOR(Runtime::method_deleteMember(engine, STACK_VALUE(instr.base), instr.member)); + if (!Runtime::method_deleteMember(engine, STACK_VALUE(instr.base), instr.member)) { + if (function->isStrict()) { + engine->throwTypeError(); + goto catchException; + } + accumulator = Encode(false); + } else { + accumulator = Encode(true); + } MOTH_END_INSTR(CallBuiltinDeleteMember) MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript) - STORE_ACCUMULATOR(Runtime::method_deleteElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index))); + if (!Runtime::method_deleteElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index))) { + if (function->isStrict()) { + engine->throwTypeError(); + goto catchException; + } + accumulator = Encode(false); + } else { + accumulator = Encode(true); + } MOTH_END_INSTR(CallBuiltinDeleteSubscript) MOTH_BEGIN_INSTR(CallBuiltinDeleteName) - STORE_ACCUMULATOR(Runtime::method_deleteName(engine, instr.name)); + if (!Runtime::method_deleteName(engine, instr.name)) { + if (function->isStrict()) { + QString name = function->compilationUnit->runtimeStrings[instr.name]->toQString(); + engine->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name)); + goto catchException; + } + accumulator = Encode(false); + } else { + accumulator = Encode(true); + } MOTH_END_INSTR(CallBuiltinDeleteName) MOTH_BEGIN_INSTR(CallBuiltinTypeofName) -- cgit v1.2.3