2007-11-12 Eric Seidel <eric@webkit.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2007 08:02:44 +0000 (08:02 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Nov 2007 08:02:44 +0000 (08:02 +0000)
        Reviewed by Oliver.

        Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
        Fix a few missing evaluateToBoolean methods
        Deploy all evaluateTo* functions to more nodes to avoid slowdowns
        http://bugs.webkit.org/show_bug.cgi?id=15950

        SunSpider claims this is at least a 1.4% speedup.

        * kjs/JSImmediate.h:
        (KJS::JSImmediate::getTruncatedInt32):
        (KJS::JSImmediate::toDouble):
        (KJS::JSImmediate::getUInt32):
        * kjs/nodes.cpp:
        (KJS::ExpressionNode::evaluateToNumber):
        (KJS::ExpressionNode::evaluateToInt32):
        (KJS::ExpressionNode::evaluateToUInt32):
        (KJS::NumberNode::evaluateToInt32):
        (KJS::NumberNode::evaluateToUInt32):
        (KJS::ImmediateNumberNode::evaluateToInt32):
        (KJS::ImmediateNumberNode::evaluateToUInt32):
        (KJS::ResolveNode::evaluate):
        (KJS::ResolveNode::evaluateToNumber):
        (KJS::ResolveNode::evaluateToBoolean):
        (KJS::ResolveNode::evaluateToInt32):
        (KJS::ResolveNode::evaluateToUInt32):
        (KJS::LocalVarAccessNode::evaluateToInt32):
        (KJS::LocalVarAccessNode::evaluateToUInt32):
        (KJS::BracketAccessorNode::evaluateToNumber):
        (KJS::BracketAccessorNode::evaluateToBoolean):
        (KJS::BracketAccessorNode::evaluateToInt32):
        (KJS::BracketAccessorNode::evaluateToUInt32):
        (KJS::DotAccessorNode::inlineEvaluate):
        (KJS::DotAccessorNode::evaluate):
        (KJS::DotAccessorNode::evaluateToNumber):
        (KJS::DotAccessorNode::evaluateToBoolean):
        (KJS::DotAccessorNode::evaluateToInt32):
        (KJS::DotAccessorNode::evaluateToUInt32):
        (KJS::NewExprNode::inlineEvaluate):
        (KJS::NewExprNode::evaluate):
        (KJS::NewExprNode::evaluateToNumber):
        (KJS::NewExprNode::evaluateToBoolean):
        (KJS::NewExprNode::evaluateToInt32):
        (KJS::NewExprNode::evaluateToUInt32):
        (KJS::FunctionCallResolveNode::inlineEvaluate):
        (KJS::FunctionCallResolveNode::evaluate):
        (KJS::FunctionCallResolveNode::evaluateToNumber):
        (KJS::FunctionCallResolveNode::evaluateToBoolean):
        (KJS::FunctionCallResolveNode::evaluateToInt32):
        (KJS::FunctionCallResolveNode::evaluateToUInt32):
        (KJS::LocalVarFunctionCallNode::evaluate):
        (KJS::LocalVarFunctionCallNode::evaluateToNumber):
        (KJS::LocalVarFunctionCallNode::evaluateToBoolean):
        (KJS::LocalVarFunctionCallNode::evaluateToInt32):
        (KJS::LocalVarFunctionCallNode::evaluateToUInt32):
        (KJS::FunctionCallDotNode::evaluate):
        (KJS::FunctionCallDotNode::evaluateToNumber):
        (KJS::FunctionCallDotNode::evaluateToBoolean):
        (KJS::FunctionCallDotNode::evaluateToInt32):
        (KJS::FunctionCallDotNode::evaluateToUInt32):
        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
        (KJS::PostDecLocalVarNode::evaluateToNumber):
        (KJS::PostDecLocalVarNode::evaluateToBoolean):
        (KJS::PostDecLocalVarNode::evaluateToInt32):
        (KJS::PostDecLocalVarNode::evaluateToUInt32):
        (KJS::typeStringForValue):
        (KJS::UnaryPlusNode::evaluate):
        (KJS::UnaryPlusNode::evaluateToBoolean):
        (KJS::UnaryPlusNode::evaluateToNumber):
        (KJS::UnaryPlusNode::evaluateToInt32):
        (KJS::BitwiseNotNode::inlineEvaluateToInt32):
        (KJS::BitwiseNotNode::evaluate):
        (KJS::BitwiseNotNode::evaluateToNumber):
        (KJS::BitwiseNotNode::evaluateToBoolean):
        (KJS::BitwiseNotNode::evaluateToInt32):
        (KJS::MultNode::evaluateToBoolean):
        (KJS::MultNode::evaluateToInt32):
        (KJS::MultNode::evaluateToUInt32):
        (KJS::DivNode::evaluateToInt32):
        (KJS::DivNode::evaluateToUInt32):
        (KJS::ModNode::evaluateToBoolean):
        (KJS::ModNode::evaluateToInt32):
        (KJS::ModNode::evaluateToUInt32):
        (KJS::AddNode::evaluateToNumber):
        (KJS::AddNode::evaluateToInt32):
        (KJS::AddNode::evaluateToUInt32):
        (KJS::AddNumbersNode::evaluateToInt32):
        (KJS::AddNumbersNode::evaluateToUInt32):
        (KJS::SubNode::evaluateToInt32):
        (KJS::SubNode::evaluateToUInt32):
        (KJS::LeftShiftNode::inlineEvaluateToInt32):
        (KJS::LeftShiftNode::evaluate):
        (KJS::LeftShiftNode::evaluateToNumber):
        (KJS::LeftShiftNode::evaluateToInt32):
        (KJS::RightShiftNode::inlineEvaluateToInt32):
        (KJS::RightShiftNode::evaluate):
        (KJS::RightShiftNode::evaluateToNumber):
        (KJS::RightShiftNode::evaluateToInt32):
        (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
        (KJS::UnsignedRightShiftNode::evaluate):
        (KJS::UnsignedRightShiftNode::evaluateToNumber):
        (KJS::UnsignedRightShiftNode::evaluateToInt32):
        (KJS::LessNode::inlineEvaluateToBoolean):
        (KJS::LessNode::evaluate):
        (KJS::LessNode::evaluateToBoolean):
        (KJS::LessNumbersNode::inlineEvaluateToBoolean):
        (KJS::LessNumbersNode::evaluate):
        (KJS::LessNumbersNode::evaluateToBoolean):
        (KJS::LessStringsNode::inlineEvaluateToBoolean):
        (KJS::LessStringsNode::evaluate):
        (KJS::BitAndNode::evaluate):
        (KJS::BitAndNode::inlineEvaluateToInt32):
        (KJS::BitAndNode::evaluateToNumber):
        (KJS::BitAndNode::evaluateToBoolean):
        (KJS::BitAndNode::evaluateToInt32):
        (KJS::BitXOrNode::inlineEvaluateToInt32):
        (KJS::BitXOrNode::evaluate):
        (KJS::BitXOrNode::evaluateToNumber):
        (KJS::BitXOrNode::evaluateToBoolean):
        (KJS::BitXOrNode::evaluateToInt32):
        (KJS::BitOrNode::inlineEvaluateToInt32):
        (KJS::BitOrNode::evaluate):
        (KJS::BitOrNode::evaluateToNumber):
        (KJS::BitOrNode::evaluateToBoolean):
        (KJS::BitOrNode::evaluateToInt32):
        (KJS::ConditionalNode::evaluateToNumber):
        (KJS::ConditionalNode::evaluateToInt32):
        (KJS::ConditionalNode::evaluateToUInt32):
        (KJS::valueForReadModifyAssignment):
        (KJS::AssignExprNode::evaluate):
        (KJS::AssignExprNode::evaluateToBoolean):
        (KJS::AssignExprNode::evaluateToNumber):
        (KJS::AssignExprNode::evaluateToInt32):
        (KJS::VarDeclNode::handleSlowCase):
        * kjs/nodes.h:
        (KJS::FunctionCallResolveNode::precedence):
        (KJS::AddNode::precedence):
        (KJS::AddNode::):
        (KJS::LessNumbersNode::):
        (KJS::LessStringsNode::):
        * kjs/value.cpp:
        (KJS::JSValue::toInt32SlowCase):
        (KJS::JSValue::toUInt32SlowCase):
        * kjs/value.h:
        (KJS::JSValue::asCell):
        (KJS::JSValue::toInt32):
        (KJS::JSValue::toUInt32):

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

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/JSImmediate.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/value.cpp
JavaScriptCore/kjs/value.h

index 3aca314e309b2d95e6f8cd0304a03eafd2c492c5..876b7299fb7866ad3aa75da1351cc74815338d75 100644 (file)
@@ -1,3 +1,153 @@
+2007-11-12  Eric Seidel  <eric@webkit.org>
+
+        Reviewed by Oliver.
+
+        Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
+        Fix a few missing evaluateToBoolean methods
+        Deploy all evaluateTo* functions to more nodes to avoid slowdowns
+        http://bugs.webkit.org/show_bug.cgi?id=15950
+        
+        SunSpider claims this is at least a 1.4% speedup.
+
+        * kjs/JSImmediate.h:
+        (KJS::JSImmediate::getTruncatedInt32):
+        (KJS::JSImmediate::toDouble):
+        (KJS::JSImmediate::getUInt32):
+        * kjs/nodes.cpp:
+        (KJS::ExpressionNode::evaluateToNumber):
+        (KJS::ExpressionNode::evaluateToInt32):
+        (KJS::ExpressionNode::evaluateToUInt32):
+        (KJS::NumberNode::evaluateToInt32):
+        (KJS::NumberNode::evaluateToUInt32):
+        (KJS::ImmediateNumberNode::evaluateToInt32):
+        (KJS::ImmediateNumberNode::evaluateToUInt32):
+        (KJS::ResolveNode::evaluate):
+        (KJS::ResolveNode::evaluateToNumber):
+        (KJS::ResolveNode::evaluateToBoolean):
+        (KJS::ResolveNode::evaluateToInt32):
+        (KJS::ResolveNode::evaluateToUInt32):
+        (KJS::LocalVarAccessNode::evaluateToInt32):
+        (KJS::LocalVarAccessNode::evaluateToUInt32):
+        (KJS::BracketAccessorNode::evaluateToNumber):
+        (KJS::BracketAccessorNode::evaluateToBoolean):
+        (KJS::BracketAccessorNode::evaluateToInt32):
+        (KJS::BracketAccessorNode::evaluateToUInt32):
+        (KJS::DotAccessorNode::inlineEvaluate):
+        (KJS::DotAccessorNode::evaluate):
+        (KJS::DotAccessorNode::evaluateToNumber):
+        (KJS::DotAccessorNode::evaluateToBoolean):
+        (KJS::DotAccessorNode::evaluateToInt32):
+        (KJS::DotAccessorNode::evaluateToUInt32):
+        (KJS::NewExprNode::inlineEvaluate):
+        (KJS::NewExprNode::evaluate):
+        (KJS::NewExprNode::evaluateToNumber):
+        (KJS::NewExprNode::evaluateToBoolean):
+        (KJS::NewExprNode::evaluateToInt32):
+        (KJS::NewExprNode::evaluateToUInt32):
+        (KJS::FunctionCallResolveNode::inlineEvaluate):
+        (KJS::FunctionCallResolveNode::evaluate):
+        (KJS::FunctionCallResolveNode::evaluateToNumber):
+        (KJS::FunctionCallResolveNode::evaluateToBoolean):
+        (KJS::FunctionCallResolveNode::evaluateToInt32):
+        (KJS::FunctionCallResolveNode::evaluateToUInt32):
+        (KJS::LocalVarFunctionCallNode::evaluate):
+        (KJS::LocalVarFunctionCallNode::evaluateToNumber):
+        (KJS::LocalVarFunctionCallNode::evaluateToBoolean):
+        (KJS::LocalVarFunctionCallNode::evaluateToInt32):
+        (KJS::LocalVarFunctionCallNode::evaluateToUInt32):
+        (KJS::FunctionCallDotNode::evaluate):
+        (KJS::FunctionCallDotNode::evaluateToNumber):
+        (KJS::FunctionCallDotNode::evaluateToBoolean):
+        (KJS::FunctionCallDotNode::evaluateToInt32):
+        (KJS::FunctionCallDotNode::evaluateToUInt32):
+        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
+        (KJS::PostDecLocalVarNode::evaluateToNumber):
+        (KJS::PostDecLocalVarNode::evaluateToBoolean):
+        (KJS::PostDecLocalVarNode::evaluateToInt32):
+        (KJS::PostDecLocalVarNode::evaluateToUInt32):
+        (KJS::typeStringForValue):
+        (KJS::UnaryPlusNode::evaluate):
+        (KJS::UnaryPlusNode::evaluateToBoolean):
+        (KJS::UnaryPlusNode::evaluateToNumber):
+        (KJS::UnaryPlusNode::evaluateToInt32):
+        (KJS::BitwiseNotNode::inlineEvaluateToInt32):
+        (KJS::BitwiseNotNode::evaluate):
+        (KJS::BitwiseNotNode::evaluateToNumber):
+        (KJS::BitwiseNotNode::evaluateToBoolean):
+        (KJS::BitwiseNotNode::evaluateToInt32):
+        (KJS::MultNode::evaluateToBoolean):
+        (KJS::MultNode::evaluateToInt32):
+        (KJS::MultNode::evaluateToUInt32):
+        (KJS::DivNode::evaluateToInt32):
+        (KJS::DivNode::evaluateToUInt32):
+        (KJS::ModNode::evaluateToBoolean):
+        (KJS::ModNode::evaluateToInt32):
+        (KJS::ModNode::evaluateToUInt32):
+        (KJS::AddNode::evaluateToNumber):
+        (KJS::AddNode::evaluateToInt32):
+        (KJS::AddNode::evaluateToUInt32):
+        (KJS::AddNumbersNode::evaluateToInt32):
+        (KJS::AddNumbersNode::evaluateToUInt32):
+        (KJS::SubNode::evaluateToInt32):
+        (KJS::SubNode::evaluateToUInt32):
+        (KJS::LeftShiftNode::inlineEvaluateToInt32):
+        (KJS::LeftShiftNode::evaluate):
+        (KJS::LeftShiftNode::evaluateToNumber):
+        (KJS::LeftShiftNode::evaluateToInt32):
+        (KJS::RightShiftNode::inlineEvaluateToInt32):
+        (KJS::RightShiftNode::evaluate):
+        (KJS::RightShiftNode::evaluateToNumber):
+        (KJS::RightShiftNode::evaluateToInt32):
+        (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
+        (KJS::UnsignedRightShiftNode::evaluate):
+        (KJS::UnsignedRightShiftNode::evaluateToNumber):
+        (KJS::UnsignedRightShiftNode::evaluateToInt32):
+        (KJS::LessNode::inlineEvaluateToBoolean):
+        (KJS::LessNode::evaluate):
+        (KJS::LessNode::evaluateToBoolean):
+        (KJS::LessNumbersNode::inlineEvaluateToBoolean):
+        (KJS::LessNumbersNode::evaluate):
+        (KJS::LessNumbersNode::evaluateToBoolean):
+        (KJS::LessStringsNode::inlineEvaluateToBoolean):
+        (KJS::LessStringsNode::evaluate):
+        (KJS::BitAndNode::evaluate):
+        (KJS::BitAndNode::inlineEvaluateToInt32):
+        (KJS::BitAndNode::evaluateToNumber):
+        (KJS::BitAndNode::evaluateToBoolean):
+        (KJS::BitAndNode::evaluateToInt32):
+        (KJS::BitXOrNode::inlineEvaluateToInt32):
+        (KJS::BitXOrNode::evaluate):
+        (KJS::BitXOrNode::evaluateToNumber):
+        (KJS::BitXOrNode::evaluateToBoolean):
+        (KJS::BitXOrNode::evaluateToInt32):
+        (KJS::BitOrNode::inlineEvaluateToInt32):
+        (KJS::BitOrNode::evaluate):
+        (KJS::BitOrNode::evaluateToNumber):
+        (KJS::BitOrNode::evaluateToBoolean):
+        (KJS::BitOrNode::evaluateToInt32):
+        (KJS::ConditionalNode::evaluateToNumber):
+        (KJS::ConditionalNode::evaluateToInt32):
+        (KJS::ConditionalNode::evaluateToUInt32):
+        (KJS::valueForReadModifyAssignment):
+        (KJS::AssignExprNode::evaluate):
+        (KJS::AssignExprNode::evaluateToBoolean):
+        (KJS::AssignExprNode::evaluateToNumber):
+        (KJS::AssignExprNode::evaluateToInt32):
+        (KJS::VarDeclNode::handleSlowCase):
+        * kjs/nodes.h:
+        (KJS::FunctionCallResolveNode::precedence):
+        (KJS::AddNode::precedence):
+        (KJS::AddNode::):
+        (KJS::LessNumbersNode::):
+        (KJS::LessStringsNode::):
+        * kjs/value.cpp:
+        (KJS::JSValue::toInt32SlowCase):
+        (KJS::JSValue::toUInt32SlowCase):
+        * kjs/value.h:
+        (KJS::JSValue::asCell):
+        (KJS::JSValue::toInt32):
+        (KJS::JSValue::toUInt32):
+
 2007-11-12  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index a71cb625422c93d87a5d49d0f3873a1262ec0596..dfcf2bc29af3222ad5b7b08a904c8abf1921a0f8 100644 (file)
@@ -116,6 +116,8 @@ public:
     static bool getTruncatedInt32(const JSValue*, int32_t&);
     static bool getTruncatedUInt32(const JSValue*, uint32_t&);
 
+    static int32_t getTruncatedInt32(const JSValue*);
+
     static JSValue* trueImmediate();
     static JSValue* falseImmediate();
     static JSValue* undefinedImmediate();
@@ -238,10 +240,15 @@ ALWAYS_INLINE JSValue* JSImmediate::from(double d)
     return tag(intVal << 2, NumberType);
 }
 
+ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(const JSValue* v)
+{
+    return static_cast<int32_t>(unTag(v)) >> 2;
+}
+
 ALWAYS_INLINE double JSImmediate::toDouble(const JSValue* v)
 {
     ASSERT(isImmediate(v));
-    const int32_t i = static_cast<int32_t>(unTag(v)) >> 2;
+    const int32_t i = getTruncatedInt32(v);
     if (JSImmediate::getTag(v) == UndefinedType && i)
         return std::numeric_limits<double>::quiet_NaN();
     return i;
@@ -249,14 +256,14 @@ ALWAYS_INLINE double JSImmediate::toDouble(const JSValue* v)
 
 ALWAYS_INLINE bool JSImmediate::getUInt32(const JSValue* v, uint32_t& i)
 {
-    const int32_t si = static_cast<int32_t>(unTag(v)) >> 2;
+    const int32_t si = getTruncatedInt32(v);
     i = si;
     return isNumber(v) & (si >= 0);
 }
 
 ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(const JSValue* v, int32_t& i)
 {
-    i = static_cast<int32_t>(unTag(v)) >> 2;
+    i = getTruncatedInt32(v);
     return isNumber(v);
 }
 
index e9f0d912eb6f944c97d0669b61be03f186b3d78a..d84b6260ba9af25a50989076140ea2ac04e582a2 100644 (file)
@@ -59,7 +59,7 @@ namespace KJS {
 #define KJS_CHECKEXCEPTIONNUMBER \
   if (exec->hadException()) { \
     handleException(exec); \
-    return 0.0; \
+    return 0; \
   }
 
 #define KJS_CHECKEXCEPTIONBOOLEAN \
@@ -227,7 +227,6 @@ double ExpressionNode::evaluateToNumber(ExecState* exec)
 {
     JSValue* value = evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
-    // No need to check exception after toNumber, caller will do so right after evaluateToNumber() call
     return value->toNumber(exec);
 }
 
@@ -238,6 +237,20 @@ bool ExpressionNode::evaluateToBoolean(ExecState* exec)
     return value->toBoolean(exec);
 }
 
+int32_t ExpressionNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* value = evaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return value->toInt32(exec);
+}
+
+uint32_t ExpressionNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* value = evaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return value->toUInt32(exec);
+}
+
 static void substitute(UString &string, const UString &substring) KJS_FAST_CALL;
 static void substitute(UString &string, const UString &substring)
 {
@@ -425,6 +438,16 @@ bool NumberNode::evaluateToBoolean(ExecState*)
     return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
 }
 
+int32_t NumberNode::evaluateToInt32(ExecState*)
+{
+    return JSValue::toInt32(m_double);
+}
+
+uint32_t NumberNode::evaluateToUInt32(ExecState*)
+{
+    return JSValue::toUInt32(m_double);
+}
+
 // ------------------------------ ImmediateNumberNode -----------------------------------
 
 JSValue* ImmediateNumberNode::evaluate(ExecState*)
@@ -432,6 +455,20 @@ JSValue* ImmediateNumberNode::evaluate(ExecState*)
     return m_value;
 }
 
+int32_t ImmediateNumberNode::evaluateToInt32(ExecState*)
+{
+    return JSImmediate::getTruncatedInt32(m_value);
+}
+
+uint32_t ImmediateNumberNode::evaluateToUInt32(ExecState*)
+{
+    uint32_t i;
+    if (JSImmediate::getTruncatedUInt32(m_value, i))
+        return i;
+    bool ok;
+    return JSValue::toUInt32SlowCase(m_double, ok);
+}
+
 // ------------------------------ StringNode -----------------------------------
 
 JSValue* StringNode::evaluate(ExecState*)
@@ -467,7 +504,7 @@ JSValue *ThisNode::evaluate(ExecState *exec)
 // ------------------------------ ResolveNode ----------------------------------
 
 // ECMA 11.1.2 & 10.1.4
-JSValue *ResolveNode::evaluate(ExecState *exec)
+JSValue* ResolveNode::inlineEvaluate(ExecState* exec)
 {
   // Check for missed optimization opportunity.
   ASSERT(!canSkipLookup(exec, ident));
@@ -492,6 +529,39 @@ JSValue *ResolveNode::evaluate(ExecState *exec)
   return throwUndefinedVariableError(exec, ident);
 }
 
+JSValue* ResolveNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
+}
+
+double ResolveNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool ResolveNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t ResolveNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t ResolveNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}
+
 void ResolveNode::optimizeVariableAccess(FunctionBodyNode* functionBody, DeclarationStacks::NodeStack&)
 {
     size_t index = functionBody->symbolTable().get(ident.ustring().rep());
@@ -521,6 +591,16 @@ bool LocalVarAccessNode::evaluateToBoolean(ExecState* exec)
     return inlineEvaluate(exec)->toBoolean(exec);
 }
 
+int32_t LocalVarAccessNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluate(exec)->toInt32(exec);
+}
+
+uint32_t LocalVarAccessNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluate(exec)->toUInt32(exec);
+}
+
 // ------------------------------ ElementNode ----------------------------------
 
 void ElementNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -672,14 +752,32 @@ JSValue* BracketAccessorNode::evaluate(ExecState* exec)
 
 double BracketAccessorNode::evaluateToNumber(ExecState* exec)
 {
-    return inlineEvaluate(exec)->toNumber(exec);
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
 }
 
 bool BracketAccessorNode::evaluateToBoolean(ExecState* exec)
 {
-    return inlineEvaluate(exec)->toBoolean(exec);
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
 }
 
+int32_t BracketAccessorNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t BracketAccessorNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}    
+
 // ------------------------------ DotAccessorNode --------------------------------
 
 void DotAccessorNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -688,14 +786,46 @@ void DotAccessorNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStack
 }
 
 // ECMA 11.2.1b
-JSValue *DotAccessorNode::evaluate(ExecState *exec)
+JSValue* DotAccessorNode::inlineEvaluate(ExecState* exec)
 {
-  JSValue *v = expr->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  return v->toObject(exec)->get(exec, ident);
+    JSValue* v = expr->evaluate(exec);
+    KJS_CHECKEXCEPTIONVALUE
+    return v->toObject(exec)->get(exec, ident);
+}
 
+JSValue* DotAccessorNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
 }
 
+double DotAccessorNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool DotAccessorNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t DotAccessorNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t DotAccessorNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}    
+
 // ------------------------------ ArgumentListNode -----------------------------
 
 void ArgumentListNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -735,9 +865,9 @@ void NewExprNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::N
 
 // ECMA 11.2.2
 
-JSValue *NewExprNode::evaluate(ExecState *exec)
+JSValue* NewExprNode::inlineEvaluate(ExecState* exec)
 {
-  JSValue *v = expr->evaluate(exec);
+  JSValuev = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
 
   List argList;
@@ -746,18 +876,49 @@ JSValue *NewExprNode::evaluate(ExecState *exec)
     KJS_CHECKEXCEPTIONVALUE
   }
 
-  if (!v->isObject()) {
+  if (!v->isObject())
     return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, expr.get());
-  }
 
   JSObject *constr = static_cast<JSObject*>(v);
-  if (!constr->implementsConstruct()) {
+  if (!constr->implementsConstruct())
     return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, expr.get());
-  }
 
   return constr->construct(exec, argList);
 }
 
+JSValue* NewExprNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
+}
+
+double NewExprNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool NewExprNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t NewExprNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t NewExprNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}    
+
 void FunctionCallValueNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
 {
     nodeStack.append(args.get());
@@ -799,7 +960,7 @@ void FunctionCallResolveNode::optimizeVariableAccess(FunctionBodyNode* functionB
 }
 
 // ECMA 11.2.3
-JSValue *FunctionCallResolveNode::evaluate(ExecState *exec)
+JSValue* FunctionCallResolveNode::inlineEvaluate(ExecState* exec)
 {
   // Check for missed optimization opportunity.
   ASSERT(!canSkipLookup(exec, ident));
@@ -819,15 +980,13 @@ JSValue *FunctionCallResolveNode::evaluate(ExecState *exec)
       JSValue *v = slot.getValue(exec, base, ident);
       KJS_CHECKEXCEPTIONVALUE
         
-      if (!v->isObject()) {
+      if (!v->isObject())
         return throwError(exec, TypeError, "Value %s (result of expression %s) is not object.", v, ident);
-      }
       
       JSObject *func = static_cast<JSObject*>(v);
       
-      if (!func->implementsCall()) {
+      if (!func->implementsCall())
         return throwError(exec, TypeError, "Object %s (result of expression %s) does not allow calls.", v, ident);
-      }
       
       List argList;
       args->evaluateList(exec, argList);
@@ -851,7 +1010,40 @@ JSValue *FunctionCallResolveNode::evaluate(ExecState *exec)
   return throwUndefinedVariableError(exec, ident);
 }
 
-JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
+JSValue* FunctionCallResolveNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
+}
+
+double FunctionCallResolveNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool FunctionCallResolveNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t FunctionCallResolveNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t FunctionCallResolveNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}
+
+JSValue* LocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
 {
     ASSERT(static_cast<ActivationImp*>(exec->variableObject())->isActivation());
     ASSERT(static_cast<ActivationImp*>(exec->variableObject()) == exec->scopeChain().top());
@@ -872,6 +1064,39 @@ JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
     return func->call(exec, exec->dynamicInterpreter()->globalObject(), argList);
 }
 
+JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
+}
+
+double LocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool LocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t LocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t LocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}
+
 void FunctionCallBracketNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
 {
     nodeStack.append(args.get());
@@ -948,7 +1173,7 @@ void FunctionCallDotNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationS
 }
 
 // ECMA 11.2.3
-JSValue *FunctionCallDotNode::evaluate(ExecState *exec)
+JSValue* FunctionCallDotNode::inlineEvaluate(ExecState* exec)
 {
   JSValue *baseVal = base->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
@@ -978,6 +1203,39 @@ JSValue *FunctionCallDotNode::evaluate(ExecState *exec)
   return func->call(exec, thisObj, argList);
 }
 
+JSValue* FunctionCallDotNode::evaluate(ExecState* exec)
+{
+    return inlineEvaluate(exec);
+}
+
+double FunctionCallDotNode::evaluateToNumber(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toNumber(exec);
+}
+
+bool FunctionCallDotNode::evaluateToBoolean(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return v->toBoolean(exec);
+}
+
+int32_t FunctionCallDotNode::evaluateToInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toInt32(exec);
+}
+
+uint32_t FunctionCallDotNode::evaluateToUInt32(ExecState* exec)
+{
+    JSValue* v = inlineEvaluate(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return v->toUInt32(exec);
+}
+
 // ECMA 11.3
 
 // ------------------------------ PostfixResolveNode ----------------------------------
@@ -1092,6 +1350,37 @@ JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
     return v;
 }
 
+double PostDecLocalVarNode::inlineEvaluateToNumber(ExecState* exec)
+{
+    ASSERT(static_cast<ActivationImp*>(exec->variableObject())->isActivation());
+    ASSERT(static_cast<ActivationImp*>(exec->variableObject()) == exec->scopeChain().top());
+    
+    JSValue** slot = &exec->localStorage()[m_index].value;
+    double n = (*slot)->toNumber(exec);
+    *slot = jsNumber(n - 1);
+    return n;
+}
+
+double PostDecLocalVarNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToNumber(exec);
+}
+
+bool PostDecLocalVarNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToNumber(exec);
+}
+
+int32_t PostDecLocalVarNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t PostDecLocalVarNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}
+
 void PostDecLocalVarNode::optimizeForUnnecessaryResult()
 {
     new (this) PreDecLocalVarNode(m_index);
@@ -1356,7 +1645,7 @@ static JSValue *typeStringForValue(JSValue *v)
             // Return "undefined" for objects that should be treated
             // as null when doing comparisons.
             if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
-                return jsString("undefined");            
+                return jsString("undefined");
             else if (static_cast<JSObject*>(v)->implementsCall())
                 return jsString("function");
         }
@@ -1647,10 +1936,29 @@ void UnaryPlusNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks:
 // ECMA 11.4.6
 JSValue* UnaryPlusNode::evaluate(ExecState* exec)
 {
-  JSValue *v = m_expr->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
+    JSValue *v = m_expr->evaluate(exec);
+    KJS_CHECKEXCEPTIONVALUE
+    return v->toJSNumber(exec);
+}
 
-  return v->toJSNumber(exec);
+bool UnaryPlusNode::evaluateToBoolean(ExecState* exec)
+{
+    return m_expr->evaluateToBoolean(exec);
+}
+
+double UnaryPlusNode::evaluateToNumber(ExecState* exec)
+{
+    return m_expr->evaluateToNumber(exec);
+}
+
+int32_t UnaryPlusNode::evaluateToInt32(ExecState* exec)
+{
+    return m_expr->evaluateToInt32(exec);
+}
+
+uint32_t UnaryPlusNode::evaluateToUInt32(ExecState* exec)
+{
+    return m_expr->evaluateToInt32(exec);
 }
 
 // ------------------------------ NegateNode -----------------------------------
@@ -1681,11 +1989,34 @@ void BitwiseNotNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks
 }
 
 // ECMA 11.4.8
-JSValue *BitwiseNotNode::evaluate(ExecState *exec)
+int32_t BitwiseNotNode::inlineEvaluateToInt32(ExecState* exec)
 {
-  JSValue *v = expr->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  return jsNumber(~v->toInt32(exec));
+    return ~expr->evaluateToInt32(exec);
+}
+
+JSValue* BitwiseNotNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToInt32(exec));
+}
+
+double BitwiseNotNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+bool BitwiseNotNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t BitwiseNotNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+uint32_t BitwiseNotNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 // ------------------------------ LogicalNotNode -------------------------------
@@ -1733,6 +2064,21 @@ double MultNode::evaluateToNumber(ExecState* exec)
     return inlineEvaluateToNumber(exec);
 }
 
+bool MultNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToNumber(exec);
+}
+
+int32_t MultNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t MultNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}
+
 void DivNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
 {
     nodeStack.append(term1.get());
@@ -1758,6 +2104,16 @@ double DivNode::evaluateToNumber(ExecState* exec)
     return inlineEvaluateToNumber(exec);
 }
 
+int32_t DivNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t DivNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}
+
 void ModNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
 {
     nodeStack.append(term1.get());
@@ -1783,6 +2139,21 @@ double ModNode::evaluateToNumber(ExecState* exec)
     return inlineEvaluateToNumber(exec);
 }
 
+bool ModNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToNumber(exec);
+}
+
+int32_t ModNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t ModNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}
+
 // ------------------------------ Additive Nodes --------------------------------------
 
 static JSValue* throwOutOfMemoryError(ExecState* exec)
@@ -1898,7 +2269,7 @@ JSValue* AddNode::evaluate(ExecState* exec)
   return add(exec, v1, v2);
 }
 
-double AddNode::evaluateToNumber(ExecState* exec)
+double AddNode::inlineEvaluateToNumber(ExecState* exec)
 {
     JSValue* v1 = term1->evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -1909,6 +2280,21 @@ double AddNode::evaluateToNumber(ExecState* exec)
     return addToNumber(exec, v1, v2);
 }
 
+double AddNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToNumber(exec);
+}
+
+int32_t AddNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t AddNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}    
+
 double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
 {
     double n1 = term1->evaluateToNumber(exec);
@@ -1927,6 +2313,16 @@ double AddNumbersNode::evaluateToNumber(ExecState* exec)
     return inlineEvaluateToNumber(exec);
 }
 
+int32_t AddNumbersNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t AddNumbersNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}
+
 JSValue* AddStringsNode::evaluate(ExecState* exec)
 {
     JSValue* v1 = term1->evaluate(exec);
@@ -1987,6 +2383,16 @@ double SubNode::evaluateToNumber(ExecState* exec)
     return inlineEvaluateToNumber(exec);
 }
 
+int32_t SubNode::evaluateToInt32(ExecState* exec)
+{
+    return JSValue::toInt32(inlineEvaluateToNumber(exec));
+}
+
+uint32_t SubNode::evaluateToUInt32(ExecState* exec)
+{
+    return JSValue::toUInt32(inlineEvaluateToNumber(exec));
+}    
+
 // ------------------------------ Shift Nodes ------------------------------------
 
 void LeftShiftNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -1996,16 +2402,32 @@ void LeftShiftNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks:
 }
 
 // ECMA 11.7.1
-JSValue *LeftShiftNode::evaluate(ExecState *exec)
+int32_t LeftShiftNode::inlineEvaluateToInt32(ExecState* exec)
 {
-  JSValue *v1 = term1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = term2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  unsigned int i2 = v2->toUInt32(exec);
-  i2 &= 0x1f;
+    int i1 = term1->evaluateToInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
+    return (i1 << i2);
+}
+
+JSValue* LeftShiftNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToInt32(exec));
+}
 
-  return jsNumber(v1->toInt32(exec) << i2);
+double LeftShiftNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t LeftShiftNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+uint32_t LeftShiftNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 void RightShiftNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -2015,16 +2437,32 @@ void RightShiftNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks
 }
 
 // ECMA 11.7.2
-JSValue *RightShiftNode::evaluate(ExecState *exec)
+int32_t RightShiftNode::inlineEvaluateToInt32(ExecState* exec)
 {
-  JSValue *v1 = term1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = term2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  unsigned int i2 = v2->toUInt32(exec);
-  i2 &= 0x1f;
+    int i1 = term1->evaluateToInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
+    return (i1 >> i2);
+}
+
+JSValue* RightShiftNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToInt32(exec));
+}
+
+double RightShiftNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t RightShiftNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
 
-  return jsNumber(v1->toInt32(exec) >> i2);
+uint32_t RightShiftNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 void UnsignedRightShiftNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -2034,16 +2472,32 @@ void UnsignedRightShiftNode::optimizeVariableAccess(FunctionBodyNode*, Declarati
 }
 
 // ECMA 11.7.3
-JSValue *UnsignedRightShiftNode::evaluate(ExecState *exec)
+uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(ExecState* exec)
 {
-  JSValue *v1 = term1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = term2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  unsigned int i2 = v2->toUInt32(exec);
-  i2 &= 0x1f;
+    unsigned int i1 = term1->evaluateToUInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    unsigned int i2 = term2->evaluateToUInt32(exec) & 0x1f;
+    return (i1 >> i2);
+}
 
-  return jsNumber(v1->toUInt32(exec) >> i2);
+JSValue* UnsignedRightShiftNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToUInt32(exec));
+}
+
+double UnsignedRightShiftNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToUInt32(exec);
+}
+
+int32_t UnsignedRightShiftNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToUInt32(exec);
+}
+
+uint32_t UnsignedRightShiftNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToUInt32(exec);
 }
 
 // ------------------------------ Relational Nodes -------------------------------
@@ -2085,38 +2539,59 @@ void LessNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::Node
 }
 
 // ECMA 11.8.1
-JSValue* LessNode::evaluate(ExecState* exec)
+bool LessNode::inlineEvaluateToBoolean(ExecState* exec)
 {
     JSValue* v1 = expr1->evaluate(exec);
-    KJS_CHECKEXCEPTIONVALUE
+    KJS_CHECKEXCEPTIONBOOLEAN
     JSValue* v2 = expr2->evaluate(exec);
-    KJS_CHECKEXCEPTIONVALUE
-    return jsBoolean(lessThan(exec, v1, v2));
+    KJS_CHECKEXCEPTIONBOOLEAN
+    return lessThan(exec, v1, v2);
+}
+
+JSValue* LessNode::evaluate(ExecState* exec)
+{
+    return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
 bool LessNode::evaluateToBoolean(ExecState* exec)
 {
-    JSValue* v1 = expr1->evaluate(exec);
-    KJS_CHECKEXCEPTIONBOOLEAN
-    JSValue* v2 = expr2->evaluate(exec);
-    KJS_CHECKEXCEPTIONBOOLEAN
-    return lessThan(exec, v1, v2);
+    return inlineEvaluateToBoolean(exec);
 }
 
-JSValue* LessNumbersNode::evaluate(ExecState* exec)
+bool LessNumbersNode::inlineEvaluateToBoolean(ExecState* exec)
 {
     double n1 = expr1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONVALUE
     double n2 = expr2->evaluateToNumber(exec);
-    return jsBoolean(n1 < n2);
+    return n1 < n2;
 }
 
-JSValue* LessStringsNode::evaluate(ExecState* exec)
+JSValue* LessNumbersNode::evaluate(ExecState* exec)
+{
+    return jsBoolean(inlineEvaluateToBoolean(exec));
+}
+
+bool LessNumbersNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToBoolean(exec);
+}
+
+bool LessStringsNode::inlineEvaluateToBoolean(ExecState* exec)
 {
     JSValue* v1 = expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
     JSValue* v2 = expr2->evaluate(exec);
-    return jsBoolean(static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value());
+    return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
+}
+
+JSValue* LessStringsNode::evaluate(ExecState* exec)
+{
+    return jsBoolean(inlineEvaluateToBoolean(exec));
+}
+
+bool LessStringsNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToBoolean(exec);
 }
 
 void GreaterNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -2399,14 +2874,42 @@ void BitAndNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::No
 }
 
 // ECMA 11.10
-JSValue *BitAndNode::evaluate(ExecState *exec)
+JSValue* BitAndNode::evaluate(ExecState* exec)
 {    
-  JSValue *v1 = expr1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = expr2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  
-  return jsNumberFromAnd(exec, v1, v2);
+    JSValue *v1 = expr1->evaluate(exec);
+    KJS_CHECKEXCEPTIONVALUE
+    JSValue *v2 = expr2->evaluate(exec);
+    KJS_CHECKEXCEPTIONVALUE
+
+    return jsNumberFromAnd(exec, v1, v2);
+}
+
+int32_t BitAndNode::inlineEvaluateToInt32(ExecState* exec)
+{
+    int32_t i1 = expr1->evaluateToInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    int32_t i2 = expr2->evaluateToInt32(exec);
+    return (i1 & i2);
+}
+
+double BitAndNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+bool BitAndNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t BitAndNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+uint32_t BitAndNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 void BitXOrNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -2415,14 +2918,37 @@ void BitXOrNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::No
     nodeStack.append(expr1.get());
 }
 
-JSValue *BitXOrNode::evaluate(ExecState *exec)
+int32_t BitXOrNode::inlineEvaluateToInt32(ExecState* exec)
 {
-  JSValue *v1 = expr1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = expr2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  
-  return jsNumber(v1->toInt32(exec) ^ v2->toInt32(exec));
+    int i1 = expr1->evaluateToInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    int i2 = expr2->evaluateToInt32(exec);
+    return (i1 ^ i2);
+}
+
+JSValue* BitXOrNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToInt32(exec));
+}
+
+double BitXOrNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+bool BitXOrNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t BitXOrNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+uint32_t BitXOrNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 void BitOrNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
@@ -2431,14 +2957,37 @@ void BitOrNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::Nod
     nodeStack.append(expr1.get());
 }
 
-JSValue *BitOrNode::evaluate(ExecState *exec)
+int32_t BitOrNode::inlineEvaluateToInt32(ExecState* exec)
 {
-  JSValue *v1 = expr1->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  JSValue *v2 = expr2->evaluate(exec);
-  KJS_CHECKEXCEPTIONVALUE
-  
-  return jsNumber(v1->toInt32(exec) | v2->toInt32(exec));
+    int i1 = expr1->evaluateToInt32(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    int i2 = expr2->evaluateToInt32(exec);
+    return (i1 | i2);
+}
+
+JSValue* BitOrNode::evaluate(ExecState* exec)
+{
+    return jsNumber(inlineEvaluateToInt32(exec));
+}
+
+double BitOrNode::evaluateToNumber(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+bool BitOrNode::evaluateToBoolean(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+int32_t BitOrNode::evaluateToInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
+}
+
+uint32_t BitOrNode::evaluateToUInt32(ExecState* exec)
+{
+    return inlineEvaluateToInt32(exec);
 }
 
 // ------------------------------ Binary Logical Nodes ----------------------------
@@ -2516,6 +3065,27 @@ bool ConditionalNode::evaluateToBoolean(ExecState* exec)
     return b ? expr1->evaluateToBoolean(exec) : expr2->evaluateToBoolean(exec);
 }
 
+double ConditionalNode::evaluateToNumber(ExecState* exec)
+{
+    bool b = logical->evaluateToBoolean(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return b ? expr1->evaluateToNumber(exec) : expr2->evaluateToNumber(exec);
+}
+
+int32_t ConditionalNode::evaluateToInt32(ExecState* exec)
+{
+    bool b = logical->evaluateToBoolean(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return b ? expr1->evaluateToInt32(exec) : expr2->evaluateToInt32(exec);
+}
+
+uint32_t ConditionalNode::evaluateToUInt32(ExecState* exec)
+{
+    bool b = logical->evaluateToBoolean(exec);
+    KJS_CHECKEXCEPTIONNUMBER
+    return b ? expr1->evaluateToUInt32(exec) : expr2->evaluateToUInt32(exec);
+}
+
 // ECMA 11.13
 
 static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
@@ -2540,32 +3110,32 @@ static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSVa
     break;
   case OpLShift:
     i1 = current->toInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(i1 << i2);
     break;
   case OpRShift:
     i1 = current->toInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(i1 >> i2);
     break;
   case OpURShift:
     ui = current->toUInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(ui >> i2);
     break;
   case OpAndEq:
     i1 = current->toInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(i1 & i2);
     break;
   case OpXOrEq:
     i1 = current->toInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(i1 ^ i2);
     break;
   case OpOrEq:
     i1 = current->toInt32(exec);
-    i2 = right->evaluate(exec)->toInt32(exec);
+    i2 = right->evaluateToInt32(exec);
     v = jsNumber(i1 | i2);
     break;
   case OpModEq: {
@@ -2854,9 +3424,29 @@ void AssignExprNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks
 }
 
 // ECMA 12.2
-JSValue *AssignExprNode::evaluate(ExecState *exec)
+JSValue* AssignExprNode::evaluate(ExecState* exec)
+{
+    return expr->evaluate(exec);
+}
+
+bool AssignExprNode::evaluateToBoolean(ExecState* exec)
+{
+    return expr->evaluateToBoolean(exec);
+}
+
+double AssignExprNode::evaluateToNumber(ExecState* exec)
+{
+    return expr->evaluateToNumber(exec);
+}
+
+int32_t AssignExprNode::evaluateToInt32(ExecState* exec)
+{
+    return expr->evaluateToInt32(exec);
+}
+
+uint32_t AssignExprNode::evaluateToUInt32(ExecState* exec)
 {
-  return expr->evaluate(exec);
+    return expr->evaluateToInt32(exec);
 }
 
 // ------------------------------ VarDeclNode ----------------------------------
@@ -2896,7 +3486,7 @@ void VarDeclNode::getDeclarations(DeclarationStacks& stacks)
 void VarDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
 {
     ScopeChainIterator iter = chain.begin();
-    ScopeChainIterator end = chain.end();        
+    ScopeChainIterator end = chain.end();
     
     // we must always have something in the scope chain
     ASSERT(iter != end);
index d60b7334232e2d2a4647f1459a697f756f0bece8..4cb38ee8d1b4b795413538d11f0a800b09e15ffc 100644 (file)
@@ -180,6 +180,8 @@ namespace KJS {
         
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
 
         // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
@@ -234,6 +236,8 @@ namespace KJS {
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -249,6 +253,8 @@ namespace KJS {
   public:
       ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::from(d)); }
       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+      virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+      virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
       
       virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
   private:
@@ -306,6 +312,10 @@ namespace KJS {
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
 
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -314,6 +324,7 @@ namespace KJS {
     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
 
   protected:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
     Identifier ident;
     size_t index; // Used by LocalVarAccessNode.
   };
@@ -330,6 +341,8 @@ namespace KJS {
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
   private:
     ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
   };
@@ -428,6 +441,8 @@ namespace KJS {
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecMember; }
 
@@ -447,6 +462,10 @@ namespace KJS {
     DotAccessorNode(ExpressionNode* e, const Identifier& s) KJS_FAST_CALL : expr(e), ident(s) { }
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecMember; }
 
@@ -456,6 +475,7 @@ namespace KJS {
     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
 
   private:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
     RefPtr<ExpressionNode> expr;
     Identifier ident;
   };
@@ -499,9 +519,14 @@ namespace KJS {
     NewExprNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecLeftHandSide; }
   private:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
     RefPtr<ExpressionNode> expr;
     RefPtr<ArgumentsNode> args;
   };
@@ -535,10 +560,15 @@ namespace KJS {
 
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecCall; }
 
   protected:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
     Identifier ident;
     RefPtr<ArgumentsNode> args;
     size_t index; // Used by LocalVarFunctionCallNode.
@@ -554,6 +584,12 @@ namespace KJS {
     }
 
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+  private:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
   };
 
   class FunctionCallBracketNode : public ExpressionNode {
@@ -574,9 +610,14 @@ namespace KJS {
     FunctionCallDotNode(ExpressionNode* b, const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecCall; }
-  protected:
+  private:
+    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
     RefPtr<ExpressionNode> base;
     Identifier ident;
     RefPtr<ArgumentsNode> args;
@@ -653,7 +694,13 @@ namespace KJS {
     }
 
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void optimizeForUnnecessaryResult();
+  private:
+    ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
   };
 
   class PostfixBracketNode : public ExpressionNode {
@@ -980,6 +1027,10 @@ namespace KJS {
     UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecUnary; }
   private:
@@ -1003,9 +1054,14 @@ namespace KJS {
     BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecUnary; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr;
   };
 
@@ -1027,6 +1083,9 @@ namespace KJS {
       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+      virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+      virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+      virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       virtual Precedence precedence() const { return PrecMultiplicitave; }
   private:
@@ -1041,6 +1100,8 @@ namespace KJS {
       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+      virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+      virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       virtual Precedence precedence() const { return PrecMultiplicitave; }
   private:
@@ -1055,6 +1116,9 @@ namespace KJS {
       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+      virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+      virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+      virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       virtual Precedence precedence() const { return PrecMultiplicitave; }
   private:
@@ -1069,12 +1133,16 @@ namespace KJS {
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecAdditive; }
   protected:
     AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
     RefPtr<ExpressionNode> term1;
     RefPtr<ExpressionNode> term2;
+  private:
+    ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
   };
 
     class AddNumbersNode : public AddNode {
@@ -1082,6 +1150,8 @@ namespace KJS {
         AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     private:
         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
     };
@@ -1110,6 +1180,8 @@ namespace KJS {
       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+      virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+      virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       virtual Precedence precedence() const { return PrecAdditive; }
   private:
@@ -1124,9 +1196,13 @@ namespace KJS {
       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecShift; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> term1;
     RefPtr<ExpressionNode> term2;
   };
@@ -1137,9 +1213,13 @@ namespace KJS {
       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecShift; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> term1;
     RefPtr<ExpressionNode> term2;
   };
@@ -1150,9 +1230,13 @@ namespace KJS {
       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecShift; }
   private:
+    ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
     RefPtr<ExpressionNode> term1;
     RefPtr<ExpressionNode> term2;
   };
@@ -1166,6 +1250,8 @@ namespace KJS {
     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecRelational; }
+  private:
+    ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
   protected:
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
@@ -1174,15 +1260,21 @@ namespace KJS {
     class LessNumbersNode : public LessNode {
     public:
         LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
-        : LessNode(e1, e2) {}
+            : LessNode(e1, e2) {}
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    private:
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
     };
 
     class LessStringsNode : public LessNode {
     public:
         LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
-        : LessNode(e1, e2) {}
+            : LessNode(e1, e2) {}
         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    private:
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
     };
 
   class GreaterNode : public ExpressionNode {
@@ -1317,9 +1409,14 @@ namespace KJS {
         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecBitwiseAnd; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
   };
@@ -1330,9 +1427,14 @@ namespace KJS {
         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecBitwiseOr; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
   };
@@ -1343,9 +1445,14 @@ namespace KJS {
         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecBitwiseXor; }
   private:
+    ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
   };
@@ -1363,6 +1470,7 @@ namespace KJS {
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecLogicalAnd; }
   private:
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
   };
@@ -1377,6 +1485,7 @@ namespace KJS {
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecLogicalOr; }
   private:
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
     RefPtr<ExpressionNode> expr1;
     RefPtr<ExpressionNode> expr2;
   };
@@ -1391,6 +1500,9 @@ namespace KJS {
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { return PrecConditional; }
   private:
@@ -1566,6 +1678,10 @@ namespace KJS {
     AssignExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+    virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
+    virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
   private:
index c0d083045992922c0ad06eaef1fb653e2f1cb34f..b854a28c6290d51155110f369b49f5b534f938c7 100644 (file)
@@ -72,11 +72,10 @@ double JSValue::toIntegerPreserveNaN(ExecState *exec) const
     return trunc(toNumber(exec));
 }
 
-int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
+int32_t JSValue::toInt32SlowCase(double d, bool& ok)
 {
     ok = true;
 
-    double d = toNumber(exec);
     if (d >= -D32 / 2 && d < D32 / 2)
         return static_cast<int32_t>(d);
 
@@ -93,11 +92,15 @@ int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
     return static_cast<int32_t>(d32);
 }
 
-uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
+int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
+{
+    return JSValue::toInt32SlowCase(toNumber(exec), ok);
+}
+
+uint32_t JSValue::toUInt32SlowCase(double d, bool& ok)
 {
     ok = true;
 
-    double d = toNumber(exec);
     if (d >= 0.0 && d < D32)
         return static_cast<uint32_t>(d);
 
@@ -112,6 +115,11 @@ uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
     return static_cast<uint32_t>(d32);
 }
 
+uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
+{
+    return JSValue::toUInt32SlowCase(toNumber(exec), ok);
+}
+
 float JSValue::toFloat(ExecState* exec) const
 {
     return static_cast<float>(toNumber(exec));
index c4c3aae6a9f420c4daccea0fc921f4d81ba9c731..5ebb5750d164556c57529ec6f079d3f57cecce43 100644 (file)
@@ -97,6 +97,10 @@ public:
     uint32_t toUInt32(ExecState*) const;
     uint32_t toUInt32(ExecState*, bool& ok) const;
 
+    // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)
+    static int32_t toInt32(double);
+    static int32_t toUInt32(double);
+
     // Floating point conversions.
     float toFloat(ExecState*) const;
 
@@ -104,6 +108,9 @@ public:
     void mark();
     bool marked() const;
 
+    static int32_t toInt32SlowCase(double, bool& ok);
+    static uint32_t toUInt32SlowCase(double, bool& ok);
+
 private:
     int32_t toInt32SlowCase(ExecState*, bool& ok) const;
     uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
@@ -288,16 +295,16 @@ inline void JSCell::mark()
     return Collector::markCell(this);
 }
 
-inline JSCell *JSValue::asCell()
+ALWAYS_INLINE JSCell* JSValue::asCell()
 {
     ASSERT(!JSImmediate::isImmediate(this));
-    return static_cast<JSCell *>(this);
+    return static_cast<JSCell*>(this);
 }
 
-inline const JSCell *JSValue::asCell() const
+ALWAYS_INLINE const JSCell* JSValue::asCell() const
 {
     ASSERT(!JSImmediate::isImmediate(this));
-    return static_cast<const JSCell *>(this);
+    return static_cast<const JSCell*>(this);
 }
 
 inline bool JSValue::isUndefined() const
@@ -473,6 +480,24 @@ inline uint32_t JSValue::toUInt32(ExecState* exec) const
     return toUInt32SlowCase(exec, ok);
 }
 
+inline int32_t JSValue::toInt32(double val)
+{
+    if (!(val >= -2147483648.0 && val < 2147483648.0)) {
+        bool ignored;
+        return toInt32SlowCase(val, ignored);
+    }
+    return static_cast<int32_t>(val);
+}
+
+inline int32_t JSValue::toUInt32(double val)
+{
+    if (!(val >= 0.0 && val < 4294967296.0)) {
+        bool ignored;
+        return toUInt32SlowCase(val, ignored);
+    }
+    return static_cast<uint32_t>(val);
+}
+
 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
 {
     int32_t i;