#include "SourceCode.h"
#include "SymbolTable.h"
#include <wtf/MathExtras.h>
-#include <wtf/OwnPtr.h>
namespace JSC {
class ArgumentListNode;
- class CodeBlock;
class BytecodeGenerator;
- class FuncDeclNode;
- class EvalCodeBlock;
- class JSFunction;
- class ProgramCodeBlock;
+ class FunctionBodyNode;
+ class Label;
class PropertyListNode;
class ReadModifyResolveNode;
class RegisterID;
class ScopeChainNode;
+ class ScopeNode;
typedef unsigned CodeFeatures;
const CodeFeatures WithFeature = 1 << 4;
const CodeFeatures CatchFeature = 1 << 5;
const CodeFeatures ThisFeature = 1 << 6;
- const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
+ const CodeFeatures StrictModeFeature = 1 << 7;
+ const CodeFeatures ShadowsArgumentsFeature = 1 << 8;
+
+
+ const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
enum Operator {
OpEqual,
OpLogicalOr
};
+ typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
+
namespace DeclarationStacks {
enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
- typedef Vector<std::pair<Identifier, unsigned> > VarStack;
- typedef Vector<FuncDeclNode*> FunctionStack;
+ typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
+ typedef Vector<FunctionBodyNode*> FunctionStack;
}
struct SwitchInfo {
SwitchType switchType;
};
- class ParserArenaDeletable {
- protected:
- ParserArenaDeletable() { }
+ class ParserArenaFreeable {
+ public:
+ // ParserArenaFreeable objects are are freed when the arena is deleted.
+ // Destructors are not called. Clients must not call delete on such objects.
+ void* operator new(size_t, JSGlobalData*);
+ };
+ class ParserArenaDeletable {
public:
virtual ~ParserArenaDeletable() { }
- // Objects created with this version of new are deleted when the arena is deleted.
+ // ParserArenaDeletable objects are deleted when the arena is deleted.
+ // Clients must not call delete directly on such objects.
void* operator new(size_t, JSGlobalData*);
-
- // Objects created with this version of new are not deleted when the arena is deleted.
- // Other arrangements must be made.
- void* operator new(size_t);
};
class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
}
};
- class Node : public ParserArenaDeletable {
+ class Node : public ParserArenaFreeable {
protected:
Node(JSGlobalData*);
public:
- /*
- Return value: The register holding the production's value.
- dst: An optional parameter specifying the most efficient
- destination at which to store the production's value.
- The callee must honor dst.
-
- dst provides for a crude form of copy propagation. For example,
+ virtual ~Node() { }
- x = 1
-
- becomes
-
- load r[x], 1
-
- instead of
-
- load r0, 1
- mov r[x], r0
-
- because the assignment node, "x =", passes r[x] as dst to the number
- node, "1".
- */
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) = 0;
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
int lineNo() const { return m_line; }
};
class ExpressionNode : public Node {
- public:
+ protected:
ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
+ public:
virtual bool isNumber() const { return false; }
virtual bool isString() const { return false; }
virtual bool isNull() const { return false; }
virtual bool isCommaNode() const { return false; }
virtual bool isSimpleArray() const { return false; }
virtual bool isAdd() const { return false; }
+ virtual bool isSubtract() const { return false; }
+ virtual bool hasConditionContextCodegen() const { return false; }
+
+ virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
virtual ExpressionNode* stripUnaryPlus() { return this; }
ResultType resultDescriptor() const { return m_resultType; }
- // This needs to be in public in order to compile using GCC 3.x
- typedef enum { EvalOperator, FunctionCall } CallerType;
-
private:
ResultType m_resultType;
};
class StatementNode : public Node {
- public:
+ protected:
StatementNode(JSGlobalData*);
- void setLoc(int line0, int line1);
+ public:
+ void setLoc(int firstLine, int lastLine);
int firstLine() const { return lineNo(); }
int lastLine() const { return m_lastLine; }
class NumberNode : public ExpressionNode {
public:
- NumberNode(JSGlobalData*, double v);
+ NumberNode(JSGlobalData*, double value);
- double value() const { return m_double; }
- void setValue(double d) { m_double = d; }
+ double value() const { return m_value; }
+ void setValue(double value) { m_value = value; }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isNumber() const { return true; }
virtual bool isPure(BytecodeGenerator&) const { return true; }
- double m_double;
+ double m_value;
};
class StringNode : public ExpressionNode {
public:
- StringNode(JSGlobalData*, const Identifier& v);
+ StringNode(JSGlobalData*, const Identifier&);
const Identifier& value() { return m_value; }
- virtual bool isPure(BytecodeGenerator&) const { return true; }
private:
+ virtual bool isPure(BytecodeGenerator&) const { return true; }
+
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isString() const { return true; }
- Identifier m_value;
+ const Identifier& m_value;
};
class ThrowableExpressionData {
uint16_t endOffset() const { return m_endOffset; }
protected:
- RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
- RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
+ RegisterID* emitThrowReferenceError(BytecodeGenerator&, const UString& message);
private:
uint32_t m_divot;
class ThrowableSubExpressionData : public ThrowableExpressionData {
public:
ThrowableSubExpressionData()
- : ThrowableExpressionData()
- , m_subexpressionDivotOffset(0)
+ : m_subexpressionDivotOffset(0)
, m_subexpressionEndOffset(0)
{
}
class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
public:
ThrowablePrefixedSubExpressionData()
- : ThrowableExpressionData()
- , m_subexpressionDivotOffset(0)
+ : m_subexpressionDivotOffset(0)
, m_subexpressionStartOffset(0)
{
}
class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
public:
- RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags);
+ RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- UString m_pattern;
- UString m_flags;
+ const Identifier& m_pattern;
+ const Identifier& m_flags;
};
class ThisNode : public ExpressionNode {
virtual bool isLocation() const { return true; }
virtual bool isResolveNode() const { return true; }
- Identifier m_ident;
+ const Identifier& m_ident;
int32_t m_startOffset;
};
- class ElementNode : public ParserArenaDeletable {
+ class ElementNode : public ParserArenaFreeable {
public:
ElementNode(JSGlobalData*, int elision, ExpressionNode*);
ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
bool m_optional;
};
- class PropertyNode : public ParserArenaDeletable {
+ class PropertyNode : public ParserArenaFreeable {
public:
- enum Type { Constant, Getter, Setter };
+ enum Type { Constant = 1, Getter = 2, Setter = 4 };
PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
+ PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
const Identifier& name() const { return m_name; }
+ Type type() const { return m_type; }
private:
friend class PropertyListNode;
- Identifier m_name;
+ const Identifier& m_name;
ExpressionNode* m_assign;
Type m_type;
};
virtual bool isDotAccessorNode() const { return true; }
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
};
class ArgumentListNode : public Node {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
};
- class ArgumentsNode : public ParserArenaDeletable {
+ class ArgumentsNode : public ParserArenaFreeable {
public:
ArgumentsNode(JSGlobalData*);
ArgumentsNode(JSGlobalData*, ArgumentListNode*);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
ArgumentsNode* m_args;
size_t m_index; // Used by LocalVarFunctionCallNode.
size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
protected:
ExpressionNode* m_base;
- const Identifier m_ident;
+ const Identifier& m_ident;
ArgumentsNode* m_args;
};
PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
protected:
- const Identifier m_ident;
+ const Identifier& m_ident;
};
class PostfixResolveNode : public PrePostResolveNode {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
Operator m_operator;
};
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
};
class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
};
class DeleteValueNode : public ExpressionNode {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
};
class TypeOfValueNode : public ExpressionNode {
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
Operator m_operator;
};
protected:
ExpressionNode* expr() { return m_expr; }
+ const ExpressionNode* expr() const { return m_expr; }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class LogicalNotNode : public UnaryOpNode {
public:
LogicalNotNode(JSGlobalData*, ExpressionNode*);
+ private:
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
+ virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
};
class BinaryOpNode : public ExpressionNode {
BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
- RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+ RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+
+ ExpressionNode* lhs() { return m_expr1; };
+ ExpressionNode* rhs() { return m_expr2; };
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
class SubNode : public BinaryOpNode {
public:
SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+
+ virtual bool isSubtract() const { return true; }
};
class LeftShiftNode : public BinaryOpNode {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
+ virtual bool hasConditionContextCodegen() const { return true; }
ExpressionNode* m_expr1;
ExpressionNode* m_expr2;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
ExpressionNode* m_right;
size_t m_index; // Used by ReadModifyLocalVarNode.
Operator m_operator;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
ExpressionNode* m_right;
size_t m_index; // Used by ReadModifyLocalVarNode.
bool m_rightHasAssignments;
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
ExpressionNode* m_right;
bool m_rightHasAssignments;
};
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
ExpressionNode* m_base;
- Identifier m_ident;
+ const Identifier& m_ident;
ExpressionNode* m_right;
Operator m_operator : 31;
bool m_rightHasAssignments : 1;
typedef Vector<ExpressionNode*, 8> ExpressionVector;
- class CommaNode : public ExpressionNode {
+ class CommaNode : public ExpressionNode, public ParserArenaDeletable {
public:
CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
+ using ParserArenaDeletable::operator new;
+
void append(ExpressionNode* expr) { m_expressions.append(expr); }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
- Identifier m_ident;
+ const Identifier& m_ident;
public:
ConstDeclNode* m_next;
ConstDeclNode* m_next;
};
- typedef Vector<StatementNode*> StatementVector;
-
class SourceElements : public ParserArenaDeletable {
public:
SourceElements(JSGlobalData*);
void append(StatementNode*);
- void releaseContentsIntoVector(StatementVector& destination)
- {
- ASSERT(destination.isEmpty());
- m_statements.swap(destination);
- destination.shrinkToFit();
- }
+
+ StatementNode* singleStatement() const;
+ StatementNode* lastStatement() const;
+
+ void emitBytecode(BytecodeGenerator&, RegisterID* destination);
private:
- StatementVector m_statements;
+ Vector<StatementNode*> m_statements;
};
class BlockNode : public StatementNode {
public:
- BlockNode(JSGlobalData*, SourceElements* children);
+ BlockNode(JSGlobalData*, SourceElements* = 0);
- StatementVector& children() { return m_children; }
+ StatementNode* singleStatement() const;
+ StatementNode* lastStatement() const;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isBlock() const { return true; }
- StatementVector m_children;
+ SourceElements* m_statements;
};
class EmptyStatementNode : public StatementNode {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
ExpressionNode* m_init;
ExpressionNode* m_lexpr;
ExpressionNode* m_expr;
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
};
class BreakNode : public StatementNode, public ThrowableExpressionData {
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_ident;
+ const Identifier& m_ident;
};
class ReturnNode : public StatementNode, public ThrowableExpressionData {
public:
ReturnNode(JSGlobalData*, ExpressionNode* value);
+ ExpressionNode* value() { return m_value; }
+
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- Identifier m_name;
+ const Identifier& m_name;
StatementNode* m_statement;
};
TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
private:
- virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0);
+ virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
StatementNode* m_tryBlock;
- Identifier m_exceptionIdent;
+ const Identifier& m_exceptionIdent;
StatementNode* m_catchBlock;
StatementNode* m_finallyBlock;
bool m_catchHasEval;
};
- class ParameterNode : public ParserArenaDeletable {
+ class ParameterNode : public ParserArenaFreeable {
public:
ParameterNode(JSGlobalData*, const Identifier&);
ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
ParameterNode* nextParam() const { return m_next; }
private:
- Identifier m_ident;
+ const Identifier& m_ident;
ParameterNode* m_next;
};
struct ScopeNodeData {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
+ ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
ParserArena m_arena;
VarStack m_varStack;
FunctionStack m_functionStack;
int m_numConstants;
- StatementVector m_children;
-
- void mark();
+ SourceElements* m_statements;
+ IdentifierSet m_capturedVariables;
};
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
- ScopeNode(JSGlobalData*);
- ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);
+ ScopeNode(JSGlobalData*, bool inStrictContext);
+ ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+
+ using ParserArenaRefCounted::operator new;
- void adoptData(std::auto_ptr<ScopeNodeData> data)
- {
- ASSERT(!data->m_arena.contains(this));
- ASSERT(!m_data);
- m_data.adopt(data);
- }
ScopeNodeData* data() const { return m_data.get(); }
void destroyData() { m_data.clear(); }
CodeFeatures features() { return m_features; }
bool usesEval() const { return m_features & EvalFeature; }
- bool usesArguments() const { return m_features & ArgumentsFeature; }
+ bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
+ bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+ bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
- StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
-
int neededConstants()
{
ASSERT(m_data);
return m_data->m_numConstants + 2;
}
- virtual void mark() { }
-
-#if ENABLE(JIT)
- JITCode& generatedJITCode()
- {
- ASSERT(m_jitCode);
- return m_jitCode;
- }
-
- ExecutablePool* getExecutablePool()
- {
- return m_jitCode.getExecutablePool();
- }
+ StatementNode* singleStatement() const;
- void setJITCode(const JITCode jitCode)
- {
- m_jitCode = jitCode;
- }
-#endif
+ void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
protected:
void setSource(const SourceCode& source) { m_source = source; }
-#if ENABLE(JIT)
- JITCode m_jitCode;
-#endif
-
private:
OwnPtr<ScopeNodeData> m_data;
CodeFeatures m_features;
class ProgramNode : public ScopeNode {
public:
- static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ static const bool isFunctionNode = false;
+ static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain)
- {
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
-
-#if ENABLE(JIT)
- JITCode& jitCode(ScopeChainNode* scopeChain)
- {
- if (!m_jitCode)
- generateJITCode(scopeChain);
- return m_jitCode;
- }
-#endif
+ static const bool scopeIsFunction = false;
private:
- ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- void generateBytecode(ScopeChainNode*);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-#if ENABLE(JIT)
- void generateJITCode(ScopeChainNode*);
-#endif
-
- OwnPtr<ProgramCodeBlock> m_code;
};
class EvalNode : public ScopeNode {
public:
- static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ static const bool isFunctionNode = false;
+ static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- EvalCodeBlock& bytecode(ScopeChainNode* scopeChain)
- {
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
-
- EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
-
- virtual void mark();
-
-#if ENABLE(JIT)
- JITCode& jitCode(ScopeChainNode* scopeChain)
- {
- if (!m_jitCode)
- generateJITCode(scopeChain);
- return m_jitCode;
- }
-#endif
+ static const bool scopeIsFunction = false;
private:
- EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- void generateBytecode(ScopeChainNode*);
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+ };
-#if ENABLE(JIT)
- void generateJITCode(ScopeChainNode*);
-#endif
-
- OwnPtr<EvalCodeBlock> m_code;
+ class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
+ WTF_MAKE_FAST_ALLOCATED;
+ public:
+ static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
+
+ private:
+ FunctionParameters(ParameterNode*);
};
class FunctionBodyNode : public ScopeNode {
- friend class JIT;
public:
-#if ENABLE(JIT)
- static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*);
-#endif
- static FunctionBodyNode* create(JSGlobalData*);
- static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
- virtual ~FunctionBodyNode();
+ static const bool isFunctionNode = true;
+ static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode);
+ static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- const Identifier* parameters() const { return m_parameters; }
- size_t parameterCount() const { return m_parameterCount; }
- UString paramString() const ;
- Identifier* copyParameters();
+ FunctionParameters* parameters() const { return m_parameters.get(); }
+ size_t parameterCount() const { return m_parameters->size(); }
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- bool isGenerated() const
- {
- return m_code;
- }
-
- bool isHostFunction() const;
-
- virtual void mark();
-
- void finishParsing(const SourceCode&, ParameterNode*);
- void finishParsing(Identifier* parameters, size_t parameterCount);
+ void finishParsing(const SourceCode&, ParameterNode*, const Identifier&);
+ void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&);
- UString toSourceString() const { return source().toString(); }
+ const Identifier& ident() { return m_ident; }
- CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
-#if ENABLE(JIT)
- JITCode& jitCode(ScopeChainNode* scopeChain)
- {
- if (!m_jitCode)
- generateJITCode(scopeChain);
- return m_jitCode;
- }
-#endif
+ static const bool scopeIsFunction = true;
- CodeBlock& bytecode(ScopeChainNode* scopeChain)
- {
- ASSERT(scopeChain);
- if (!m_code)
- generateBytecode(scopeChain);
- return *m_code;
- }
-
- CodeBlock& generatedBytecode()
- {
- ASSERT(m_code);
- return *m_code;
- }
-
private:
- FunctionBodyNode(JSGlobalData*);
- FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+ FunctionBodyNode(JSGlobalData*, bool inStrictContext);
+ FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
- void generateBytecode(ScopeChainNode*);
-#if ENABLE(JIT)
- void generateJITCode(ScopeChainNode*);
-#endif
- Identifier* m_parameters;
- size_t m_parameterCount;
- OwnPtr<CodeBlock> m_code;
+ Identifier m_ident;
+ RefPtr<FunctionParameters> m_parameters;
};
- class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted {
+ class FuncExprNode : public ExpressionNode {
public:
FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
- JSFunction* makeFunction(ExecState*, ScopeChainNode*);
-
- FunctionBodyNode* body() { return m_body.get(); }
+ FunctionBodyNode* body() { return m_body; }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
virtual bool isFuncExprNode() const { return true; }
- Identifier m_ident;
- RefPtr<FunctionBodyNode> m_body;
+ FunctionBodyNode* m_body;
};
- class FuncDeclNode : public StatementNode, public ParserArenaRefCounted {
+ class FuncDeclNode : public StatementNode {
public:
FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
- JSFunction* makeFunction(ExecState*, ScopeChainNode*);
-
- Identifier m_ident;
-
- FunctionBodyNode* body() { return m_body.get(); }
+ FunctionBodyNode* body() { return m_body; }
private:
virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
- RefPtr<FunctionBodyNode> m_body;
+ FunctionBodyNode* m_body;
};
- class CaseClauseNode : public ParserArenaDeletable {
+ class CaseClauseNode : public ParserArenaFreeable {
public:
- CaseClauseNode(JSGlobalData*, ExpressionNode*);
- CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*);
+ CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
ExpressionNode* expr() const { return m_expr; }
- StatementVector& children() { return m_children; }
+
+ void emitBytecode(BytecodeGenerator&, RegisterID* destination);
private:
ExpressionNode* m_expr;
- StatementVector m_children;
+ SourceElements* m_statements;
};
- class ClauseListNode : public ParserArenaDeletable {
+ class ClauseListNode : public ParserArenaFreeable {
public:
ClauseListNode(JSGlobalData*, CaseClauseNode*);
ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
ClauseListNode* m_next;
};
- class CaseBlockNode : public ParserArenaDeletable {
+ class CaseBlockNode : public ParserArenaFreeable {
public:
CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
- RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0);
+ RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
private:
SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);