aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-01-03 22:56:52 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2013-01-04 09:16:06 +0100
commit9d1e3e301d88a3dad6115043396fdd8d0ee31ca4 (patch)
tree65b2f130a4f24bc5e17b6140485ab1a5ff07cf51 /qv4codegen.cpp
parent22480fc638afdc0bc860602381e81654e4cbfa3c (diff)
Set data properties using __defineOwnProperties__
Properties in object literals are defined using defineOwnProperty, so that they get set even if the object prototype contains a non writable property with the same name. This fixes all remaining test cases for 11.1.5 Change-Id: I3928a144d09c51c5bf20a25bcb1c6c3c243975ee Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qv4codegen.cpp')
-rw-r--r--qv4codegen.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/qv4codegen.cpp b/qv4codegen.cpp
index 9e4c0c90cd..6446a81111 100644
--- a/qv4codegen.cpp
+++ b/qv4codegen.cpp
@@ -1402,25 +1402,36 @@ bool Codegen::visit(ObjectLiteral *ast)
}
}
if (!valueMap.isEmpty()) {
- const unsigned getter = _block->newTemp();
- const unsigned setter = _block->newTemp();
+ unsigned value = 0;
+ unsigned getter = 0;
+ unsigned setter = 0;
for (QMap<QString, ObjectPropertyValue>::const_iterator it = valueMap.constBegin(); it != valueMap.constEnd(); ++it) {
+ IR::ExprList *args = _function->New<IR::ExprList>();
+ IR::ExprList *current = args;
+ current->expr = _block->TEMP(t);
+ current->next = _function->New<IR::ExprList>();
+ current = current->next;
+ current->expr = _block->NAME(it.key(), 0, 0);
+ current->next = _function->New<IR::ExprList>();
+ current = current->next;
+
if (it->value) {
- move(member(_block->TEMP(t), _function->newString(it.key())), it->value);
+ if (!value)
+ value = _block->newTemp();
+ move(_block->TEMP(value), it->value);
+ // __qmljs_builtin_define_property(Value object, String *name, Value val, ExecutionContext *ctx)
+ current->expr = _block->TEMP(value);
+ _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_define_property, 0, 0), args));
} else {
+ if (!getter) {
+ getter = _block->newTemp();
+ setter = _block->newTemp();
+ }
move(_block->TEMP(getter), it->getter ? _block->CLOSURE(it->getter) : _block->CONST(IR::UndefinedType, 0));
move(_block->TEMP(setter), it->setter ? _block->CLOSURE(it->setter) : _block->CONST(IR::UndefinedType, 0));
// __qmljs_builtin_define_getter_setter(Value object, String *name, Value getter, Value setter, ExecutionContext *ctx);
- IR::ExprList *args = _function->New<IR::ExprList>();
- IR::ExprList *current = args;
- current->expr = _block->TEMP(t);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->NAME(it.key(), 0, 0);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
current->expr = _block->TEMP(getter);
current->next = _function->New<IR::ExprList>();
current = current->next;