Changeset 27589 in webkit
- Timestamp:
- Nov 7, 2007 11:58:15 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r27574 r27589 1 2007-11-07 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Darin and Oliver. 4 5 Add evaluateToNumber parallel evaluation tree to speed up number operations. 6 Make ImmediateNumberNode a subclass of NumberNode. 7 Share evaluate logic between evaluate and evaluateToNumber using inline functions 8 There is still a lot of improvement to be made here. 9 10 SunSpider claims this is a 1.0% speedup overall (nbody 7.9%), base64 slowing 2.0% 11 Given the huge win that this prepares us for with simple type inferencing I see the small 12 regression in base64 being worth the substantial overall improvement. 13 14 * kjs/grammar.y: 15 * kjs/nodes.cpp: 16 (KJS::Node::evaluateToNumber): 17 (KJS::NumberNode::evaluate): 18 (KJS::NumberNode::evaluateToNumber): 19 (KJS::StringNode::evaluateToNumber): 20 (KJS::LocalVarAccessNode::inlineEvaluate): 21 (KJS::LocalVarAccessNode::evaluate): 22 (KJS::LocalVarAccessNode::evaluateToNumber): 23 (KJS::BracketAccessorNode::inlineEvaluate): 24 (KJS::BracketAccessorNode::evaluate): 25 (KJS::BracketAccessorNode::evaluateToNumber): 26 (KJS::NegateNode::evaluate): 27 (KJS::NegateNode::evaluateToNumber): 28 (KJS::MultNode::inlineEvaluateToNumber): 29 (KJS::MultNode::evaluate): 30 (KJS::MultNode::evaluateToNumber): 31 (KJS::DivNode::inlineEvaluateToNumber): 32 (KJS::DivNode::evaluate): 33 (KJS::DivNode::evaluateToNumber): 34 (KJS::ModNode::inlineEvaluateToNumber): 35 (KJS::ModNode::evaluate): 36 (KJS::ModNode::evaluateToNumber): 37 (KJS::throwOutOfMemoryErrorToNumber): 38 (KJS::addSlowCaseToNumber): 39 (KJS::add): 40 (KJS::addToNumber): 41 (KJS::AddNode::evaluateToNumber): 42 (KJS::SubNode::inlineEvaluateToNumber): 43 (KJS::SubNode::evaluate): 44 (KJS::SubNode::evaluateToNumber): 45 (KJS::valueForReadModifyAssignment): 46 (KJS::ReadModifyLocalVarNode::evaluate): 47 (KJS::ReadModifyResolveNode::evaluate): 48 (KJS::ReadModifyDotNode::evaluate): 49 (KJS::ReadModifyBracketNode::evaluate): 50 * kjs/nodes.h: 51 (KJS::Node::): 52 (KJS::NumberNode::): 53 (KJS::ImmediateNumberNode::): 54 (KJS::AddNode::precedence): 55 * kjs/nodes2string.cpp: 56 (KJS::NumberNode::streamTo): 57 1 58 2007-11-07 Mark Rowe <mrowe@apple.com> 2 59 -
trunk/JavaScriptCore/kjs/grammar.y
r27394 r27589 4 4 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 5 5 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 6 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 1021 1022 } 1022 1023 1023 static Node* makeNegateNode(Node *n)1024 static Node* makeNegateNode(Node* n) 1024 1025 { 1025 1026 if (n->isNumber()) { … … 1030 1031 return number; 1031 1032 } 1032 } else if (n->isImmediateValue()) {1033 ImmediateNumberNode* number = static_cast<ImmediateNumberNode*>(n);1034 double value = number->value();1035 if (value > 0.0) {1036 number->setValue(-value);1037 return number;1038 }1039 1033 } 1040 1034 … … 1046 1040 JSValue* value = JSImmediate::fromDouble(d); 1047 1041 if (value) 1048 return new ImmediateNumberNode(value );1042 return new ImmediateNumberNode(value, d); 1049 1043 return new NumberNode(d); 1050 1044 } -
trunk/JavaScriptCore/kjs/nodes.cpp
r27501 r27589 5 5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) 6 6 * Copyright (C) 2007 Maks Orlovich 7 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 7 8 * 8 9 * This library is free software; you can redistribute it and/or … … 56 57 } 57 58 59 #define KJS_CHECKEXCEPTIONNUMBER \ 60 if (exec->hadException()) { \ 61 handleException(exec); \ 62 return 0.0; \ 63 } 64 58 65 #define KJS_CHECKEXCEPTIONLIST \ 59 66 if (exec->hadException()) { \ … … 195 202 delete newNodes; 196 203 newNodes = 0; 204 } 205 206 double Node::evaluateToNumber(ExecState* exec) 207 { 208 JSValue* value = evaluate(exec); 209 KJS_CHECKEXCEPTIONNUMBER 210 // No need to check exception after toNumber, caller will do so right after evaluateToNumber() call 211 return value->toNumber(exec); 197 212 } 198 213 … … 361 376 // ------------------------------ NumberNode ----------------------------------- 362 377 363 JSValue *NumberNode::evaluate(ExecState*)378 JSValue* NumberNode::evaluate(ExecState*) 364 379 { 365 380 // Number nodes are only created when the number can't fit in a JSImmediate, so no need to check again. 366 return jsNumberCell(val); 381 return jsNumberCell(m_double); 382 } 383 384 double NumberNode::evaluateToNumber(ExecState*) 385 { 386 return m_double; 367 387 } 368 388 … … 378 398 return jsOwnedString(value); 379 399 } 380 400 401 double StringNode::evaluateToNumber(ExecState*) 402 { 403 return value.toDouble(); 404 } 405 381 406 // ------------------------------ RegExpNode ----------------------------------- 382 407 … … 434 459 } 435 460 436 JSValue* LocalVarAccessNode:: evaluate(ExecState* exec)461 JSValue* LocalVarAccessNode::inlineEvaluate(ExecState* exec) 437 462 { 438 463 ASSERT(static_cast<ActivationImp*>(exec->variableObject())->isActivation()); 439 464 ASSERT(static_cast<ActivationImp*>(exec->variableObject()) == exec->scopeChain().top()); 440 465 return exec->localStorage()[index].value; 466 } 467 468 JSValue* LocalVarAccessNode::evaluate(ExecState* exec) 469 { 470 return inlineEvaluate(exec); 471 } 472 473 double LocalVarAccessNode::evaluateToNumber(ExecState* exec) 474 { 475 return inlineEvaluate(exec)->toNumber(exec); 441 476 } 442 477 … … 572 607 573 608 // ECMA 11.2.1a 574 JSValue *BracketAccessorNode::evaluate(ExecState *exec)575 { 576 JSValue *v1 = expr1->evaluate(exec);577 KJS_CHECKEXCEPTIONVALUE 578 JSValue *v2 = expr2->evaluate(exec);579 KJS_CHECKEXCEPTIONVALUE 580 JSObject *o = v1->toObject(exec);609 JSValue* BracketAccessorNode::inlineEvaluate(ExecState* exec) 610 { 611 JSValue* v1 = expr1->evaluate(exec); 612 KJS_CHECKEXCEPTIONVALUE 613 JSValue* v2 = expr2->evaluate(exec); 614 KJS_CHECKEXCEPTIONVALUE 615 JSObject* o = v1->toObject(exec); 581 616 uint32_t i; 582 617 if (v2->getUInt32(i)) 583 618 return o->get(exec, i); 584 619 return o->get(exec, Identifier(v2->toString(exec))); 620 } 621 622 JSValue* BracketAccessorNode::evaluate(ExecState* exec) 623 { 624 return inlineEvaluate(exec); 625 } 626 627 double BracketAccessorNode::evaluateToNumber(ExecState* exec) 628 { 629 return inlineEvaluate(exec)->toNumber(exec); 585 630 } 586 631 … … 1580 1625 JSValue *NegateNode::evaluate(ExecState *exec) 1581 1626 { 1582 JSValue *v = expr->evaluate(exec); 1583 KJS_CHECKEXCEPTIONVALUE 1584 1585 double n = v->toNumber(exec); 1586 return jsNumber(-n); 1627 // No need to check exception, caller will do so right after evaluate() 1628 return jsNumber(-expr->evaluateToNumber(exec)); 1629 } 1630 1631 double NegateNode::evaluateToNumber(ExecState* exec) 1632 { 1633 // No need to check exception, caller will do so right after evaluateToNumber() 1634 return -expr->evaluateToNumber(exec); 1587 1635 } 1588 1636 … … 1626 1674 1627 1675 // ECMA 11.5.1 1628 JSValue *MultNode::evaluate(ExecState *exec) 1629 { 1630 JSValue *v1 = term1->evaluate(exec); 1631 KJS_CHECKEXCEPTIONVALUE 1632 1633 JSValue *v2 = term2->evaluate(exec); 1634 KJS_CHECKEXCEPTIONVALUE 1635 1636 return jsNumber(v1->toNumber(exec) * v2->toNumber(exec)); 1676 double MultNode::inlineEvaluateToNumber(ExecState* exec) 1677 { 1678 double n1 = term1->evaluateToNumber(exec); 1679 KJS_CHECKEXCEPTIONNUMBER 1680 1681 double n2 = term2->evaluateToNumber(exec); 1682 KJS_CHECKEXCEPTIONNUMBER 1683 1684 return n1 * n2; 1685 } 1686 1687 JSValue *MultNode::evaluate(ExecState* exec) 1688 { 1689 return jsNumber(inlineEvaluateToNumber(exec)); 1690 } 1691 1692 double MultNode::evaluateToNumber(ExecState* exec) 1693 { 1694 return inlineEvaluateToNumber(exec); 1637 1695 } 1638 1696 … … 1644 1702 1645 1703 // ECMA 11.5.2 1646 JSValue *DivNode::evaluate(ExecState *exec) 1647 { 1648 JSValue *v1 = term1->evaluate(exec); 1649 KJS_CHECKEXCEPTIONVALUE 1650 1651 JSValue *v2 = term2->evaluate(exec); 1652 KJS_CHECKEXCEPTIONVALUE 1653 1654 return jsNumber(v1->toNumber(exec) / v2->toNumber(exec)); 1704 double DivNode::inlineEvaluateToNumber(ExecState* exec) 1705 { 1706 double n1 = term1->evaluateToNumber(exec); 1707 KJS_CHECKEXCEPTIONNUMBER 1708 1709 double n2 = term2->evaluateToNumber(exec); 1710 KJS_CHECKEXCEPTIONNUMBER 1711 1712 return n1 / n2; 1713 } 1714 1715 JSValue* DivNode::evaluate(ExecState* exec) 1716 { 1717 return jsNumber(inlineEvaluateToNumber(exec)); 1718 } 1719 1720 double DivNode::evaluateToNumber(ExecState* exec) 1721 { 1722 return inlineEvaluateToNumber(exec); 1655 1723 } 1656 1724 … … 1662 1730 1663 1731 // ECMA 11.5.3 1664 JSValue *ModNode::evaluate(ExecState *exec) 1665 { 1666 JSValue *v1 = term1->evaluate(exec); 1667 KJS_CHECKEXCEPTIONVALUE 1668 1669 JSValue *v2 = term2->evaluate(exec); 1670 KJS_CHECKEXCEPTIONVALUE 1671 1672 return jsNumber(fmod(v1->toNumber(exec), v2->toNumber(exec))); 1732 double ModNode::inlineEvaluateToNumber(ExecState* exec) 1733 { 1734 double n1 = term1->evaluateToNumber(exec); 1735 KJS_CHECKEXCEPTIONNUMBER 1736 1737 double n2 = term2->evaluateToNumber(exec); 1738 KJS_CHECKEXCEPTIONNUMBER 1739 1740 return fmod(n1, n2); 1741 } 1742 1743 JSValue* ModNode::evaluate(ExecState* exec) 1744 { 1745 return jsNumber(inlineEvaluateToNumber(exec)); 1746 } 1747 1748 double ModNode::evaluateToNumber(ExecState* exec) 1749 { 1750 return inlineEvaluateToNumber(exec); 1673 1751 } 1674 1752 … … 1681 1759 return error; 1682 1760 } 1761 1762 static double throwOutOfMemoryErrorToNumber(ExecState* exec) 1763 { 1764 JSObject* error = Error::create(exec, GeneralError, "Out of memory"); 1765 exec->setException(error); 1766 return 0.0; 1767 } 1683 1768 1684 1769 // ECMA 11.6 … … 1697 1782 1698 1783 return jsNumber(p1->toNumber(exec) + p2->toNumber(exec)); 1784 } 1785 1786 static double addSlowCaseToNumber(ExecState* exec, JSValue* v1, JSValue* v2) 1787 { 1788 // exception for the Date exception in defaultValue() 1789 JSValue *p1 = v1->toPrimitive(exec, UnspecifiedType); 1790 JSValue *p2 = v2->toPrimitive(exec, UnspecifiedType); 1791 1792 if (p1->isString() || p2->isString()) { 1793 UString value = p1->toString(exec) + p2->toString(exec); 1794 if (value.isNull()) 1795 return throwOutOfMemoryErrorToNumber(exec); 1796 return value.toDouble(); 1797 } 1798 1799 return p1->toNumber(exec) + p2->toNumber(exec); 1699 1800 } 1700 1801 … … 1717 1818 if (bothTypes == ((NumberType << 3) | NumberType)) 1718 1819 return jsNumber(v1->toNumber(exec) + v2->toNumber(exec)); 1719 elseif (bothTypes == ((StringType << 3) | StringType)) {1820 if (bothTypes == ((StringType << 3) | StringType)) { 1720 1821 UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value(); 1721 1822 if (value.isNull()) … … 1728 1829 } 1729 1830 1831 static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue *v2) 1832 { 1833 JSType t1 = v1->type(); 1834 JSType t2 = v2->type(); 1835 const unsigned bothTypes = (t1 << 3) | t2; 1836 1837 if (bothTypes == ((NumberType << 3) | NumberType)) 1838 return v1->toNumber(exec) + v2->toNumber(exec); 1839 if (bothTypes == ((StringType << 3) | StringType)) { 1840 UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value(); 1841 if (value.isNull()) 1842 return throwOutOfMemoryErrorToNumber(exec); 1843 return value.toDouble(); 1844 } 1845 1846 // All other cases are pretty uncommon 1847 return addSlowCaseToNumber(exec, v1, v2); 1848 } 1849 1730 1850 void AddNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack) 1731 1851 { … … 1746 1866 } 1747 1867 1868 double AddNode::evaluateToNumber(ExecState* exec) 1869 { 1870 JSValue *v1 = term1->evaluate(exec); 1871 KJS_CHECKEXCEPTIONNUMBER 1872 1873 JSValue *v2 = term2->evaluate(exec); 1874 KJS_CHECKEXCEPTIONNUMBER 1875 1876 return addToNumber(exec, v1, v2); 1877 } 1878 1748 1879 void SubNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack) 1749 1880 { … … 1753 1884 1754 1885 // ECMA 11.6.2 1755 JSValue *SubNode::evaluate(ExecState *exec) 1756 { 1757 JSValue *v1 = term1->evaluate(exec); 1758 KJS_CHECKEXCEPTIONVALUE 1759 1760 JSValue *v2 = term2->evaluate(exec); 1761 KJS_CHECKEXCEPTIONVALUE 1762 1763 return jsNumber(v1->toNumber(exec) - v2->toNumber(exec)); 1886 double SubNode::inlineEvaluateToNumber(ExecState* exec) 1887 { 1888 double n1 = term1->evaluateToNumber(exec); 1889 KJS_CHECKEXCEPTIONNUMBER 1890 1891 double n2 = term2->evaluateToNumber(exec); 1892 KJS_CHECKEXCEPTIONNUMBER 1893 1894 return n1 - n2; 1895 } 1896 1897 JSValue* SubNode::evaluate(ExecState* exec) 1898 { 1899 return jsNumber(inlineEvaluateToNumber(exec)); 1900 } 1901 1902 double SubNode::evaluateToNumber(ExecState* exec) 1903 { 1904 return inlineEvaluateToNumber(exec); 1764 1905 } 1765 1906 … … 2156 2297 // ECMA 11.13 2157 2298 2158 static ALWAYS_INLINE JSValue *valueForReadModifyAssignment(ExecState * exec, JSValue *v1, JSValue *v2, Operator oper) KJS_FAST_CALL;2159 static ALWAYS_INLINE JSValue *valueForReadModifyAssignment(ExecState * exec, JSValue *v1, JSValue *v2, Operator oper)2299 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, Node* right, Operator oper) KJS_FAST_CALL; 2300 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, Node* right, Operator oper) 2160 2301 { 2161 2302 JSValue *v; … … 2165 2306 switch (oper) { 2166 2307 case OpMultEq: 2167 v = jsNumber( v1->toNumber(exec) * v2->toNumber(exec));2308 v = jsNumber(current->toNumber(exec) * right->evaluateToNumber(exec)); 2168 2309 break; 2169 2310 case OpDivEq: 2170 v = jsNumber( v1->toNumber(exec) / v2->toNumber(exec));2311 v = jsNumber(current->toNumber(exec) / right->evaluateToNumber(exec)); 2171 2312 break; 2172 2313 case OpPlusEq: 2173 v = add(exec, v1, v2);2314 v = add(exec, current, right->evaluate(exec)); 2174 2315 break; 2175 2316 case OpMinusEq: 2176 v = jsNumber( v1->toNumber(exec) - v2->toNumber(exec));2317 v = jsNumber(current->toNumber(exec) - right->evaluateToNumber(exec)); 2177 2318 break; 2178 2319 case OpLShift: 2179 i1 = v1->toInt32(exec);2180 i2 = v2->toInt32(exec);2320 i1 = current->toInt32(exec); 2321 i2 = right->evaluate(exec)->toInt32(exec); 2181 2322 v = jsNumber(i1 << i2); 2182 2323 break; 2183 2324 case OpRShift: 2184 i1 = v1->toInt32(exec);2185 i2 = v2->toInt32(exec);2325 i1 = current->toInt32(exec); 2326 i2 = right->evaluate(exec)->toInt32(exec); 2186 2327 v = jsNumber(i1 >> i2); 2187 2328 break; 2188 2329 case OpURShift: 2189 ui = v1->toUInt32(exec);2190 i2 = v2->toInt32(exec);2330 ui = current->toUInt32(exec); 2331 i2 = right->evaluate(exec)->toInt32(exec); 2191 2332 v = jsNumber(ui >> i2); 2192 2333 break; 2193 2334 case OpAndEq: 2194 i1 = v1->toInt32(exec);2195 i2 = v2->toInt32(exec);2335 i1 = current->toInt32(exec); 2336 i2 = right->evaluate(exec)->toInt32(exec); 2196 2337 v = jsNumber(i1 & i2); 2197 2338 break; 2198 2339 case OpXOrEq: 2199 i1 = v1->toInt32(exec);2200 i2 = v2->toInt32(exec);2340 i1 = current->toInt32(exec); 2341 i2 = right->evaluate(exec)->toInt32(exec); 2201 2342 v = jsNumber(i1 ^ i2); 2202 2343 break; 2203 2344 case OpOrEq: 2204 i1 = v1->toInt32(exec);2205 i2 = v2->toInt32(exec);2345 i1 = current->toInt32(exec); 2346 i2 = right->evaluate(exec)->toInt32(exec); 2206 2347 v = jsNumber(i1 | i2); 2207 2348 break; 2208 2349 case OpModEq: { 2209 double d1 = v1->toNumber(exec);2210 double d2 = v2->toNumber(exec);2350 double d1 = current->toNumber(exec); 2351 double d2 = right->evaluateToNumber(exec); 2211 2352 v = jsNumber(fmod(d1, d2)); 2212 2353 } 2213 2354 break; 2214 2355 default: 2215 ASSERT (0);2356 ASSERT_NOT_REACHED(); 2216 2357 v = jsUndefined(); 2217 2358 } … … 2245 2386 2246 2387 ASSERT(m_oper != OpEqual); 2247 JSValue* v2 = m_right->evaluate(exec); 2248 JSValue* v = valueForReadModifyAssignment(exec, *slot, v2, m_oper); 2388 JSValue* v = valueForReadModifyAssignment(exec, *slot, m_right.get(), m_oper); 2249 2389 2250 2390 KJS_CHECKEXCEPTIONVALUE … … 2296 2436 JSValue *v1 = slot.getValue(exec, base, m_ident); 2297 2437 KJS_CHECKEXCEPTIONVALUE 2298 JSValue *v2 = m_right->evaluate(exec); 2299 v = valueForReadModifyAssignment(exec, v1, v2, m_oper); 2438 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper); 2300 2439 2301 2440 KJS_CHECKEXCEPTIONVALUE … … 2373 2512 JSValue *v1 = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined(); 2374 2513 KJS_CHECKEXCEPTIONVALUE 2375 JSValue *v2 = m_right->evaluate(exec); 2376 v = valueForReadModifyAssignment(exec, v1, v2, m_oper); 2514 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper); 2377 2515 2378 2516 KJS_CHECKEXCEPTIONVALUE … … 2448 2586 JSValue *v1 = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined(); 2449 2587 KJS_CHECKEXCEPTIONVALUE 2450 JSValue *v2 = m_right->evaluate(exec); 2451 v = valueForReadModifyAssignment(exec, v1, v2, m_oper); 2588 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper); 2452 2589 2453 2590 KJS_CHECKEXCEPTIONVALUE … … 2464 2601 JSValue *v1 = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined(); 2465 2602 KJS_CHECKEXCEPTIONVALUE 2466 JSValue *v2 = m_right->evaluate(exec); 2467 v = valueForReadModifyAssignment(exec, v1, v2, m_oper); 2603 v = valueForReadModifyAssignment(exec, v1, m_right.get(), m_oper); 2468 2604 2469 2605 KJS_CHECKEXCEPTIONVALUE -
trunk/JavaScriptCore/kjs/nodes.h
r27501 r27589 6 6 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) 7 7 * Copyright (C) 2007 Maks Orlovich 8 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 8 9 * 9 10 * This library is free software; you can redistribute it and/or … … 117 118 virtual ~Node(); 118 119 119 virtual JSValue *evaluate(ExecState *exec) KJS_FAST_CALL = 0; 120 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0; 121 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 120 122 UString toString() const KJS_FAST_CALL; 121 123 int lineNo() const KJS_FAST_CALL { return m_line; } … … 126 128 127 129 virtual bool isNumber() const KJS_FAST_CALL { return false; } 128 virtual bool isImmediateValue() const KJS_FAST_CALL { return false; }129 130 virtual bool isLocation() const KJS_FAST_CALL { return false; } 130 131 virtual bool isResolveNode() const KJS_FAST_CALL { return false; } … … 210 211 class NumberNode : public Node { 211 212 public: 212 NumberNode(double v) KJS_FAST_CALL : val(v) {} 213 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 213 NumberNode(double v) KJS_FAST_CALL : m_double(v) {} 214 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 215 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 214 216 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 215 217 virtual Precedence precedence() const { return PrecPrimary; } 216 218 217 219 virtual bool isNumber() const KJS_FAST_CALL { return true; } 218 double value() const KJS_FAST_CALL { return val; }219 v oid setValue(double v) KJS_FAST_CALL { val = v; }220 pr ivate:221 double val;220 double value() const KJS_FAST_CALL { return m_double; } 221 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; } 222 protected: 223 double m_double; 222 224 }; 223 225 224 class ImmediateNumberNode : public Node { 225 public: 226 ImmediateNumberNode(JSValue* v) KJS_FAST_CALL : m_value(v) {} 227 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 228 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 229 virtual Precedence precedence() const { return PrecPrimary; } 226 class ImmediateNumberNode : public NumberNode { 227 public: 228 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::fromDouble(d)); } 229 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 230 230 231 virtual bool isImmediateValue() const KJS_FAST_CALL { return true; } 232 double value() const KJS_FAST_CALL { return JSImmediate::toDouble(m_value); } 233 void setValue(double v) KJS_FAST_CALL { m_value = JSImmediate::fromDouble(v); ASSERT(m_value); } 231 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::fromDouble(d); ASSERT(m_value); } 234 232 private: 235 233 JSValue* m_value; … … 239 237 public: 240 238 StringNode(const UString *v) KJS_FAST_CALL { value = *v; } 241 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 239 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 240 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 242 241 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 243 242 virtual Precedence precedence() const { return PrecPrimary; } … … 304 303 } 305 304 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 305 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 306 private: 307 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 306 308 }; 307 309 … … 390 392 BracketAccessorNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {} 391 393 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 392 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 394 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 395 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 393 396 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 394 397 virtual Precedence precedence() const { return PrecMember; } … … 400 403 401 404 private: 405 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*); 402 406 RefPtr<Node> expr1; 403 407 RefPtr<Node> expr2; … … 950 954 NegateNode(Node *e) KJS_FAST_CALL : expr(e) {} 951 955 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 952 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 956 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 957 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 953 958 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 954 959 virtual Precedence precedence() const { return PrecUnary; } … … 983 988 MultNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {} 984 989 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 985 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 990 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 991 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 986 992 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 987 993 virtual Precedence precedence() const { return PrecMultiplicitave; } 988 994 private: 995 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 989 996 RefPtr<Node> term1; 990 997 RefPtr<Node> term2; … … 995 1002 DivNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {} 996 1003 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 997 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1004 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1005 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 998 1006 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 999 1007 virtual Precedence precedence() const { return PrecMultiplicitave; } 1000 1008 private: 1009 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1001 1010 RefPtr<Node> term1; 1002 1011 RefPtr<Node> term2; … … 1007 1016 ModNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {} 1008 1017 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 1009 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1018 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1019 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1010 1020 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1011 1021 virtual Precedence precedence() const { return PrecMultiplicitave; } 1012 1022 private: 1023 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1013 1024 RefPtr<Node> term1; 1014 1025 RefPtr<Node> term2; … … 1019 1030 AddNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {} 1020 1031 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 1021 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1022 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1023 virtual Precedence precedence() const { return PrecAdditive; } 1032 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1033 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1034 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1035 virtual Precedence precedence() const { return PrecAdditive; } 1024 1036 private: 1025 1037 RefPtr<Node> term1; … … 1031 1043 SubNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {} 1032 1044 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL; 1033 JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1045 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL; 1046 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL; 1034 1047 virtual void streamTo(SourceStream&) const KJS_FAST_CALL; 1035 1048 virtual Precedence precedence() const { return PrecAdditive; } 1036 1049 private: 1050 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*); 1037 1051 RefPtr<Node> term1; 1038 1052 RefPtr<Node> term2; -
trunk/JavaScriptCore/kjs/nodes2string.cpp
r27410 r27589 2 2 * Copyright (C) 2002 Harri Porten (porten@kde.org) 3 3 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2007 Eric Seidel <eric@webkit.org> 4 5 * 5 6 * This library is free software; you can redistribute it and/or … … 275 276 void NumberNode::streamTo(SourceStream& s) const 276 277 { 277 s << val;278 }279 280 void ImmediateNumberNode::streamTo(SourceStream& s) const281 {282 278 s << value(); 283 279 }
Note: See TracChangeset
for help on using the changeset viewer.