]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - parser/Nodes.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / parser / Nodes.h
index a9f88b7378352994bf6ccf3049d8a0227fb1b0ce..6e73c00ccce939286826b3beb5a67d2537d82d4b 100644 (file)
 #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;
 
@@ -60,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,
@@ -84,10 +85,12 @@ namespace JSC {
         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 {
@@ -96,19 +99,20 @@ namespace JSC {
         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> {
@@ -122,34 +126,14 @@ namespace JSC {
         }
     };
 
-    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; }
 
@@ -158,9 +142,10 @@ namespace JSC {
     };
 
     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; }
@@ -173,23 +158,25 @@ 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(); }
 
         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; }
 
@@ -227,10 +214,10 @@ namespace JSC {
 
     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);
@@ -238,22 +225,23 @@ namespace JSC {
         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 {
@@ -284,8 +272,7 @@ namespace JSC {
         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;
@@ -296,8 +283,7 @@ namespace JSC {
     class ThrowableSubExpressionData : public ThrowableExpressionData {
     public:
         ThrowableSubExpressionData()
-            : ThrowableExpressionData()
-            , m_subexpressionDivotOffset(0)
+            : m_subexpressionDivotOffset(0)
             , m_subexpressionEndOffset(0)
         {
         }
@@ -326,8 +312,7 @@ namespace JSC {
     class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
     public:
         ThrowablePrefixedSubExpressionData()
-            : ThrowableExpressionData()
-            , m_subexpressionDivotOffset(0)
+            : m_subexpressionDivotOffset(0)
             , m_subexpressionStartOffset(0)
         {
         }
@@ -355,13 +340,13 @@ namespace JSC {
 
     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 {
@@ -385,11 +370,11 @@ namespace JSC {
         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*);
@@ -422,17 +407,19 @@ namespace JSC {
         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;
     };
@@ -492,7 +479,7 @@ namespace JSC {
         virtual bool isDotAccessorNode() const { return true; }
 
         ExpressionNode* m_base;
-        Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class ArgumentListNode : public Node {
@@ -507,7 +494,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
-    class ArgumentsNode : public ParserArenaDeletable {
+    class ArgumentsNode : public ParserArenaFreeable {
     public:
         ArgumentsNode(JSGlobalData*);
         ArgumentsNode(JSGlobalData*, ArgumentListNode*);
@@ -555,7 +542,7 @@ namespace JSC {
     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
@@ -582,7 +569,7 @@ namespace JSC {
 
     protected:
         ExpressionNode* m_base;
-        const Identifier m_ident;
+        const Identifier& m_ident;
         ArgumentsNode* m_args;
     };
 
@@ -607,7 +594,7 @@ namespace JSC {
         PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     protected:
-        const Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class PostfixResolveNode : public PrePostResolveNode {
@@ -640,7 +627,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_base;
-        Identifier m_ident;
+        const Identifier& m_ident;
         Operator m_operator;
     };
 
@@ -662,7 +649,7 @@ namespace JSC {
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
@@ -684,7 +671,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_base;
-        Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class DeleteValueNode : public ExpressionNode {
@@ -716,7 +703,7 @@ namespace JSC {
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class TypeOfValueNode : public ExpressionNode {
@@ -759,7 +746,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_base;
-        Identifier m_ident;
+        const Identifier& m_ident;
         Operator m_operator;
     };
 
@@ -780,6 +767,7 @@ namespace JSC {
 
     protected:
         ExpressionNode* expr() { return m_expr; }
+        const ExpressionNode* expr() const { return m_expr; }
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -811,6 +799,9 @@ namespace JSC {
     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 {
@@ -818,7 +809,10 @@ namespace JSC {
         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);
@@ -868,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 {
@@ -975,6 +971,8 @@ namespace JSC {
 
     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;
@@ -1001,7 +999,7 @@ namespace JSC {
     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;
@@ -1015,7 +1013,7 @@ namespace JSC {
     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;
@@ -1058,7 +1056,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_base;
-        Identifier m_ident;
+        const Identifier& m_ident;
         ExpressionNode* m_right;
         bool m_rightHasAssignments;
     };
@@ -1071,7 +1069,7 @@ namespace JSC {
         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;
@@ -1091,10 +1089,12 @@ namespace JSC {
     
     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:
@@ -1115,7 +1115,7 @@ namespace JSC {
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
         virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
 
-        Identifier m_ident;
+        const Identifier& m_ident;
 
     public:
         ConstDeclNode* m_next;
@@ -1134,36 +1134,34 @@ namespace JSC {
         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 {
@@ -1273,7 +1271,7 @@ namespace JSC {
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        Identifier m_ident;
+        const Identifier& m_ident;
         ExpressionNode* m_init;
         ExpressionNode* m_lexpr;
         ExpressionNode* m_expr;
@@ -1289,7 +1287,7 @@ namespace JSC {
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        Identifier m_ident;
+        const Identifier& m_ident;
     };
 
     class BreakNode : public StatementNode, public ThrowableExpressionData {
@@ -1300,13 +1298,15 @@ namespace JSC {
     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);
 
@@ -1335,7 +1335,7 @@ namespace JSC {
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        Identifier m_name;
+        const Identifier& m_name;
         StatementNode* m_statement;
     };
 
@@ -1354,16 +1354,16 @@ namespace JSC {
         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&);
@@ -1372,23 +1372,24 @@ namespace JSC {
         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 {
@@ -1396,15 +1397,11 @@ 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;
 
-        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(); }
 
@@ -1416,16 +1413,19 @@ 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; }
 
-        StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
-
         int neededConstants()
         {
             ASSERT(m_data);
@@ -1434,33 +1434,13 @@ namespace JSC {
             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;
@@ -1469,189 +1449,105 @@ namespace JSC {
 
     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*);
@@ -1664,11 +1560,11 @@ namespace JSC {
         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);