Changeset 27664 in webkit


Ignore:
Timestamp:
Nov 10, 2007, 10:29:17 AM (18 years ago)
Author:
Darin Adler
Message:

Reviewed by Sam.

Gives 1.1% on SunSpider.

  • kjs/grammar.y: Create TrueNode and FalseNode instead of BooleanNode.
  • kjs/nodes.h: Changed to use Noncopyable. Moved optimizeForUnnecessaryResult down from Node to ExpressionNode. Changed some classes to not inherit from ExpressionNode where not necessary, and removed unnneeded evaluate functions as well as evaluate functions that need not be virtual. Call the optimizeForUnnecessaryResult function on the start of a for loop too.
  • kjs/nodes.cpp: (KJS::ExpressionNode::evaluateToBoolean): Added. (KJS::FalseNode::evaluate): Added. (KJS::TrueNode::evaluate): Added. (KJS::NumberNode::evaluateToBoolean): Added. (KJS::StringNode::evaluateToBoolean): Added. (KJS::LocalVarAccessNode::evaluateToBoolean): Added. (KJS::BracketAccessorNode::evaluateToBoolean): Added. (KJS::LogicalNotNode::evaluate): Changed to call evaluateToBoolean. (KJS::LogicalNotNode::evaluateToBoolean): Added. (KJS::lessThan): Changed to return bool. (KJS::lessThanEq): Ditto. (KJS::LessNode::evaluate): Changed since lessThan returns bool. (KJS::LessNode::evaluateToBoolean): Added. (KJS::GreaterNode::evaluate): Changed since lessThanEq returns bool. (KJS::GreaterNode::evaluateToBoolean): Added. (KJS::LessEqNode::evaluate): Changed since lessThanEq returns bool. (KJS::LessEqNode::evaluateToBoolean): Added. (KJS::GreaterEqNode::evaluate): Changed since lessThan returns bool. (KJS::GreaterEqNode::evaluateToBoolean): Added. (KJS::InstanceOfNode::evaluateToBoolean): Added. (KJS::InNode::evaluateToBoolean): Added. (KJS::EqualNode::evaluateToBoolean): Added. (KJS::NotEqualNode::evaluateToBoolean): Added. (KJS::StrictEqualNode::evaluateToBoolean): Added. (KJS::NotStrictEqualNode::evaluateToBoolean): Added. (KJS::ConditionalNode::evaluate): Changed to call evaluateToBoolean. (KJS::IfNode::execute): Ditto. (KJS::DoWhileNode::execute): Ditto. (KJS::WhileNode::execute): Ditto. (KJS::ForNode::execute): Ditto.
  • kjs/nodes2string.cpp: (KJS::FalseNode::streamTo): Added. (KJS::TrueNode::streamTo): Added.
Location:
trunk/JavaScriptCore
Files:
3 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27648 r27664  
     12007-11-10  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Sam.
     4
     5        - http://bugs.webkit.org/show_bug.cgi?id=15915
     6          add an evaluation path for booleans like the one we have for numbers
     7
     8        Gives 1.1% on SunSpider.
     9
     10        * kjs/grammar.y: Create TrueNode and FalseNode instead of BooleanNode.
     11
     12        * kjs/nodes.h: Changed to use Noncopyable. Moved optimizeForUnnecessaryResult
     13        down from Node to ExpressionNode. Changed some classes to not inherit from
     14        ExpressionNode where not necessary, and removed unnneeded evaluate functions
     15        as well as evaluate functions that need not be virtual. Call the
     16        optimizeForUnnecessaryResult function on the start of a for loop too.
     17        * kjs/nodes.cpp:
     18        (KJS::ExpressionNode::evaluateToBoolean): Added.
     19        (KJS::FalseNode::evaluate): Added.
     20        (KJS::TrueNode::evaluate): Added.
     21        (KJS::NumberNode::evaluateToBoolean): Added.
     22        (KJS::StringNode::evaluateToBoolean): Added.
     23        (KJS::LocalVarAccessNode::evaluateToBoolean): Added.
     24        (KJS::BracketAccessorNode::evaluateToBoolean): Added.
     25        (KJS::LogicalNotNode::evaluate): Changed to call evaluateToBoolean.
     26        (KJS::LogicalNotNode::evaluateToBoolean): Added.
     27        (KJS::lessThan): Changed to return bool.
     28        (KJS::lessThanEq): Ditto.
     29        (KJS::LessNode::evaluate): Changed since lessThan returns bool.
     30        (KJS::LessNode::evaluateToBoolean): Added.
     31        (KJS::GreaterNode::evaluate): Changed since lessThanEq returns bool.
     32        (KJS::GreaterNode::evaluateToBoolean): Added.
     33        (KJS::LessEqNode::evaluate): Changed since lessThanEq returns bool.
     34        (KJS::LessEqNode::evaluateToBoolean): Added.
     35        (KJS::GreaterEqNode::evaluate): Changed since lessThan returns bool.
     36        (KJS::GreaterEqNode::evaluateToBoolean): Added.
     37        (KJS::InstanceOfNode::evaluateToBoolean): Added.
     38        (KJS::InNode::evaluateToBoolean): Added.
     39        (KJS::EqualNode::evaluateToBoolean): Added.
     40        (KJS::NotEqualNode::evaluateToBoolean): Added.
     41        (KJS::StrictEqualNode::evaluateToBoolean): Added.
     42        (KJS::NotStrictEqualNode::evaluateToBoolean): Added.
     43        (KJS::ConditionalNode::evaluate): Changed to call evaluateToBoolean.
     44        (KJS::IfNode::execute): Ditto.
     45        (KJS::DoWhileNode::execute): Ditto.
     46        (KJS::WhileNode::execute): Ditto.
     47        (KJS::ForNode::execute): Ditto.
     48
     49        * kjs/nodes2string.cpp:
     50        (KJS::FalseNode::streamTo): Added.
     51        (KJS::TrueNode::streamTo): Added.
     52
    1532007-11-09  Adam Roben  <aroben@apple.com>
    254
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r27420 r27664  
    568568                        >
    569569                        <File
    570                                 RelativePath="..\..\wtf\FastMallocPCRE.cpp"
    571                                 >
    572                         </File>
    573                         <File
    574                                 RelativePath="..\..\pcre\pcre-config.h"
    575                                 >
    576                         </File>
    577                         <File
    578570                                RelativePath="..\..\pcre\pcre.h"
    579571                                >
    580572                        </File>
    581573                        <File
    582                                 RelativePath="..\..\pcre\pcre_compile.c"
    583                                 >
    584                         </File>
    585                         <File
    586                                 RelativePath="..\..\pcre\pcre_exec.c"
     574                                RelativePath="..\..\pcre\pcre_compile.cpp"
     575                                >
     576                        </File>
     577                        <File
     578                                RelativePath="..\..\pcre\pcre_exec.cpp"
    587579                                >
    588580                        </File>
     
    592584                        </File>
    593585                        <File
    594                                 RelativePath="..\..\pcre\pcre_ord2utf8.c"
    595                                 >
    596                         </File>
    597                         <File
    598                                 RelativePath="..\..\pcre\pcre_tables.c"
    599                                 >
    600                         </File>
    601                         <File
    602                                 RelativePath="..\..\pcre\pcre_ucp_searchfuncs.c"
    603                                 >
    604                         </File>
    605                         <File
    606                                 RelativePath="..\..\pcre\pcre_xclass.c"
     586                                RelativePath="..\..\pcre\pcre_ord2utf8.cpp"
     587                                >
     588                        </File>
     589                        <File
     590                                RelativePath="..\..\pcre\pcre_tables.cpp"
     591                                >
     592                        </File>
     593                        <File
     594                                RelativePath="..\..\pcre\pcre_ucp_searchfuncs.cpp"
     595                                >
     596                        </File>
     597                        <File
     598                                RelativePath="..\..\pcre\pcre_xclass.cpp"
    607599                                >
    608600                        </File>
  • trunk/JavaScriptCore/JavaScriptCore.vcproj/dftables/dftables.vcproj

    r27061 r27664  
    100100        <Files>
    101101                <File
    102                         RelativePath="..\..\pcre\dftables.c"
     102                        RelativePath="..\..\pcre\dftables.cpp"
    103103                        >
    104104                </File>
  • trunk/JavaScriptCore/kjs/grammar.y

    r27637 r27664  
    207207
    208208Literal:
    209     NULLTOKEN                           { $$ = new NullNode(); }
    210   | TRUETOKEN                           { $$ = new BooleanNode(true); }
    211   | FALSETOKEN                          { $$ = new BooleanNode(false); }
     209    NULLTOKEN                           { $$ = new NullNode; }
     210  | TRUETOKEN                           { $$ = new TrueNode; }
     211  | FALSETOKEN                          { $$ = new FalseNode; }
    212212  | NUMBER                              { $$ = makeNumberNode($1); }
    213213  | STRING                              { $$ = new StringNode($1); }
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r27635 r27664  
    212212}
    213213
     214bool ExpressionNode::evaluateToBoolean(ExecState* exec)
     215{
     216    JSValue* value = evaluate(exec);
     217    if (exec->hadException()) {
     218        handleException(exec);
     219        return false;
     220    }
     221    return value->toBoolean(exec);
     222}
     223
    214224static void substitute(UString &string, const UString &substring) KJS_FAST_CALL;
    215225static void substitute(UString &string, const UString &substring)
     
    367377}
    368378
    369 // ------------------------------ BooleanNode ----------------------------------
    370 
    371 JSValue *BooleanNode::evaluate(ExecState *)
    372 {
    373   return jsBoolean(value);
     379// ------------------------------ FalseNode ----------------------------------
     380
     381JSValue* FalseNode::evaluate(ExecState*)
     382{
     383    return jsBoolean(false);
     384}
     385
     386// ------------------------------ TrueNode ----------------------------------
     387
     388JSValue* TrueNode::evaluate(ExecState*)
     389{
     390    return jsBoolean(true);
    374391}
    375392
     
    387404}
    388405
     406bool NumberNode::evaluateToBoolean(ExecState*)
     407{
     408    return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
     409}
     410
     411// ------------------------------ ImmediateNumberNode -----------------------------------
     412
    389413JSValue* ImmediateNumberNode::evaluate(ExecState*)
    390414{
     
    398422  return jsOwnedString(value);
    399423}
    400    
     424
    401425double StringNode::evaluateToNumber(ExecState*)
    402426{
    403427    return value.toDouble();
     428}
     429
     430bool StringNode::evaluateToBoolean(ExecState*)
     431{
     432    return !value.isEmpty();
    404433}
    405434   
     
    474503{
    475504    return inlineEvaluate(exec)->toNumber(exec);
     505}
     506
     507bool LocalVarAccessNode::evaluateToBoolean(ExecState* exec)
     508{
     509    return inlineEvaluate(exec)->toBoolean(exec);
    476510}
    477511
     
    630664}
    631665
     666bool BracketAccessorNode::evaluateToBoolean(ExecState* exec)
     667{
     668    return inlineEvaluate(exec)->toBoolean(exec);
     669}
     670
    632671// ------------------------------ DotAccessorNode --------------------------------
    633672
     
    654693    ASSERT(expr);
    655694    nodeStack.append(expr.get());
    656 }
    657 
    658 JSValue *ArgumentListNode::evaluate(ExecState *)
    659 {
    660   ASSERT(0);
    661   return 0; // dummy, see evaluateList()
    662695}
    663696
     
    678711    if (listNode)
    679712        nodeStack.append(listNode.get());
    680 }
    681 
    682 JSValue *ArgumentsNode::evaluate(ExecState *)
    683 {
    684   ASSERT(0);
    685   return 0; // dummy, see evaluateList()
    686713}
    687714
     
    16581685
    16591686// ECMA 11.4.9
    1660 JSValue *LogicalNotNode::evaluate(ExecState *exec)
    1661 {
    1662   JSValue *v = expr->evaluate(exec);
    1663   KJS_CHECKEXCEPTIONVALUE
    1664   return jsBoolean(!v->toBoolean(exec));
     1687JSValue* LogicalNotNode::evaluate(ExecState* exec)
     1688{
     1689    return jsBoolean(!expr->evaluateToBoolean(exec));
     1690}
     1691
     1692bool LogicalNotNode::evaluateToBoolean(ExecState* exec)
     1693{
     1694    return !expr->evaluateToBoolean(exec);
    16651695}
    16661696
     
    19661996// ------------------------------ Relational Nodes -------------------------------
    19671997
    1968 static inline JSValue* lessThan(ExecState *exec, JSValue* v1, JSValue* v2)
     1998static inline bool lessThan(ExecState *exec, JSValue* v1, JSValue* v2)
    19691999{
    19702000    double n1;
     
    19742004   
    19752005    if (wasNotString1 | wasNotString2)
    1976         return jsBoolean(n1 < n2);
    1977 
    1978     return jsBoolean(v1->toString(exec) < v2->toString(exec));
    1979 }
    1980 
    1981 static inline JSValue* lessThanEq(ExecState *exec, JSValue* v1, JSValue* v2)
     2006        return n1 < n2;
     2007
     2008    return v1->toString(exec) < v2->toString(exec);
     2009}
     2010
     2011static inline bool lessThanEq(ExecState *exec, JSValue* v1, JSValue* v2)
    19822012{
    19832013    double n1;
     
    19872017   
    19882018    if (wasNotString1 | wasNotString2)
    1989         return jsBoolean(n1 <= n2);
    1990 
    1991     return jsBoolean(!(v2->toString(exec) < v1->toString(exec)));
     2019        return n1 <= n2;
     2020
     2021    return !(v2->toString(exec) < v1->toString(exec));
    19922022}
    19932023
     
    19992029
    20002030// ECMA 11.8.1
    2001 JSValue *LessNode::evaluate(ExecState *exec)
    2002 {
    2003   JSValue *v1 = expr1->evaluate(exec);
    2004   KJS_CHECKEXCEPTIONVALUE
    2005   JSValue *v2 = expr2->evaluate(exec);
    2006   KJS_CHECKEXCEPTIONVALUE
    2007   return lessThan(exec, v1, v2);
     2031JSValue* LessNode::evaluate(ExecState* exec)
     2032{
     2033    JSValue* v1 = expr1->evaluate(exec);
     2034    KJS_CHECKEXCEPTIONVALUE
     2035    JSValue* v2 = expr2->evaluate(exec);
     2036    KJS_CHECKEXCEPTIONVALUE
     2037    return jsBoolean(lessThan(exec, v1, v2));
     2038}
     2039
     2040bool LessNode::evaluateToBoolean(ExecState* exec)
     2041{
     2042    JSValue* v1 = expr1->evaluate(exec);
     2043    if (exec->hadException()) {
     2044        handleException(exec);
     2045        return false;
     2046    }
     2047    JSValue* v2 = expr2->evaluate(exec);
     2048    if (exec->hadException()) {
     2049        handleException(exec);
     2050        return false;
     2051    }
     2052    return lessThan(exec, v1, v2);
    20082053}
    20092054
     
    20152060
    20162061// ECMA 11.8.2
    2017 JSValue *GreaterNode::evaluate(ExecState *exec)
    2018 {
    2019   JSValue *v1 = expr1->evaluate(exec);
    2020   KJS_CHECKEXCEPTIONVALUE
    2021   JSValue *v2 = expr2->evaluate(exec);
    2022   KJS_CHECKEXCEPTIONVALUE
    2023   return lessThan(exec, v2, v1);
     2062JSValue* GreaterNode::evaluate(ExecState* exec)
     2063{
     2064    JSValue* v1 = expr1->evaluate(exec);
     2065    KJS_CHECKEXCEPTIONVALUE
     2066    JSValue* v2 = expr2->evaluate(exec);
     2067    KJS_CHECKEXCEPTIONVALUE
     2068    return jsBoolean(lessThan(exec, v2, v1));
     2069}
     2070
     2071bool GreaterNode::evaluateToBoolean(ExecState *exec)
     2072{
     2073    JSValue* v1 = expr1->evaluate(exec);
     2074    if (exec->hadException()) {
     2075        handleException(exec);
     2076        return false;
     2077    }
     2078    JSValue* v2 = expr2->evaluate(exec);
     2079    if (exec->hadException()) {
     2080        handleException(exec);
     2081        return false;
     2082    }
     2083    return lessThan(exec, v2, v1);
    20242084}
    20252085
     
    20312091
    20322092// ECMA 11.8.3
    2033 JSValue *LessEqNode::evaluate(ExecState *exec)
    2034 {
    2035   JSValue *v1 = expr1->evaluate(exec);
    2036   KJS_CHECKEXCEPTIONVALUE
    2037   JSValue *v2 = expr2->evaluate(exec);
    2038   KJS_CHECKEXCEPTIONVALUE
    2039   return lessThanEq(exec, v1, v2);
     2093JSValue* LessEqNode::evaluate(ExecState* exec)
     2094{
     2095    JSValue* v1 = expr1->evaluate(exec);
     2096    KJS_CHECKEXCEPTIONVALUE
     2097    JSValue* v2 = expr2->evaluate(exec);
     2098    KJS_CHECKEXCEPTIONVALUE
     2099    return jsBoolean(lessThanEq(exec, v1, v2));
     2100}
     2101
     2102bool LessEqNode::evaluateToBoolean(ExecState* exec)
     2103{
     2104    JSValue* v1 = expr1->evaluate(exec);
     2105    if (exec->hadException()) {
     2106        handleException(exec);
     2107        return false;
     2108    }
     2109    JSValue* v2 = expr2->evaluate(exec);
     2110    if (exec->hadException()) {
     2111        handleException(exec);
     2112        return false;
     2113    }
     2114    return lessThanEq(exec, v1, v2);
    20402115}
    20412116
     
    20472122
    20482123// ECMA 11.8.4
    2049 JSValue *GreaterEqNode::evaluate(ExecState *exec)
    2050 {
    2051   JSValue *v1 = expr1->evaluate(exec);
    2052   KJS_CHECKEXCEPTIONVALUE
    2053   JSValue *v2 = expr2->evaluate(exec);
    2054   KJS_CHECKEXCEPTIONVALUE
    2055   return lessThanEq(exec, v2, v1);
     2124JSValue* GreaterEqNode::evaluate(ExecState* exec)
     2125{
     2126    JSValue* v1 = expr1->evaluate(exec);
     2127    KJS_CHECKEXCEPTIONVALUE
     2128    JSValue* v2 = expr2->evaluate(exec);
     2129    KJS_CHECKEXCEPTIONVALUE
     2130    return jsBoolean(lessThanEq(exec, v2, v1));
     2131}
     2132
     2133bool GreaterEqNode::evaluateToBoolean(ExecState* exec)
     2134{
     2135    JSValue* v1 = expr1->evaluate(exec);
     2136    if (exec->hadException()) {
     2137        handleException(exec);
     2138        return false;
     2139    }
     2140    JSValue* v2 = expr2->evaluate(exec);
     2141    if (exec->hadException()) {
     2142        handleException(exec);
     2143        return false;
     2144    }
     2145    return lessThanEq(exec, v2, v1);
    20562146}
    20572147
     
    20632153
    20642154// ECMA 11.8.6
    2065 JSValue *InstanceOfNode::evaluate(ExecState *exec)
    2066 {
    2067   JSValue *v1 = expr1->evaluate(exec);
    2068   KJS_CHECKEXCEPTIONVALUE
    2069   JSValue *v2 = expr2->evaluate(exec);
    2070   KJS_CHECKEXCEPTIONVALUE
    2071 
    2072   if (!v2->isObject())
    2073       return throwError(exec,  TypeError,
    2074                           "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
    2075 
    2076   JSObject *o2(static_cast<JSObject*>(v2));
    2077   if (!o2->implementsHasInstance())
    2078       // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
    2079       // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
    2080       // property. It seems that all object have the property, but not all implement it, so in this
    2081       // case we return false (consistent with mozilla)
    2082       return jsBoolean(false);
    2083   return jsBoolean(o2->hasInstance(exec, v1));
     2155JSValue* InstanceOfNode::evaluate(ExecState* exec)
     2156{
     2157    JSValue* v1 = expr1->evaluate(exec);
     2158    KJS_CHECKEXCEPTIONVALUE
     2159    JSValue* v2 = expr2->evaluate(exec);
     2160    KJS_CHECKEXCEPTIONVALUE
     2161
     2162    if (!v2->isObject())
     2163        return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with instanceof operator.", v2, expr2.get());
     2164
     2165    JSObject* o2 = static_cast<JSObject*>(v2);
     2166
     2167    // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
     2168    // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
     2169    // property. It seems that all objects have the property, but not all implement it, so in this
     2170    // case we return false (consistent with Mozilla).
     2171    if (!o2->implementsHasInstance())
     2172        return jsBoolean(false);
     2173
     2174    return jsBoolean(o2->hasInstance(exec, v1));
     2175}
     2176
     2177bool InstanceOfNode::evaluateToBoolean(ExecState* exec)
     2178{
     2179    JSValue* v1 = expr1->evaluate(exec);
     2180    if (exec->hadException()) {
     2181        handleException(exec);
     2182        return false;
     2183    }
     2184    JSValue* v2 = expr2->evaluate(exec);
     2185    if (exec->hadException()) {
     2186        handleException(exec);
     2187        return false;
     2188    }
     2189
     2190    if (!v2->isObject()) {
     2191        throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'instanceof' operator.", v2, expr2.get());
     2192        return false;
     2193    }
     2194
     2195    JSObject* o2 = static_cast<JSObject*>(v2);
     2196
     2197    // According to the spec, only some types of objects "implement" the [[HasInstance]] property.
     2198    // But we are supposed to throw an exception where the object does not "have" the [[HasInstance]]
     2199    // property. It seems that all objects have the property, but not all implement it, so in this
     2200    // case we return false (consistent with Mozilla).
     2201    if (!o2->implementsHasInstance())
     2202        return false;
     2203
     2204    return o2->hasInstance(exec, v1);
    20842205}
    20852206
     
    20912212
    20922213// ECMA 11.8.7
    2093 JSValue *InNode::evaluate(ExecState *exec)
    2094 {
    2095   JSValue *v1 = expr1->evaluate(exec);
    2096   KJS_CHECKEXCEPTIONVALUE
    2097   JSValue *v2 = expr2->evaluate(exec);
    2098   KJS_CHECKEXCEPTIONVALUE
    2099 
    2100   // Is all of this OK for host objects?
    2101   if (!v2->isObject())
    2102       return throwError(exec,  TypeError,
    2103                          "Value %s (result of expression %s) is not an object. Cannot be used with IN expression.", v2, expr2.get());
    2104   JSObject *o2(static_cast<JSObject*>(v2));
    2105   return jsBoolean(o2->hasProperty(exec, Identifier(v1->toString(exec))));
     2214JSValue* InNode::evaluate(ExecState *exec)
     2215{
     2216    JSValue* v1 = expr1->evaluate(exec);
     2217    KJS_CHECKEXCEPTIONVALUE
     2218    JSValue* v2 = expr2->evaluate(exec);
     2219    KJS_CHECKEXCEPTIONVALUE
     2220
     2221    if (!v2->isObject())
     2222        return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, expr2.get());
     2223
     2224    return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
     2225}
     2226
     2227bool InNode::evaluateToBoolean(ExecState *exec)
     2228{
     2229    JSValue* v1 = expr1->evaluate(exec);
     2230    if (exec->hadException()) {
     2231        handleException(exec);
     2232        return false;
     2233    }
     2234    JSValue* v2 = expr2->evaluate(exec);
     2235    if (exec->hadException()) {
     2236        handleException(exec);
     2237        return false;
     2238    }
     2239
     2240    if (!v2->isObject())
     2241        return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with 'in' operator.", v2, expr2.get());
     2242
     2243    return static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec)));
    21062244}
    21072245
     
    21152253
    21162254// ECMA 11.9.1
    2117 JSValue *EqualNode::evaluate(ExecState *exec)
    2118 {
    2119   JSValue *v1 = expr1->evaluate(exec);
    2120   KJS_CHECKEXCEPTIONVALUE
    2121   JSValue *v2 = expr2->evaluate(exec);
    2122   KJS_CHECKEXCEPTIONVALUE
    2123 
    2124   return jsBoolean(equal(exec,v1, v2));
     2255JSValue* EqualNode::evaluate(ExecState* exec)
     2256{
     2257    JSValue* v1 = expr1->evaluate(exec);
     2258    KJS_CHECKEXCEPTIONVALUE
     2259    JSValue* v2 = expr2->evaluate(exec);
     2260    KJS_CHECKEXCEPTIONVALUE
     2261
     2262    return jsBoolean(equal(exec, v1, v2));
     2263}
     2264
     2265bool EqualNode::evaluateToBoolean(ExecState* exec)
     2266{
     2267    JSValue* v1 = expr1->evaluate(exec);
     2268    if (exec->hadException()) {
     2269        handleException(exec);
     2270        return false;
     2271    }
     2272    JSValue* v2 = expr2->evaluate(exec);
     2273    if (exec->hadException()) {
     2274        handleException(exec);
     2275        return false;
     2276    }
     2277
     2278    return equal(exec, v1, v2);
    21252279}
    21262280
     
    21322286
    21332287// ECMA 11.9.2
    2134 JSValue *NotEqualNode::evaluate(ExecState *exec)
    2135 {
    2136   JSValue *v1 = expr1->evaluate(exec);
    2137   KJS_CHECKEXCEPTIONVALUE
    2138   JSValue *v2 = expr2->evaluate(exec);
    2139   KJS_CHECKEXCEPTIONVALUE
    2140 
    2141   return jsBoolean(!equal(exec,v1, v2));
     2288JSValue* NotEqualNode::evaluate(ExecState* exec)
     2289{
     2290    JSValue* v1 = expr1->evaluate(exec);
     2291    KJS_CHECKEXCEPTIONVALUE
     2292    JSValue* v2 = expr2->evaluate(exec);
     2293    KJS_CHECKEXCEPTIONVALUE
     2294
     2295    return jsBoolean(!equal(exec,v1, v2));
     2296}
     2297
     2298bool NotEqualNode::evaluateToBoolean(ExecState* exec)
     2299{
     2300    JSValue* v1 = expr1->evaluate(exec);
     2301    if (exec->hadException()) {
     2302        handleException(exec);
     2303        return false;
     2304    }
     2305    JSValue* v2 = expr2->evaluate(exec);
     2306    if (exec->hadException()) {
     2307        handleException(exec);
     2308        return false;
     2309    }
     2310
     2311    return !equal(exec,v1, v2);
    21422312}
    21432313
     
    21492319
    21502320// ECMA 11.9.4
    2151 JSValue *StrictEqualNode::evaluate(ExecState *exec)
    2152 {
    2153   JSValue *v1 = expr1->evaluate(exec);
    2154   KJS_CHECKEXCEPTIONVALUE
    2155   JSValue *v2 = expr2->evaluate(exec);
    2156   KJS_CHECKEXCEPTIONVALUE
    2157 
    2158   return jsBoolean(strictEqual(exec,v1, v2));
     2321JSValue* StrictEqualNode::evaluate(ExecState* exec)
     2322{
     2323    JSValue* v1 = expr1->evaluate(exec);
     2324    KJS_CHECKEXCEPTIONVALUE
     2325    JSValue* v2 = expr2->evaluate(exec);
     2326    KJS_CHECKEXCEPTIONVALUE
     2327
     2328    return jsBoolean(strictEqual(exec,v1, v2));
     2329}
     2330
     2331bool StrictEqualNode::evaluateToBoolean(ExecState* exec)
     2332{
     2333    JSValue* v1 = expr1->evaluate(exec);
     2334    if (exec->hadException()) {
     2335        handleException(exec);
     2336        return false;
     2337    }
     2338    JSValue* v2 = expr2->evaluate(exec);
     2339    if (exec->hadException()) {
     2340        handleException(exec);
     2341        return false;
     2342    }
     2343
     2344    return strictEqual(exec,v1, v2);
    21592345}
    21602346
     
    21662352
    21672353// ECMA 11.9.5
    2168 JSValue *NotStrictEqualNode::evaluate(ExecState *exec)
    2169 {
    2170   JSValue *v1 = expr1->evaluate(exec);
    2171   KJS_CHECKEXCEPTIONVALUE
    2172   JSValue *v2 = expr2->evaluate(exec);
    2173   KJS_CHECKEXCEPTIONVALUE
    2174 
    2175   return jsBoolean(!strictEqual(exec,v1, v2));
     2354JSValue* NotStrictEqualNode::evaluate(ExecState* exec)
     2355{
     2356    JSValue* v1 = expr1->evaluate(exec);
     2357    KJS_CHECKEXCEPTIONVALUE
     2358    JSValue* v2 = expr2->evaluate(exec);
     2359    KJS_CHECKEXCEPTIONVALUE
     2360
     2361    return jsBoolean(!strictEqual(exec,v1, v2));
     2362}
     2363
     2364bool NotStrictEqualNode::evaluateToBoolean(ExecState* exec)
     2365{
     2366    JSValue* v1 = expr1->evaluate(exec);
     2367    if (exec->hadException()) {
     2368        handleException(exec);
     2369        return false;
     2370    }
     2371    JSValue* v2 = expr2->evaluate(exec);
     2372    if (exec->hadException()) {
     2373        handleException(exec);
     2374        return false;
     2375    }
     2376
     2377    return !strictEqual(exec,v1, v2);
    21762378}
    21772379
     
    22362438
    22372439// ECMA 11.11
    2238 JSValue *LogicalAndNode::evaluate(ExecState *exec)
    2239 {
    2240   JSValue *v1 = expr1->evaluate(exec);
    2241   KJS_CHECKEXCEPTIONVALUE
    2242   bool b1 = v1->toBoolean(exec);
    2243   if (!b1)
    2244     return v1;
    2245 
    2246   JSValue *v2 = expr2->evaluate(exec);
    2247   KJS_CHECKEXCEPTIONVALUE
    2248 
    2249   return v2;
     2440JSValue* LogicalAndNode::evaluate(ExecState* exec)
     2441{
     2442    JSValue* v1 = expr1->evaluate(exec);
     2443    KJS_CHECKEXCEPTIONVALUE
     2444    bool b1 = v1->toBoolean(exec);
     2445    KJS_CHECKEXCEPTIONVALUE
     2446    if (!b1)
     2447        return v1;
     2448    JSValue* v2 = expr2->evaluate(exec);
     2449    KJS_CHECKEXCEPTIONVALUE
     2450    return v2;
     2451}
     2452
     2453bool LogicalAndNode::evaluateToBoolean(ExecState* exec)
     2454{
     2455    bool b = expr1->evaluateToBoolean(exec);
     2456    if (exec->hadException()) {
     2457        handleException(exec);
     2458        return false;
     2459    }
     2460    return b && expr2->evaluateToBoolean(exec);
    22502461}
    22512462
     
    22562467}
    22572468
    2258 JSValue *LogicalOrNode::evaluate(ExecState *exec)
    2259 {
    2260   JSValue *v1 = expr1->evaluate(exec);
    2261   KJS_CHECKEXCEPTIONVALUE
    2262   bool b1 = v1->toBoolean(exec);
    2263   if (b1)
    2264     return v1;
    2265 
    2266   JSValue *v2 = expr2->evaluate(exec);
    2267   KJS_CHECKEXCEPTIONVALUE
    2268 
    2269   return v2;
     2469JSValue* LogicalOrNode::evaluate(ExecState* exec)
     2470{
     2471    JSValue* v1 = expr1->evaluate(exec);
     2472    KJS_CHECKEXCEPTIONVALUE
     2473    if (v1->toBoolean(exec))
     2474        return v1;
     2475    return expr2->evaluate(exec);
     2476}
     2477
     2478bool LogicalOrNode::evaluateToBoolean(ExecState* exec)
     2479{
     2480    bool b = expr1->evaluateToBoolean(exec);
     2481    if (exec->hadException()) {
     2482        handleException(exec);
     2483        return false;
     2484    }
     2485    return b || expr2->evaluateToBoolean(exec);
    22702486}
    22712487
     
    22802496
    22812497// ECMA 11.12
    2282 JSValue *ConditionalNode::evaluate(ExecState *exec)
    2283 {
    2284   JSValue *v = logical->evaluate(exec);
    2285   KJS_CHECKEXCEPTIONVALUE
    2286   bool b = v->toBoolean(exec);
    2287 
    2288   if (b)
    2289     v = expr1->evaluate(exec);
    2290   else
    2291     v = expr2->evaluate(exec);
    2292   KJS_CHECKEXCEPTIONVALUE
    2293 
    2294   return v;
     2498JSValue* ConditionalNode::evaluate(ExecState* exec)
     2499{
     2500    bool b = logical->evaluateToBoolean(exec);
     2501    KJS_CHECKEXCEPTIONVALUE
     2502    return b ? expr1->evaluate(exec) : expr2->evaluate(exec);
     2503}
     2504
     2505bool ConditionalNode::evaluateToBoolean(ExecState* exec)
     2506{
     2507    bool b = logical->evaluateToBoolean(exec);
     2508    if (exec->hadException()) {
     2509        handleException(exec);
     2510        return false;
     2511    }
     2512    return b ? expr1->evaluateToBoolean(exec) : expr2->evaluateToBoolean(exec);
    22952513}
    22962514
     
    26182836
    26192837// ECMA 11.14
    2620 JSValue *CommaNode::evaluate(ExecState *exec)
    2621 {
    2622   expr1->evaluate(exec);
    2623   KJS_CHECKEXCEPTIONVALUE
    2624   JSValue *v = expr2->evaluate(exec);
    2625   KJS_CHECKEXCEPTIONVALUE
    2626 
    2627   return v;
     2838JSValue* CommaNode::evaluate(ExecState *exec)
     2839{
     2840    expr1->evaluate(exec);
     2841    KJS_CHECKEXCEPTIONVALUE
     2842    return expr2->evaluate(exec);
    26282843}
    26292844
     
    29033118
    29043119// ECMA 12.5
    2905 Completion IfNode::execute(ExecState *exec)
    2906 {
    2907   KJS_BREAKPOINT;
    2908 
    2909   JSValue *v = expr->evaluate(exec);
    2910   KJS_CHECKEXCEPTION
    2911   bool b = v->toBoolean(exec);
    2912 
    2913   // if ... then
    2914   if (b)
    2915     return statement1->execute(exec);
    2916 
    2917   // no else
    2918   if (!statement2)
    2919     return Completion(Normal);
    2920 
    2921   // else
    2922   return statement2->execute(exec);
     3120Completion IfNode::execute(ExecState* exec)
     3121{
     3122    KJS_BREAKPOINT;
     3123
     3124    bool b = expr->evaluateToBoolean(exec);
     3125    KJS_CHECKEXCEPTION
     3126
     3127    // if ... then
     3128    if (b)
     3129        return statement1->execute(exec);
     3130
     3131    // no else
     3132    if (!statement2)
     3133        return Completion(Normal);
     3134
     3135    // else
     3136    return statement2->execute(exec);
    29233137}
    29243138
     
    29423156Completion DoWhileNode::execute(ExecState *exec)
    29433157{
    2944   KJS_BREAKPOINT;
    2945 
    2946   JSValue *bv;
    2947   Completion c;
    2948   JSValue* value = 0;
    2949 
    2950   do {
    2951     exec->pushIteration();
    2952     c = statement->execute(exec);
    2953     exec->popIteration();
    2954    
    2955     if (exec->dynamicInterpreter()->timedOut())
    2956         return Completion(Interrupted);
    2957 
    2958     if (c.isValueCompletion())
    2959         value = c.value();
    2960 
    2961     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    2962       if ((c.complType() == Break) && ls.contains(c.target()))
    2963         return Completion(Normal, value);
    2964       if (c.complType() != Normal)
    2965         return c;
    2966     }
    2967     bv = expr->evaluate(exec);
    2968     KJS_CHECKEXCEPTION
    2969   } while (bv->toBoolean(exec));
    2970 
    2971   return Completion(Normal, value);
     3158    KJS_BREAKPOINT;
     3159
     3160    JSValue* value = 0;
     3161
     3162    while (1) {
     3163        exec->pushIteration();
     3164        Completion c = statement->execute(exec);
     3165        exec->popIteration();
     3166
     3167        if (exec->dynamicInterpreter()->timedOut())
     3168            return Completion(Interrupted);
     3169
     3170        if (c.isValueCompletion())
     3171            value = c.value();
     3172
     3173        if (!((c.complType() == Continue) && ls.contains(c.target()))) {
     3174            if ((c.complType() == Break) && ls.contains(c.target()))
     3175                return Completion(Normal, value);
     3176            if (c.complType() != Normal)
     3177                return c;
     3178        }
     3179
     3180        bool b = expr->evaluateToBoolean(exec);
     3181        KJS_CHECKEXCEPTION
     3182        if (!b)
     3183            return Completion(Normal, value);
     3184    }
     3185
     3186    return Completion(); // work around gcc 4.0 bug
    29723187}
    29733188
     
    29893204Completion WhileNode::execute(ExecState *exec)
    29903205{
    2991   KJS_BREAKPOINT;
    2992 
    2993   JSValue *bv;
    2994   Completion c;
    2995   bool b(false);
    2996   JSValue *value = 0;
    2997 
    2998   while (1) {
    2999     bv = expr->evaluate(exec);
    3000     KJS_CHECKEXCEPTION
    3001     b = bv->toBoolean(exec);
    3002 
    3003     if (!b)
    3004       return Completion(Normal, value);
    3005 
    3006     exec->pushIteration();
    3007     c = statement->execute(exec);
    3008     exec->popIteration();
    3009 
    3010     if (exec->dynamicInterpreter()->timedOut())
    3011         return Completion(Interrupted);
    3012    
    3013     if (c.isValueCompletion())
    3014       value = c.value();
    3015 
    3016     if ((c.complType() == Continue) && ls.contains(c.target()))
    3017       continue;
    3018     if ((c.complType() == Break) && ls.contains(c.target()))
    3019       return Completion(Normal, value);
    3020     if (c.complType() != Normal)
    3021       return c;
    3022   }
    3023 
    3024   return Completion(); // work around gcc 4.0 bug
     3206    KJS_BREAKPOINT;
     3207
     3208    JSValue* value = 0;
     3209
     3210    while (1) {
     3211        bool b = expr->evaluateToBoolean(exec);
     3212        KJS_CHECKEXCEPTION
     3213        if (!b)
     3214            return Completion(Normal, value);
     3215
     3216        exec->pushIteration();
     3217        Completion c = statement->execute(exec);
     3218        exec->popIteration();
     3219
     3220        if (exec->dynamicInterpreter()->timedOut())
     3221            return Completion(Interrupted);
     3222   
     3223        if (c.isValueCompletion())
     3224            value = c.value();
     3225
     3226        if ((c.complType() == Continue) && ls.contains(c.target()))
     3227            continue;
     3228        if ((c.complType() == Break) && ls.contains(c.target()))
     3229            return Completion(Normal, value);
     3230        if (c.complType() != Normal)
     3231            return c;
     3232    }
     3233
     3234    return Completion(); // work around gcc 4.0 bug
    30253235}
    30263236
     
    30473257Completion ForNode::execute(ExecState *exec)
    30483258{
    3049   JSValue *v, *cval = 0;
    3050 
    3051   if (expr1) {
    3052     v = expr1->evaluate(exec);
    3053     KJS_CHECKEXCEPTION
    3054   }
    3055   while (1) {
    3056     if (expr2) {
    3057       v = expr2->evaluate(exec);
    3058       KJS_CHECKEXCEPTION
    3059       if (!v->toBoolean(exec))
    3060         return Completion(Normal, cval);
    3061     }
    3062 
    3063     exec->pushIteration();
    3064     Completion c = statement->execute(exec);
    3065     exec->popIteration();
    3066     if (c.isValueCompletion())
    3067       cval = c.value();
    3068     if (!((c.complType() == Continue) && ls.contains(c.target()))) {
    3069       if ((c.complType() == Break) && ls.contains(c.target()))
    3070         return Completion(Normal, cval);
    3071       if (c.complType() != Normal)
    3072       return c;
    3073     }
    3074    
    3075     if (exec->dynamicInterpreter()->timedOut())
    3076         return Completion(Interrupted);
    3077    
    3078     if (expr3) {
    3079       v = expr3->evaluate(exec);
    3080       KJS_CHECKEXCEPTION
    3081     }
    3082   }
     3259    JSValue* cval = 0;
     3260
     3261    if (expr1) {
     3262        expr1->evaluate(exec);
     3263        KJS_CHECKEXCEPTION
     3264    }
     3265
     3266    while (1) {
     3267        if (expr2) {
     3268            bool b = expr2->evaluateToBoolean(exec);
     3269            KJS_CHECKEXCEPTION
     3270            if (!b)
     3271                return Completion(Normal, cval);
     3272        }
     3273
     3274        exec->pushIteration();
     3275        Completion c = statement->execute(exec);
     3276        exec->popIteration();
     3277        if (c.isValueCompletion())
     3278            cval = c.value();
     3279        if (!((c.complType() == Continue) && ls.contains(c.target()))) {
     3280            if ((c.complType() == Break) && ls.contains(c.target()))
     3281                return Completion(Normal, cval);
     3282            if (c.complType() != Normal)
     3283                return c;
     3284        }
     3285
     3286        if (exec->dynamicInterpreter()->timedOut())
     3287            return Completion(Interrupted);
     3288
     3289        if (expr3) {
     3290            expr3->evaluate(exec);
     3291            KJS_CHECKEXCEPTION
     3292        }
     3293    }
    30833294 
    3084   return Completion(); // work around gcc 4.0 bug
     3295    return Completion(); // work around gcc 4.0 bug
    30853296}
    30863297
     
    33633574}
    33643575
    3365 JSValue *ClauseListNode::evaluate(ExecState *)
    3366 {
    3367   // should never be called
    3368   ASSERT(false);
    3369   return 0;
    3370 }
    3371 
    33723576// ------------------------------ CaseBlockNode --------------------------------
    33733577
     
    33983602    if (list1 && list1->mayHaveDeclarations())
    33993603        stacks.nodeStack.append(list1.get());
    3400 }
    3401 
    3402 JSValue *CaseBlockNode::evaluate(ExecState *)
    3403 {
    3404   // should never be called
    3405   ASSERT(false);
    3406   return 0;
    34073604}
    34083605
     
    35933790}
    35943791
    3595 // ------------------------------ ParameterNode --------------------------------
    3596 
    3597 // ECMA 13
    3598 JSValue *ParameterNode::evaluate(ExecState *)
    3599 {
    3600   return jsUndefined();
    3601 }
    3602 
    36033792// ------------------------------ FunctionBodyNode -----------------------------
    36043793
  • trunk/JavaScriptCore/kjs/nodes.h

    r27637 r27664  
    1 // -*- c-basic-offset: 2 -*-
    21/*
    32 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
     
    112111  };
    113112
    114   class Node {
     113  class Node : Noncopyable {
    115114  public:
    116115    Node() KJS_FAST_CALL;
     
    136135    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
    137136
    138     // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
    139     virtual void optimizeForUnnecessaryResult() { }
    140      
    141137  protected:
    142138    Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
     
    160156    int m_line : 31;
    161157    bool m_mayHaveDeclarations : 1;
    162   private:
    163     // disallow assignment
    164     Node& operator=(const Node&) KJS_FAST_CALL;
    165     Node(const Node &other) KJS_FAST_CALL;
    166158  };
    167159   
    168160    class ExpressionNode : public Node {
    169161    public:
    170         ExpressionNode() KJS_FAST_CALL
    171             : Node()
    172         {
    173         }
     162        ExpressionNode() KJS_FAST_CALL { }
    174163       
    175164        // Special constructor for cases where we overwrite an object in place.
     
    187176        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
    188177        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    189     };
     178        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
     179
     180        // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
     181        virtual void optimizeForUnnecessaryResult() { }
     182   };
    190183
    191184  class StatementNode : public Node {
     
    207200  class NullNode : public ExpressionNode {
    208201  public:
    209     NullNode() KJS_FAST_CALL {}
     202    NullNode() KJS_FAST_CALL { }
    210203    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    211204    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    213206  };
    214207
    215   class BooleanNode : public ExpressionNode {
    216   public:
    217     BooleanNode(bool v) KJS_FAST_CALL : value(v) {}
    218     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     208  class FalseNode : public ExpressionNode {
     209  public:
     210    FalseNode() KJS_FAST_CALL { }
     211    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     212    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
    219213    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    220214    virtual Precedence precedence() const { return PrecPrimary; }
    221   private:
    222     bool value;
     215  };
     216
     217  class TrueNode : public ExpressionNode {
     218  public:
     219    TrueNode() KJS_FAST_CALL { }
     220    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     221    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
     222    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     223    virtual Precedence precedence() const { return PrecPrimary; }
    223224  };
    224225
     
    228229    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    229230    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     231    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    230232    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    231233    virtual Precedence precedence() const { return PrecPrimary; }
     
    234236    double value() const KJS_FAST_CALL { return m_double; }
    235237    virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
     238
    236239  protected:
    237240    double m_double;
     
    253256    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    254257    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     258    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    255259    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    256260    virtual Precedence precedence() const { return PrecPrimary; }
     261
    257262  private:
    258263    UString value;
     
    318323    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    319324    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     325    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    320326  private:
    321327    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
    322328  };
    323329
    324   class ElementNode : public ExpressionNode {
     330  class ElementNode : public Node {
    325331  public:
    326332    ElementNode(int e, ExpressionNode* n) KJS_FAST_CALL : elision(e), node(n) { }
    327333    ElementNode(ElementNode* l, int e, ExpressionNode* n) KJS_FAST_CALL
    328334      : elision(e), node(n) { l->next = this; }
    329     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    330     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    331     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     335    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     336    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     337    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     338
    332339    PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
    333     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     340
     341    JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     342
    334343  private:
    335344    friend class ArrayNode;
     
    356365  };
    357366
    358   class PropertyNode : public ExpressionNode {
     367  class PropertyNode : public Node {
    359368  public:
    360369    enum Type { Constant, Getter, Setter };
     
    362371      : m_name(n), assign(a), type(t) { }
    363372    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    364     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    365     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     373    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     374    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     375
     376    JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     377    const Identifier& name() const { return m_name; }
     378
     379  private:
    366380    friend class PropertyListNode;
    367     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
    368     const Identifier& name() const { return m_name; }
    369   private:
    370381    Identifier m_name;
    371382    RefPtr<ExpressionNode> assign;
     
    373384  };
    374385 
    375   class PropertyListNode : public ExpressionNode {
     386  class PropertyListNode : public Node {
    376387  public:
    377388    PropertyListNode(PropertyNode* n) KJS_FAST_CALL
     
    380391      : node(n) { l->next = this; }
    381392    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    382     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    383     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     393    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     394    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     395
     396    JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    384397    PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
    385     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     398
    386399  private:
    387400    friend class ObjectLiteralNode;
     
    408421    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    409422    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     423    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    410424    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    411425    virtual Precedence precedence() const { return PrecMember; }
     
    440454  };
    441455
    442   class ArgumentListNode : public ExpressionNode {
     456  class ArgumentListNode : public Node {
    443457  public:
    444458    ArgumentListNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
     
    446460      : expr(e) { l->next = this; }
    447461    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    448     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     462    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     463    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     464
    449465    void evaluateList(ExecState*, List&) KJS_FAST_CALL;
    450     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    451466    PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
    452     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     467
    453468  private:
    454469    friend class ArgumentsNode;
     
    457472  };
    458473
    459   class ArgumentsNode : public ExpressionNode {
     474  class ArgumentsNode : public Node {
    460475  public:
    461476    ArgumentsNode() KJS_FAST_CALL { }
     
    463478      : listNode(l) { }
    464479    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    465     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     480    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     481    virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     482
    466483    void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (listNode) listNode->evaluateList(exec, list); }
    467     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    468     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     484
    469485  private:
    470486    RefPtr<ArgumentListNode> listNode;
     
    560576  };
    561577
    562     class PrePostResolveNode : public ExpressionNode {
     578  class PrePostResolveNode : public ExpressionNode {
    563579  public:
    564580    PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
     
    634650  };
    635651
    636     class PostfixBracketNode : public ExpressionNode {
     652  class PostfixBracketNode : public ExpressionNode {
    637653  public:
    638654    PostfixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
     
    9921008    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    9931009    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1010    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    9941011    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    9951012    virtual Precedence precedence() const { return PrecUnary; }
     
    11121129    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11131130    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1131    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11141132    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11151133    virtual Precedence precedence() const { return PrecRelational; }
     
    11251143    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11261144    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1145    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11271146    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11281147    virtual Precedence precedence() const { return PrecRelational; }
     
    11381157    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11391158    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1159    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11401160    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11411161    virtual Precedence precedence() const { return PrecRelational; }
     
    11511171    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11521172    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1173    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11531174    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11541175    virtual Precedence precedence() const { return PrecRelational; }
     
    11641185    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11651186    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1187    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11661188    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11671189    virtual Precedence precedence() const { return PrecRelational; }
     
    11771199    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11781200    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1201    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11791202    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11801203    virtual Precedence precedence() const { return PrecRelational; }
     
    11901213    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11911214    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1215    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    11921216    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11931217    virtual Precedence precedence() const { return PrecEquality; }
     
    12031227    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12041228    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1229    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    12051230    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    12061231    virtual Precedence precedence() const { return PrecEquality; }
     
    12161241    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12171242    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1243    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    12181244    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    12191245    virtual Precedence precedence() const { return PrecEquality; }
     
    12291255    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12301256    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1257    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    12311258    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    12321259    virtual Precedence precedence() const { return PrecEquality; }
     
    12841311    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12851312    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1313    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    12861314    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    12871315    virtual Precedence precedence() const { return PrecLogicalAnd; }
     
    12971325    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12981326    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1327    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    12991328    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    13001329    virtual Precedence precedence() const { return PrecLogicalOr; }
     
    13131342    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    13141343    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1344    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
    13151345    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    13161346    virtual Precedence precedence() const { return PrecConditional; }
     
    14701500    class CommaNode : public ExpressionNode {
    14711501  public:
    1472     CommaNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
     1502    CommaNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2)
     1503    {
     1504        e1->optimizeForUnnecessaryResult();
     1505    }
    14731506    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    14741507    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    15441577  class ExprStatementNode : public StatementNode {
    15451578  public:
    1546     ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
     1579    ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e)
     1580    {
     1581        e->optimizeForUnnecessaryResult();
     1582    }
    15471583    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    15481584    virtual Completion execute(ExecState*) KJS_FAST_CALL;
     
    15961632    {
    15971633        m_mayHaveDeclarations = true;
     1634        if (expr1)
     1635            expr1->optimizeForUnnecessaryResult();
    15981636        if (expr3)
    15991637            expr3->optimizeForUnnecessaryResult();
     
    17071745  };
    17081746
    1709     class ParameterNode : public ExpressionNode {
     1747    class ParameterNode : public Node {
    17101748  public:
    17111749    ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
    17121750    ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
    17131751      : id(i) { l->next = this; }
    1714     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    17151752    Identifier ident() KJS_FAST_CALL { return id; }
    17161753    ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
     
    17991836  };
    18001837
    1801     class CaseClauseNode : public ExpressionNode {
     1838    class CaseClauseNode : public Node {
    18021839  public:
    18031840      CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
     
    18051842      : expr(e), m_children(children) { m_mayHaveDeclarations = true; }
    18061843      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1807       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    1808       Completion evalStatements(ExecState*) KJS_FAST_CALL;
    18091844      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18101845      virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
    18111846      virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
     1847
     1848      JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1849      Completion evalStatements(ExecState*) KJS_FAST_CALL;
     1850
    18121851  private:
    18131852      RefPtr<ExpressionNode> expr;
     
    18151854  };
    18161855 
    1817     class ClauseListNode : public ExpressionNode {
     1856    class ClauseListNode : public Node {
    18181857  public:
    18191858      ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
     
    18211860      : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
    18221861      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1823       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    1824       CaseClauseNode *getClause() const KJS_FAST_CALL { return clause.get(); }
    1825       ClauseListNode *getNext() const KJS_FAST_CALL { return next.get(); }
     1862      CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
     1863      ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
    18261864      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    18271865      PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
     
    18341872  };
    18351873 
    1836     class CaseBlockNode : public ExpressionNode {
     1874    class CaseBlockNode : public Node {
    18371875  public:
    18381876      CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
    18391877      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1840       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    18411878      Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
    18421879      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
  • trunk/JavaScriptCore/kjs/nodes2string.cpp

    r27589 r27664  
    269269}
    270270
    271 void BooleanNode::streamTo(SourceStream& s) const
    272 {
    273     s << (value ? "true" : "false");
     271void FalseNode::streamTo(SourceStream& s) const
     272{
     273    s << "false";
     274}
     275
     276void TrueNode::streamTo(SourceStream& s) const
     277{
     278    s << "true";
    274279}
    275280
Note: See TracChangeset for help on using the changeset viewer.