aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-02-15 02:16:43 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-24 20:41:40 +0100
commitc78d1052c2509646c8cf13b460a8d098de836ad0 (patch)
treeb32bb074293b87996596789ec259f9170887298c /src/qml/compiler
parent00be968679152105fece89c3243a457b52d3f268 (diff)
Clean up object literal handling with integral indices
* Object literals with array indices are now created with one run-time call, instead of an initial one for non-integral keys followed by sub-sequent define_builtin_property calls. * Cleaned up propert name retrieval. Instead of using a visitor, it's easier to define a virtual method on the PropertyName type. The visitor doesn't buy us much as it's not possible to recurse within property names, and this way we can use it also from the function scanner to correctly determine the number of arguments needed for object literal initalizations. * Similarly the duplicated/common name member for all property assignments has been moved into PropertyName, for convenient access without AST casts. * Removed now unused builtin_define_property/settergetter functions from IR, run-time and moth. Change-Id: I90d54c81ea5f3f500f4f4a9c14f7caf5135e7f9f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4codegen.cpp199
-rw-r--r--src/qml/compiler/qv4codegen_p.h6
-rw-r--r--src/qml/compiler/qv4compiler.cpp8
-rw-r--r--src/qml/compiler/qv4compiler_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h19
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp103
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h4
-rw-r--r--src/qml/compiler/qv4isel_p.cpp53
-rw-r--r--src/qml/compiler/qv4isel_p.h6
-rw-r--r--src/qml/compiler/qv4jsir.cpp4
-rw-r--r--src/qml/compiler/qv4jsir_p.h2
11 files changed, 184 insertions, 222 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 6685336b5f..f08ebaf6cd 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -261,6 +261,9 @@ bool Codegen::ScanFunctions::visit(ObjectLiteral *ast)
{
int argc = 0;
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
+ QString key = it->assignment->name->asString();
+ if (QV4::String::toArrayIndex(key) != UINT_MAX)
+ ++argc;
++argc;
if (AST::cast<AST::PropertyGetterSetter *>(it->assignment))
++argc;
@@ -776,17 +779,6 @@ Codegen::Result Codegen::expression(ExpressionNode *ast)
return r;
}
-QString Codegen::propertyName(PropertyName *ast)
-{
- QString p;
- if (ast) {
- qSwap(_property, p);
- accept(ast);
- qSwap(_property, p);
- }
- return p;
-}
-
Codegen::Result Codegen::sourceElement(SourceElement *ast)
{
Result r(nx);
@@ -1597,8 +1589,8 @@ bool Codegen::visit(ObjectLiteral *ast)
QMap<QString, ObjectPropertyValue> valueMap;
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
+ QString name = it->assignment->name->asString();
if (PropertyNameAndValue *nv = AST::cast<AST::PropertyNameAndValue *>(it->assignment)) {
- QString name = propertyName(nv->name);
Result value = expression(nv->value);
ObjectPropertyValue &v = valueMap[name];
if (v.hasGetter() || v.hasSetter() || (_function->isStrict && v.value)) {
@@ -1609,7 +1601,6 @@ bool Codegen::visit(ObjectLiteral *ast)
valueMap[name].value = *value;
} else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) {
- QString name = propertyName(gs->name);
const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : 0);
ObjectPropertyValue &v = valueMap[name];
if (v.value ||
@@ -1628,104 +1619,99 @@ bool Codegen::visit(ObjectLiteral *ast)
}
}
- IR::ExprList *args = 0;
+ // The linked-list arguments to builtin_define_object_literal
+ // begin with a CONST counting the number of key/value pairs, followed by the
+ // key value pairs, followed by the array entries.
+ IR::ExprList *args = _function->New<IR::ExprList>();
- if (!valueMap.isEmpty()) {
- IR::ExprList *current;
- for (QMap<QString, ObjectPropertyValue>::iterator it = valueMap.begin(); it != valueMap.end(); ) {
- if (QV4::String::toArrayIndex(it.key()) != UINT_MAX) {
- ++it;
- continue;
+ IR::Const *entryCountParam = _function->New<IR::Const>();
+ entryCountParam->init(IR::SInt32Type, 0);
+ args->expr = entryCountParam;
+ args->next = 0;
+
+ IR::ExprList *keyValueEntries = 0;
+ IR::ExprList *currentKeyValueEntry = 0;
+ int keyValueEntryCount = 0;
+ IR::ExprList *arrayEntries = 0;
+
+ IR::ExprList *currentArrayEntry = 0;
+
+ for (QMap<QString, ObjectPropertyValue>::iterator it = valueMap.begin(); it != valueMap.end(); ) {
+ IR::ExprList **currentPtr = 0;
+ uint keyAsIndex = QV4::String::toArrayIndex(it.key());
+ if (keyAsIndex != UINT_MAX) {
+ if (!arrayEntries) {
+ arrayEntries = _function->New<IR::ExprList>();
+ currentArrayEntry = arrayEntries;
+ } else {
+ currentArrayEntry->next = _function->New<IR::ExprList>();
+ currentArrayEntry = currentArrayEntry->next;
}
-
- if (!args) {
- args = _function->New<IR::ExprList>();
- current = args;
+ currentPtr = &currentArrayEntry;
+ IR::Const *idx = _function->New<IR::Const>();
+ idx->init(IR::UInt32Type, keyAsIndex);
+ (*currentPtr)->expr = idx;
+ } else {
+ if (!keyValueEntries) {
+ keyValueEntries = _function->New<IR::ExprList>();
+ currentKeyValueEntry = keyValueEntries;
} else {
- current->next = _function->New<IR::ExprList>();
- current = current->next;
+ currentKeyValueEntry->next = _function->New<IR::ExprList>();
+ currentKeyValueEntry = currentKeyValueEntry->next;
}
+ currentPtr = &currentKeyValueEntry;
+ (*currentPtr)->expr = _block->NAME(it.key(), 0, 0);
+ keyValueEntryCount++;
+ }
- current->expr = _block->NAME(it.key(), 0, 0);
-
- if (it->value) {
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->CONST(IR::BoolType, true);
-
- unsigned value = _block->newTemp();
- move(_block->TEMP(value), it->value);
+ IR::ExprList *&current = *currentPtr;
+ if (it->value) {
+ current->next = _function->New<IR::ExprList>();
+ current = current->next;
+ current->expr = _block->CONST(IR::BoolType, true);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(value);
- } else {
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->CONST(IR::BoolType, false);
-
- unsigned getter = _block->newTemp();
- unsigned setter = _block->newTemp();
- move(_block->TEMP(getter), it->hasGetter() ? _block->CLOSURE(it->getter) : _block->CONST(IR::UndefinedType, 0));
- move(_block->TEMP(setter), it->hasSetter() ? _block->CLOSURE(it->setter) : _block->CONST(IR::UndefinedType, 0));
-
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(getter);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(setter);
- }
+ unsigned value = _block->newTemp();
+ move(_block->TEMP(value), it->value);
- it = valueMap.erase(it);
- }
- }
+ current->next = _function->New<IR::ExprList>();
+ current = current->next;
+ current->expr = _block->TEMP(value);
+ } else {
+ current->next = _function->New<IR::ExprList>();
+ current = current->next;
+ current->expr = _block->CONST(IR::BoolType, false);
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), _block->CALL(_block->NAME(IR::Name::builtin_define_object_literal,
- ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), args));
+ unsigned getter = _block->newTemp();
+ unsigned setter = _block->newTemp();
+ move(_block->TEMP(getter), it->hasGetter() ? _block->CLOSURE(it->getter) : _block->CONST(IR::UndefinedType, 0));
+ move(_block->TEMP(setter), it->hasSetter() ? _block->CLOSURE(it->setter) : _block->CONST(IR::UndefinedType, 0));
- // What's left are array entries
- if (!valueMap.isEmpty()) {
- 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->expr = _block->TEMP(getter);
current->next = _function->New<IR::ExprList>();
current = current->next;
+ current->expr = _block->TEMP(setter);
+ }
- if (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->hasGetter() ? _block->CLOSURE(it->getter) : _block->CONST(IR::UndefinedType, 0));
- move(_block->TEMP(setter), it->hasSetter() ? _block->CLOSURE(it->setter) : _block->CONST(IR::UndefinedType, 0));
+ it = valueMap.erase(it);
+ }
+ entryCountParam->value = keyValueEntryCount;
- // __qmljs_builtin_define_getter_setter(Value object, String *name, Value getter, Value setter, ExecutionContext *ctx);
- current->expr = _block->TEMP(getter);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(setter);
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_define_getter_setter, 0, 0), args));
- }
- }
+ if (keyValueEntries)
+ args->next = keyValueEntries;
+ if (arrayEntries) {
+ if (currentKeyValueEntry)
+ currentKeyValueEntry->next = arrayEntries;
+ else
+ args->next = arrayEntries;
}
+ const unsigned t = _block->newTemp();
+ move(_block->TEMP(t), _block->CALL(_block->NAME(IR::Name::builtin_define_object_literal,
+ ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), args));
+
_expr.code = _block->TEMP(t);
return false;
}
@@ -2072,33 +2058,6 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
return functionIndex;
}
-bool Codegen::visit(IdentifierPropertyName *ast)
-{
- if (hasError)
- return false;
-
- _property = ast->id.toString();
- return false;
-}
-
-bool Codegen::visit(NumericLiteralPropertyName *ast)
-{
- if (hasError)
- return false;
-
- _property = QString::number(ast->id, 'g', 16);
- return false;
-}
-
-bool Codegen::visit(StringLiteralPropertyName *ast)
-{
- if (hasError)
- return false;
-
- _property = ast->id.toString();
- return false;
-}
-
bool Codegen::visit(FunctionSourceElement *ast)
{
if (hasError)
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index 37055171b1..9c43dc17fe 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -315,7 +315,6 @@ protected:
void statement(AST::ExpressionNode *ast);
void condition(AST::ExpressionNode *ast, QV4::IR::BasicBlock *iftrue, QV4::IR::BasicBlock *iffalse);
Result expression(AST::ExpressionNode *ast);
- QString propertyName(AST::PropertyName *ast);
Result sourceElement(AST::SourceElement *ast);
UiMember uiObjectMember(AST::UiObjectMember *ast);
@@ -397,11 +396,6 @@ protected:
virtual bool visit(AST::VoidExpression *ast);
virtual bool visit(AST::FunctionDeclaration *ast);
- // property names
- virtual bool visit(AST::IdentifierPropertyName *ast);
- virtual bool visit(AST::NumericLiteralPropertyName *ast);
- virtual bool visit(AST::StringLiteralPropertyName *ast);
-
// source elements
virtual bool visit(AST::FunctionSourceElement *ast);
virtual bool visit(AST::StatementSourceElement *ast);
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 7be902f1c1..b28195960f 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -151,14 +151,14 @@ void QV4::Compiler::JSUnitGenerator::registerLineNumberMapping(QV4::IR::Function
lineNumberMappingsPerFunction.insert(function, mappings);
}
-int QV4::Compiler::JSUnitGenerator::registerJSClass(QV4::IR::ExprList *args)
+int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, IR::ExprList *args)
{
// ### re-use existing class definitions.
QList<CompiledData::JSClassMember> members;
- QV4::IR::ExprList *it = args;
- while (it) {
+ IR::ExprList *it = args;
+ for (int i = 0; i < count; ++i, it = it->next) {
CompiledData::JSClassMember member;
QV4::IR::Name *name = it->expr->asName();
@@ -173,8 +173,6 @@ int QV4::Compiler::JSUnitGenerator::registerJSClass(QV4::IR::ExprList *args)
if (!isData)
it = it->next;
-
- it = it->next;
}
jsClasses << members;
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index 29cf82e2bc..a917ea3d94 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -79,7 +79,7 @@ struct Q_QML_EXPORT JSUnitGenerator {
void registerLineNumberMapping(IR::Function *function, const QVector<uint> &mappings);
- int registerJSClass(IR::ExprList *args);
+ int registerJSClass(int count, IR::ExprList *args);
QV4::CompiledData::Unit *generateUnit(int *totalUnitSize = 0);
// Returns bytes written
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index bca878d648..08c523ce56 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -95,8 +95,6 @@ QT_BEGIN_NAMESPACE
F(CallBuiltinTypeofName, callBuiltinTypeofName) \
F(CallBuiltinTypeofValue, callBuiltinTypeofValue) \
F(CallBuiltinDeclareVar, callBuiltinDeclareVar) \
- F(CallBuiltinDefineGetterSetter, callBuiltinDefineGetterSetter) \
- F(CallBuiltinDefineProperty, callBuiltinDefineProperty) \
F(CallBuiltinDefineArray, callBuiltinDefineArray) \
F(CallBuiltinDefineObjectLiteral, callBuiltinDefineObjectLiteral) \
F(CallBuiltinSetupArgumentsObject, callBuiltinSetupArgumentsObject) \
@@ -481,19 +479,6 @@ union Instr
int varName;
bool isDeletable;
};
- struct instr_callBuiltinDefineGetterSetter {
- MOTH_INSTR_HEADER
- int name;
- Param object;
- Param getter;
- Param setter;
- };
- struct instr_callBuiltinDefineProperty {
- MOTH_INSTR_HEADER
- int name;
- Param object;
- Param value;
- };
struct instr_callBuiltinDefineArray {
MOTH_INSTR_HEADER
quint32 argc;
@@ -503,6 +488,8 @@ union Instr
struct instr_callBuiltinDefineObjectLiteral {
MOTH_INSTR_HEADER
int internalClassId;
+ int arrayValueCount;
+ int arrayGetterSetterCount;
quint32 args;
Param result;
};
@@ -768,8 +755,6 @@ union Instr
instr_callBuiltinTypeofName callBuiltinTypeofName;
instr_callBuiltinTypeofValue callBuiltinTypeofValue;
instr_callBuiltinDeclareVar callBuiltinDeclareVar;
- instr_callBuiltinDefineGetterSetter callBuiltinDefineGetterSetter;
- instr_callBuiltinDefineProperty callBuiltinDefineProperty;
instr_callBuiltinDefineArray callBuiltinDefineArray;
instr_callBuiltinDefineObjectLiteral callBuiltinDefineObjectLiteral;
instr_callBuiltinSetupArgumentsObject callBuiltinSetupArgumentsObject;
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index ba4f2331a1..8045b811ea 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -1252,26 +1252,6 @@ void InstructionSelection::callBuiltinDeclareVar(bool deletable, const QString &
addInstruction(call);
}
-void InstructionSelection::callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter)
-{
- Instruction::CallBuiltinDefineGetterSetter call;
- call.object = getParam(object);
- call.name = registerString(name);
- call.getter = getParam(getter);
- call.setter = getParam(setter);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDefineProperty(IR::Temp *object, const QString &name,
- IR::Expr *value)
-{
- Instruction::CallBuiltinDefineProperty call;
- call.object = getParam(object);
- call.name = registerString(name);
- call.value = getParam(value);
- addInstruction(call);
-}
-
void InstructionSelection::callBuiltinDefineArray(IR::Temp *result, IR::ExprList *args)
{
Instruction::CallBuiltinDefineArray call;
@@ -1280,13 +1260,16 @@ void InstructionSelection::callBuiltinDefineArray(IR::Temp *result, IR::ExprList
addInstruction(call);
}
-void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Temp *result, IR::ExprList *args)
+void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Temp *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries)
{
int argLocation = outgoingArgumentTempStart();
- const int classId = registerJSClass(args);
- IR::ExprList *it = args;
- while (it) {
+ const int classId = registerJSClass(keyValuePairCount, keyValuePairs);
+
+ // Process key/value pairs first
+ IR::ExprList *it = keyValuePairs;
+ for (int i = 0; i < keyValuePairCount; ++i, it = it->next) {
+ // Skip name
it = it->next;
bool isData = it->expr->asConst()->value;
@@ -1314,12 +1297,84 @@ void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Temp *result, IR::
addInstruction(move);
++argLocation;
}
+ }
+
+ // Process array values
+ int arrayValueCount = 0;
+ it = arrayEntries;
+ while (it) {
+ IR::Const *index = it->expr->asConst();
+ it = it->next;
+
+ bool isData = it->expr->asConst()->value;
+ it = it->next;
+
+ if (!isData) {
+ it = it->next; // getter
+ it = it->next; // setter
+ continue;
+ }
+ ++arrayValueCount;
+
+ Instruction::MoveConst indexMove;
+ indexMove.source = convertToValue(index).asReturnedValue();
+ indexMove.result = Param::createTemp(argLocation);
+ addInstruction(indexMove);
+ ++argLocation;
+
+ Instruction::Move move;
+ move.source = getParam(it->expr);
+ move.result = Param::createTemp(argLocation);
+ addInstruction(move);
+ ++argLocation;
+ it = it->next;
+ }
+
+ // Process array getter/setter pairs
+ int arrayGetterSetterCount = 0;
+ it = arrayEntries;
+ while (it) {
+ IR::Const *index = it->expr->asConst();
+ it = it->next;
+
+ bool isData = it->expr->asConst()->value;
+ it = it->next;
+
+ if (isData) {
+ it = it->next; // value
+ continue;
+ }
+
+ ++arrayGetterSetterCount;
+
+ Instruction::MoveConst indexMove;
+ indexMove.source = convertToValue(index).asReturnedValue();
+ indexMove.result = Param::createTemp(argLocation);
+ addInstruction(indexMove);
+ ++argLocation;
+
+ // getter
+ Instruction::Move moveGetter;
+ moveGetter.source = getParam(it->expr);
+ moveGetter.result = Param::createTemp(argLocation);
+ addInstruction(moveGetter);
+ ++argLocation;
+ it = it->next;
+
+ // setter
+ Instruction::Move moveSetter;
+ moveSetter.source = getParam(it->expr);
+ moveSetter.result = Param::createTemp(argLocation);
+ addInstruction(moveSetter);
+ ++argLocation;
it = it->next;
}
Instruction::CallBuiltinDefineObjectLiteral call;
call.internalClassId = classId;
+ call.arrayValueCount = arrayValueCount;
+ call.arrayGetterSetterCount = arrayGetterSetterCount;
call.args = outgoingArgumentTempStart();
call.result = getResultParam(result);
addInstruction(call);
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index e2ba971e26..732341c3ca 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -98,10 +98,8 @@ protected:
virtual void callBuiltinPushWithScope(IR::Temp *arg);
virtual void callBuiltinPopScope();
virtual void callBuiltinDeclareVar(bool deletable, const QString &name);
- virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter);
- virtual void callBuiltinDefineProperty(IR::Temp *object, const QString &name, IR::Expr *value);
virtual void callBuiltinDefineArray(IR::Temp *result, IR::ExprList *args);
- virtual void callBuiltinDefineObjectLiteral(IR::Temp *result, IR::ExprList *args);
+ virtual void callBuiltinDefineObjectLiteral(IR::Temp *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries);
virtual void callBuiltinSetupArgumentObject(IR::Temp *result);
virtual void callBuiltinConvertThisToObject();
virtual void callValue(IR::Temp *value, IR::ExprList *args, IR::Temp *result);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 4c70c1ddd8..2a73b55ed2 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -347,48 +347,29 @@ void IRDecoder::callBuiltin(IR::Call *call, IR::Temp *result)
}
} return;
- case IR::Name::builtin_define_getter_setter: {
- if (!call->args)
- return;
- IR::ExprList *args = call->args;
- IR::Temp *object = args->expr->asTemp();
- assert(object);
- args = args->next;
- assert(args);
- IR::Name *name = args->expr->asName();
- args = args->next;
- assert(args);
- IR::Temp *getter = args->expr->asTemp();
- args = args->next;
- assert(args);
- IR::Temp *setter = args->expr->asTemp();
-
- callBuiltinDefineGetterSetter(object, *name->id, getter, setter);
- } return;
+ case IR::Name::builtin_define_array:
+ callBuiltinDefineArray(result, call->args);
+ return;
- case IR::Name::builtin_define_property: {
- if (!call->args)
- return;
+ case IR::Name::builtin_define_object_literal: {
IR::ExprList *args = call->args;
- IR::Temp *object = args->expr->asTemp();
- assert(object);
- args = args->next;
- assert(args);
- IR::Name *name = args->expr->asName();
+ const int keyValuePairsCount = args->expr->asConst()->value;
args = args->next;
- assert(args);
- IR::Expr *value = args->expr;
- callBuiltinDefineProperty(object, *name->id, value);
- } return;
+ IR::ExprList *keyValuePairs = args;
+ for (int i = 0; i < keyValuePairsCount; ++i) {
+ args = args->next; // name
+ bool isData = args->expr->asConst()->value;
+ args = args->next; // isData flag
+ args = args->next; // value or getter
+ if (!isData)
+ args = args->next; // setter
+ }
- case IR::Name::builtin_define_array:
- callBuiltinDefineArray(result, call->args);
- return;
+ IR::ExprList *arrayEntries = args;
- case IR::Name::builtin_define_object_literal:
- callBuiltinDefineObjectLiteral(result, call->args);
- return;
+ callBuiltinDefineObjectLiteral(result, keyValuePairsCount, keyValuePairs, arrayEntries);
+ } return;
case IR::Name::builtin_setup_argument_object:
callBuiltinSetupArgumentObject(result);
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index bfe0adc431..7137979b66 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -76,7 +76,7 @@ public:
uint registerSetterLookup(const QString &name) { return jsGenerator->registerSetterLookup(name); }
uint registerGlobalGetterLookup(const QString &name) { return jsGenerator->registerGlobalGetterLookup(name); }
int registerRegExp(IR::RegExp *regexp) { return jsGenerator->registerRegExp(regexp); }
- int registerJSClass(IR::ExprList *args) { return jsGenerator->registerJSClass(args); }
+ int registerJSClass(int count, IR::ExprList *args) { return jsGenerator->registerJSClass(count, args); }
QV4::Compiler::JSUnitGenerator *jsUnitGenerator() const { return jsGenerator; }
protected:
@@ -130,10 +130,8 @@ public: // to implement by subclasses:
virtual void callBuiltinPushWithScope(IR::Temp *arg) = 0;
virtual void callBuiltinPopScope() = 0;
virtual void callBuiltinDeclareVar(bool deletable, const QString &name) = 0;
- virtual void callBuiltinDefineGetterSetter(IR::Temp *object, const QString &name, IR::Temp *getter, IR::Temp *setter) = 0;
- virtual void callBuiltinDefineProperty(IR::Temp *object, const QString &name, IR::Expr *value) = 0;
virtual void callBuiltinDefineArray(IR::Temp *result, IR::ExprList *args) = 0;
- virtual void callBuiltinDefineObjectLiteral(IR::Temp *result, IR::ExprList *args) = 0;
+ virtual void callBuiltinDefineObjectLiteral(IR::Temp *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries) = 0;
virtual void callBuiltinSetupArgumentObject(IR::Temp *result) = 0;
virtual void callBuiltinConvertThisToObject() = 0;
virtual void callValue(IR::Temp *value, IR::ExprList *args, IR::Temp *result) = 0;
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 2683278b12..d9d0742b68 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -427,12 +427,8 @@ static const char *builtin_to_string(Name::Builtin b)
return "builtin_pop_scope";
case IR::Name::builtin_declare_vars:
return "builtin_declare_vars";
- case IR::Name::builtin_define_property:
- return "builtin_define_property";
case IR::Name::builtin_define_array:
return "builtin_define_array";
- case IR::Name::builtin_define_getter_setter:
- return "builtin_define_getter_setter";
case IR::Name::builtin_define_object_literal:
return "builtin_define_object_literal";
case IR::Name::builtin_setup_argument_object:
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 89b6da6278..58a569b862 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -349,9 +349,7 @@ struct Name: Expr {
builtin_push_with_scope,
builtin_pop_scope,
builtin_declare_vars,
- builtin_define_property,
builtin_define_array,
- builtin_define_getter_setter,
builtin_define_object_literal,
builtin_setup_argument_object,
builtin_convert_this_to_object,