diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-09 13:02:26 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-10 08:19:44 +0000 |
commit | 25c5e356353aab15dbf144391a455811c160c3e4 (patch) | |
tree | fde3f9dd9e16ee941564bb268f9ab62bed6017f0 | |
parent | 5fa0bd1f0323bd8c031224e22d52027e38ea9702 (diff) |
Split StoreName into StoreNameStrict and StoreNameSloppy
And adjust the name of the corresponding runtime functions.
Change-Id: I4adf7b0e069d9b0dff9162cd1271dafc60be854b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 8 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 26 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4enginebase_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimeapi_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 15 |
9 files changed, 79 insertions, 30 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index a0f1ce5879..8ede8a6818 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -2866,9 +2866,16 @@ void Codegen::Reference::storeAccumulator() const return; } case Name: { - Instruction::StoreName store; - store.name = unqualifiedNameIndex; - codegen->bytecodeGenerator->addInstruction(store); + Context *c = codegen->currentContext(); + if (c->isStrict) { + Instruction::StoreNameStrict store; + store.name = unqualifiedNameIndex; + codegen->bytecodeGenerator->addInstruction(store); + } else { + Instruction::StoreNameSloppy store; + store.name = unqualifiedNameIndex; + codegen->bytecodeGenerator->addInstruction(store); + } } return; case Member: if (codegen->useFastLookups) { diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index db68c2d76f..52f2190959 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -173,9 +173,13 @@ void dumpBytecode(const char *code, int len, int nFormals) d << instr.index; MOTH_END_INSTR(GetGlobalLookup) - MOTH_BEGIN_INSTR(StoreName) + MOTH_BEGIN_INSTR(StoreNameSloppy) d << instr.name; - MOTH_END_INSTR(StoreName) + MOTH_END_INSTR(StoreNameSloppy) + + MOTH_BEGIN_INSTR(StoreNameStrict) + d << instr.name; + MOTH_END_INSTR(StoreNameStrict) MOTH_BEGIN_INSTR(LoadElement) d << instr.base.dump(nFormals) << "[" << instr.index.dump(nFormals) << "]"; diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 52d0497926..d840cda090 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -85,7 +85,8 @@ QT_BEGIN_NAMESPACE F(LoadClosure, loadClosure) \ F(LoadName, loadName) \ F(GetGlobalLookup, getGlobalLookup) \ - F(StoreName, storeName) \ + F(StoreNameSloppy, storeNameSloppy) \ + F(StoreNameStrict, storeNameStrict) \ F(LoadElement, loadElement) \ F(LoadElementA, loadElementA) \ F(StoreElement, storeElement) \ @@ -322,7 +323,11 @@ union Instr MOTH_INSTR_HEADER int index; }; - struct instr_storeName { + struct instr_storeNameSloppy { + MOTH_INSTR_HEADER + int name; + }; + struct instr_storeNameStrict { MOTH_INSTR_HEADER int name; }; @@ -706,7 +711,8 @@ union Instr instr_loadClosure loadClosure; instr_loadName loadName; instr_getGlobalLookup getGlobalLookup; - instr_storeName storeName; + instr_storeNameSloppy storeNameSloppy; + instr_storeNameStrict storeNameStrict; instr_loadElement loadElement; instr_loadElementA loadElementA; instr_storeElement storeElement; diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 0bcc864b85..5732b904da 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -253,7 +253,7 @@ ReturnedValue ExecutionContext::call(Heap::ExecutionContext *context, CallData * return res; } -bool ExecutionContext::setProperty(String *name, const Value &value) +ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value &value) { name->makeIdentifier(); Identifier *id = name->identifier(); @@ -267,16 +267,18 @@ bool ExecutionContext::setProperty(String *name, const Value &value) Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx); if (c->exceptionVarName->isEqualTo(name->d())) { c->exceptionValue.set(v4, value); - return true; + return NoError; } break; } case Heap::ExecutionContext::Type_WithContext: { - // the semantics are different from the setProperty calls of other activations Scope scope(v4); ScopedObject w(scope, ctx->activation); - if (w->hasProperty(name)) - return w->put(name, value); + if (w->hasProperty(name)) { + if (!w->put(name, value)) + return TypeError; + return NoError; + } break; } case Heap::ExecutionContext::Type_CallContext: { @@ -291,7 +293,7 @@ bool ExecutionContext::setProperty(String *name, const Value &value) index -= c->v4Function->nFormals; static_cast<Heap::CallContext *>(c)->locals.set(v4, index, value); } - return true; + return NoError; } } } @@ -302,22 +304,24 @@ bool ExecutionContext::setProperty(String *name, const Value &value) if (member < UINT_MAX) { Scope scope(v4); ScopedObject a(scope, ctx->activation); - return a->putValue(member, value); + if (!a->putValue(member, value)) + return TypeError; + return NoError; } } break; case Heap::ExecutionContext::Type_QmlContext: { Scope scope(v4); ScopedObject activation(scope, ctx->activation); - return activation->put(name, value); + if (!activation->put(name, value)) + return TypeError; + return NoError; } } } - if (d()->v4Function->isStrict()) - return false; - return engine()->globalObject->put(name, value); + return RangeError; } ReturnedValue ExecutionContext::getProperty(String *name) diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 8c533f775c..399c06c47e 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -198,7 +198,14 @@ struct Q_QML_EXPORT ExecutionContext : public Managed void createMutableBinding(String *name, bool deletable); - bool setProperty(String *name, const Value &value); + enum Error { + NoError, + TypeError, + RangeError + }; + + Error setProperty(String *name, const Value &value); + ReturnedValue getProperty(String *name); ReturnedValue getPropertyAndBase(String *name, Value *base); bool deleteProperty(String *name); diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h index 71cedfd093..fa07fb6566 100644 --- a/src/qml/jsruntime/qv4enginebase_p.h +++ b/src/qml/jsruntime/qv4enginebase_p.h @@ -64,6 +64,11 @@ namespace QV4 { #endif struct Q_QML_EXPORT EngineBase { struct JSStackFrame { + enum Offsets { + JSFunction = 0, + Context = 1, + Accumulator = 2 + }; // callData is directly before this Value jsFunction; Value context; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a693128755..9cb2ca049c 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -739,11 +739,25 @@ ReturnedValue Runtime::method_foreachNextPropertyName(const Value &foreach_itera } -bool Runtime::method_setActivationProperty(ExecutionEngine *engine, int nameIndex, const Value &value) +void Runtime::method_storeNameSloppy(ExecutionEngine *engine, int nameIndex, const Value &value) { Scope scope(engine); ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); - return static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).setProperty(name, value); + ExecutionContext::Error e = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).setProperty(name, value); + + if (e == ExecutionContext::RangeError) + engine->globalObject->put(name, value); +} + +void Runtime::method_storeNameStrict(ExecutionEngine *engine, int nameIndex, const Value &value) +{ + Scope scope(engine); + ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]); + ExecutionContext::Error e = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).setProperty(name, value); + if (e == ExecutionContext::TypeError) + engine->throwTypeError(); + else if (e == ExecutionContext::RangeError) + engine->throwReferenceError(name); } ReturnedValue Runtime::method_getProperty(ExecutionEngine *engine, const Value &object, int nameIndex) diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 7c0c44136c..406f1a3ab5 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -107,7 +107,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { F(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \ \ /* set & get */ \ - F(bool, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value)) \ + F(void, storeNameStrict, (ExecutionEngine *engine, int nameIndex, const Value &value)) \ + F(void, storeNameSloppy, (ExecutionEngine *engine, int nameIndex, const Value &value)) \ F(bool, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)) \ F(bool, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)) \ F(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 02c346cf38..b772055787 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -516,14 +516,15 @@ QV4::ReturnedValue VME::exec(Heap::ExecutionContext *context, Function *function STORE_ACCUMULATOR(l->globalGetter(l, engine)); MOTH_END_INSTR(GetGlobalLookup) - MOTH_BEGIN_INSTR(StoreName) - if (!Runtime::method_setActivationProperty(engine, instr.name, accumulator) && function->isStrict()) { - Scope scope(engine); - ScopedString n(scope, function->compilationUnit->runtimeStrings[instr.name]); - engine->throwReferenceError(n); - } + MOTH_BEGIN_INSTR(StoreNameStrict) + Runtime::method_storeNameStrict(engine, instr.name, accumulator); + CHECK_EXCEPTION; + MOTH_END_INSTR(StoreNameSloppy) + + MOTH_BEGIN_INSTR(StoreNameSloppy) + Runtime::method_storeNameSloppy(engine, instr.name, accumulator); CHECK_EXCEPTION; - MOTH_END_INSTR(StoreName) + MOTH_END_INSTR(StoreNameSloppy) MOTH_BEGIN_INSTR(LoadElement) STORE_ACCUMULATOR(Runtime::method_getElement(engine, STACK_VALUE(instr.base), STACK_VALUE(instr.index))); |