Changeset 27210 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Oct 28, 2007, 10:32:23 PM (18 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/function.cpp
r27201 r27210 5 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 6 6 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 7 * Copyright (C) 2007 Maks Orlovich 7 8 * 8 9 * This library is free software; you can redistribute it and/or -
trunk/JavaScriptCore/kjs/function.h
r27199 r27210 3 3 * Copyright (C) 1999-2000 Harri Porten ([email protected]) 4 4 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. 5 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 6 * Copyright (C) 2007 Maks Orlovich 5 7 * 6 8 * This library is free software; you can redistribute it and/or -
trunk/JavaScriptCore/kjs/nodes.cpp
r27204 r27210 4 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 6 * Copyright (C) 2007 Maks Orlovich 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 60 61 } 61 62 63 #if !ASSERT_DISABLED 64 static inline bool canSkipLookup(ExecState* exec, const Identifier& ident) 65 { 66 // Static lookup in EvalCode is impossible because variables aren't DontDelete. 67 // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet. 68 if (exec->codeType() != FunctionCode) 69 return false; 70 71 // Static lookup is impossible when something dynamic has been added to the front of the scope chain. 72 if (exec->variableObject() != exec->scopeChain().top()) 73 return false; 74 75 ASSERT(exec->variableObject()->isActivation()); // Because this is function code. 76 77 // Static lookup is impossible if the symbol isn't statically declared. 78 if (!static_cast<ActivationImp*>(exec->variableObject())->symbolTable().contains(ident.ustring().rep())) 79 return false; 80 81 return true; 82 } 83 #endif 84 62 85 // ------------------------------ Node ----------------------------------------- 63 86 … … 375 398 { 376 399 // Check for missed optimization opportunity. 377 ASSERT(exec->codeType() != FunctionCode 378 || exec->variableObject() != exec->scopeChain().top() 379 || (exec->variableObject()->isActivation() && !static_cast<ActivationImp*>(exec->variableObject())->symbolTable().contains(ident.ustring().rep()))); 400 ASSERT(!canSkipLookup(exec, ident)); 380 401 381 402 const ScopeChain& chain = exec->scopeChain(); … … 697 718 } 698 719 699 void FunctionCallResolveNode::optimizeVariableAccess(FunctionBodyNode* , DeclarationStacks::NodeStack& nodeStack)720 void FunctionCallResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack& nodeStack) 700 721 { 701 722 nodeStack.append(args.get()); 723 724 size_t index = functionBody->symbolTable().get(ident.ustring().rep()); 725 if (index != missingSymbolMarker()) 726 new (this) LocalVarFunctionCallNode(index); 702 727 } 703 728 … … 705 730 JSValue *FunctionCallResolveNode::evaluate(ExecState *exec) 706 731 { 732 // Check for missed optimization opportunity. 733 ASSERT(!canSkipLookup(exec, ident)); 734 707 735 const ScopeChain& chain = exec->scopeChain(); 708 736 ScopeChainIterator iter = chain.begin(); … … 751 779 } 752 780 781 JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec) 782 { 783 ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject()); 784 ASSERT(variableObject->isActivation()); 785 ASSERT(variableObject == exec->scopeChain().top()); 786 787 JSValue* v = variableObject->localStorage()[index].value; 788 789 if (!v->isObject()) 790 return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident); 791 792 JSObject* func = static_cast<JSObject*>(v); 793 if (!func->implementsCall()) 794 return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident); 795 796 List argList = args->evaluateList(exec); 797 KJS_CHECKEXCEPTIONVALUE 798 799 return func->call(exec, exec->dynamicInterpreter()->globalObject(), argList); 800 } 801 753 802 void FunctionCallBracketNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack) 754 803 { … … 859 908 // ------------------------------ PostfixResolveNode ---------------------------------- 860 909 910 void PostfixResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&) 911 { 912 size_t index = functionBody->symbolTable().get(m_ident.ustring().rep()); 913 if (index != missingSymbolMarker()) 914 new (this) LocalVarPostfixNode(index); 915 } 916 861 917 JSValue *PostfixResolveNode::evaluate(ExecState *exec) 862 918 { 919 // Check for missed optimization opportunity. 920 ASSERT(!canSkipLookup(exec, m_ident)); 921 863 922 const ScopeChain& chain = exec->scopeChain(); 864 923 ScopeChainIterator iter = chain.begin(); … … 889 948 } 890 949 950 JSValue* LocalVarPostfixNode::evaluate(ExecState* exec) 951 { 952 ActivationImp* variableObject = static_cast<ActivationImp*>(exec->variableObject()); 953 ASSERT(variableObject->isActivation()); 954 ASSERT(variableObject == exec->scopeChain().top()); 955 956 JSValue** v = &variableObject->localStorage()[index].value; 957 double n = (*v)->toNumber(exec); 958 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 959 *v = jsNumber(newValue); 960 return jsNumber(n); 961 } 962 891 963 // ------------------------------ PostfixBracketNode ---------------------------------- 892 964 … … 970 1042 // ------------------------------ DeleteResolveNode ----------------------------------- 971 1043 1044 void DeleteResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&) 1045 { 1046 size_t index = functionBody->symbolTable().get(m_ident.ustring().rep()); 1047 if (index != missingSymbolMarker()) 1048 new (this) LocalVarDeleteNode(); 1049 } 1050 972 1051 // ECMA 11.4.1 973 1052 974 1053 JSValue *DeleteResolveNode::evaluate(ExecState *exec) 975 1054 { 1055 // Check for missed optimization opportunity. 1056 ASSERT(!canSkipLookup(exec, m_ident)); 1057 976 1058 const ScopeChain& chain = exec->scopeChain(); 977 1059 ScopeChainIterator iter = chain.begin(); … … 993 1075 994 1076 return jsBoolean(true); 1077 } 1078 1079 JSValue* LocalVarDeleteNode::evaluate(ExecState*) 1080 { 1081 return jsBoolean(false); 995 1082 } 996 1083 -
trunk/JavaScriptCore/kjs/nodes.h
r27206 r27210 4 4 * Copyright (C) 2001 Peter Kelly ([email protected]) 5 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 6 * Copyright (C) 2007 Cameron Zwarich ([email protected]) 7 * Copyright (C) 2007 Maks Orlovich 6 8 * 7 9 * This library is free software; you can redistribute it and/or … … 294 296 public: 295 297 // Overwrites a ResolveNode in place. 296 LocalVarAccessNode(size_t i) 298 LocalVarAccessNode(size_t i) KJS_FAST_CALL 297 299 : ResolveNode(PlacementNewAdopt) 298 300 { … … 483 485 class FunctionCallResolveNode : public Node { 484 486 public: 485 FunctionCallResolveNode(const Identifier& i, ArgumentsNode *a) KJS_FAST_CALL : ident(i), args(a) {} 487 FunctionCallResolveNode(const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL 488 : ident(i) 489 , args(a) 490 { 491 } 492 493 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 494 : Node(PlacementNewAdopt) 495 , ident(PlacementNewAdopt) 496 , args(PlacementNewAdopt) 497 { 498 } 499 486 500 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 487 501 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 488 502 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 489 503 virtual Precedence precedence() const { return PrecCall; } 490 private: 504 505 protected: 491 506 Identifier ident; 492 507 RefPtr<ArgumentsNode> args; 508 size_t index; // Used by LocalVarFunctionCallNode. 509 }; 510 511 class LocalVarFunctionCallNode : public FunctionCallResolveNode { 512 public: 513 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL 514 : FunctionCallResolveNode(PlacementNewAdopt) 515 { 516 ASSERT(i != missingSymbolMarker()); 517 index = i; 518 } 519 520 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 493 521 }; 494 522 … … 522 550 public: 523 551 PostfixResolveNode(const Identifier& i, Operator o) KJS_FAST_CALL : m_ident(i), m_oper(o) {} 552 553 PostfixResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 554 : Node(PlacementNewAdopt) 555 , m_ident(PlacementNewAdopt) 556 { 557 } 558 559 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 524 560 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 525 561 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 526 562 virtual Precedence precedence() const { return PrecPostfix; } 527 private: 563 564 protected: 528 565 Identifier m_ident; 529 566 Operator m_oper; 567 size_t index; // Used by LocalVarPostfixNode. 568 }; 569 570 class LocalVarPostfixNode : public PostfixResolveNode { 571 public: 572 LocalVarPostfixNode(size_t i) KJS_FAST_CALL 573 : PostfixResolveNode(PlacementNewAdopt) 574 { 575 ASSERT(i != missingSymbolMarker()); 576 index = i; 577 } 578 579 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 530 580 }; 531 581 … … 570 620 public: 571 621 DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {} 622 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 623 : Node(PlacementNewAdopt) 624 , m_ident(PlacementNewAdopt) 625 { 626 } 627 628 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 572 629 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 573 630 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; … … 575 632 private: 576 633 Identifier m_ident; 634 }; 635 636 class LocalVarDeleteNode : public DeleteResolveNode { 637 public: 638 LocalVarDeleteNode() KJS_FAST_CALL 639 : DeleteResolveNode(PlacementNewAdopt) 640 { 641 } 642 643 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 577 644 }; 578 645
Note:
See TracChangeset
for help on using the changeset viewer.