Changeset 27695 in webkit


Ignore:
Timestamp:
Nov 11, 2007 4:34:37 PM (16 years ago)
Author:
eseidel
Message:

2007-11-10 Eric Seidel <eric@webkit.org>

Reviewed by darin.

Add simple type inferencing to the parser, and create custom
AddNode and LessNode subclasses based on inferred types.
http://bugs.webkit.org/show_bug.cgi?id=15884

SunSpider claims this is at least a 0.5% speedup.

  • JavaScriptCore.exp:
  • kjs/grammar.y:
  • kjs/internal.cpp: (KJS::NumberImp::getPrimitiveNumber): (KJS::GetterSetterImp::getPrimitiveNumber):
  • kjs/internal.h:
  • kjs/lexer.cpp: (KJS::Lexer::lex):
  • kjs/nodes.cpp: (KJS::Node::Node): (KJS::StringNode::evaluate): (KJS::StringNode::evaluateToNumber): (KJS::StringNode::evaluateToBoolean): (KJS::RegExpNode::evaluate): (KJS::UnaryPlusNode::optimizeVariableAccess): (KJS::AddNode::evaluate): (KJS::AddNode::evaluateToNumber): (KJS::AddNumbersNode::inlineEvaluateToNumber): (KJS::AddNumbersNode::evaluate): (KJS::AddNumbersNode::evaluateToNumber): (KJS::AddStringsNode::evaluate): (KJS::AddStringLeftNode::evaluate): (KJS::AddStringRightNode::evaluate): (KJS::lessThan): (KJS::lessThanEq): (KJS::LessNumbersNode::evaluate): (KJS::LessStringsNode::evaluate):
  • kjs/nodes.h: (KJS::ExpressionNode::): (KJS::RegExpNode::): (KJS::RegExpNode::precedence): (KJS::TypeOfResolveNode::): (KJS::LocalVarTypeOfNode::): (KJS::UnaryPlusNode::): (KJS::UnaryPlusNode::precedence): (KJS::AddNode::): (KJS::AddNode::precedence): (KJS::AddNumbersNode::): (KJS::AddStringLeftNode::): (KJS::AddStringRightNode::): (KJS::AddStringsNode::): (KJS::LessNode::): (KJS::LessNode::precedence): (KJS::LessNumbersNode::): (KJS::LessStringsNode::):
  • kjs/nodes2string.cpp: (KJS::StringNode::streamTo):
  • kjs/object.cpp:
  • kjs/object.h:
  • kjs/value.h: (KJS::JSValue::getPrimitiveNumber):
Location:
trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27689 r27695  
     12007-11-10  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by darin.
     4       
     5        Add simple type inferencing to the parser, and create custom
     6        AddNode and LessNode subclasses based on inferred types.
     7        http://bugs.webkit.org/show_bug.cgi?id=15884
     8       
     9        SunSpider claims this is at least a 0.5% speedup.
     10
     11        * JavaScriptCore.exp:
     12        * kjs/grammar.y:
     13        * kjs/internal.cpp:
     14        (KJS::NumberImp::getPrimitiveNumber):
     15        (KJS::GetterSetterImp::getPrimitiveNumber):
     16        * kjs/internal.h:
     17        * kjs/lexer.cpp:
     18        (KJS::Lexer::lex):
     19        * kjs/nodes.cpp:
     20        (KJS::Node::Node):
     21        (KJS::StringNode::evaluate):
     22        (KJS::StringNode::evaluateToNumber):
     23        (KJS::StringNode::evaluateToBoolean):
     24        (KJS::RegExpNode::evaluate):
     25        (KJS::UnaryPlusNode::optimizeVariableAccess):
     26        (KJS::AddNode::evaluate):
     27        (KJS::AddNode::evaluateToNumber):
     28        (KJS::AddNumbersNode::inlineEvaluateToNumber):
     29        (KJS::AddNumbersNode::evaluate):
     30        (KJS::AddNumbersNode::evaluateToNumber):
     31        (KJS::AddStringsNode::evaluate):
     32        (KJS::AddStringLeftNode::evaluate):
     33        (KJS::AddStringRightNode::evaluate):
     34        (KJS::lessThan):
     35        (KJS::lessThanEq):
     36        (KJS::LessNumbersNode::evaluate):
     37        (KJS::LessStringsNode::evaluate):
     38        * kjs/nodes.h:
     39        (KJS::ExpressionNode::):
     40        (KJS::RegExpNode::):
     41        (KJS::RegExpNode::precedence):
     42        (KJS::TypeOfResolveNode::):
     43        (KJS::LocalVarTypeOfNode::):
     44        (KJS::UnaryPlusNode::):
     45        (KJS::UnaryPlusNode::precedence):
     46        (KJS::AddNode::):
     47        (KJS::AddNode::precedence):
     48        (KJS::AddNumbersNode::):
     49        (KJS::AddStringLeftNode::):
     50        (KJS::AddStringRightNode::):
     51        (KJS::AddStringsNode::):
     52        (KJS::LessNode::):
     53        (KJS::LessNode::precedence):
     54        (KJS::LessNumbersNode::):
     55        (KJS::LessStringsNode::):
     56        * kjs/nodes2string.cpp:
     57        (KJS::StringNode::streamTo):
     58        * kjs/object.cpp:
     59        * kjs/object.h:
     60        * kjs/value.h:
     61        (KJS::JSValue::getPrimitiveNumber):
     62
    1632007-11-11  Darin Adler  <darin@apple.com>
    264
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r27686 r27695  
    270270__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
    271271__ZNK3KJS8JSObject14implementsCallEv
    272 __ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
    273 __ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
     272__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
    274273__ZNK3KJS8JSObject19implementsConstructEv
    275274__ZNK3KJS8JSObject21implementsHasInstanceEv
  • trunk/JavaScriptCore/kjs/grammar.y

    r27664 r27695  
    5858using namespace KJS;
    5959
     60static AddNode* makeAddNode(ExpressionNode*, ExpressionNode*);
     61static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*);
    6062static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr);
    6163static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator);
     
    8587
    8688%union {
    87   int                 ival;
    88   double              dval;
    89   UString             *ustr;
    90   Identifier          *ident;
    91   ExpressionNode      *node;
    92   StatementNode       *stat;
    93   ParameterList       param;
    94   FunctionBodyNode    *body;
    95   FuncDeclNode        *func;
    96   FuncExprNode        *funcExpr;
    97   ProgramNode         *prog;
    98   AssignExprNode      *init;
    99   SourceElements      *srcs;
    100   ArgumentsNode       *args;
    101   ArgumentList        alist;
    102   VarDeclNode         *decl;
    103   VarDeclList         vlist;
    104   CaseBlockNode       *cblk;
    105   ClauseList          clist;
    106   CaseClauseNode      *ccl;
    107   ElementList         elm;
    108   Operator            op;
    109   PropertyList        plist;
    110   PropertyNode       *pnode;
     89    int                 intValue;
     90    double              doubleValue;
     91    UString*            string;
     92    Identifier*         ident;
     93
     94    // expression subtrees
     95    ExpressionNode*     expressionNode;
     96    FuncDeclNode*       funcDeclNode;
     97    PropertyNode*       propertyNode;
     98    ArgumentsNode*      argumentsNode;
     99    VarDeclNode*        varDeclNode;
     100    CaseBlockNode*      caseBlockNode;
     101    CaseClauseNode*     caseClauseNode;
     102    FuncExprNode*       funcExprNode;
     103    AssignExprNode*     assignExprNode;
     104
     105    // statement nodes
     106    StatementNode*      statementNode;
     107    FunctionBodyNode*   functionBodyNode;
     108    ProgramNode*        programNode;
     109
     110    SourceElements*     sourceElements;
     111    PropertyList        propertyList;
     112    ArgumentList        argumentList;
     113    VarDeclList         varDeclList;
     114    ClauseList          clauseList;
     115    ElementList         elementList;
     116    ParameterList       parameterList;
     117
     118    Operator            op;
    111119}
    112120
     
    144152
    145153/* terminal types */
    146 %token <dval> NUMBER
    147 %token <ustr> STRING
     154%token <doubleValue> NUMBER
     155%token <string> STRING
    148156%token <ident> IDENT
    149157
     
    152160
    153161/* non-terminal types */
    154 %type <node>  Literal ArrayLiteral
    155 
    156 %type <node>  PrimaryExpr PrimaryExprNoBrace
    157 %type <node>  MemberExpr MemberExprNoBF /* BF => brace or function */
    158 %type <node>  NewExpr NewExprNoBF
    159 %type <node>  CallExpr CallExprNoBF
    160 %type <node>  LeftHandSideExpr LeftHandSideExprNoBF
    161 %type <node>  PostfixExpr PostfixExprNoBF
    162 %type <node>  UnaryExpr UnaryExprNoBF UnaryExprCommon
    163 %type <node>  MultiplicativeExpr MultiplicativeExprNoBF
    164 %type <node>  AdditiveExpr AdditiveExprNoBF
    165 %type <node>  ShiftExpr ShiftExprNoBF
    166 %type <node>  RelationalExpr RelationalExprNoIn RelationalExprNoBF
    167 %type <node>  EqualityExpr EqualityExprNoIn EqualityExprNoBF
    168 %type <node>  BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
    169 %type <node>  BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
    170 %type <node>  BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
    171 %type <node>  LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
    172 %type <node>  LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
    173 %type <node>  ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
    174 %type <node>  AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
    175 %type <node>  Expr ExprNoIn ExprNoBF
    176 
    177 %type <node>  ExprOpt ExprNoInOpt
    178 
    179 %type <stat>  Statement Block
    180 %type <stat>  VariableStatement ConstStatement EmptyStatement ExprStatement
    181 %type <stat>  IfStatement IterationStatement ContinueStatement
    182 %type <stat>  BreakStatement ReturnStatement WithStatement
    183 %type <stat>  SwitchStatement LabelledStatement
    184 %type <stat>  ThrowStatement TryStatement
    185 %type <stat>  DebuggerStatement
    186 %type <stat>  SourceElement
    187 
    188 %type <init>  Initializer InitializerNoIn
    189 %type <func>  FunctionDeclaration
    190 %type <funcExpr>  FunctionExpr
    191 %type <body>  FunctionBody
    192 %type <srcs>  SourceElements
    193 %type <param> FormalParameterList
    194 %type <op>    AssignmentOperator
    195 %type <args>  Arguments
    196 %type <alist> ArgumentList
    197 %type <vlist> VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
    198 %type <decl>  VariableDeclaration VariableDeclarationNoIn ConstDeclaration
    199 %type <cblk>  CaseBlock
    200 %type <ccl>   CaseClause DefaultClause
    201 %type <clist> CaseClauses CaseClausesOpt
    202 %type <ival>  Elision ElisionOpt
    203 %type <elm>   ElementList
    204 %type <pnode> Property
    205 %type <plist> PropertyList
     162%type <expressionNode>  Literal ArrayLiteral
     163
     164%type <expressionNode>  PrimaryExpr PrimaryExprNoBrace
     165%type <expressionNode>  MemberExpr MemberExprNoBF /* BF => brace or function */
     166%type <expressionNode>  NewExpr NewExprNoBF
     167%type <expressionNode>  CallExpr CallExprNoBF
     168%type <expressionNode>  LeftHandSideExpr LeftHandSideExprNoBF
     169%type <expressionNode>  PostfixExpr PostfixExprNoBF
     170%type <expressionNode>  UnaryExpr UnaryExprNoBF UnaryExprCommon
     171%type <expressionNode>  MultiplicativeExpr MultiplicativeExprNoBF
     172%type <expressionNode>  AdditiveExpr AdditiveExprNoBF
     173%type <expressionNode>  ShiftExpr ShiftExprNoBF
     174%type <expressionNode>  RelationalExpr RelationalExprNoIn RelationalExprNoBF
     175%type <expressionNode>  EqualityExpr EqualityExprNoIn EqualityExprNoBF
     176%type <expressionNode>  BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
     177%type <expressionNode>  BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
     178%type <expressionNode>  BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
     179%type <expressionNode>  LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
     180%type <expressionNode>  LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
     181%type <expressionNode>  ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
     182%type <expressionNode>  AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
     183%type <expressionNode>  Expr ExprNoIn ExprNoBF
     184
     185%type <expressionNode>  ExprOpt ExprNoInOpt
     186
     187%type <statementNode>   Statement Block
     188%type <statementNode>   VariableStatement ConstStatement EmptyStatement ExprStatement
     189%type <statementNode>   IfStatement IterationStatement ContinueStatement
     190%type <statementNode>   BreakStatement ReturnStatement WithStatement
     191%type <statementNode>   SwitchStatement LabelledStatement
     192%type <statementNode>   ThrowStatement TryStatement
     193%type <statementNode>   DebuggerStatement
     194%type <statementNode>   SourceElement
     195
     196%type <assignExprNode>  Initializer InitializerNoIn
     197%type <funcDeclNode>    FunctionDeclaration
     198%type <funcExprNode>    FunctionExpr
     199%type <functionBodyNode>  FunctionBody
     200%type <sourceElements>  SourceElements
     201%type <parameterList>  FormalParameterList
     202%type <op>              AssignmentOperator
     203%type <argumentsNode>   Arguments
     204%type <argumentList>    ArgumentList
     205%type <varDeclList>    VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
     206%type <varDeclNode>     VariableDeclaration VariableDeclarationNoIn ConstDeclaration
     207%type <caseBlockNode>   CaseBlock
     208%type <caseClauseNode>  CaseClause DefaultClause
     209%type <clauseList>      CaseClauses CaseClausesOpt
     210%type <intValue>        Elision ElisionOpt
     211%type <elementList>     ElementList
     212%type <propertyNode>    Property
     213%type <propertyList>    PropertyList
    206214%%
    207215
     
    263271
    264272ElementList:
    265     ElisionOpt AssignmentExpr           { $$.head = new ElementNode($1, $2); 
     273    ElisionOpt AssignmentExpr           { $$.head = new ElementNode($1, $2);
    266274                                          $$.tail = $$.head; }
    267275  | ElementList ',' ElisionOpt AssignmentExpr
     
    395403AdditiveExpr:
    396404    MultiplicativeExpr
    397   | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3); }
     405  | AdditiveExpr '+' MultiplicativeExpr { $$ = makeAddNode($1, $3); }
    398406  | AdditiveExpr '-' MultiplicativeExpr { $$ = new SubNode($1, $3); }
    399407;
     
    402410    MultiplicativeExprNoBF
    403411  | AdditiveExprNoBF '+' MultiplicativeExpr
    404                                         { $$ = new AddNode($1, $3); }
     412                                        { $$ = makeAddNode($1, $3); }
    405413  | AdditiveExprNoBF '-' MultiplicativeExpr
    406414                                        { $$ = new SubNode($1, $3); }
     
    423431RelationalExpr:
    424432    ShiftExpr
    425   | RelationalExpr '<' ShiftExpr        { $$ = new LessNode($1, $3); }
     433  | RelationalExpr '<' ShiftExpr        { $$ = makeLessNode($1, $3); }
    426434  | RelationalExpr '>' ShiftExpr        { $$ = new GreaterNode($1, $3); }
    427435  | RelationalExpr LE ShiftExpr         { $$ = new LessEqNode($1, $3); }
     
    433441RelationalExprNoIn:
    434442    ShiftExpr
    435   | RelationalExprNoIn '<' ShiftExpr    { $$ = new LessNode($1, $3); }
     443  | RelationalExprNoIn '<' ShiftExpr    { $$ = makeLessNode($1, $3); }
    436444  | RelationalExprNoIn '>' ShiftExpr    { $$ = new GreaterNode($1, $3); }
    437445  | RelationalExprNoIn LE ShiftExpr     { $$ = new LessEqNode($1, $3); }
     
    443451RelationalExprNoBF:
    444452    ShiftExprNoBF
    445   | RelationalExprNoBF '<' ShiftExpr    { $$ = new LessNode($1, $3); }
     453  | RelationalExprNoBF '<' ShiftExpr    { $$ = makeLessNode($1, $3); }
    446454  | RelationalExprNoBF '>' ShiftExpr    { $$ = new GreaterNode($1, $3); }
    447455  | RelationalExprNoBF LE ShiftExpr     { $$ = new LessEqNode($1, $3); }
     
    888896%%
    889897
     898static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right)
     899{
     900    JSType t1 = left->expectedReturnType();
     901    JSType t2 = right->expectedReturnType();
     902
     903    if (t1 == NumberType && t2 == NumberType)
     904        return new AddNumbersNode(left, right);
     905    if (t1 == StringType && t2 == StringType)
     906        return new AddStringsNode(left, right);
     907    if (t1 == StringType)
     908        return new AddStringLeftNode(left, right);
     909    if (t2 == StringType)
     910        return new AddStringRightNode(left, right);
     911    return new AddNode(left, right);
     912}
     913
     914static LessNode* makeLessNode(ExpressionNode* left, ExpressionNode* right)
     915{
     916    JSType t1 = left->expectedReturnType();
     917    JSType t2 = right->expectedReturnType();
     918   
     919    if (t1 == StringType && t2 == StringType)
     920        return new LessStringsNode(left, right);
     921
     922    // There are certainly more efficient ways to do this type check if necessary
     923    if (t1 == NumberType || t1 == BooleanType || t1 == UndefinedType || t1 == NullType ||
     924        t2 == NumberType || t2 == BooleanType || t2 == UndefinedType || t2 == NullType)
     925        return new LessNumbersNode(left, right);
     926
     927    // Neither is certain to be a number, nor were both certain to be strings, so we use the default (slow) implementation.
     928    return new LessNode(left, right);
     929}
     930
    890931static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr)
    891932{
  • trunk/JavaScriptCore/kjs/internal.cpp

    r27413 r27695  
    5757}
    5858
    59 bool StringImp::getPrimitiveNumber(ExecState*, double& number) const
    60 {
     59bool StringImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
     60{
     61    value = this;
    6162    number = val.toDouble();
    6263    return false;
     
    9091}
    9192
    92 bool NumberImp::getPrimitiveNumber(ExecState*, double& number) const
     93bool NumberImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
    9394{
    9495    number = val;
     96    value = this;
    9597    return true;
    9698}
     
    159161}
    160162
    161 bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number) const
    162 {
    163     ASSERT(false);
     163bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
     164{
     165    ASSERT_NOT_REACHED();
    164166    number = 0;
     167    value = 0;
    165168    return true;
    166169}
  • trunk/JavaScriptCore/kjs/internal.h

    r27218 r27695  
    5656
    5757    virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
    58     virtual bool getPrimitiveNumber(ExecState*, double& number) const;
     58    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
    5959    virtual bool toBoolean(ExecState *exec) const;
    6060    virtual double toNumber(ExecState *exec) const;
     
    7474
    7575    virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
    76     virtual bool getPrimitiveNumber(ExecState*, double& number) const;
     76    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
    7777    virtual bool toBoolean(ExecState *exec) const;
    7878    virtual double toNumber(ExecState *exec) const;
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r27011 r27695  
    557557    break;
    558558  case String:
    559     kjsyylval.ustr = makeUString(buffer16, pos16);
     559    kjsyylval.string = makeUString(buffer16, pos16);
    560560    token = STRING;
    561561    break;
    562562  case Number:
    563     kjsyylval.dval = dval;
     563    kjsyylval.doubleValue = dval;
    564564    token = NUMBER;
    565565    break;
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r27684 r27695  
    128128Node::Node()
    129129    : m_mayHaveDeclarations(false)
     130    , m_expectedReturnType(ObjectType)
    130131{
    131132#ifndef NDEBUG
     
    136137      newNodes = new HashSet<Node*>;
    137138  newNodes->add(this);
     139}
     140
     141Node::Node(JSType expectedReturn)
     142    : m_mayHaveDeclarations(false)
     143    , m_expectedReturnType(expectedReturn)
     144{
     145#ifndef NDEBUG
     146    ++NodeCounter::count;
     147#endif
     148    m_line = Lexer::curr()->lineNo();
     149    if (!newNodes)
     150        newNodes = new HashSet<Node*>;
     151    newNodes->add(this);
    138152}
    139153
     
    421435// ------------------------------ StringNode -----------------------------------
    422436
    423 JSValue *StringNode::evaluate(ExecState *)
    424 {
    425   return jsOwnedString(value);
     437JSValue* StringNode::evaluate(ExecState*)
     438{
     439  return jsOwnedString(m_value);
    426440}
    427441
    428442double StringNode::evaluateToNumber(ExecState*)
    429443{
    430     return value.toDouble();
     444    return m_value.toDouble();
    431445}
    432446
    433447bool StringNode::evaluateToBoolean(ExecState*)
    434448{
    435     return !value.isEmpty();
     449    return !m_value.isEmpty();
    436450}
    437451   
    438452// ------------------------------ RegExpNode -----------------------------------
    439453
    440 JSValue *RegExpNode::evaluate(ExecState *exec)
     454JSValue* RegExpNode::evaluate(ExecState* exec)
    441455{
    442456  List list;
    443   list.append(jsOwnedString(pattern));
    444   list.append(jsOwnedString(flags));
    445 
    446   JSObject *reg = exec->lexicalInterpreter()->builtinRegExp();
    447   return reg->construct(exec,list);
     457  list.append(jsOwnedString(m_pattern));
     458  list.append(jsOwnedString(m_flags));
     459
     460  JSObject* reg = exec->lexicalInterpreter()->builtinRegExp();
     461  return reg->construct(exec, list);
    448462}
    449463
     
    16331647void UnaryPlusNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
    16341648{
    1635     nodeStack.append(expr.get());
     1649    nodeStack.append(m_expr.get());
    16361650}
    16371651
    16381652// ECMA 11.4.6
    1639 JSValue *UnaryPlusNode::evaluate(ExecState *exec)
    1640 {
    1641   JSValue *v = expr->evaluate(exec);
     1653JSValue* UnaryPlusNode::evaluate(ExecState* exec)
     1654{
     1655  JSValue *v = m_expr->evaluate(exec);
    16421656  KJS_CHECKEXCEPTIONVALUE
    16431657
     
    17111725    double n1 = term1->evaluateToNumber(exec);
    17121726    KJS_CHECKEXCEPTIONNUMBER
    1713    
    17141727    double n2 = term2->evaluateToNumber(exec);
    1715     KJS_CHECKEXCEPTIONNUMBER
    1716    
    17171728    return n1 * n2;
    17181729}
     
    17391750    double n1 = term1->evaluateToNumber(exec);
    17401751    KJS_CHECKEXCEPTIONNUMBER
    1741    
    17421752    double n2 = term2->evaluateToNumber(exec);
    1743     KJS_CHECKEXCEPTIONNUMBER
    1744    
    17451753    return n1 / n2;
    17461754}
     
    17671775    double n1 = term1->evaluateToNumber(exec);
    17681776    KJS_CHECKEXCEPTIONNUMBER
    1769    
    17701777    double n2 = term2->evaluateToNumber(exec);
    1771     KJS_CHECKEXCEPTIONNUMBER
    1772    
    17731778    return fmod(n1, n2);
    17741779}
     
    18881893
    18891894// ECMA 11.6.1
    1890 JSValue *AddNode::evaluate(ExecState *exec)
    1891 {
    1892   JSValue *v1 = term1->evaluate(exec);
    1893   KJS_CHECKEXCEPTIONVALUE
    1894 
    1895   JSValue *v2 = term2->evaluate(exec);
     1895JSValue* AddNode::evaluate(ExecState* exec)
     1896{
     1897  JSValue* v1 = term1->evaluate(exec);
     1898  KJS_CHECKEXCEPTIONVALUE
     1899
     1900  JSValue* v2 = term2->evaluate(exec);
    18961901  KJS_CHECKEXCEPTIONVALUE
    18971902
     
    19011906double AddNode::evaluateToNumber(ExecState* exec)
    19021907{
    1903     JSValue *v1 = term1->evaluate(exec);
     1908    JSValue* v1 = term1->evaluate(exec);
    19041909    KJS_CHECKEXCEPTIONNUMBER
    19051910   
    1906     JSValue *v2 = term2->evaluate(exec);
     1911    JSValue* v2 = term2->evaluate(exec);
    19071912    KJS_CHECKEXCEPTIONNUMBER
    19081913   
    19091914    return addToNumber(exec, v1, v2);
     1915}
     1916
     1917double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
     1918{
     1919    double n1 = term1->evaluateToNumber(exec);
     1920    KJS_CHECKEXCEPTIONNUMBER
     1921    double n2 = term2->evaluateToNumber(exec);
     1922    return n1 + n2;
     1923}
     1924
     1925JSValue* AddNumbersNode::evaluate(ExecState* exec)
     1926{
     1927    return jsNumber(inlineEvaluateToNumber(exec));
     1928}
     1929
     1930double AddNumbersNode::evaluateToNumber(ExecState* exec)
     1931{
     1932    return inlineEvaluateToNumber(exec);
     1933}
     1934
     1935JSValue* AddStringsNode::evaluate(ExecState* exec)
     1936{
     1937    JSValue* v1 = term1->evaluate(exec);
     1938    KJS_CHECKEXCEPTIONVALUE
     1939   
     1940    JSValue* v2 = term2->evaluate(exec);
     1941    KJS_CHECKEXCEPTIONVALUE
     1942   
     1943    return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
     1944}
     1945
     1946JSValue* AddStringLeftNode::evaluate(ExecState* exec)
     1947{
     1948    JSValue* v1 = term1->evaluate(exec);
     1949    KJS_CHECKEXCEPTIONVALUE
     1950   
     1951    JSValue* v2 = term2->evaluate(exec);
     1952    KJS_CHECKEXCEPTIONVALUE
     1953   
     1954    JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
     1955    return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
     1956}
     1957
     1958JSValue* AddStringRightNode::evaluate(ExecState* exec)
     1959{
     1960    JSValue* v1 = term1->evaluate(exec);
     1961    KJS_CHECKEXCEPTIONVALUE
     1962   
     1963    JSValue* v2 = term2->evaluate(exec);
     1964    KJS_CHECKEXCEPTIONVALUE
     1965   
     1966    JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
     1967    return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
    19101968}
    19111969
     
    19211979    double n1 = term1->evaluateToNumber(exec);
    19221980    KJS_CHECKEXCEPTIONNUMBER
    1923    
    19241981    double n2 = term2->evaluateToNumber(exec);
    1925     KJS_CHECKEXCEPTIONNUMBER
    1926    
    19271982    return n1 - n2;
    19281983}
     
    20032058    double n1;
    20042059    double n2;
    2005     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1);
    2006     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2);
     2060    JSValue* p1;
     2061    JSValue* p2;
     2062    bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
     2063    bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
    20072064   
    20082065    if (wasNotString1 | wasNotString2)
    20092066        return n1 < n2;
    20102067
    2011     return v1->toString(exec) < v2->toString(exec);
     2068    return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
    20122069}
    20132070
     
    20162073    double n1;
    20172074    double n2;
    2018     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1);
    2019     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2);
     2075    JSValue* p1;
     2076    JSValue* p2;
     2077    bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
     2078    bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
    20202079   
    20212080    if (wasNotString1 | wasNotString2)
    20222081        return n1 <= n2;
    20232082
    2024     return !(v2->toString(exec) < v1->toString(exec));
     2083    return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
    20252084}
    20262085
     
    20482107    KJS_CHECKEXCEPTIONBOOLEAN
    20492108    return lessThan(exec, v1, v2);
     2109}
     2110
     2111JSValue* LessNumbersNode::evaluate(ExecState* exec)
     2112{
     2113    double n1 = expr1->evaluateToNumber(exec);
     2114    KJS_CHECKEXCEPTIONVALUE
     2115    double n2 = expr2->evaluateToNumber(exec);
     2116    return jsBoolean(n1 < n2);
     2117}
     2118
     2119JSValue* LessStringsNode::evaluate(ExecState* exec)
     2120{
     2121    JSValue* v1 = expr1->evaluate(exec);
     2122    KJS_CHECKEXCEPTIONVALUE
     2123    JSValue* v2 = expr2->evaluate(exec);
     2124    return jsBoolean(static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value());
    20502125}
    20512126
  • trunk/JavaScriptCore/kjs/nodes.h

    r27678 r27695  
    136136
    137137  protected:
     138    Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
    138139    Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
    139140    Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
     
    154155    Completion rethrowException(ExecState*) KJS_FAST_CALL;
    155156
    156     int m_line : 31;
     157    int m_line : 28;
    157158    bool m_mayHaveDeclarations : 1;
     159    unsigned m_expectedReturnType : 3; // JSType
    158160  };
    159161   
    160162    class ExpressionNode : public Node {
    161163    public:
    162         ExpressionNode() KJS_FAST_CALL { }
     164        ExpressionNode() KJS_FAST_CALL : Node() {}
     165        ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
     166            : Node(expectedReturn) {}
    163167       
    164168        // Special constructor for cases where we overwrite an object in place.
    165169        ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
    166             : Node(PlacementNewAdopt)
    167         {
    168         }
     170            : Node(PlacementNewAdopt) {}
    169171       
    170172        virtual bool isNumber() const KJS_FAST_CALL { return false; }
     
    173175        virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
    174176        virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
     177       
     178        JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
    175179       
    176180        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
     
    200204  class NullNode : public ExpressionNode {
    201205  public:
    202     NullNode() KJS_FAST_CALL { }
     206    NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
    203207    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    204208    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     
    208212  class FalseNode : public ExpressionNode {
    209213  public:
    210     FalseNode() KJS_FAST_CALL { }
     214    FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
    211215    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    212216    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
     
    217221  class TrueNode : public ExpressionNode {
    218222  public:
    219     TrueNode() KJS_FAST_CALL { }
     223    TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
    220224    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    221225    virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
     
    226230  class NumberNode : public ExpressionNode {
    227231  public:
    228     NumberNode(double v) KJS_FAST_CALL : m_double(v) {}
     232    NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {}
    229233    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    230234    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    248252      virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
    249253  private:
    250       JSValue* m_value;
     254      JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
    251255  };
    252256
    253257  class StringNode : public ExpressionNode {
    254258  public:
    255     StringNode(const UString *v) KJS_FAST_CALL { value = *v; }
     259    StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {}
    256260    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    257261    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     
    261265
    262266  private:
    263     UString value;
     267    UString m_value;
    264268  };
    265269
    266270  class RegExpNode : public ExpressionNode {
    267271  public:
    268     RegExpNode(const UString &p, const UString &f) KJS_FAST_CALL
    269       : pattern(p), flags(f) { }
     272    RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
     273      : m_pattern(pattern), m_flags(flags) { }
    270274    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    271275    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    272276    virtual Precedence precedence() const { return PrecPrimary; }
    273277  private:
    274     UString pattern, flags;
     278    UString m_pattern;
     279    UString m_flags;
    275280  };
    276281
     
    578583  class PrePostResolveNode : public ExpressionNode {
    579584  public:
    580     PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
     585    PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {}
    581586     
    582587    PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
     
    793798  public:
    794799    TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL
    795         : m_ident(s)
    796     {
    797     }
     800        : ExpressionNode(StringType), m_ident(s) {}
    798801   
    799802    TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
     
    801804        , m_ident(PlacementNewAdopt)
    802805    {
     806        m_expectedReturnType = StringType;
    803807    }
    804808
     
    820824    LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
    821825        : TypeOfResolveNode(PlacementNewAdopt)
    822     {
     826    {
     827        m_expectedReturnType = StringType;
    823828        ASSERT(i != missingSymbolMarker());
    824829        m_index = i;
     
    830835  class TypeOfValueNode : public ExpressionNode {
    831836  public:
    832     TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
     837    TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
    833838    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    834839    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    971976  class UnaryPlusNode : public ExpressionNode {
    972977  public:
    973     UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
     978    UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
    974979    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    975980    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    977982    virtual Precedence precedence() const { return PrecUnary; }
    978983  private:
     984    RefPtr<ExpressionNode> m_expr;
     985  };
     986
     987  class NegateNode : public ExpressionNode {
     988  public:
     989    NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
     990    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     991    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     992    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     993    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     994    virtual Precedence precedence() const { return PrecUnary; }
     995  private:
    979996    RefPtr<ExpressionNode> expr;
    980997  };
    981998
    982   class NegateNode : public ExpressionNode {
    983   public:
    984     NegateNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
    985     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    986     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    987     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     999  class BitwiseNotNode : public ExpressionNode {
     1000  public:
     1001    BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
     1002    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
     1003    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    9881004    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    9891005    virtual Precedence precedence() const { return PrecUnary; }
     
    9921008  };
    9931009
    994   class BitwiseNotNode : public ExpressionNode {
    995   public:
    996     BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
    997     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    998     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    999     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1000     virtual Precedence precedence() const { return PrecUnary; }
    1001   private:
    1002     RefPtr<ExpressionNode> expr;
    1003   };
    1004 
    10051010  class LogicalNotNode : public ExpressionNode {
    10061011  public:
    1007     LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
     1012    LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
    10081013    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10091014    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10171022  class MultNode : public ExpressionNode {
    10181023  public:
    1019       MultNode(ExpressionNode*  t1, ExpressionNode*  t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
     1024      MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    10201025      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10211026      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10311036  class DivNode : public ExpressionNode {
    10321037  public:
    1033       DivNode(ExpressionNode*  t1, ExpressionNode*  t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
     1038      DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    10341039      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10351040      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10451050  class ModNode : public ExpressionNode {
    10461051  public:
    1047       ModNode(ExpressionNode*  t1, ExpressionNode*  t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
     1052      ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    10481053      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10491054      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10591064  class AddNode : public ExpressionNode {
    10601065  public:
    1061     AddNode(ExpressionNode*  t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
     1066    AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    10621067    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10631068    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10651070    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    10661071    virtual Precedence precedence() const { return PrecAdditive; }
    1067   private:
     1072  protected:
     1073    AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
    10681074    RefPtr<ExpressionNode> term1;
    10691075    RefPtr<ExpressionNode> term2;
    10701076  };
    1071  
     1077
     1078    class AddNumbersNode : public AddNode {
     1079    public:
     1080        AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
     1081        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1082        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     1083    private:
     1084        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
     1085    };
     1086
     1087    class AddStringLeftNode : public AddNode {
     1088    public:
     1089        AddStringLeftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
     1090        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1091    };
     1092
     1093    class AddStringRightNode : public AddNode {
     1094    public:
     1095        AddStringRightNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
     1096        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1097    };
     1098
     1099    class AddStringsNode : public AddNode {
     1100    public:
     1101        AddStringsNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
     1102        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1103    };
     1104
    10721105  class SubNode : public ExpressionNode {
    10731106  public:
    1074       SubNode(ExpressionNode*  t1, ExpressionNode*  t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
     1107      SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    10751108      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10761109      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10861119  class LeftShiftNode : public ExpressionNode {
    10871120  public:
    1088     LeftShiftNode(ExpressionNode*  t1, ExpressionNode* t2) KJS_FAST_CALL
    1089       : term1(t1), term2(t2) {}
     1121    LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
     1122      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    10901123    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    10911124    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    10991132  class RightShiftNode : public ExpressionNode {
    11001133  public:
    1101     RightShiftNode(ExpressionNode*  t1, ExpressionNode* t2) KJS_FAST_CALL
    1102       : term1(t1), term2(t2) {}
     1134    RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
     1135      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    11031136    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11041137    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    11121145  class UnsignedRightShiftNode : public ExpressionNode {
    11131146  public:
    1114     UnsignedRightShiftNode(ExpressionNode*  t1, ExpressionNode* t2) KJS_FAST_CALL
    1115       : term1(t1), term2(t2) {}
     1147    UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
     1148      : ExpressionNode(NumberType), term1(t1), term2(t2) {}
    11161149    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11171150    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    11251158  class LessNode : public ExpressionNode {
    11261159  public:
    1127     LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1128       expr1(e1), expr2(e2) {}
     1160    LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1161      : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    11291162    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11301163    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    11321165    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    11331166    virtual Precedence precedence() const { return PrecRelational; }
    1134   private:
     1167  protected:
    11351168    RefPtr<ExpressionNode> expr1;
    11361169    RefPtr<ExpressionNode> expr2;
    11371170  };
    11381171
     1172    class LessNumbersNode : public LessNode {
     1173    public:
     1174        LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1175        : LessNode(e1, e2) {}
     1176        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1177    };
     1178
     1179    class LessStringsNode : public LessNode {
     1180    public:
     1181        LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1182        : LessNode(e1, e2) {}
     1183        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1184    };
     1185
    11391186  class GreaterNode : public ExpressionNode {
    11401187  public:
     
    11811228    class InstanceOfNode : public ExpressionNode {
    11821229  public:
    1183     InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1184       expr1(e1), expr2(e2) {}
     1230    InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1231        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    11851232    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    11861233    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12101257  public:
    12111258    EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    1212       : expr1(e1), expr2(e2) {}
     1259        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    12131260    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12141261    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12241271  public:
    12251272    NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    1226       : expr1(e1), expr2(e2) {}
     1273        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    12271274    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12281275    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12381285  public:
    12391286    StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    1240       : expr1(e1), expr2(e2) {}
     1287        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    12411288    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12421289    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12521299  public:
    12531300    NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
    1254       : expr1(e1), expr2(e2) {}
     1301        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    12551302    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12561303    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12651312    class BitAndNode : public ExpressionNode {
    12661313  public:
    1267     BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1268       expr1(e1), expr2(e2) {}
     1314    BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1315        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    12691316    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12701317    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12781325    class BitOrNode : public ExpressionNode {
    12791326  public:
    1280     BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1281       expr1(e1), expr2(e2) {}
     1327    BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1328        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    12821329    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12831330    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    12911338    class BitXOrNode : public ExpressionNode {
    12921339  public:
    1293     BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1294       expr1(e1), expr2(e2) {}
     1340    BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1341        : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
    12951342    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    12961343    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    13071354    class LogicalAndNode : public ExpressionNode {
    13081355  public:
    1309     LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1310       expr1(e1), expr2(e2) {}
     1356    LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1357        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    13111358    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    13121359    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     
    13211368    class LogicalOrNode : public ExpressionNode {
    13221369  public:
    1323     LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
    1324       expr1(e1), expr2(e2) {}
     1370    LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
     1371        : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
    13251372    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    13261373    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
  • trunk/JavaScriptCore/kjs/nodes2string.cpp

    r27664 r27695  
    286286void StringNode::streamTo(SourceStream& s) const
    287287{
    288     s << '"' << escapeStringForPrettyPrinting(value) << '"';
     288    s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
    289289}
    290290
    291291void RegExpNode::streamTo(SourceStream& s) const
    292292{
    293     s << '/' <<  pattern << '/' << flags;
     293    s << '/' <<  m_pattern << '/' << m_flags;
    294294}
    295295
     
    525525void UnaryPlusNode::streamTo(SourceStream& s) const
    526526{
    527     s << "+ " << PrecUnary << expr;
     527    s << "+ " << PrecUnary << m_expr;
    528528}
    529529
  • trunk/JavaScriptCore/kjs/object.cpp

    r27086 r27695  
    355355}
    356356
    357 bool JSObject::getPrimitiveNumber(ExecState* exec, double& number) const
    358 {
    359     JSValue* result = defaultValue(exec, NumberType);
     357bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
     358{
     359    result = defaultValue(exec, NumberType);
    360360    number = result->toNumber(exec);
    361361    return !result->isString();
  • trunk/JavaScriptCore/kjs/object.h

    r27413 r27695  
    7979     
    8080    virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
    81     virtual bool getPrimitiveNumber(ExecState*, double& number) const;
     81    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
    8282    virtual bool toBoolean(ExecState *exec) const;
    8383    virtual double toNumber(ExecState *exec) const;
     
    413413
    414414    virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
    415     virtual bool getPrimitiveNumber(ExecState*, double& number) const;
     415    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
    416416    virtual bool toBoolean(ExecState *exec) const;
    417417    virtual double toNumber(ExecState *exec) const;
  • trunk/JavaScriptCore/kjs/value.h

    r27648 r27695  
    8282    // Basic conversions.
    8383    JSValue* toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;
    84     bool getPrimitiveNumber(ExecState* exec, double& number) const;
     84    bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);
    8585
    8686    bool toBoolean(ExecState *exec) const;
     
    150150    // Basic conversions.
    151151    virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0;
    152     virtual bool getPrimitiveNumber(ExecState* exec, double& number) const = 0;
     152    virtual bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value) = 0;
    153153    virtual bool toBoolean(ExecState *exec) const = 0;
    154154    virtual double toNumber(ExecState *exec) const = 0;
     
    421421}
    422422
    423 inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number) const
     423inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
    424424{
    425425    if (JSImmediate::isImmediate(this)) {
    426426        number = JSImmediate::toDouble(this);
     427        value = this;
    427428        return true;
    428429    }
    429     return asCell()->getPrimitiveNumber(exec, number);
     430    return asCell()->getPrimitiveNumber(exec, number, value);
    430431}
    431432
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r27680 r27695  
    1397413974                        isa = PBXProject;
    1397513975                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
     13976                        compatibilityVersion = "Xcode 2.4";
    1397613977                        hasScannedForEncodings = 1;
    1397713978                        knownRegions = (
Note: See TracChangeset for help on using the changeset viewer.