2008-06-05 Cameron Zwarich <cwzwarich@uwaterloo.ca>
authorcwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Jun 2008 09:19:48 +0000 (09:19 +0000)
committercwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Jun 2008 09:19:48 +0000 (09:19 +0000)
        Reviewed by Maciej.

        Bug 19400: subscript operator does not protect base when necessary
        <https://bugs.webkit.org/show_bug.cgi?id=19400>

        Use a temporary for the base in BracketAccessorNode if the subscript
        might possibly modify it.

        JavaScriptCore:

        * kjs/grammar.y:
        * kjs/nodes.cpp:
        (KJS::BracketAccessorNode::emitCode):
        * kjs/nodes.h:
        (KJS::BracketAccessorNode::):

        LayoutTests:

        * fast/js/codegen-temporaries-expected.txt:
        * fast/js/resources/codegen-temporaries.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@34373 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/grammar.y
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
LayoutTests/ChangeLog
LayoutTests/fast/js/codegen-temporaries-expected.txt
LayoutTests/fast/js/resources/codegen-temporaries.js

index 2b3ba336237e229432438cb05c73edde6bf6dcb3..739d6b9bf039ca4b9b914d612d856b1062b2799d 100644 (file)
@@ -1,3 +1,19 @@
+2008-06-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Maciej.
+
+        Bug 19400: subscript operator does not protect base when necessary
+        <https://bugs.webkit.org/show_bug.cgi?id=19400>
+
+        Use a temporary for the base in BracketAccessorNode if the subscript
+        might possibly modify it.
+
+        * kjs/grammar.y:
+        * kjs/nodes.cpp:
+        (KJS::BracketAccessorNode::emitCode):
+        * kjs/nodes.h:
+        (KJS::BracketAccessorNode::):
+
 2008-06-04  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Maciej Stachowiak.
index c144cec894b719088142f23e5ee2dba470fb1315..d7d449d8a3747651b177b025e6be486d0e27e1f1 100644 (file)
@@ -361,14 +361,14 @@ Elision:
 MemberExpr:
     PrimaryExpr
   | FunctionExpr                        { $$ = createNodeFeatureInfo<ExpressionNode*>($1.m_node, $1.m_featureInfo); }
-  | MemberExpr '[' Expr ']'             { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+  | MemberExpr '[' Expr ']'             { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
   | MemberExpr '.' IDENT                { $$ = createNodeFeatureInfo<ExpressionNode*>(new DotAccessorNode($1.m_node, *$3), $1.m_featureInfo); }
   | NEW MemberExpr Arguments            { $$ = createNodeFeatureInfo<ExpressionNode*>(new NewExprNode($2.m_node, $3.m_node), $2.m_featureInfo | $3.m_featureInfo); }
 ;
 
 MemberExprNoBF:
     PrimaryExprNoBrace
-  | MemberExprNoBF '[' Expr ']'         { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+  | MemberExprNoBF '[' Expr ']'         { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
   | MemberExprNoBF '.' IDENT            { $$ = createNodeFeatureInfo<ExpressionNode*>(new DotAccessorNode($1.m_node, *$3), $1.m_featureInfo); }
   | NEW MemberExpr Arguments            { $$ = createNodeFeatureInfo<ExpressionNode*>(new NewExprNode($2.m_node, $3.m_node), $2.m_featureInfo | $3.m_featureInfo); }
 ;
@@ -386,14 +386,14 @@ NewExprNoBF:
 CallExpr:
     MemberExpr Arguments                { $$ = makeFunctionCallNode($1, $2); }
   | CallExpr Arguments                  { $$ = makeFunctionCallNode($1, $2); }
-  | CallExpr '[' Expr ']'               { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+  | CallExpr '[' Expr ']'               { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
   | CallExpr '.' IDENT                  { $$ = createNodeFeatureInfo<ExpressionNode*>(new DotAccessorNode($1.m_node, *$3), $1.m_featureInfo); }
 ;
 
 CallExprNoBF:
     MemberExprNoBF Arguments            { $$ = makeFunctionCallNode($1, $2); }
   | CallExprNoBF Arguments              { $$ = makeFunctionCallNode($1, $2); }
-  | CallExprNoBF '[' Expr ']'           { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+  | CallExprNoBF '[' Expr ']'           { $$ = createNodeFeatureInfo<ExpressionNode*>(new BracketAccessorNode($1.m_node, $3.m_node, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo); }
   | CallExprNoBF '.' IDENT              { $$ = createNodeFeatureInfo<ExpressionNode*>(new DotAccessorNode($1.m_node, *$3), $1.m_featureInfo); }
 ;
 
index 6faa684b79d8831a76cc7d4acbfbfbf23445acd3..d1b57983a6852c456d3b2879c4d31259eba04e28 100644 (file)
@@ -409,7 +409,7 @@ RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst
 
 RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments);
     RegisterID* property = generator.emitNode(m_subscript.get());
 
     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
index 1357e164e42a85b2a355ffc9473085ffe586c2d2..19a53abd7df0f286bc57f0a6b7f8653148e459ad 100644 (file)
@@ -527,9 +527,10 @@ namespace KJS {
 
     class BracketAccessorNode : public ExpressionNode {
     public:
-        BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
+        BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_subscript(subscript)
+            , m_subscriptHasAssignments(subscriptHasAssignments)
         {
         }
 
@@ -546,6 +547,7 @@ namespace KJS {
     private:
         RefPtr<ExpressionNode> m_base;
         RefPtr<ExpressionNode> m_subscript;
+        bool m_subscriptHasAssignments;
     };
 
     class DotAccessorNode : public ExpressionNode {
index 8bf8e79e3ea66fbf502a196cc51d21402e276b1a..00792e78fa58d877902a8ca65fbc90acda68f64c 100644 (file)
@@ -1,3 +1,15 @@
+2008-06-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Maciej.
+
+        Tests for:
+
+        Bug 19400: subscript operator does not protect base when necessary
+        <https://bugs.webkit.org/show_bug.cgi?id=19400>
+
+        * fast/js/codegen-temporaries-expected.txt:
+        * fast/js/resources/codegen-temporaries.js:
+
 2008-06-04  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Dave Hyatt.
index 6195cb8427457bb48a80b69ea7aa52b6a19bf721..01b0c6fd975c94d4d23320b6707fa265905473d8 100644 (file)
@@ -36,6 +36,12 @@ PASS assign_test28() is 3
 PASS assign_test29() is 3
 PASS assign_test30() is 'fooNaN'
 PASS assign_test31() is 'PASS'
+PASS bracket_test1() is -1
+PASS bracket_test2() is 1
+PASS bracket_test3() is 0
+PASS bracket_test4() is 0
+PASS bracket_test5() is 1
+PASS bracket_test6() is 1
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 7a7a1431d78c8d08715987e0454f82f02fcf115f..9b17df46050a763f0b8554d4fada17d870ad984e 100644 (file)
@@ -296,4 +296,58 @@ function assign_test31()
 
 shouldBe("assign_test31()", "'PASS'");
 
+function bracket_test1()
+{
+    var o = [-1];
+    var a = o[++o];
+    return a;
+}
+
+shouldBe("bracket_test1()", "-1");
+
+function bracket_test2()
+{
+    var o = [1];
+    var a = o[--o];
+    return a;
+}
+
+shouldBe("bracket_test2()", "1");
+
+function bracket_test3()
+{
+    var o = [0];
+    var a = o[o++];
+    return a;
+}
+
+shouldBe("bracket_test3()", "0");
+
+function bracket_test4()
+{
+    var o = [0];
+    var a = o[o--];
+    return a;
+}
+
+shouldBe("bracket_test4()", "0");
+
+function bracket_test5()
+{
+    var o = [1];
+    var a = o[o ^= 1];
+    return a;
+}
+
+shouldBe("bracket_test5()", "1");
+
+function bracket_test6()
+{
+    var o = { b: 1 }
+    var b = o[o = { b: 2 }, "b"];
+    return b;
+}
+
+shouldBe("bracket_test6()", "1");
+
 successfullyParsed = true;