- for (PropertyListNode* p = this; p; p = p->m_next) {
- RegisterID* value = generator.emitNode(p->m_node->m_assign);
-
- switch (p->m_node->m_type) {
- case PropertyNode::Constant: {
- generator.emitDirectPutById(newObj.get(), p->m_node->name(), value);
- break;
- }
- case PropertyNode::Getter: {
- generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
- break;
+ // Fast case: this loop just handles regular value properties.
+ PropertyListNode* p = this;
+ for (; p && p->m_node->m_type == PropertyNode::Constant; p = p->m_next)
+ generator.emitDirectPutById(newObj.get(), p->m_node->name(), generator.emitNode(p->m_node->m_assign));
+
+ // Were there any get/set properties?
+ if (p) {
+ typedef std::pair<PropertyNode*, PropertyNode*> GetterSetterPair;
+ typedef HashMap<StringImpl*, GetterSetterPair> GetterSetterMap;
+ GetterSetterMap map;
+
+ // Build a map, pairing get/set values together.
+ for (PropertyListNode* q = p; q; q = q->m_next) {
+ PropertyNode* node = q->m_node;
+ if (node->m_type == PropertyNode::Constant)
+ continue;
+
+ GetterSetterPair pair(node, static_cast<PropertyNode*>(0));
+ GetterSetterMap::AddResult result = map.add(node->name().impl(), pair);
+ if (!result.isNewEntry)
+ result.iterator->second.second = node;
+ }
+
+ // Iterate over the remaining properties in the list.
+ for (; p; p = p->m_next) {
+ PropertyNode* node = p->m_node;
+ RegisterID* value = generator.emitNode(node->m_assign);
+
+ // Handle regular values.
+ if (node->m_type == PropertyNode::Constant) {
+ generator.emitDirectPutById(newObj.get(), node->name(), value);
+ continue;