diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-09-06 13:38:23 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-09-07 10:31:57 +0000 |
commit | bd4064eabf79a6166805c877ee622931df6fb172 (patch) | |
tree | 9a9d96fbb224ada879836dbfb7cff9e93b44946f /src | |
parent | 15bdbd89639c29f88db1798de66066a4a95759c0 (diff) |
Throw a type error when trying to destructure null or undefined
Change-Id: Id1bba1a729124bccb8a90dcf40252fe5c69d27a3
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4bytecodehandler.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4baselinejit.cpp | 11 | ||||
-rw-r--r-- | src/qml/jit/qv4baselinejit_p.h | 1 | ||||
-rw-r--r-- | src/qml/jit/qv4jithelpers.cpp | 6 | ||||
-rw-r--r-- | src/qml/jit/qv4jithelpers_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 7 |
9 files changed, 38 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp index 3a3f4a6adb..5b836c2e9c 100644 --- a/src/qml/compiler/qv4bytecodehandler.cpp +++ b/src/qml/compiler/qv4bytecodehandler.cpp @@ -528,6 +528,9 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint COLLECTOR_BEGIN_INSTR(InitializeBlockDeadTemporalZone) COLLECTOR_END_INSTR(InitializeBlockDeadTemporalZone) + COLLECTOR_BEGIN_INSTR(ThrowOnNullOrUndefined) + COLLECTOR_END_INSTR(ThrowOnNullOrUndefined) + COLLECTOR_BEGIN_INSTR(LoadQmlContext) COLLECTOR_END_INSTR(LoadQmlContext) diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 1d6e8819f5..2415142df4 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -619,6 +619,10 @@ void Codegen::destructurePropertyList(const Codegen::Reference &object, PatternP { RegisterScope scope(this); + object.loadInAccumulator(); + Instruction::ThrowOnNullOrUndefined t; + bytecodeGenerator->addInstruction(t); + for (PatternPropertyList *it = bindingList; it; it = it->next) { PatternProperty *p = it->property; RegisterScope scope(this); diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index b09f1d09d0..00a1e8470b 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -702,6 +702,9 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st d << dumpRegister(firstReg, nFormals) << ", " << count; MOTH_END_INSTR(InitializeBlockDeadTemporalZone) + MOTH_BEGIN_INSTR(ThrowOnNullOrUndefined) + MOTH_END_INSTR(ThrowOnNullOrUndefined) + MOTH_BEGIN_INSTR(LoadQmlContext) d << dumpRegister(result, nFormals); MOTH_END_INSTR(LoadQmlContext) diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 40313551e8..34c80db0e8 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -195,6 +195,7 @@ QT_BEGIN_NAMESPACE #define INSTR_LoadQmlContext(op) INSTRUCTION(op, LoadQmlContext, 1, result) #define INSTR_LoadQmlImportedScripts(op) INSTRUCTION(op, LoadQmlImportedScripts, 1, result) #define INSTR_InitializeBlockDeadTemporalZone(op) INSTRUCTION(op, InitializeBlockDeadTemporalZone, 2, firstReg, count) +#define INSTR_ThrowOnNullOrUndefined(op) INSTRUCTION(op, ThrowOnNullOrUndefined, 0) #define FOR_EACH_MOTH_INSTR_ALL(F) \ F(Nop) \ @@ -332,6 +333,7 @@ QT_BEGIN_NAMESPACE F(PushScriptContext) \ F(PopScriptContext) \ F(InitializeBlockDeadTemporalZone) \ + F(ThrowOnNullOrUndefined) \ F(Debug) \ #define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::Debug_Wide) + 1) diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp index d0ac169e4f..baaab75158 100644 --- a/src/qml/jit/qv4baselinejit.cpp +++ b/src/qml/jit/qv4baselinejit.cpp @@ -956,6 +956,17 @@ void BaselineJIT::generate_InitializeBlockDeadTemporalZone(int firstReg, int cou as->storeReg(i); } +void BaselineJIT::generate_ThrowOnNullOrUndefined() +{ + STORE_ACC(); + as->prepareCallWithArgCount(2); + as->passAccumulatorAsArg(1); + as->passEngineAsArg(0); + BASELINEJIT_GENERATE_RUNTIME_CALL(Helpers::throwOnNullOrUndefined, CallResultDestination::Ignore); + as->checkException(); +} + + void BaselineJIT::startInstruction(Instr::Type /*instr*/) { if (hasLabel()) diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h index 7e3fcfa5e6..f9c876a1e9 100644 --- a/src/qml/jit/qv4baselinejit_p.h +++ b/src/qml/jit/qv4baselinejit_p.h @@ -211,6 +211,7 @@ public: void generate_LoadQmlContext(int result) override; void generate_LoadQmlImportedScripts(int result) override; void generate_InitializeBlockDeadTemporalZone(int firstReg, int count) override; + void generate_ThrowOnNullOrUndefined() override; void startInstruction(Moth::Instr::Type instr) override; void endInstruction(Moth::Instr::Type instr) override; diff --git a/src/qml/jit/qv4jithelpers.cpp b/src/qml/jit/qv4jithelpers.cpp index 7bac5d968d..427356e5ed 100644 --- a/src/qml/jit/qv4jithelpers.cpp +++ b/src/qml/jit/qv4jithelpers.cpp @@ -146,6 +146,12 @@ ReturnedValue deleteName(Function *function, int name) } } +void throwOnNullOrUndefined(ExecutionEngine *engine, const Value &v) +{ + if (v.isNullOrUndefined()) + engine->throwTypeError(); +} + } // Helpers namespace } // JIT namespace } // QV4 namespace diff --git a/src/qml/jit/qv4jithelpers_p.h b/src/qml/jit/qv4jithelpers_p.h index bb10d5722b..dd68452e7f 100644 --- a/src/qml/jit/qv4jithelpers_p.h +++ b/src/qml/jit/qv4jithelpers_p.h @@ -76,6 +76,7 @@ void pushScriptContext(Value *stack, ExecutionEngine *engine, int index); void popScriptContext(Value *stack, ExecutionEngine *engine); ReturnedValue deleteProperty(QV4::Function *function, const QV4::Value &base, const QV4::Value &index); ReturnedValue deleteName(Function *function, int name); +void throwOnNullOrUndefined(ExecutionEngine *engine, const Value &v); } // Helpers namespace } // JIT namespace diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index f38bd7b48e..6ed371bbf2 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -1344,6 +1344,13 @@ QV4::ReturnedValue VME::interpret(CppStackFrame *frame, ExecutionEngine *engine, STACK_VALUE(i) = acc; MOTH_END_INSTR(InitializeBlockDeadTemporalZone) + MOTH_BEGIN_INSTR(ThrowOnNullOrUndefined) + if (Primitive::fromReturnedValue(acc).isNullOrUndefined()) { + engine->throwTypeError(); + goto handleUnwind; + } + MOTH_END_INSTR(ThrowOnNullOrUndefined) + MOTH_BEGIN_INSTR(Debug) #if QT_CONFIG(qml_debug) STORE_IP(); |