X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/4e4e5a6f2694187498445a6ac6f1634ce8141119..14957cd040308e3eeec43d26bae5d76da13fcd85:/parser/Nodes.h diff --git a/parser/Nodes.h b/parser/Nodes.h index 7852165..6e73c00 100644 --- a/parser/Nodes.h +++ b/parser/Nodes.h @@ -57,7 +57,11 @@ namespace JSC { 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, @@ -81,6 +85,8 @@ namespace JSC { OpLogicalOr }; + typedef HashSet, IdentifierRepHash> IdentifierSet; + namespace DeclarationStacks { enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; typedef Vector > VarStack; @@ -152,6 +158,7 @@ namespace JSC { 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(); } @@ -265,9 +272,7 @@ namespace JSC { uint16_t endOffset() const { return m_endOffset; } protected: - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message); - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const UString&); - RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const Identifier&); + RegisterID* emitThrowReferenceError(BytecodeGenerator&, const UString& message); private: uint32_t m_divot; @@ -404,12 +409,13 @@ namespace JSC { 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; @@ -805,6 +811,9 @@ namespace JSC { 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); @@ -853,6 +862,8 @@ namespace JSC { class SubNode : public BinaryOpNode { public: SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); + + virtual bool isSubtract() const { return true; } }; class LeftShiftNode : public BinaryOpNode { @@ -1142,6 +1153,7 @@ namespace JSC { public: BlockNode(JSGlobalData*, SourceElements* = 0); + StatementNode* singleStatement() const; StatementNode* lastStatement() const; private: @@ -1293,6 +1305,8 @@ namespace JSC { public: ReturnNode(JSGlobalData*, ExpressionNode* value); + ExpressionNode* value() { return m_value; } + private: virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); @@ -1362,17 +1376,20 @@ namespace JSC { ParameterNode* m_next; }; - struct ScopeNodeData : FastAllocBase { + 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; SourceElements* m_statements; + IdentifierSet m_capturedVariables; }; class ScopeNode : public StatementNode, public ParserArenaRefCounted { @@ -1380,8 +1397,8 @@ namespace JSC { 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; @@ -1396,10 +1413,15 @@ namespace JSC { 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; } @@ -1427,29 +1449,32 @@ namespace JSC { class ProgramNode : public ScopeNode { public: - static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); + static const bool isFunctionNode = false; + static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 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); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); }; class EvalNode : public ScopeNode { public: - static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); + static const bool isFunctionNode = false; + static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 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); virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); }; class FunctionParameters : public Vector, public RefCounted { + WTF_MAKE_FAST_ALLOCATED; public: static PassRefPtr create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); } @@ -1459,8 +1484,9 @@ namespace JSC { class FunctionBodyNode : public ScopeNode { public: - static FunctionBodyNode* create(JSGlobalData*); - static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); + static const bool isFunctionNode = true; + static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode); + static PassRefPtr create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); FunctionParameters* parameters() const { return m_parameters.get(); } size_t parameterCount() const { return m_parameters->size(); } @@ -1475,8 +1501,8 @@ namespace JSC { static const bool scopeIsFunction = true; 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); Identifier m_ident; RefPtr m_parameters;