aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4runtime.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-30 12:58:55 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-31 06:08:41 +0000
commitee565b3db656b5b9bfd57d98d53b898c1a62e1f0 (patch)
tree857b0f3c09144e68ee0d6cfdf25a227df2f76c8b /src/qml/jsruntime/qv4runtime.cpp
parentebf9365b5c7ec1e4828be88beeb930b4de52f35b (diff)
Correctly create methods for functions in object literals
Methods behave slightly different than normal functions as they have a home object and define how super property access is being done. To implement this correctly, we need to create these methods during object initialization time. Change-Id: Ib3f670c8790b882c6472de786938ca4f0b73f66f Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4runtime.cpp')
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 3317003ea4..fbddcb6ee1 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1529,30 +1529,48 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, int classId
ScopedProperty pd(scope);
ScopedFunctionObject fn(scope);
ScopedString fnName(scope);
+ ScopedValue value(scope);
for (int i = 0; i < additionalArgs; ++i) {
Q_ASSERT(args->isInteger());
ObjectLiteralArgument arg = ObjectLiteralArgument(args->integerValue());
name = args[1].toPropertyKey(engine);
+ value = args[2];
if (engine->hasException)
return Encode::undefined();
- if (args[2].isFunctionObject()) {
- fn = static_cast<const FunctionObject &>(args[2]);
+ if (arg != ObjectLiteralArgument::Value) {
+ Q_ASSERT(args[2].isInteger());
+ int functionId = args[2].integerValue();
+ QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeFunctions[functionId];
+ Q_ASSERT(clos);
+
PropertyKey::FunctionNamePrefix prefix = PropertyKey::None;
if (arg == ObjectLiteralArgument::Getter)
prefix = PropertyKey::Getter;
else if (arg == ObjectLiteralArgument::Setter)
prefix = PropertyKey::Setter;
-
+ else
+ arg = ObjectLiteralArgument::Value;
fnName = name->asFunctionName(engine, prefix);
+
+ ExecutionContext *current = static_cast<ExecutionContext *>(&engine->currentStackFrame->jsFrame->context);
+ if (clos->isGenerator())
+ value = MemberGeneratorFunction::create(current, clos, fnName)->asReturnedValue();
+ else
+ value = FunctionObject::createMemberFunction(current, clos, fnName)->asReturnedValue();
+ } else if (args[2].isFunctionObject()) {
+ fn = static_cast<const FunctionObject &>(args[2]);
+
+ fnName = name->asFunctionName(engine, PropertyKey::None);
fn->setName(fnName);
}
- Q_ASSERT(arg == ObjectLiteralArgument::Value || args[2].isFunctionObject());
+ Q_ASSERT(arg != ObjectLiteralArgument::Method);
+ Q_ASSERT(arg == ObjectLiteralArgument::Value || value->isFunctionObject());
if (arg == ObjectLiteralArgument::Value || arg == ObjectLiteralArgument::Getter) {
- pd->value = args[2];
+ pd->value = value;
pd->set = Primitive::emptyValue();
} else {
pd->value = Primitive::emptyValue();
- pd->set = args[2];
+ pd->set = value;
}
bool ok = o->defineOwnProperty(name, pd, (arg == ObjectLiteralArgument::Value ? Attr_Data : Attr_Accessor));
if (!ok)