+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):
+
2007-11-11 Darin Adler <darin@apple.com>
- try another way of fixing dftables builds -- refactor pcre_internal.h a bit
__ZNK3KJS8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
__ZNK3KJS8JSObject14implementsCallEv
-__ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
-__ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
+__ZN3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRPNS_7JSValueE
__ZNK3KJS8JSObject19implementsConstructEv
__ZNK3KJS8JSObject21implementsHasInstanceEv
__ZNK3KJS8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
using namespace KJS;
+static AddNode* makeAddNode(ExpressionNode*, ExpressionNode*);
+static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*);
static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr);
static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator);
static ExpressionNode* makePostfixNode(ExpressionNode* expr, Operator);
%}
%union {
- int ival;
- double dval;
- UString *ustr;
- Identifier *ident;
- ExpressionNode *node;
- StatementNode *stat;
- ParameterList param;
- FunctionBodyNode *body;
- FuncDeclNode *func;
- FuncExprNode *funcExpr;
- ProgramNode *prog;
- AssignExprNode *init;
- SourceElements *srcs;
- ArgumentsNode *args;
- ArgumentList alist;
- VarDeclNode *decl;
- VarDeclList vlist;
- CaseBlockNode *cblk;
- ClauseList clist;
- CaseClauseNode *ccl;
- ElementList elm;
- Operator op;
- PropertyList plist;
- PropertyNode *pnode;
+ int intValue;
+ double doubleValue;
+ UString* string;
+ Identifier* ident;
+
+ // expression subtrees
+ ExpressionNode* expressionNode;
+ FuncDeclNode* funcDeclNode;
+ PropertyNode* propertyNode;
+ ArgumentsNode* argumentsNode;
+ VarDeclNode* varDeclNode;
+ CaseBlockNode* caseBlockNode;
+ CaseClauseNode* caseClauseNode;
+ FuncExprNode* funcExprNode;
+ AssignExprNode* assignExprNode;
+
+ // statement nodes
+ StatementNode* statementNode;
+ FunctionBodyNode* functionBodyNode;
+ ProgramNode* programNode;
+
+ SourceElements* sourceElements;
+ PropertyList propertyList;
+ ArgumentList argumentList;
+ VarDeclList varDeclList;
+ ClauseList clauseList;
+ ElementList elementList;
+ ParameterList parameterList;
+
+ Operator op;
}
%start Program
%token XOREQUAL OREQUAL /* ^= and |= */
/* terminal types */
-%token <dval> NUMBER
-%token <ustr> STRING
+%token <doubleValue> NUMBER
+%token <string> STRING
%token <ident> IDENT
/* automatically inserted semicolon */
%token AUTOPLUSPLUS AUTOMINUSMINUS
/* non-terminal types */
-%type <node> Literal ArrayLiteral
-
-%type <node> PrimaryExpr PrimaryExprNoBrace
-%type <node> MemberExpr MemberExprNoBF /* BF => brace or function */
-%type <node> NewExpr NewExprNoBF
-%type <node> CallExpr CallExprNoBF
-%type <node> LeftHandSideExpr LeftHandSideExprNoBF
-%type <node> PostfixExpr PostfixExprNoBF
-%type <node> UnaryExpr UnaryExprNoBF UnaryExprCommon
-%type <node> MultiplicativeExpr MultiplicativeExprNoBF
-%type <node> AdditiveExpr AdditiveExprNoBF
-%type <node> ShiftExpr ShiftExprNoBF
-%type <node> RelationalExpr RelationalExprNoIn RelationalExprNoBF
-%type <node> EqualityExpr EqualityExprNoIn EqualityExprNoBF
-%type <node> BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
-%type <node> BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
-%type <node> BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
-%type <node> LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
-%type <node> LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
-%type <node> ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
-%type <node> AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
-%type <node> Expr ExprNoIn ExprNoBF
-
-%type <node> ExprOpt ExprNoInOpt
-
-%type <stat> Statement Block
-%type <stat> VariableStatement ConstStatement EmptyStatement ExprStatement
-%type <stat> IfStatement IterationStatement ContinueStatement
-%type <stat> BreakStatement ReturnStatement WithStatement
-%type <stat> SwitchStatement LabelledStatement
-%type <stat> ThrowStatement TryStatement
-%type <stat> DebuggerStatement
-%type <stat> SourceElement
-
-%type <init> Initializer InitializerNoIn
-%type <func> FunctionDeclaration
-%type <funcExpr> FunctionExpr
-%type <body> FunctionBody
-%type <srcs> SourceElements
-%type <param> FormalParameterList
-%type <op> AssignmentOperator
-%type <args> Arguments
-%type <alist> ArgumentList
-%type <vlist> VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
-%type <decl> VariableDeclaration VariableDeclarationNoIn ConstDeclaration
-%type <cblk> CaseBlock
-%type <ccl> CaseClause DefaultClause
-%type <clist> CaseClauses CaseClausesOpt
-%type <ival> Elision ElisionOpt
-%type <elm> ElementList
-%type <pnode> Property
-%type <plist> PropertyList
+%type <expressionNode> Literal ArrayLiteral
+
+%type <expressionNode> PrimaryExpr PrimaryExprNoBrace
+%type <expressionNode> MemberExpr MemberExprNoBF /* BF => brace or function */
+%type <expressionNode> NewExpr NewExprNoBF
+%type <expressionNode> CallExpr CallExprNoBF
+%type <expressionNode> LeftHandSideExpr LeftHandSideExprNoBF
+%type <expressionNode> PostfixExpr PostfixExprNoBF
+%type <expressionNode> UnaryExpr UnaryExprNoBF UnaryExprCommon
+%type <expressionNode> MultiplicativeExpr MultiplicativeExprNoBF
+%type <expressionNode> AdditiveExpr AdditiveExprNoBF
+%type <expressionNode> ShiftExpr ShiftExprNoBF
+%type <expressionNode> RelationalExpr RelationalExprNoIn RelationalExprNoBF
+%type <expressionNode> EqualityExpr EqualityExprNoIn EqualityExprNoBF
+%type <expressionNode> BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
+%type <expressionNode> BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
+%type <expressionNode> BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
+%type <expressionNode> LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
+%type <expressionNode> LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
+%type <expressionNode> ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
+%type <expressionNode> AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
+%type <expressionNode> Expr ExprNoIn ExprNoBF
+
+%type <expressionNode> ExprOpt ExprNoInOpt
+
+%type <statementNode> Statement Block
+%type <statementNode> VariableStatement ConstStatement EmptyStatement ExprStatement
+%type <statementNode> IfStatement IterationStatement ContinueStatement
+%type <statementNode> BreakStatement ReturnStatement WithStatement
+%type <statementNode> SwitchStatement LabelledStatement
+%type <statementNode> ThrowStatement TryStatement
+%type <statementNode> DebuggerStatement
+%type <statementNode> SourceElement
+
+%type <assignExprNode> Initializer InitializerNoIn
+%type <funcDeclNode> FunctionDeclaration
+%type <funcExprNode> FunctionExpr
+%type <functionBodyNode> FunctionBody
+%type <sourceElements> SourceElements
+%type <parameterList> FormalParameterList
+%type <op> AssignmentOperator
+%type <argumentsNode> Arguments
+%type <argumentList> ArgumentList
+%type <varDeclList> VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
+%type <varDeclNode> VariableDeclaration VariableDeclarationNoIn ConstDeclaration
+%type <caseBlockNode> CaseBlock
+%type <caseClauseNode> CaseClause DefaultClause
+%type <clauseList> CaseClauses CaseClausesOpt
+%type <intValue> Elision ElisionOpt
+%type <elementList> ElementList
+%type <propertyNode> Property
+%type <propertyList> PropertyList
%%
Literal:
;
ElementList:
- ElisionOpt AssignmentExpr { $$.head = new ElementNode($1, $2);
+ ElisionOpt AssignmentExpr { $$.head = new ElementNode($1, $2);
$$.tail = $$.head; }
| ElementList ',' ElisionOpt AssignmentExpr
{ $$.head = $1.head;
AdditiveExpr:
MultiplicativeExpr
- | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3); }
+ | AdditiveExpr '+' MultiplicativeExpr { $$ = makeAddNode($1, $3); }
| AdditiveExpr '-' MultiplicativeExpr { $$ = new SubNode($1, $3); }
;
AdditiveExprNoBF:
MultiplicativeExprNoBF
| AdditiveExprNoBF '+' MultiplicativeExpr
- { $$ = new AddNode($1, $3); }
+ { $$ = makeAddNode($1, $3); }
| AdditiveExprNoBF '-' MultiplicativeExpr
{ $$ = new SubNode($1, $3); }
;
RelationalExpr:
ShiftExpr
- | RelationalExpr '<' ShiftExpr { $$ = new LessNode($1, $3); }
+ | RelationalExpr '<' ShiftExpr { $$ = makeLessNode($1, $3); }
| RelationalExpr '>' ShiftExpr { $$ = new GreaterNode($1, $3); }
| RelationalExpr LE ShiftExpr { $$ = new LessEqNode($1, $3); }
| RelationalExpr GE ShiftExpr { $$ = new GreaterEqNode($1, $3); }
RelationalExprNoIn:
ShiftExpr
- | RelationalExprNoIn '<' ShiftExpr { $$ = new LessNode($1, $3); }
+ | RelationalExprNoIn '<' ShiftExpr { $$ = makeLessNode($1, $3); }
| RelationalExprNoIn '>' ShiftExpr { $$ = new GreaterNode($1, $3); }
| RelationalExprNoIn LE ShiftExpr { $$ = new LessEqNode($1, $3); }
| RelationalExprNoIn GE ShiftExpr { $$ = new GreaterEqNode($1, $3); }
RelationalExprNoBF:
ShiftExprNoBF
- | RelationalExprNoBF '<' ShiftExpr { $$ = new LessNode($1, $3); }
+ | RelationalExprNoBF '<' ShiftExpr { $$ = makeLessNode($1, $3); }
| RelationalExprNoBF '>' ShiftExpr { $$ = new GreaterNode($1, $3); }
| RelationalExprNoBF LE ShiftExpr { $$ = new LessEqNode($1, $3); }
| RelationalExprNoBF GE ShiftExpr { $$ = new GreaterEqNode($1, $3); }
%%
+static AddNode* makeAddNode(ExpressionNode* left, ExpressionNode* right)
+{
+ JSType t1 = left->expectedReturnType();
+ JSType t2 = right->expectedReturnType();
+
+ if (t1 == NumberType && t2 == NumberType)
+ return new AddNumbersNode(left, right);
+ if (t1 == StringType && t2 == StringType)
+ return new AddStringsNode(left, right);
+ if (t1 == StringType)
+ return new AddStringLeftNode(left, right);
+ if (t2 == StringType)
+ return new AddStringRightNode(left, right);
+ return new AddNode(left, right);
+}
+
+static LessNode* makeLessNode(ExpressionNode* left, ExpressionNode* right)
+{
+ JSType t1 = left->expectedReturnType();
+ JSType t2 = right->expectedReturnType();
+
+ if (t1 == StringType && t2 == StringType)
+ return new LessStringsNode(left, right);
+
+ // There are certainly more efficient ways to do this type check if necessary
+ if (t1 == NumberType || t1 == BooleanType || t1 == UndefinedType || t1 == NullType ||
+ t2 == NumberType || t2 == BooleanType || t2 == UndefinedType || t2 == NullType)
+ return new LessNumbersNode(left, right);
+
+ // Neither is certain to be a number, nor were both certain to be strings, so we use the default (slow) implementation.
+ return new LessNode(left, right);
+}
+
static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr)
{
if (!loc->isLocation())
return const_cast<StringImp*>(this);
}
-bool StringImp::getPrimitiveNumber(ExecState*, double& number) const
+bool StringImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
{
+ value = this;
number = val.toDouble();
return false;
}
return const_cast<NumberImp*>(this);
}
-bool NumberImp::getPrimitiveNumber(ExecState*, double& number) const
+bool NumberImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
{
number = val;
+ value = this;
return true;
}
return jsNull();
}
-bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number) const
+bool GetterSetterImp::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
{
- ASSERT(false);
+ ASSERT_NOT_REACHED();
number = 0;
+ value = 0;
return true;
}
virtual JSType type() const { return StringType; }
virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState *exec) const;
virtual double toNumber(ExecState *exec) const;
virtual JSObject *toObject(ExecState *exec) const;
virtual JSType type() const { return NumberType; }
virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState *exec) const;
virtual double toNumber(ExecState *exec) const;
virtual UString toString(ExecState *exec) const;
restrKeyword = true;
break;
case String:
- kjsyylval.ustr = makeUString(buffer16, pos16);
+ kjsyylval.string = makeUString(buffer16, pos16);
token = STRING;
break;
case Number:
- kjsyylval.dval = dval;
+ kjsyylval.doubleValue = dval;
token = NUMBER;
break;
case Bad:
Node::Node()
: m_mayHaveDeclarations(false)
+ , m_expectedReturnType(ObjectType)
{
#ifndef NDEBUG
++NodeCounter::count;
newNodes->add(this);
}
+Node::Node(JSType expectedReturn)
+ : m_mayHaveDeclarations(false)
+ , m_expectedReturnType(expectedReturn)
+{
+#ifndef NDEBUG
+ ++NodeCounter::count;
+#endif
+ m_line = Lexer::curr()->lineNo();
+ if (!newNodes)
+ newNodes = new HashSet<Node*>;
+ newNodes->add(this);
+}
+
Node::~Node()
{
#ifndef NDEBUG
// ------------------------------ StringNode -----------------------------------
-JSValue *StringNode::evaluate(ExecState *)
+JSValue* StringNode::evaluate(ExecState*)
{
- return jsOwnedString(value);
+ return jsOwnedString(m_value);
}
double StringNode::evaluateToNumber(ExecState*)
{
- return value.toDouble();
+ return m_value.toDouble();
}
bool StringNode::evaluateToBoolean(ExecState*)
{
- return !value.isEmpty();
+ return !m_value.isEmpty();
}
// ------------------------------ RegExpNode -----------------------------------
-JSValue *RegExpNode::evaluate(ExecState *exec)
+JSValue* RegExpNode::evaluate(ExecState* exec)
{
List list;
- list.append(jsOwnedString(pattern));
- list.append(jsOwnedString(flags));
+ list.append(jsOwnedString(m_pattern));
+ list.append(jsOwnedString(m_flags));
- JSObject *reg = exec->lexicalInterpreter()->builtinRegExp();
- return reg->construct(exec,list);
+ JSObject* reg = exec->lexicalInterpreter()->builtinRegExp();
+ return reg->construct(exec, list);
}
// ------------------------------ ThisNode -------------------------------------
void UnaryPlusNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
{
- nodeStack.append(expr.get());
+ nodeStack.append(m_expr.get());
}
// ECMA 11.4.6
-JSValue *UnaryPlusNode::evaluate(ExecState *exec)
+JSValue* UnaryPlusNode::evaluate(ExecState* exec)
{
- JSValue *v = expr->evaluate(exec);
+ JSValue *v = m_expr->evaluate(exec);
KJS_CHECKEXCEPTIONVALUE
return v->toJSNumber(exec);
{
double n1 = term1->evaluateToNumber(exec);
KJS_CHECKEXCEPTIONNUMBER
-
double n2 = term2->evaluateToNumber(exec);
- KJS_CHECKEXCEPTIONNUMBER
-
return n1 * n2;
}
{
double n1 = term1->evaluateToNumber(exec);
KJS_CHECKEXCEPTIONNUMBER
-
double n2 = term2->evaluateToNumber(exec);
- KJS_CHECKEXCEPTIONNUMBER
-
return n1 / n2;
}
{
double n1 = term1->evaluateToNumber(exec);
KJS_CHECKEXCEPTIONNUMBER
-
double n2 = term2->evaluateToNumber(exec);
- KJS_CHECKEXCEPTIONNUMBER
-
return fmod(n1, n2);
}
}
// ECMA 11.6.1
-JSValue *AddNode::evaluate(ExecState *exec)
+JSValue* AddNode::evaluate(ExecState* exec)
{
- JSValue *v1 = term1->evaluate(exec);
+ JSValue* v1 = term1->evaluate(exec);
KJS_CHECKEXCEPTIONVALUE
- JSValue *v2 = term2->evaluate(exec);
+ JSValue* v2 = term2->evaluate(exec);
KJS_CHECKEXCEPTIONVALUE
return add(exec, v1, v2);
double AddNode::evaluateToNumber(ExecState* exec)
{
- JSValue *v1 = term1->evaluate(exec);
+ JSValue* v1 = term1->evaluate(exec);
KJS_CHECKEXCEPTIONNUMBER
- JSValue *v2 = term2->evaluate(exec);
+ JSValue* v2 = term2->evaluate(exec);
KJS_CHECKEXCEPTIONNUMBER
return addToNumber(exec, v1, v2);
}
+double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
+{
+ double n1 = term1->evaluateToNumber(exec);
+ KJS_CHECKEXCEPTIONNUMBER
+ double n2 = term2->evaluateToNumber(exec);
+ return n1 + n2;
+}
+
+JSValue* AddNumbersNode::evaluate(ExecState* exec)
+{
+ return jsNumber(inlineEvaluateToNumber(exec));
+}
+
+double AddNumbersNode::evaluateToNumber(ExecState* exec)
+{
+ return inlineEvaluateToNumber(exec);
+}
+
+JSValue* AddStringsNode::evaluate(ExecState* exec)
+{
+ JSValue* v1 = term1->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ JSValue* v2 = term2->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
+}
+
+JSValue* AddStringLeftNode::evaluate(ExecState* exec)
+{
+ JSValue* v1 = term1->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ JSValue* v2 = term2->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
+ return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
+}
+
+JSValue* AddStringRightNode::evaluate(ExecState* exec)
+{
+ JSValue* v1 = term1->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ JSValue* v2 = term2->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+
+ JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
+ return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
+}
+
void SubNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
{
nodeStack.append(term1.get());
{
double n1 = term1->evaluateToNumber(exec);
KJS_CHECKEXCEPTIONNUMBER
-
double n2 = term2->evaluateToNumber(exec);
- KJS_CHECKEXCEPTIONNUMBER
-
return n1 - n2;
}
{
double n1;
double n2;
- bool wasNotString1 = v1->getPrimitiveNumber(exec, n1);
- bool wasNotString2 = v2->getPrimitiveNumber(exec, n2);
+ JSValue* p1;
+ JSValue* p2;
+ bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
+ bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
if (wasNotString1 | wasNotString2)
return n1 < n2;
- return v1->toString(exec) < v2->toString(exec);
+ return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
}
static inline bool lessThanEq(ExecState *exec, JSValue* v1, JSValue* v2)
{
double n1;
double n2;
- bool wasNotString1 = v1->getPrimitiveNumber(exec, n1);
- bool wasNotString2 = v2->getPrimitiveNumber(exec, n2);
+ JSValue* p1;
+ JSValue* p2;
+ bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
+ bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
if (wasNotString1 | wasNotString2)
return n1 <= n2;
- return !(v2->toString(exec) < v1->toString(exec));
+ return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
}
void LessNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
return lessThan(exec, v1, v2);
}
+JSValue* LessNumbersNode::evaluate(ExecState* exec)
+{
+ double n1 = expr1->evaluateToNumber(exec);
+ KJS_CHECKEXCEPTIONVALUE
+ double n2 = expr2->evaluateToNumber(exec);
+ return jsBoolean(n1 < n2);
+}
+
+JSValue* LessStringsNode::evaluate(ExecState* exec)
+{
+ JSValue* v1 = expr1->evaluate(exec);
+ KJS_CHECKEXCEPTIONVALUE
+ JSValue* v2 = expr2->evaluate(exec);
+ return jsBoolean(static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value());
+}
+
void GreaterNode::optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack& nodeStack)
{
nodeStack.append(expr2.get());
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
protected:
+ Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
Completion rethrowException(ExecState*) KJS_FAST_CALL;
- int m_line : 31;
+ int m_line : 28;
bool m_mayHaveDeclarations : 1;
+ unsigned m_expectedReturnType : 3; // JSType
};
class ExpressionNode : public Node {
public:
- ExpressionNode() KJS_FAST_CALL { }
+ ExpressionNode() KJS_FAST_CALL : Node() {}
+ ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
+ : Node(expectedReturn) {}
// Special constructor for cases where we overwrite an object in place.
ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
- : Node(PlacementNewAdopt)
- {
- }
+ : Node(PlacementNewAdopt) {}
virtual bool isNumber() const KJS_FAST_CALL { return false; }
virtual bool isLocation() const KJS_FAST_CALL { return false; }
virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
+ JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
+
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class NullNode : public ExpressionNode {
public:
- NullNode() KJS_FAST_CALL { }
+ NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecPrimary; }
class FalseNode : public ExpressionNode {
public:
- FalseNode() KJS_FAST_CALL { }
+ FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class TrueNode : public ExpressionNode {
public:
- TrueNode() KJS_FAST_CALL { }
+ TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class NumberNode : public ExpressionNode {
public:
- NumberNode(double v) KJS_FAST_CALL : m_double(v) {}
+ NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {}
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
private:
- JSValue* m_value;
+ JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
};
class StringNode : public ExpressionNode {
public:
- StringNode(const UString *v) KJS_FAST_CALL { value = *v; }
+ StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {}
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecPrimary; }
private:
- UString value;
+ UString m_value;
};
class RegExpNode : public ExpressionNode {
public:
- RegExpNode(const UString &p, const UString &f) KJS_FAST_CALL
- : pattern(p), flags(f) { }
+ RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
+ : m_pattern(pattern), m_flags(flags) { }
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecPrimary; }
private:
- UString pattern, flags;
+ UString m_pattern;
+ UString m_flags;
};
class ThisNode : public ExpressionNode {
class PrePostResolveNode : public ExpressionNode {
public:
- PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
+ PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {}
PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
: ExpressionNode(PlacementNewAdopt)
class TypeOfResolveNode : public ExpressionNode {
public:
TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL
- : m_ident(s)
- {
- }
+ : ExpressionNode(StringType), m_ident(s) {}
TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
: ExpressionNode(PlacementNewAdopt)
, m_ident(PlacementNewAdopt)
{
+ m_expectedReturnType = StringType;
}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
public:
LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
: TypeOfResolveNode(PlacementNewAdopt)
- {
+ {
+ m_expectedReturnType = StringType;
ASSERT(i != missingSymbolMarker());
m_index = i;
}
class TypeOfValueNode : public ExpressionNode {
public:
- TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
+ TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class UnaryPlusNode : public ExpressionNode {
public:
- UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
+ UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecUnary; }
private:
- RefPtr<ExpressionNode> expr;
+ RefPtr<ExpressionNode> m_expr;
};
class NegateNode : public ExpressionNode {
public:
- NegateNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
+ NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
class BitwiseNotNode : public ExpressionNode {
public:
- BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
+ BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class LogicalNotNode : public ExpressionNode {
public:
- LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
+ LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class MultNode : public ExpressionNode {
public:
- MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
+ MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
class DivNode : public ExpressionNode {
public:
- DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
+ DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
class ModNode : public ExpressionNode {
public:
- ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
+ ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
class AddNode : public ExpressionNode {
public:
- AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
+ AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecAdditive; }
- private:
+ protected:
+ AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
RefPtr<ExpressionNode> term1;
RefPtr<ExpressionNode> term2;
};
-
+
+ class AddNumbersNode : public AddNode {
+ public:
+ AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+ private:
+ ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
+ };
+
+ class AddStringLeftNode : public AddNode {
+ public:
+ AddStringLeftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ };
+
+ class AddStringRightNode : public AddNode {
+ public:
+ AddStringRightNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ };
+
+ class AddStringsNode : public AddNode {
+ public:
+ AddStringsNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ };
+
class SubNode : public ExpressionNode {
public:
- SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
+ SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
class LeftShiftNode : public ExpressionNode {
public:
- LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
- : term1(t1), term2(t2) {}
+ LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class RightShiftNode : public ExpressionNode {
public:
- RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
- : term1(t1), term2(t2) {}
+ RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class UnsignedRightShiftNode : public ExpressionNode {
public:
- UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
- : term1(t1), term2(t2) {}
+ UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), term1(t1), term2(t2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class LessNode : public ExpressionNode {
public:
- LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
virtual Precedence precedence() const { return PrecRelational; }
- private:
+ protected:
RefPtr<ExpressionNode> expr1;
RefPtr<ExpressionNode> expr2;
};
+ class LessNumbersNode : public LessNode {
+ public:
+ LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : LessNode(e1, e2) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ };
+
+ class LessStringsNode : public LessNode {
+ public:
+ LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : LessNode(e1, e2) {}
+ virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+ };
+
class GreaterNode : public ExpressionNode {
public:
GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
class InstanceOfNode : public ExpressionNode {
public:
- InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class EqualNode : public ExpressionNode {
public:
EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
- : expr1(e1), expr2(e2) {}
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class NotEqualNode : public ExpressionNode {
public:
NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
- : expr1(e1), expr2(e2) {}
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class StrictEqualNode : public ExpressionNode {
public:
StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
- : expr1(e1), expr2(e2) {}
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class NotStrictEqualNode : public ExpressionNode {
public:
NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
- : expr1(e1), expr2(e2) {}
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class BitAndNode : public ExpressionNode {
public:
- BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class BitOrNode : public ExpressionNode {
public:
- BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
class BitXOrNode : public ExpressionNode {
public:
- BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
*/
class LogicalAndNode : public ExpressionNode {
public:
- LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
class LogicalOrNode : public ExpressionNode {
public:
- LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
- expr1(e1), expr2(e2) {}
+ LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
+ : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
void StringNode::streamTo(SourceStream& s) const
{
- s << '"' << escapeStringForPrettyPrinting(value) << '"';
+ s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
}
void RegExpNode::streamTo(SourceStream& s) const
{
- s << '/' << pattern << '/' << flags;
+ s << '/' << m_pattern << '/' << m_flags;
}
void ThisNode::streamTo(SourceStream& s) const
void UnaryPlusNode::streamTo(SourceStream& s) const
{
- s << "+ " << PrecUnary << expr;
+ s << "+ " << PrecUnary << m_expr;
}
void NegateNode::streamTo(SourceStream& s) const
return NULL;
}
-bool JSObject::getPrimitiveNumber(ExecState* exec, double& number) const
+bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& result)
{
- JSValue* result = defaultValue(exec, NumberType);
+ result = defaultValue(exec, NumberType);
number = result->toNumber(exec);
return !result->isString();
}
GetterSetterImp() : getter(0), setter(0) { }
virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState *exec) const;
virtual double toNumber(ExecState *exec) const;
virtual UString toString(ExecState *exec) const;
virtual void getPropertyNames(ExecState*, PropertyNameArray&);
virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number) const;
+ virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState *exec) const;
virtual double toNumber(ExecState *exec) const;
virtual UString toString(ExecState *exec) const;
// Basic conversions.
JSValue* toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;
- bool getPrimitiveNumber(ExecState* exec, double& number) const;
+ bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);
bool toBoolean(ExecState *exec) const;
double toNumber(ExecState *exec) const;
// Basic conversions.
virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0;
- virtual bool getPrimitiveNumber(ExecState* exec, double& number) const = 0;
+ virtual bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value) = 0;
virtual bool toBoolean(ExecState *exec) const = 0;
virtual double toNumber(ExecState *exec) const = 0;
virtual UString toString(ExecState *exec) const = 0;
return JSImmediate::isImmediate(this) ? const_cast<JSValue*>(this) : asCell()->toPrimitive(exec, preferredType);
}
-inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number) const
+inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value)
{
if (JSImmediate::isImmediate(this)) {
number = JSImmediate::toDouble(this);
+ value = this;
return true;
}
- return asCell()->getPrimitiveNumber(exec, number);
+ return asCell()->getPrimitiveNumber(exec, number, value);
}
inline bool JSValue::toBoolean(ExecState *exec) const
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,