<?xml version="1.0"?>
<paste-with-annotations>
  <paste>
    <number>
      <integer>60572</integer>
    </number>
    <user>
      <string>cpst</string>
    </user>
    <title>
      <string>Patch for olliej</string>
    </title>
    <contents>
      <string>Index: VM/CodeGenerator.h
===================================================================
--- VM/CodeGenerator.h	(revision 33029)
+++ VM/CodeGenerator.h	(working copy)
@@ -145,6 +145,17 @@ namespace KJS {
             return emitNode(0, n);
         }
 
+        RegisterID* emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments)
+        {
+            if (n-&gt;isResolveNode() &amp;&amp; (m_codeBlock-&gt;usesEval || m_codeBlock-&gt;needsClosure || rightHasAssignments)) {
+                RefPtr&lt;RegisterID&gt; dst = newTemporary();
+                emitNode(dst.get(), n);
+                return dst.get();
+            }
+            
+            return emitNode(n);
+        }
+
         RegisterID* emitLoad(RegisterID* dst, bool);
         RegisterID* emitLoad(RegisterID* dst, double);
         RegisterID* emitLoad(RegisterID* dst, JSValue*);
Index: kjs/NodeInfo.h
===================================================================
--- kjs/NodeInfo.h	(revision 33029)
+++ kjs/NodeInfo.h	(working copy)
@@ -30,6 +30,7 @@ namespace KJS {
     const FeatureInfo NoFeatures = 0;
     const FeatureInfo EvalFeature = 1 &lt;&lt; 0;
     const FeatureInfo ClosureFeature = 1 &lt;&lt; 1;
+    const FeatureInfo AssignFeature = 1 &lt;&lt; 2;
 
     template &lt;typename T&gt; struct NodeFeatureInfo {
         T m_node;
Index: kjs/grammar.y
===================================================================
--- kjs/grammar.y	(revision 33029)
+++ kjs/grammar.y	(working copy)
@@ -63,7 +63,7 @@ using namespace std;
 
 static AddNode* makeAddNode(ExpressionNode*, ExpressionNode*);
 static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*);
-static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr);
+static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr, bool exprHasAssignments);
 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator);
 static ExpressionNode* makePostfixNode(ExpressionNode* expr, Operator);
 static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier &amp;getOrSet, const Identifier&amp; name, ParameterNode*, FunctionBodyNode*, const SourceRange&amp;);
@@ -97,14 +97,14 @@ template &lt;typename T&gt; NodeDeclarationInf
                                                                        ParserRefCountedData&lt;DeclarationStacks::FunctionStack&gt;* funcDecls,
                                                                        FeatureInfo info) 
 {
-    ASSERT((info &amp; ~(EvalFeature | ClosureFeature)) == 0);
+    ASSERT((info &amp; ~(EvalFeature | ClosureFeature | AssignFeature)) == 0);
     NodeDeclarationInfo&lt;T&gt; result = {node, varDecls, funcDecls, info};
     return result;
 }
 
 template &lt;typename T&gt; NodeFeatureInfo&lt;T&gt; createNodeFeatureInfo(T node, FeatureInfo info) 
 {
-    ASSERT((info &amp; ~(EvalFeature | ClosureFeature)) == 0);
+    ASSERT((info &amp; ~(EvalFeature | ClosureFeature | AssignFeature)) == 0);
     NodeFeatureInfo&lt;T&gt; result = {node, info};
     return result;
 }
@@ -667,19 +667,19 @@ ConditionalExprNoBF:
 AssignmentExpr:
     ConditionalExpr
   | LeftHandSideExpr AssignmentOperator AssignmentExpr
-                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node, $3.m_featureInfo &amp; AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentExprNoIn:
     ConditionalExprNoIn
   | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn
-                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node, $3.m_featureInfo &amp; AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentExprNoBF:
     ConditionalExprNoBF
   | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr
-                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo&lt;ExpressionNode*&gt;(makeAssignNode($1.m_node, $2, $3.m_node, $3.m_featureInfo &amp; AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentOperator:
@@ -1125,7 +1125,7 @@ static LessNode* makeLessNode(Expression
     return new LessNode(left, right);
 }
 
-static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr)
+static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool exprHasAssignments)
 {
     if (!loc-&gt;isLocation())
         return new AssignErrorNode(loc, op, expr);
@@ -1140,15 +1140,15 @@ static ExpressionNode* makeAssignNode(Ex
     if (loc-&gt;isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast&lt;BracketAccessorNode*&gt;(loc);
         if (op == OpEqual)
-            return new AssignBracketNode(bracket-&gt;base(), bracket-&gt;subscript(), expr);
+            return new AssignBracketNode(bracket-&gt;base(), bracket-&gt;subscript(), expr, exprHasAssignments);
         else
-            return new ReadModifyBracketNode(bracket-&gt;base(), bracket-&gt;subscript(), op, expr);
+            return new ReadModifyBracketNode(bracket-&gt;base(), bracket-&gt;subscript(), op, expr, exprHasAssignments);
     }
     ASSERT(loc-&gt;isDotAccessorNode());
     DotAccessorNode* dot = static_cast&lt;DotAccessorNode*&gt;(loc);
     if (op == OpEqual)
-        return new AssignDotNode(dot-&gt;base(), dot-&gt;identifier(), expr);
-    return new ReadModifyDotNode(dot-&gt;base(), dot-&gt;identifier(), op, expr);
+        return new AssignDotNode(dot-&gt;base(), dot-&gt;identifier(), expr, exprHasAssignments);
+    return new ReadModifyDotNode(dot-&gt;base(), dot-&gt;identifier(), op, expr, exprHasAssignments);
 }
 
 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator op)
Index: kjs/nodes.cpp
===================================================================
--- kjs/nodes.cpp	(revision 33029)
+++ kjs/nodes.cpp	(working copy)
@@ -4344,7 +4344,7 @@ found:
 
 RegisterID* AssignDotNode::emitCode(CodeGenerator&amp; generator, RegisterID* dst)
 {
-    RefPtr&lt;RegisterID&gt; base = generator.emitNode(m_base.get());
+    RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
     RegisterID* value = generator.emitNode(dst, m_right.get());
     return generator.emitPutById(base.get(), m_ident, value);
 }
@@ -4371,7 +4371,7 @@ JSValue* AssignDotNode::evaluate(OldInte
 
 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator&amp; generator, RegisterID* dst)
 {
-    RefPtr&lt;RegisterID&gt; base = generator.emitNode(m_base.get());
+    RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
 
     // FIXME: should not write temp value to dst if dst is a local!
     RefPtr&lt;RegisterID&gt; value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
@@ -4424,8 +4424,8 @@ JSValue* AssignErrorNode::evaluate(OldIn
 
 RegisterID* AssignBracketNode::emitCode(CodeGenerator&amp; generator, RegisterID* dst)
 {
-    RefPtr&lt;RegisterID&gt; base = generator.emitNode(m_base.get());
-    RefPtr&lt;RegisterID&gt; property = generator.emitNode(m_subscript.get());
+    RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
+    RefPtr&lt;RegisterID&gt; property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
     RegisterID* value = generator.emitNode(dst, m_right.get());
     return generator.emitPutByVal(base.get(), property.get(), value);
 }
@@ -4465,8 +4465,8 @@ JSValue* AssignBracketNode::evaluate(Old
 
 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator&amp; generator, RegisterID* dst)
 {
-    RefPtr&lt;RegisterID&gt; base = generator.emitNode(m_base.get());
-    RefPtr&lt;RegisterID&gt; property = generator.emitNode(m_subscript.get());
+    RefPtr&lt;RegisterID&gt; base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
+    RefPtr&lt;RegisterID&gt; property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
 
     RefPtr&lt;RegisterID&gt; value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
     RegisterID* change = generator.emitNode(m_right.get());
Index: kjs/nodes.h
===================================================================
--- kjs/nodes.h	(revision 33029)
+++ kjs/nodes.h	(working copy)
@@ -2404,11 +2404,12 @@ namespace KJS {
 
     class ReadModifyBracketNode : public ExpressionNode {
     public:
-        ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
+        ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_subscript(subscript)
-            , m_operator(oper)
             , m_right(right)
+            , m_operator(oper)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2422,16 +2423,18 @@ namespace KJS {
     protected:
         RefPtr&lt;ExpressionNode&gt; m_base;
         RefPtr&lt;ExpressionNode&gt; m_subscript;
-        Operator m_operator;
         RefPtr&lt;ExpressionNode&gt; m_right;
+        Operator m_operator : 31;
+        bool m_rightHasAssignments : 1;
     };
 
     class AssignBracketNode : public ExpressionNode {
     public:
-        AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
+        AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_subscript(subscript)
             , m_right(right)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2446,14 +2449,16 @@ namespace KJS {
         RefPtr&lt;ExpressionNode&gt; m_base;
         RefPtr&lt;ExpressionNode&gt; m_subscript;
         RefPtr&lt;ExpressionNode&gt; m_right;
+        bool m_rightHasAssignments;
     };
 
     class AssignDotNode : public ExpressionNode {
     public:
-        AssignDotNode(ExpressionNode* base, const Identifier&amp; ident, ExpressionNode* right) KJS_FAST_CALL
+        AssignDotNode(ExpressionNode* base, const Identifier&amp; ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_ident(ident)
             , m_right(right)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2467,15 +2472,17 @@ namespace KJS {
         RefPtr&lt;ExpressionNode&gt; m_base;
         Identifier m_ident;
         RefPtr&lt;ExpressionNode&gt; m_right;
+        bool m_rightHasAssignments;
     };
 
     class ReadModifyDotNode : public ExpressionNode {
     public:
-        ReadModifyDotNode(ExpressionNode* base, const Identifier&amp; ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
+        ReadModifyDotNode(ExpressionNode* base, const Identifier&amp; ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_ident(ident)
-            , m_operator(oper)
             , m_right(right)
+            , m_operator(oper)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2489,8 +2496,9 @@ namespace KJS {
     protected:
         RefPtr&lt;ExpressionNode&gt; m_base;
         Identifier m_ident;
-        Operator m_operator;
         RefPtr&lt;ExpressionNode&gt; m_right;
+        Operator m_operator : 31;
+        bool m_rightHasAssignments : 1;
     };
 
     class AssignErrorNode : public ExpressionNode {

</string>
    </contents>
    <universal-time>
      <integer>3419479584</integer>
    </universal-time>
    <channel>
      <string>#webkit</string>
    </channel>
    <colorization-mode>
      <string></string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <keyword>TRUE</keyword>
    </is-unicode>
  </paste>
</paste-with-annotations>