Changeset 33552 in webkit
- Timestamp:
- May 17, 2008 4:00:56 AM (16 years ago)
- Location:
- branches/squirrelfish
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/squirrelfish/JavaScriptCore/ChangeLog
r33550 r33552 1 2008-05-17 Cameron Zwarich <cwzwarich@uwaterloo.ca> 2 3 Reviewed by Oliver. 4 5 Partial fix for: 6 7 Bug 18991: SquirrelFish: Major codegen issue in a.b=expr, a[b]=expr 8 <https://bugs.webkit.org/show_bug.cgi?id=18991> 9 10 Ensure that the code generated for assignments uses temporaries whenever 11 necessary. This patch covers the vast majority of situations, but there 12 are still a few left. 13 14 This patch also adds some missing cases to CodeBlock::dump(). 15 16 * VM/CodeBlock.cpp: 17 (KJS::CodeBlock::dump): 18 * VM/CodeGenerator.h: 19 (KJS::CodeGenerator::destinationForAssignResult): 20 (KJS::CodeGenerator::leftHandSideNeedsCopy): 21 (KJS::CodeGenerator::emitNodeForLeftHandSide): 22 * kjs/NodeInfo.h: 23 * kjs/grammar.y: 24 * kjs/nodes.cpp: 25 (KJS::AssignDotNode::emitCode): 26 (KJS::ReadModifyDotNode::emitCode): 27 (KJS::AssignBracketNode::emitCode): 28 (KJS::ReadModifyBracketNode::emitCode): 29 (KJS::ForInNode::ForInNode): 30 * kjs/nodes.h: 31 (KJS::ReadModifyResolveNode::): 32 (KJS::AssignResolveNode::): 33 (KJS::ReadModifyBracketNode::): 34 (KJS::AssignBracketNode::): 35 (KJS::AssignDotNode::): 36 (KJS::ReadModifyDotNode::): 37 1 38 2008-05-17 Oliver Hunt <oliver@apple.com> 2 39 -
branches/squirrelfish/JavaScriptCore/VM/CodeBlock.cpp
r33484 r33552 383 383 break; 384 384 } 385 case op_put_getter: { 386 int r0 = (++it)->u.operand; 387 int id0 = (++it)->u.operand; 388 int r1 = (++it)->u.operand; 389 printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str()); 390 break; 391 } 392 case op_put_setter: { 393 int r0 = (++it)->u.operand; 394 int id0 = (++it)->u.operand; 395 int r1 = (++it)->u.operand; 396 printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, identifiers[id0]).c_str(), registerName(r1).c_str()); 397 break; 398 } 385 399 case op_del_by_id: { 386 400 int r0 = (++it)->u.operand; -
branches/squirrelfish/JavaScriptCore/VM/CodeGenerator.h
r33541 r33552 127 127 return newTemporary(); 128 128 } 129 130 RegisterID* destinationForAssignResult(RegisterID* dst) { 131 if (dst && m_codeBlock->needsFullScopeChain) 132 return dst->isTemporary() ? dst : newTemporary(); 133 return 0; 134 } 129 135 130 136 // moves src to dst if dst is not null and is different from src, otherwise just returns src … … 149 155 { 150 156 return emitNode(0, n); 157 } 158 159 ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments) 160 { 161 return m_codeBlock->needsFullScopeChain || rightHasAssignments; 162 } 163 164 ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments) 165 { 166 if (leftHandSideNeedsCopy(rightHasAssignments)) { 167 PassRefPtr<RegisterID> dst = newTemporary(); 168 emitNode(dst.get(), n); 169 return dst; 170 } 171 172 return PassRefPtr<RegisterID>(emitNode(n)); 151 173 } 152 174 -
branches/squirrelfish/JavaScriptCore/kjs/NodeInfo.h
r31072 r33552 31 31 const FeatureInfo EvalFeature = 1 << 0; 32 32 const FeatureInfo ClosureFeature = 1 << 1; 33 const FeatureInfo AssignFeature = 1 << 2; 33 34 34 35 template <typename T> struct NodeFeatureInfo { -
branches/squirrelfish/JavaScriptCore/kjs/grammar.y
r33386 r33552 64 64 static AddNode* makeAddNode(ExpressionNode*, ExpressionNode*); 65 65 static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*); 66 static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr );66 static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments); 67 67 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator); 68 68 static ExpressionNode* makePostfixNode(ExpressionNode* expr, Operator); … … 98 98 FeatureInfo info) 99 99 { 100 ASSERT((info & ~(EvalFeature | ClosureFeature )) == 0);100 ASSERT((info & ~(EvalFeature | ClosureFeature | AssignFeature)) == 0); 101 101 NodeDeclarationInfo<T> result = {node, varDecls, funcDecls, info}; 102 102 return result; … … 105 105 template <typename T> NodeFeatureInfo<T> createNodeFeatureInfo(T node, FeatureInfo info) 106 106 { 107 ASSERT((info & ~(EvalFeature | ClosureFeature )) == 0);107 ASSERT((info & ~(EvalFeature | ClosureFeature | AssignFeature)) == 0); 108 108 NodeFeatureInfo<T> result = {node, info}; 109 109 return result; … … 438 438 | VOIDTOKEN UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new VoidNode($2.m_node), $2.m_featureInfo); } 439 439 | TYPEOF UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makeTypeOfNode($2.m_node), $2.m_featureInfo); } 440 | PLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo ); }441 | AUTOPLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo ); }442 | MINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo ); }443 | AUTOMINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo ); }440 | PLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); } 441 | AUTOPLUSPLUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); } 442 | MINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); } 443 | AUTOMINUSMINUS UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); } 444 444 | '+' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnaryPlusNode($2.m_node), $2.m_featureInfo); } 445 445 | '-' UnaryExpr { $$ = createNodeFeatureInfo<ExpressionNode*>(makeNegateNode($2.m_node), $2.m_featureInfo); } … … 668 668 ConditionalExpr 669 669 | LeftHandSideExpr AssignmentOperator AssignmentExpr 670 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node ), $1.m_featureInfo | $3.m_featureInfo); }670 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } 671 671 ; 672 672 … … 674 674 ConditionalExprNoIn 675 675 | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn 676 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node ), $1.m_featureInfo | $3.m_featureInfo); }676 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } 677 677 ; 678 678 … … 680 680 ConditionalExprNoBF 681 681 | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr 682 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node ), $1.m_featureInfo | $3.m_featureInfo); }682 { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); } 683 683 ; 684 684 … … 754 754 $$.m_featureInfo = 0; 755 755 } 756 | IDENT Initializer { $$.m_node = new AssignResolveNode(*$1, $2.m_node );756 | IDENT Initializer { $$.m_node = new AssignResolveNode(*$1, $2.m_node, $2.m_featureInfo & AssignFeature); 757 757 $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 758 758 appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); … … 768 768 } 769 769 | VariableDeclarationList ',' IDENT Initializer 770 { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node ));770 { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node, $4.m_featureInfo & AssignFeature)); 771 771 $$.m_varDeclarations = $1.m_varDeclarations; 772 772 appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); … … 783 783 $$.m_featureInfo = 0; 784 784 } 785 | IDENT InitializerNoIn { $$.m_node = new AssignResolveNode(*$1, $2.m_node );785 | IDENT InitializerNoIn { $$.m_node = new AssignResolveNode(*$1, $2.m_node, $2.m_featureInfo & AssignFeature); 786 786 $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>; 787 787 appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer); … … 797 797 } 798 798 | VariableDeclarationListNoIn ',' IDENT InitializerNoIn 799 { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node ));799 { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node, $4.m_featureInfo & AssignFeature)); 800 800 $$.m_varDeclarations = $1.m_varDeclarations; 801 801 appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer); … … 1126 1126 } 1127 1127 1128 static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr )1128 static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments) 1129 1129 { 1130 1130 if (!loc->isLocation()) … … 1134 1134 ResolveNode* resolve = static_cast<ResolveNode*>(loc); 1135 1135 if (op == OpEqual) 1136 return new AssignResolveNode(resolve->identifier(), expr );1136 return new AssignResolveNode(resolve->identifier(), expr, exprHasAssignments); 1137 1137 else 1138 return new ReadModifyResolveNode(resolve->identifier(), op, expr );1138 return new ReadModifyResolveNode(resolve->identifier(), op, expr, exprHasAssignments); 1139 1139 } 1140 1140 if (loc->isBracketAccessorNode()) { 1141 1141 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc); 1142 1142 if (op == OpEqual) 1143 return new AssignBracketNode(bracket->base(), bracket->subscript(), expr );1143 return new AssignBracketNode(bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments); 1144 1144 else 1145 return new ReadModifyBracketNode(bracket->base(), bracket->subscript(), op, expr );1145 return new ReadModifyBracketNode(bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments); 1146 1146 } 1147 1147 ASSERT(loc->isDotAccessorNode()); 1148 1148 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); 1149 1149 if (op == OpEqual) 1150 return new AssignDotNode(dot->base(), dot->identifier(), expr );1151 return new ReadModifyDotNode(dot->base(), dot->identifier(), op, expr );1150 return new AssignDotNode(dot->base(), dot->identifier(), expr, exprHasAssignments); 1151 return new ReadModifyDotNode(dot->base(), dot->identifier(), op, expr, exprHasAssignments); 1152 1152 } 1153 1153 -
branches/squirrelfish/JavaScriptCore/kjs/nodes.cpp
r33541 r33552 4342 4342 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4343 4343 { 4344 RefPtr<RegisterID> base = generator.emitNode(m_base.get()); 4345 RegisterID* value = generator.emitNode(dst, m_right.get()); 4346 return generator.emitPutById(base.get(), m_ident, value); 4344 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments); 4345 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst); 4346 RegisterID* result = generator.emitNode(value.get(), m_right.get()); 4347 generator.emitPutById(base.get(), m_ident, result); 4348 return generator.moveToDestinationIfNeeded(dst, result); 4347 4349 } 4348 4350 … … 4369 4371 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4370 4372 { 4371 RefPtr<RegisterID> base = generator.emitNode(m_base.get()); 4372 4373 // FIXME: should not write temp value to dst if dst is a local! 4373 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments); 4374 4374 RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident); 4375 4375 RegisterID* change = generator.emitNode(m_right.get()); … … 4422 4422 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4423 4423 { 4424 RefPtr<RegisterID> base = generator.emitNode(m_base.get()); 4425 RefPtr<RegisterID> property = generator.emitNode(m_subscript.get()); 4426 RegisterID* value = generator.emitNode(dst, m_right.get()); 4427 return generator.emitPutByVal(base.get(), property.get(), value); 4424 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments); 4425 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments); 4426 RefPtr<RegisterID> value = generator.destinationForAssignResult(dst); 4427 RegisterID* result = generator.emitNode(value.get(), m_right.get()); 4428 generator.emitPutByVal(base.get(), property.get(), result); 4429 return generator.moveToDestinationIfNeeded(dst, result); 4428 4430 } 4429 4431 … … 4463 4465 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst) 4464 4466 { 4465 RefPtr<RegisterID> base = generator.emitNode (m_base.get());4466 RefPtr<RegisterID> property = generator.emitNode (m_subscript.get());4467 RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments); 4468 RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments); 4467 4469 4468 4470 RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get()); … … 5096 5098 { 5097 5099 if (in) 5098 m_init = new AssignResolveNode(ident, in );5100 m_init = new AssignResolveNode(ident, in, true); 5099 5101 // for( var foo = bar in baz ) 5100 5102 } -
branches/squirrelfish/JavaScriptCore/kjs/nodes.h
r33434 r33552 2301 2301 class ReadModifyResolveNode : public ExpressionNode { 2302 2302 public: 2303 ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode* right ) KJS_FAST_CALL2303 ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL 2304 2304 : m_ident(ident) 2305 , m_right(right) 2305 2306 , m_operator(oper) 2306 , m_right (right)2307 , m_rightHasAssignments(rightHasAssignments) 2307 2308 { 2308 2309 } … … 2312 2313 , m_ident(PlacementNewAdopt) 2313 2314 , m_right(PlacementNewAdopt) 2315 , m_rightHasAssignments(true) 2314 2316 { 2315 2317 } … … 2324 2326 protected: 2325 2327 Identifier m_ident; 2326 Operator m_operator;2327 2328 RefPtr<ExpressionNode> m_right; 2328 2329 size_t m_index; // Used by ReadModifyLocalVarNode. 2330 Operator m_operator : 31; 2331 bool m_rightHasAssignments : 1; 2329 2332 }; 2330 2333 … … 2355 2358 class AssignResolveNode : public ExpressionNode { 2356 2359 public: 2357 AssignResolveNode(const Identifier& ident, ExpressionNode* right ) KJS_FAST_CALL2360 AssignResolveNode(const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL 2358 2361 : m_ident(ident) 2359 2362 , m_right(right) 2363 , m_rightHasAssignments(rightHasAssignments) 2360 2364 { 2361 2365 } … … 2379 2383 RefPtr<ExpressionNode> m_right; 2380 2384 size_t m_index; // Used by ReadModifyLocalVarNode. 2385 bool m_rightHasAssignments; 2381 2386 }; 2382 2387 … … 2405 2410 class ReadModifyBracketNode : public ExpressionNode { 2406 2411 public: 2407 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL 2408 : m_base(base) 2409 , m_subscript(subscript) 2410 , m_operator(oper) 2411 , m_right(right) 2412 { 2413 } 2414 2415 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2416 2417 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2418 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL; 2419 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2420 virtual Precedence precedence() const { return PrecAssignment; } 2421 2422 protected: 2423 RefPtr<ExpressionNode> m_base; 2424 RefPtr<ExpressionNode> m_subscript; 2425 Operator m_operator; 2426 RefPtr<ExpressionNode> m_right; 2427 }; 2428 2429 class AssignBracketNode : public ExpressionNode { 2430 public: 2431 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL 2412 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL 2432 2413 : m_base(base) 2433 2414 , m_subscript(subscript) 2434 2415 , m_right(right) 2416 , m_operator(oper) 2417 , m_subscriptHasAssignments(subscriptHasAssignments) 2418 , m_rightHasAssignments(rightHasAssignments) 2435 2419 { 2436 2420 } … … 2447 2431 RefPtr<ExpressionNode> m_subscript; 2448 2432 RefPtr<ExpressionNode> m_right; 2433 Operator m_operator : 30; 2434 bool m_subscriptHasAssignments : 1; 2435 bool m_rightHasAssignments : 1; 2436 }; 2437 2438 class AssignBracketNode : public ExpressionNode { 2439 public: 2440 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL 2441 : m_base(base) 2442 , m_subscript(subscript) 2443 , m_right(right) 2444 , m_subscriptHasAssignments(subscriptHasAssignments) 2445 , m_rightHasAssignments(rightHasAssignments) 2446 { 2447 } 2448 2449 virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL; 2450 2451 virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL; 2452 virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL; 2453 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 2454 virtual Precedence precedence() const { return PrecAssignment; } 2455 2456 protected: 2457 RefPtr<ExpressionNode> m_base; 2458 RefPtr<ExpressionNode> m_subscript; 2459 RefPtr<ExpressionNode> m_right; 2460 bool m_subscriptHasAssignments : 1; 2461 bool m_rightHasAssignments : 1; 2449 2462 }; 2450 2463 2451 2464 class AssignDotNode : public ExpressionNode { 2452 2465 public: 2453 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right ) KJS_FAST_CALL2466 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL 2454 2467 : m_base(base) 2455 2468 , m_ident(ident) 2456 2469 , m_right(right) 2470 , m_rightHasAssignments(rightHasAssignments) 2457 2471 { 2458 2472 } … … 2468 2482 Identifier m_ident; 2469 2483 RefPtr<ExpressionNode> m_right; 2484 bool m_rightHasAssignments; 2470 2485 }; 2471 2486 2472 2487 class ReadModifyDotNode : public ExpressionNode { 2473 2488 public: 2474 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right ) KJS_FAST_CALL2489 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL 2475 2490 : m_base(base) 2476 2491 , m_ident(ident) 2492 , m_right(right) 2477 2493 , m_operator(oper) 2478 , m_right (right)2494 , m_rightHasAssignments(rightHasAssignments) 2479 2495 { 2480 2496 } … … 2490 2506 RefPtr<ExpressionNode> m_base; 2491 2507 Identifier m_ident; 2492 Operator m_operator;2493 2508 RefPtr<ExpressionNode> m_right; 2509 Operator m_operator : 31; 2510 bool m_rightHasAssignments : 1; 2494 2511 }; 2495 2512 -
branches/squirrelfish/LayoutTests/ChangeLog
r33551 r33552 1 2008-05-17 Cameron Zwarich <cwzwarich@uwaterloo.ca> 2 3 Reviewed by Oliver. 4 5 Add tests for: 6 7 Bug 18991: SquirrelFish: Major codegen issue in a.b=expr, a[b]=expr 8 <https://bugs.webkit.org/show_bug.cgi?id=18991> 9 10 * fast/js/codegen-temporaries-expected.txt: 11 * fast/js/resources/codegen-temporaries.js: 12 1 13 2008-05-17 Oliver Hunt <oliver@apple.com> 2 14 -
branches/squirrelfish/LayoutTests/fast/js/codegen-temporaries-expected.txt
r33369 r33552 6 6 PASS a is true 7 7 PASS b is false 8 PASS assign_test1() is 'PASS' 9 PASS assign_test2() is 'PASS' 10 PASS assign_test3() is 'PASS' 11 PASS testObject4.test is 'PASS' 12 PASS testObject5.test is 'PASS' 13 PASS assign_test6() is 'PASS' 14 PASS assign_test7() is 'PASS' 15 PASS assign_test8() is 'PASS' 16 PASS assign_test9() is 'PASS' 17 PASS testObject10.test is 'PASS' 18 PASS assign_test11() is 'PASS' 19 PASS assign_test12() is 'PASS' 20 PASS assign_test13() is 'PASS' 21 PASS assign_test14() is 'PASS' 22 PASS assign_test15() is 'PASS' 23 PASS assign_test16() is 2 8 24 PASS successfullyParsed is true 9 25 -
branches/squirrelfish/LayoutTests/fast/js/resources/codegen-temporaries.js
r33369 r33552 11 11 shouldBeFalse("b"); 12 12 13 function TestObject() { 14 this.toString = function() { return this.test; } 15 this.test = "FAIL"; 16 return this; 17 } 18 19 function assign_test1() 20 { 21 var testObject = new TestObject; 22 var a = testObject; 23 a.test = "PASS"; 24 return testObject.test; 25 } 26 27 shouldBe("assign_test1()", "'PASS'"); 28 29 function assign_test2() 30 { 31 var testObject = new TestObject; 32 var a = testObject; 33 a = a.test = "PASS"; 34 return testObject.test; 35 } 36 37 shouldBe("assign_test2()", "'PASS'"); 38 39 function assign_test3() 40 { 41 var testObject = new TestObject; 42 var a = testObject; 43 a.test = a = "PASS"; 44 return testObject.test; 45 } 46 47 shouldBe("assign_test3()", "'PASS'"); 48 49 var testObject4 = new TestObject; 50 var a4 = testObject4; 51 a4.test = this.a4 = "PASS"; 52 53 shouldBe("testObject4.test", "'PASS'"); 54 55 var testObject5 = new TestObject; 56 var a5 = testObject5; 57 a5 = this.a5.test = "PASS"; 58 59 shouldBe("testObject5.test", "'PASS'"); 60 61 function assign_test6() 62 { 63 var testObject = new TestObject; 64 var a = testObject; 65 a["test"] = "PASS"; 66 return testObject.test; 67 } 68 69 shouldBe("assign_test6()", "'PASS'"); 70 71 function assign_test7() 72 { 73 var testObject = new TestObject; 74 var a = testObject; 75 a = a["test"] = "PASS"; 76 return testObject.test; 77 } 78 79 shouldBe("assign_test7()", "'PASS'"); 80 81 function assign_test8() 82 { 83 var testObject = new TestObject; 84 var a = testObject; 85 a["test"] = a = "PASS"; 86 return testObject.test; 87 } 88 89 shouldBe("assign_test8()", "'PASS'"); 90 91 function assign_test9() 92 { 93 var testObject = new TestObject; 94 var a = testObject; 95 a["test"] = this.a = "PASS"; 96 return testObject.test; 97 } 98 99 shouldBe("assign_test9()", "'PASS'"); 100 101 var testObject10 = new TestObject; 102 var a10 = testObject10; 103 a10 = this.a10["test"] = "PASS"; 104 105 shouldBe("testObject10.test", "'PASS'"); 106 107 function assign_test11() 108 { 109 var testObject = new TestObject; 110 var a = testObject; 111 a[a = "test"] = "PASS"; 112 return testObject.test; 113 } 114 115 shouldBe("assign_test11()", "'PASS'"); 116 117 function assign_test12() 118 { 119 var test = "test"; 120 var testObject = new TestObject; 121 var a = testObject; 122 a[test] = "PASS"; 123 return testObject.test; 124 } 125 126 shouldBe("assign_test12()", "'PASS'"); 127 128 function assign_test13() 129 { 130 var testObject = new TestObject; 131 var a = testObject; 132 a.test = (a = "FAIL", "PASS"); 133 return testObject.test; 134 } 135 136 shouldBe("assign_test13()", "'PASS'"); 137 138 function assign_test14() 139 { 140 var testObject = new TestObject; 141 var a = testObject; 142 a["test"] = (a = "FAIL", "PASS"); 143 return testObject.test; 144 } 145 146 shouldBe("assign_test14()", "'PASS'"); 147 148 function assign_test15() 149 { 150 var test = "test"; 151 var testObject = new TestObject; 152 var a = testObject; 153 a[test] = (test = "FAIL", "PASS"); 154 return testObject.test; 155 } 156 157 shouldBe("assign_test15()", "'PASS'"); 158 159 function assign_test16() 160 { 161 var a = 1; 162 a = (a = 2); 163 return a; 164 } 165 166 shouldBe("assign_test16()", "2"); 167 13 168 successfullyParsed = true;
Note: See TracChangeset
for help on using the changeset viewer.