aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-09 13:02:26 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-10 08:19:44 +0000
commit25c5e356353aab15dbf144391a455811c160c3e4 (patch)
treefde3f9dd9e16ee941564bb268f9ab62bed6017f0 /src
parent5fa0bd1f0323bd8c031224e22d52027e38ea9702 (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>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4codegen.cpp13
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp8
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h12
-rw-r--r--src/qml/jsruntime/qv4context.cpp26
-rw-r--r--src/qml/jsruntime/qv4context_p.h9
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h5
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp18
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h3
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp15
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)));