Changeset 10621 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Sep 24, 2005, 3:34:15 PM (20 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/grammar.y
r10588 r10621 50 50 using namespace KJS; 51 51 52 static bool makeAssignNode(Node*& result, Node *loc, Operator op, Node *expr); 53 static bool makePrefixNode(Node*& result, Node *expr, Operator op); 54 static bool makePostfixNode(Node*& result, Node *expr, Operator op); 52 55 static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args); 56 static Node *makeTypeOfNode(Node *expr); 57 static Node *makeDeleteNode(Node *expr); 53 58 54 59 %} … … 166 171 %type <plist> PropertyNameAndValueList 167 172 %type <pnode> PropertyName 168 %type <ident> ParenthesizedIdent169 173 170 174 %% … … 185 189 ; 186 190 187 ParenthesizedIdent:188 IDENT189 | '(' ParenthesizedIdent ')' { $$ = $2; }190 ;191 192 191 PrimaryExpr: 193 192 THIS { $$ = new ThisNode(); } 194 193 | Literal 195 194 | ArrayLiteral 196 | ParenthesizedIdent{ $$ = new ResolveNode(*$1); }197 | '(' Expr ')' { $$ = new GroupNode($2); }195 | IDENT { $$ = new ResolveNode(*$1); } 196 | '(' Expr ')' { if ($2->isResolveNode()) $$ = $2; else $$ = new GroupNode($2); } 198 197 | '{' '}' { $$ = new ObjectLiteralNode(); } 199 198 | '{' PropertyNameAndValueList '}' { $$ = new ObjectLiteralNode($2); } … … 271 270 PostfixExpr: /* TODO: no line terminator here */ 272 271 LeftHandSideExpr 273 | LeftHandSideExpr PLUSPLUS { $$ = new PostfixNode($1, OpPlusPlus); }274 | LeftHandSideExpr MINUSMINUS { $$ = new PostfixNode($1, OpMinusMinus); }272 | LeftHandSideExpr PLUSPLUS { if (!makePostfixNode($$, $1, OpPlusPlus)) YYABORT; } 273 | LeftHandSideExpr MINUSMINUS { if (!makePostfixNode($$, $1, OpMinusMinus)) YYABORT; } 275 274 ; 276 275 277 276 UnaryExpr: 278 277 PostfixExpr 279 | DELETE UnaryExpr { $$ = newDeleteNode($2); }278 | DELETE UnaryExpr { $$ = makeDeleteNode($2); } 280 279 | VOID UnaryExpr { $$ = new VoidNode($2); } 281 | TYPEOF UnaryExpr { $$ = newTypeOfNode($2); }282 | PLUSPLUS UnaryExpr { $$ = new PrefixNode(OpPlusPlus, $2); }283 | AUTOPLUSPLUS UnaryExpr { $$ = new PrefixNode(OpPlusPlus, $2); }284 | MINUSMINUS UnaryExpr { $$ = new PrefixNode(OpMinusMinus, $2); }285 | AUTOMINUSMINUS UnaryExpr { $$ = new PrefixNode(OpMinusMinus, $2); }280 | TYPEOF UnaryExpr { $$ = makeTypeOfNode($2); } 281 | PLUSPLUS UnaryExpr { if (!makePrefixNode($$, $2, OpPlusPlus)) YYABORT; } 282 | AUTOPLUSPLUS UnaryExpr { if (!makePrefixNode($$, $2, OpPlusPlus)) YYABORT; } 283 | MINUSMINUS UnaryExpr { if (!makePrefixNode($$, $2, OpMinusMinus)) YYABORT; } 284 | AUTOMINUSMINUS UnaryExpr { if (!makePrefixNode($$, $2, OpMinusMinus)) YYABORT; } 286 285 | '+' UnaryExpr { $$ = new UnaryPlusNode($2); } 287 286 | '-' UnaryExpr { $$ = new NegateNode($2); } … … 370 369 ConditionalExpr 371 370 | LeftHandSideExpr AssignmentOperator AssignmentExpr 372 { 373 Node *n = $1; 374 bool paren = n->isGroupNode(); 375 if (paren) 376 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 377 378 if (!n->isLocation()) 379 YYABORT; 380 else if (n->isResolveNode()) { 381 ResolveNode *resolve = static_cast<ResolveNode *>(n); 382 $$ = new AssignResolveNode(resolve->identifier(), $2, $3); 383 } else if (n->isBracketAccessorNode()) { 384 BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n); 385 $$ = new AssignBracketNode(bracket->base(), bracket->subscript(), $2, $3); 386 } else { 387 assert(n->isDotAccessorNode()); 388 DotAccessorNode *dot = static_cast<DotAccessorNode *>(n); 389 $$ = new AssignDotNode(dot->base(), dot->identifier(), $2, $3); 390 } 391 } 371 { if (!makeAssignNode($$, $1, $2, $3)) YYABORT; } 392 372 ; 393 373 … … 520 500 DBG($$,@1,@9); } 521 501 | FOR '(' LeftHandSideExpr IN Expr ')' 522 Statement { $$ = new ForInNode($3, $5, $7); 523 DBG($$,@1,@6); } 502 Statement { 503 Node *n = $3; 504 bool paren = n->isGroupNode(); 505 if (paren) 506 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 507 508 if (!n->isLocation()) 509 YYABORT; 510 511 $$ = new ForInNode(n, $5, $7); 512 DBG($$,@1,@6); 513 } 524 514 | FOR '(' VAR IDENT IN Expr ')' 525 515 Statement { $$ = new ForInNode(*$4,0,$6,$8); … … 685 675 686 676 %% 677 678 static bool makeAssignNode(Node*& result, Node *loc, Operator op, Node *expr) 679 { 680 Node *n = loc; 681 bool paren = n->isGroupNode(); 682 if (paren) 683 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 684 685 if (!n->isLocation()) 686 return false; 687 688 if (n->isResolveNode()) { 689 ResolveNode *resolve = static_cast<ResolveNode *>(n); 690 result = new AssignResolveNode(resolve->identifier(), op, expr); 691 } else if (n->isBracketAccessorNode()) { 692 BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n); 693 result = new AssignBracketNode(bracket->base(), bracket->subscript(), op, expr); 694 } else { 695 assert(n->isDotAccessorNode()); 696 DotAccessorNode *dot = static_cast<DotAccessorNode *>(n); 697 result = new AssignDotNode(dot->base(), dot->identifier(), op, expr); 698 } 699 700 return true; 701 } 702 703 static bool makePrefixNode(Node*& result, Node *expr, Operator op) 704 { 705 Node *n = expr; 706 bool paren = n->isGroupNode(); 707 if (paren) 708 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 709 710 if (!n->isLocation()) 711 return false; 712 713 if (n->isResolveNode()) { 714 ResolveNode *resolve = static_cast<ResolveNode *>(n); 715 result = new PrefixResolveNode(resolve->identifier(), op); 716 } else if (n->isBracketAccessorNode()) { 717 BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n); 718 result = new PrefixBracketNode(bracket->base(), bracket->subscript(), op); 719 } else { 720 assert(n->isDotAccessorNode()); 721 DotAccessorNode *dot = static_cast<DotAccessorNode *>(n); 722 result = new PrefixDotNode(dot->base(), dot->identifier(), op); 723 } 724 725 return true; 726 } 727 728 static bool makePostfixNode(Node*& result, Node *expr, Operator op) 729 { 730 Node *n = expr; 731 bool paren = n->isGroupNode(); 732 if (paren) 733 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 734 735 if (!n->isLocation()) 736 return false; 737 738 if (n->isResolveNode()) { 739 ResolveNode *resolve = static_cast<ResolveNode *>(n); 740 result = new PostfixResolveNode(resolve->identifier(), op); 741 } else if (n->isBracketAccessorNode()) { 742 BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n); 743 result = new PostfixBracketNode(bracket->base(), bracket->subscript(), op); 744 } else { 745 assert(n->isDotAccessorNode()); 746 DotAccessorNode *dot = static_cast<DotAccessorNode *>(n); 747 result = new PostfixDotNode(dot->base(), dot->identifier(), op); 748 } 749 750 return true; 751 } 687 752 688 753 static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args) … … 714 779 } 715 780 781 static Node *makeTypeOfNode(Node *expr) 782 { 783 Node *n = expr; 784 bool paren = n->isGroupNode(); 785 if (paren) 786 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 787 788 if (n->isResolveNode()) { 789 ResolveNode *resolve = static_cast<ResolveNode *>(n); 790 return new TypeOfResolveNode(resolve->identifier()); 791 } else 792 return new TypeOfValueNode(n); 793 } 794 795 static Node *makeDeleteNode(Node *expr) 796 { 797 Node *n = expr; 798 bool paren = n->isGroupNode(); 799 if (paren) 800 n = static_cast<GroupNode *>(n)->nodeInsideAllParens(); 801 802 if (!n->isLocation()) 803 return new DeleteValueNode(expr); 804 else if (n->isResolveNode()) { 805 ResolveNode *resolve = static_cast<ResolveNode *>(n); 806 return new DeleteResolveNode(resolve->identifier()); 807 } else if (n->isBracketAccessorNode()) { 808 BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n); 809 return new DeleteBracketNode(bracket->base(), bracket->subscript()); 810 } else { 811 assert(n->isDotAccessorNode()); 812 DotAccessorNode *dot = static_cast<DotAccessorNode *>(n); 813 return new DeleteDotNode(dot->base(), dot->identifier()); 814 } 815 } 816 716 817 int yyerror (const char * /* s */) /* Called by yyparse on error */ 717 818 { -
trunk/JavaScriptCore/kjs/nodes.cpp
r10496 r10621 73 73 return Undefined(); // will be picked up by KJS_CHECKEXCEPTION 74 74 75 #define KJS_CHECKEXCEPTIONREFERENCE \76 if (exec->hadException()) { \77 setExceptionDetailsIfNeeded(exec); \78 return Reference::makeValueReference(Undefined()); \79 } \80 if (Collector::outOfMemory()) \81 return Reference::makeValueReference(Undefined()); // will be picked up by KJS_CHECKEXCEPTION82 83 75 #define KJS_CHECKEXCEPTIONLIST \ 84 76 if (exec->hadException()) { \ … … 105 97 Node::~Node() 106 98 { 107 }108 109 Reference Node::evaluateReference(ExecState *exec)110 {111 ValueImp *v = evaluate(exec);112 KJS_CHECKEXCEPTIONREFERENCE113 return Reference::makeValueReference(v);114 99 } 115 100 … … 307 292 } 308 293 309 Reference ResolveNode::evaluateReference(ExecState *exec)310 {311 const ScopeChain& chain = exec->context().imp()->scopeChain();312 ScopeChainIterator iter = chain.begin();313 ScopeChainIterator end = chain.end();314 315 // we must always have something in the scope chain316 assert(iter != end);317 318 PropertySlot slot;319 do {320 ObjectImp *o = *iter;321 if (o->getPropertySlot(exec, ident, slot))322 return Reference(o, ident);323 324 ++iter;325 } while (iter != end);326 327 return Reference(ident);328 }329 330 294 // ------------------------------ GroupNode ------------------------------------ 331 295 … … 334 298 { 335 299 return group->evaluate(exec); 336 }337 338 Reference GroupNode::evaluateReference(ExecState *exec)339 {340 return group->evaluateReference(exec);341 300 } 342 301 … … 443 402 } 444 403 445 Reference BracketAccessorNode::evaluateReference(ExecState *exec)446 {447 ValueImp *v1 = expr1->evaluate(exec);448 KJS_CHECKEXCEPTIONREFERENCE449 ValueImp *v2 = expr2->evaluate(exec);450 KJS_CHECKEXCEPTIONREFERENCE451 ObjectImp *o = v1->toObject(exec);452 uint32_t i;453 if (v2->getUInt32(i))454 return Reference(o, i);455 return Reference(o, Identifier(v2->toString(exec)));456 }457 458 404 // ------------------------------ DotAccessorNode -------------------------------- 459 405 … … 465 411 return v->toObject(exec)->get(exec, ident); 466 412 467 }468 469 Reference DotAccessorNode::evaluateReference(ExecState *exec)470 {471 ValueImp *v = expr->evaluate(exec);472 KJS_CHECKEXCEPTIONREFERENCE473 ObjectImp *o = v->toObject(exec);474 return Reference(o, ident);475 413 } 476 414 … … 702 640 } 703 641 704 // ------------------------------ PostfixNode ----------------------------------705 706 642 // ECMA 11.3 707 ValueImp *PostfixNode::evaluate(ExecState *exec) 708 { 709 Reference ref = expr->evaluateReference(exec); 710 KJS_CHECKEXCEPTIONVALUE 711 ValueImp *v = ref.getValue(exec); 643 644 // ------------------------------ PostfixResolveNode ---------------------------------- 645 646 ValueImp *PostfixResolveNode::evaluate(ExecState *exec) 647 { 648 const ScopeChain& chain = exec->context().imp()->scopeChain(); 649 ScopeChainIterator iter = chain.begin(); 650 ScopeChainIterator end = chain.end(); 651 652 // we must always have something in the scope chain 653 assert(iter != end); 654 655 PropertySlot slot; 656 ObjectImp *base; 657 do { 658 base = *iter; 659 if (base->getPropertySlot(exec, m_ident, slot)) { 660 ValueImp *v = slot.getValue(exec, m_ident); 661 662 bool knownToBeInteger; 663 double n = v->toNumber(exec, knownToBeInteger); 664 665 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 666 base->put(exec, m_ident, jsNumber(newValue, knownToBeInteger)); 667 668 return jsNumber(n, knownToBeInteger); 669 } 670 671 ++iter; 672 } while (iter != end); 673 674 return undefinedVariableError(exec, m_ident); 675 } 676 677 // ------------------------------ PostfixBracketNode ---------------------------------- 678 679 ValueImp *PostfixBracketNode::evaluate(ExecState *exec) 680 { 681 ValueImp *baseValue = m_base->evaluate(exec); 682 KJS_CHECKEXCEPTIONVALUE 683 ValueImp *subscript = m_subscript->evaluate(exec); 684 KJS_CHECKEXCEPTIONVALUE 685 686 ObjectImp *base = baseValue->toObject(exec); 687 688 uint32_t propertyIndex; 689 if (subscript->getUInt32(propertyIndex)) { 690 PropertySlot slot; 691 ValueImp *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, propertyIndex) : Undefined(); 692 KJS_CHECKEXCEPTIONVALUE 693 694 bool knownToBeInteger; 695 double n = v->toNumber(exec, knownToBeInteger); 696 697 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 698 base->put(exec, propertyIndex, jsNumber(newValue, knownToBeInteger)); 699 700 return jsNumber(n, knownToBeInteger); 701 } 702 703 Identifier propertyName(subscript->toString(exec)); 704 PropertySlot slot; 705 ValueImp *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, propertyName) : Undefined(); 706 KJS_CHECKEXCEPTIONVALUE 712 707 713 708 bool knownToBeInteger; 714 709 double n = v->toNumber(exec, knownToBeInteger); 715 716 double newValue = ( oper == OpPlusPlus) ? n + 1 : n - 1;717 ref.putValue(exec, jsNumber(newValue, knownToBeInteger));718 710 711 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 712 base->put(exec, propertyName, jsNumber(newValue, knownToBeInteger)); 713 719 714 return jsNumber(n, knownToBeInteger); 720 715 } 721 716 722 // ------------------------------ DeleteNode ----------------------------------- 717 // ------------------------------ PostfixDotNode ---------------------------------- 718 719 ValueImp *PostfixDotNode::evaluate(ExecState *exec) 720 { 721 ValueImp *baseValue = m_base->evaluate(exec); 722 KJS_CHECKEXCEPTIONVALUE 723 ObjectImp *base = baseValue->toObject(exec); 724 725 PropertySlot slot; 726 ValueImp *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, m_ident) : Undefined(); 727 KJS_CHECKEXCEPTIONVALUE 728 729 bool knownToBeInteger; 730 double n = v->toNumber(exec, knownToBeInteger); 731 732 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 733 base->put(exec, m_ident, jsNumber(newValue, knownToBeInteger)); 734 735 return jsNumber(n, knownToBeInteger); 736 } 723 737 724 738 // ECMA 11.4.1 725 ValueImp *DeleteNode::evaluate(ExecState *exec) 726 { 727 Reference ref = expr->evaluateReference(exec); 728 KJS_CHECKEXCEPTIONVALUE 729 return jsBoolean(ref.deleteValue(exec)); 739 740 // ------------------------------ DeleteResolveNode ----------------------------------- 741 ValueImp *DeleteResolveNode::evaluate(ExecState *exec) 742 { 743 const ScopeChain& chain = exec->context().imp()->scopeChain(); 744 ScopeChainIterator iter = chain.begin(); 745 ScopeChainIterator end = chain.end(); 746 747 // we must always have something in the scope chain 748 assert(iter != end); 749 750 PropertySlot slot; 751 ObjectImp *base; 752 do { 753 base = *iter; 754 if (base->getPropertySlot(exec, m_ident, slot)) { 755 return jsBoolean(base->deleteProperty(exec, m_ident)); 756 } 757 758 ++iter; 759 } while (iter != end); 760 761 return jsBoolean(true); 762 } 763 764 // ------------------------------ DeleteBracketNode ----------------------------------- 765 ValueImp *DeleteBracketNode::evaluate(ExecState *exec) 766 { 767 ValueImp *baseValue = m_base->evaluate(exec); 768 KJS_CHECKEXCEPTIONVALUE 769 ValueImp *subscript = m_subscript->evaluate(exec); 770 KJS_CHECKEXCEPTIONVALUE 771 772 ObjectImp *base = baseValue->toObject(exec); 773 774 uint32_t propertyIndex; 775 if (subscript->getUInt32(propertyIndex)) 776 return jsBoolean(base->deleteProperty(exec, propertyIndex)); 777 778 Identifier propertyName(subscript->toString(exec)); 779 return jsBoolean(base->deleteProperty(exec, propertyName)); 780 } 781 782 // ------------------------------ DeleteDotNode ----------------------------------- 783 ValueImp *DeleteDotNode::evaluate(ExecState *exec) 784 { 785 ValueImp *baseValue = m_base->evaluate(exec); 786 ObjectImp *base = baseValue->toObject(exec); 787 KJS_CHECKEXCEPTIONVALUE 788 789 return jsBoolean(base->deleteProperty(exec, m_ident)); 790 } 791 792 // ------------------------------ DeleteValueNode ----------------------------------- 793 ValueImp *DeleteValueNode::evaluate(ExecState *exec) 794 { 795 m_expr->evaluate(exec); 796 KJS_CHECKEXCEPTIONVALUE 797 798 // delete on a non-location expression ignores the value and returns true 799 return jsBoolean(true); 730 800 } 731 801 … … 741 811 } 742 812 743 // ------------------------------ TypeOfNode -----------------------------------744 745 813 // ECMA 11.4.3 746 ValueImp *TypeOfNode::evaluate(ExecState *exec) 747 { 748 const char *s = 0L; 749 Reference ref = expr->evaluateReference(exec); 750 KJS_CHECKEXCEPTIONVALUE 751 ValueImp *b = ref.baseIfMutable(); 752 if (b && b->isNull()) 753 return jsString("undefined"); 754 ValueImp *v = ref.getValue(exec); 755 switch (v->type()) 756 { 814 815 // ------------------------------ TypeOfValueNode ----------------------------------- 816 817 static ValueImp *typeStringForValue(ValueImp *v) 818 { 819 switch (v->type()) { 757 820 case UndefinedType: 758 s = "undefined"; 759 break; 821 return jsString("undefined"); 760 822 case NullType: 761 s = "object"; 762 break; 823 return jsString("object"); 763 824 case BooleanType: 764 s = "boolean"; 765 break; 825 return jsString("boolean"); 766 826 case NumberType: 767 s = "number"; 768 break; 827 return jsString("number"); 769 828 case StringType: 770 s = "string"; 771 break; 829 return jsString("string"); 772 830 default: 773 if (v->isObject() && static_cast<ObjectImp*>(v)->implementsCall()) 774 s = "function"; 775 else 776 s = "object"; 777 break; 831 if (v->isObject() && static_cast<ObjectImp*>(v)->implementsCall()) 832 return jsString("function"); 833 else 834 return jsString("object"); 778 835 } 779 780 return jsString(s); 781 } 782 783 // ------------------------------ PrefixNode ----------------------------------- 836 } 837 838 ValueImp *TypeOfResolveNode::evaluate(ExecState *exec) 839 { 840 const ScopeChain& chain = exec->context().imp()->scopeChain(); 841 ScopeChainIterator iter = chain.begin(); 842 ScopeChainIterator end = chain.end(); 843 844 // we must always have something in the scope chain 845 assert(iter != end); 846 847 PropertySlot slot; 848 ObjectImp *base; 849 do { 850 base = *iter; 851 if (base->getPropertySlot(exec, m_ident, slot)) { 852 ValueImp *v = slot.getValue(exec, m_ident); 853 return typeStringForValue(v); 854 } 855 856 ++iter; 857 } while (iter != end); 858 859 return jsString("undefined"); 860 } 861 862 // ------------------------------ TypeOfValueNode ----------------------------------- 863 864 ValueImp *TypeOfValueNode::evaluate(ExecState *exec) 865 { 866 ValueImp *v = m_expr->evaluate(exec); 867 KJS_CHECKEXCEPTIONVALUE 868 869 return typeStringForValue(v); 870 } 784 871 785 872 // ECMA 11.4.4 and 11.4.5 786 ValueImp *PrefixNode::evaluate(ExecState *exec) 787 { 788 Reference ref = expr->evaluateReference(exec); 789 KJS_CHECKEXCEPTIONVALUE 790 ValueImp *v = ref.getValue(exec); 873 874 // ------------------------------ PrefixResolveNode ---------------------------------- 875 876 ValueImp *PrefixResolveNode::evaluate(ExecState *exec) 877 { 878 const ScopeChain& chain = exec->context().imp()->scopeChain(); 879 ScopeChainIterator iter = chain.begin(); 880 ScopeChainIterator end = chain.end(); 881 882 // we must always have something in the scope chain 883 assert(iter != end); 884 885 PropertySlot slot; 886 ObjectImp *base; 887 do { 888 base = *iter; 889 if (base->getPropertySlot(exec, m_ident, slot)) { 890 ValueImp *v = slot.getValue(exec, m_ident); 891 892 bool knownToBeInteger; 893 double n = v->toNumber(exec, knownToBeInteger); 894 895 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 896 ValueImp *n2 = jsNumber(newValue, knownToBeInteger); 897 base->put(exec, m_ident, n2); 898 899 return n2; 900 } 901 902 ++iter; 903 } while (iter != end); 904 905 return undefinedVariableError(exec, m_ident); 906 } 907 908 // ------------------------------ PrefixBracketNode ---------------------------------- 909 910 ValueImp *PrefixBracketNode::evaluate(ExecState *exec) 911 { 912 ValueImp *baseValue = m_base->evaluate(exec); 913 KJS_CHECKEXCEPTIONVALUE 914 ValueImp *subscript = m_subscript->evaluate(exec); 915 KJS_CHECKEXCEPTIONVALUE 916 917 ObjectImp *base = baseValue->toObject(exec); 918 919 uint32_t propertyIndex; 920 if (subscript->getUInt32(propertyIndex)) { 921 PropertySlot slot; 922 ValueImp *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, propertyIndex) : Undefined(); 923 KJS_CHECKEXCEPTIONVALUE 924 925 bool knownToBeInteger; 926 double n = v->toNumber(exec, knownToBeInteger); 927 928 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 929 ValueImp *n2 = jsNumber(newValue, knownToBeInteger); 930 base->put(exec, propertyIndex, n2); 931 932 return n2; 933 } 934 935 Identifier propertyName(subscript->toString(exec)); 936 PropertySlot slot; 937 ValueImp *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, propertyName) : Undefined(); 938 KJS_CHECKEXCEPTIONVALUE 791 939 792 940 bool knownToBeInteger; 793 941 double n = v->toNumber(exec, knownToBeInteger); 794 795 double newValue = ( oper == OpPlusPlus) ? n + 1 : n - 1;942 943 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 796 944 ValueImp *n2 = jsNumber(newValue, knownToBeInteger); 797 798 ref.putValue(exec, n2); 945 base->put(exec, propertyName, n2); 946 947 return n2; 948 } 949 950 // ------------------------------ PrefixDotNode ---------------------------------- 951 952 ValueImp *PrefixDotNode::evaluate(ExecState *exec) 953 { 954 ValueImp *baseValue = m_base->evaluate(exec); 955 KJS_CHECKEXCEPTIONVALUE 956 ObjectImp *base = baseValue->toObject(exec); 957 958 PropertySlot slot; 959 ValueImp *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, m_ident) : Undefined(); 960 KJS_CHECKEXCEPTIONVALUE 961 962 bool knownToBeInteger; 963 double n = v->toNumber(exec, knownToBeInteger); 964 965 double newValue = (m_oper == OpPlusPlus) ? n + 1 : n - 1; 966 ValueImp *n2 = jsNumber(newValue, knownToBeInteger); 967 base->put(exec, m_ident, n2); 799 968 800 969 return n2; … … 1623 1792 ReferenceList propList; 1624 1793 1625 if ( varDecl) {1794 if (varDecl) { 1626 1795 varDecl->evaluate(exec); 1627 1796 KJS_CHECKEXCEPTION … … 1646 1815 while (propIt != propList.end()) { 1647 1816 Identifier name = propIt->getPropertyName(exec); 1648 if (!v->hasProperty(exec, name)) {1817 if (!v->hasProperty(exec, name)) { 1649 1818 propIt++; 1650 1819 continue; 1651 1820 } 1652 1821 1653 Reference ref = lexpr->evaluateReference(exec); 1822 ValueImp *str = jsString(name.ustring()); 1823 1824 if (lexpr->isResolveNode()) { 1825 const Identifier &ident = static_cast<ResolveNode *>(lexpr.get())->identifier(); 1826 1827 const ScopeChain& chain = exec->context().imp()->scopeChain(); 1828 ScopeChainIterator iter = chain.begin(); 1829 ScopeChainIterator end = chain.end(); 1830 1831 // we must always have something in the scope chain 1832 assert(iter != end); 1833 1834 PropertySlot slot; 1835 ObjectImp *o; 1836 do { 1837 o = *iter; 1838 if (o->getPropertySlot(exec, ident, slot)) 1839 o->put(exec, ident, str); 1840 1841 ++iter; 1842 } while (iter != end); 1843 1844 if (iter == end) 1845 o->put(exec, ident, str); 1846 } else if (lexpr->isDotAccessorNode()) { 1847 const Identifier& ident = static_cast<DotAccessorNode *>(lexpr.get())->identifier(); 1848 ValueImp *v = static_cast<DotAccessorNode *>(lexpr.get())->base()->evaluate(exec); 1849 KJS_CHECKEXCEPTION 1850 ObjectImp *o = v->toObject(exec); 1851 1852 o->put(exec, ident, str); 1853 } else { 1854 assert(lexpr->isBracketAccessorNode()); 1855 ValueImp *v = static_cast<BracketAccessorNode *>(lexpr.get())->base()->evaluate(exec); 1856 KJS_CHECKEXCEPTION 1857 ValueImp *v2 = static_cast<BracketAccessorNode *>(lexpr.get())->subscript()->evaluate(exec); 1858 KJS_CHECKEXCEPTION 1859 ObjectImp *o = v->toObject(exec); 1860 1861 uint32_t i; 1862 if (v2->getUInt32(i)) 1863 o->put(exec, i, str); 1864 o->put(exec, Identifier(v2->toString(exec)), str); 1865 } 1866 1654 1867 KJS_CHECKEXCEPTION 1655 ref.putValue(exec, String(name.ustring()));1656 1868 1657 1869 exec->context().imp()->seenLabels()->pushIteration(); -
trunk/JavaScriptCore/kjs/nodes.h
r10588 r10621 86 86 87 87 virtual ValueImp *evaluate(ExecState *exec) = 0; 88 virtual Reference evaluateReference(ExecState *exec);89 88 UString toString() const; 90 89 virtual void streamTo(SourceStream &s) const = 0; … … 200 199 ResolveNode(const Identifier &s) : ident(s) { } 201 200 ValueImp *evaluate(ExecState *exec); 202 virtual Reference evaluateReference(ExecState *exec);203 201 virtual void streamTo(SourceStream &s) const; 204 202 … … 215 213 GroupNode(Node *g) : group(g) { } 216 214 virtual ValueImp *evaluate(ExecState *exec); 217 virtual Reference evaluateReference(ExecState *exec);218 215 virtual void streamTo(SourceStream &s) const; 219 216 … … 303 300 BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {} 304 301 ValueImp *evaluate(ExecState *exec); 305 virtual Reference evaluateReference(ExecState *exec);306 302 virtual void streamTo(SourceStream &s) const; 307 303 … … 320 316 DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { } 321 317 ValueImp *evaluate(ExecState *exec); 322 virtual Reference evaluateReference(ExecState *exec);323 318 virtual void streamTo(SourceStream &s) const; 324 319 … … 425 420 }; 426 421 427 class PostfixNode : public Node { 428 public: 429 PostfixNode(Node *e, Operator o) : expr(e), oper(o) {} 430 ValueImp *evaluate(ExecState *exec); 431 virtual void streamTo(SourceStream &s) const; 432 private: 433 KXMLCore::SharedPtr<Node> expr; 434 Operator oper; 435 }; 436 437 class DeleteNode : public Node { 438 public: 439 DeleteNode(Node *e) : expr(e) {} 440 ValueImp *evaluate(ExecState *exec); 441 virtual void streamTo(SourceStream &s) const; 442 private: 443 KXMLCore::SharedPtr<Node> expr; 422 class PostfixResolveNode : public Node { 423 public: 424 PostfixResolveNode(const Identifier& i, Operator o) : m_ident(i), m_oper(o) {} 425 ValueImp *evaluate(ExecState *exec); 426 virtual void streamTo(SourceStream &s) const; 427 private: 428 Identifier m_ident; 429 Operator m_oper; 430 }; 431 432 class PostfixBracketNode : public Node { 433 public: 434 PostfixBracketNode(Node *b, Node *s, Operator o) : m_base(b), m_subscript(s), m_oper(o) {} 435 ValueImp *evaluate(ExecState *exec); 436 virtual void streamTo(SourceStream &s) const; 437 private: 438 KXMLCore::SharedPtr<Node> m_base; 439 KXMLCore::SharedPtr<Node> m_subscript; 440 Operator m_oper; 441 }; 442 443 class PostfixDotNode : public Node { 444 public: 445 PostfixDotNode(Node *b, const Identifier& i, Operator o) : m_base(b), m_ident(i), m_oper(o) {} 446 ValueImp *evaluate(ExecState *exec); 447 virtual void streamTo(SourceStream &s) const; 448 private: 449 KXMLCore::SharedPtr<Node> m_base; 450 Identifier m_ident; 451 Operator m_oper; 452 }; 453 454 class DeleteResolveNode : public Node { 455 public: 456 DeleteResolveNode(const Identifier& i) : m_ident(i) {} 457 ValueImp *evaluate(ExecState *exec); 458 virtual void streamTo(SourceStream &s) const; 459 private: 460 Identifier m_ident; 461 }; 462 463 class DeleteBracketNode : public Node { 464 public: 465 DeleteBracketNode(Node *base, Node *subscript) : m_base(base), m_subscript(subscript) {} 466 ValueImp *evaluate(ExecState *exec); 467 virtual void streamTo(SourceStream &s) const; 468 private: 469 KXMLCore::SharedPtr<Node> m_base; 470 KXMLCore::SharedPtr<Node> m_subscript; 471 }; 472 473 class DeleteDotNode : public Node { 474 public: 475 DeleteDotNode(Node *base, const Identifier& i) : m_base(base), m_ident(i) {} 476 ValueImp *evaluate(ExecState *exec); 477 virtual void streamTo(SourceStream &s) const; 478 private: 479 KXMLCore::SharedPtr<Node> m_base; 480 Identifier m_ident; 481 }; 482 483 class DeleteValueNode : public Node { 484 public: 485 DeleteValueNode(Node *e) : m_expr(e) {} 486 ValueImp *evaluate(ExecState *exec); 487 virtual void streamTo(SourceStream &s) const; 488 private: 489 KXMLCore::SharedPtr<Node> m_expr; 444 490 }; 445 491 … … 453 499 }; 454 500 455 class TypeOfNode : public Node { 456 public: 457 TypeOfNode(Node *e) : expr(e) {} 458 ValueImp *evaluate(ExecState *exec); 459 virtual void streamTo(SourceStream &s) const; 460 private: 461 KXMLCore::SharedPtr<Node> expr; 462 }; 463 464 class PrefixNode : public Node { 465 public: 466 PrefixNode(Operator o, Node *e) : oper(o), expr(e) {} 467 ValueImp *evaluate(ExecState *exec); 468 virtual void streamTo(SourceStream &s) const; 469 private: 470 Operator oper; 471 KXMLCore::SharedPtr<Node> expr; 501 class TypeOfResolveNode : public Node { 502 public: 503 TypeOfResolveNode(const Identifier& i) : m_ident(i) {} 504 ValueImp *evaluate(ExecState *exec); 505 virtual void streamTo(SourceStream &s) const; 506 private: 507 Identifier m_ident; 508 }; 509 510 class TypeOfValueNode : public Node { 511 public: 512 TypeOfValueNode(Node *e) : m_expr(e) {} 513 ValueImp *evaluate(ExecState *exec); 514 virtual void streamTo(SourceStream &s) const; 515 private: 516 KXMLCore::SharedPtr<Node> m_expr; 517 }; 518 519 class PrefixResolveNode : public Node { 520 public: 521 PrefixResolveNode(const Identifier& i, Operator o) : m_ident(i), m_oper(o) {} 522 ValueImp *evaluate(ExecState *exec); 523 virtual void streamTo(SourceStream &s) const; 524 private: 525 Identifier m_ident; 526 Operator m_oper; 527 }; 528 529 class PrefixBracketNode : public Node { 530 public: 531 PrefixBracketNode(Node *b, Node *s, Operator o) : m_base(b), m_subscript(s), m_oper(o) {} 532 ValueImp *evaluate(ExecState *exec); 533 virtual void streamTo(SourceStream &s) const; 534 private: 535 KXMLCore::SharedPtr<Node> m_base; 536 KXMLCore::SharedPtr<Node> m_subscript; 537 Operator m_oper; 538 }; 539 540 class PrefixDotNode : public Node { 541 public: 542 PrefixDotNode(Node *b, const Identifier& i, Operator o) : m_base(b), m_ident(i), m_oper(o) {} 543 ValueImp *evaluate(ExecState *exec); 544 virtual void streamTo(SourceStream &s) const; 545 private: 546 KXMLCore::SharedPtr<Node> m_base; 547 Identifier m_ident; 548 Operator m_oper; 472 549 }; 473 550 -
trunk/JavaScriptCore/kjs/nodes2string.cpp
r10399 r10621 229 229 } 230 230 231 void Postfix Node::streamTo(SourceStream &s) const232 { 233 s << expr;234 if ( oper == OpPlusPlus)231 void PostfixResolveNode::streamTo(SourceStream &s) const 232 { 233 s << m_ident; 234 if (m_oper == OpPlusPlus) 235 235 s << "++"; 236 236 else … … 238 238 } 239 239 240 void DeleteNode::streamTo(SourceStream &s) const 241 { 242 s << "delete " << expr; 240 void PostfixBracketNode::streamTo(SourceStream &s) const 241 { 242 s << m_base << "[" << m_subscript << "]"; 243 if (m_oper == OpPlusPlus) 244 s << "++"; 245 else 246 s << "--"; 247 } 248 249 void PostfixDotNode::streamTo(SourceStream &s) const 250 { 251 s << m_base << "." << m_ident; 252 if (m_oper == OpPlusPlus) 253 s << "++"; 254 else 255 s << "--"; 256 } 257 258 void DeleteResolveNode::streamTo(SourceStream &s) const 259 { 260 s << "delete " << m_ident; 261 } 262 263 void DeleteBracketNode::streamTo(SourceStream &s) const 264 { 265 s << "delete " << m_base << "[" << m_subscript << "]"; 266 } 267 268 void DeleteDotNode::streamTo(SourceStream &s) const 269 { 270 s << "delete " << m_base << "." << m_ident; 271 } 272 273 void DeleteValueNode::streamTo(SourceStream &s) const 274 { 275 s << "delete " << m_expr; 243 276 } 244 277 … … 248 281 } 249 282 250 void TypeOfNode::streamTo(SourceStream &s) const 251 { 252 s << "typeof " << expr; 253 } 254 255 void PrefixNode::streamTo(SourceStream &s) const 256 { 257 s << expr << (oper == OpPlusPlus ? "++" : "--"); 283 void TypeOfValueNode::streamTo(SourceStream &s) const 284 { 285 s << "typeof " << m_expr; 286 } 287 288 void TypeOfResolveNode::streamTo(SourceStream &s) const 289 { 290 s << "typeof " << m_ident; 291 } 292 293 void PrefixResolveNode::streamTo(SourceStream &s) const 294 { 295 if (m_oper == OpPlusPlus) 296 s << "++"; 297 else 298 s << "--"; 299 s << m_ident; 300 } 301 302 void PrefixBracketNode::streamTo(SourceStream &s) const 303 { 304 if (m_oper == OpPlusPlus) 305 s << "++"; 306 else 307 s << "--"; 308 s << m_base << "[" << m_subscript << "]"; 309 } 310 311 void PrefixDotNode::streamTo(SourceStream &s) const 312 { 313 if (m_oper == OpPlusPlus) 314 s << "++"; 315 else 316 s << "--"; 317 s << m_base << "." << m_ident; 258 318 } 259 319 -
trunk/JavaScriptCore/kjs/reference.cpp
r10207 r10621 30 30 Reference::Reference(ObjectImp *b, const Identifier& p) 31 31 : base(b), 32 baseIsValue(false),33 32 propertyNameIsNumber(false), 34 33 prop(p) … … 39 38 : base(b), 40 39 propertyNameAsNumber(p), 41 baseIsValue(false),42 40 propertyNameIsNumber(true) 43 41 { 44 42 } 45 43 46 Reference::Reference(const Identifier& p)47 : base(jsNull()),48 baseIsValue(false),49 propertyNameIsNumber(false),50 prop(p)51 {52 }53 54 Reference::Reference(unsigned p)55 : base(jsNull()),56 propertyNameAsNumber(p),57 baseIsValue(false),58 propertyNameIsNumber(true)59 {60 }61 62 Reference Reference::makeValueReference(ValueImp *v)63 {64 Reference valueRef;65 valueRef.base = v;66 valueRef.baseIsValue = true;67 return valueRef;68 }69 70 ValueImp *Reference::getBase(ExecState *exec) const71 {72 if (baseIsValue)73 return throwError(exec, ReferenceError, "Invalid reference base");74 return base;75 }76 77 44 Identifier Reference::getPropertyName(ExecState *exec) const 78 45 { 79 if (baseIsValue) {80 // the spec wants a runtime error here. But getValue() and putValue()81 // will catch this case on their own earlier. When returning a Null82 // string we should be on the safe side.83 return Identifier();84 }85 86 46 if (propertyNameIsNumber && prop.isNull()) 87 47 prop = Identifier::from(propertyNameAsNumber); … … 91 51 ValueImp *Reference::getValue(ExecState *exec) const 92 52 { 93 if (baseIsValue)94 return base;95 96 53 ValueImp *o = base; 97 54 if (!o || !o->isObject()) { … … 106 63 } 107 64 108 void Reference::putValue(ExecState *exec, ValueImp *w)109 {110 if (baseIsValue) {111 throwError(exec, ReferenceError);112 return;113 }114 115 #ifdef KJS_VERBOSE116 printInfo(exec,(UString("setting property ")+getPropertyName(exec).ustring()).cstring().c_str(),w);117 #endif118 119 ValueImp *o = base;120 Type t = o ? o->type() : NullType;121 122 if (t == NullType)123 o = exec->lexicalInterpreter()->globalObject();124 125 if (propertyNameIsNumber)126 return static_cast<ObjectImp*>(o)->put(exec, propertyNameAsNumber, w);127 return static_cast<ObjectImp*>(o)->put(exec, prop, w);128 }129 130 65 bool Reference::deleteValue(ExecState *exec) 131 66 { 132 if (baseIsValue) {133 throwError(exec, ReferenceError);134 return false;135 }136 137 67 ValueImp *o = base; 138 68 Type t = o ? o->type() : NullType; -
trunk/JavaScriptCore/kjs/reference.h
r10563 r10621 37 37 Reference(ObjectImp *b, const Identifier& p); 38 38 Reference(ObjectImp *b, unsigned p); 39 Reference(const Identifier& p);40 Reference(unsigned p);41 static Reference makeValueReference(ValueImp *);42 39 43 /**44 * Performs the GetBase type conversion operation on this value (ECMA 8.7)45 *46 * Since references are supposed to have an Object or null as their base,47 * this method is guaranteed to return either Null() or an Object value.48 */49 ValueImp *getBase(ExecState *exec) const;50 51 40 /** 52 41 * Performs the GetPropertyName type conversion operation on this value … … 65 54 * (ECMA 8.7.1) 66 55 */ 67 void putValue(ExecState *exec, ValueImp *);68 56 bool deleteValue(ExecState *exec); 69 70 ValueImp *baseIfMutable() const { return baseIsValue ? 0 : base; }71 57 72 58 protected: … … 77 63 78 64 unsigned propertyNameAsNumber; 79 bool baseIsValue;80 65 bool propertyNameIsNumber; 81 66 mutable Identifier prop;
Note:
See TracChangeset
for help on using the changeset viewer.