| Index: src/full-codegen.h
|
| ===================================================================
|
| --- src/full-codegen.h (revision 9006)
|
| +++ src/full-codegen.h (working copy)
|
| @@ -111,10 +111,7 @@
|
| private:
|
| class Breakable;
|
| class Iteration;
|
| - class TryCatch;
|
| - class TryFinally;
|
| - class Finally;
|
| - class ForIn;
|
| +
|
| class TestContext;
|
|
|
| class NestedStatement BASE_EMBEDDED {
|
| @@ -132,136 +129,137 @@
|
|
|
| virtual Breakable* AsBreakable() { return NULL; }
|
| virtual Iteration* AsIteration() { return NULL; }
|
| - virtual TryCatch* AsTryCatch() { return NULL; }
|
| - virtual TryFinally* AsTryFinally() { return NULL; }
|
| - virtual Finally* AsFinally() { return NULL; }
|
| - virtual ForIn* AsForIn() { return NULL; }
|
|
|
| virtual bool IsContinueTarget(Statement* target) { return false; }
|
| virtual bool IsBreakTarget(Statement* target) { return false; }
|
|
|
| - // Generate code to leave the nested statement. This includes
|
| - // cleaning up any stack elements in use and restoring the
|
| - // stack to the expectations of the surrounding statements.
|
| - // Takes a number of stack elements currently on top of the
|
| - // nested statement's stack, and returns a number of stack
|
| - // elements left on top of the surrounding statement's stack.
|
| - // The generated code must preserve the result register (which
|
| - // contains the value in case of a return).
|
| - virtual int Exit(int stack_depth) {
|
| - // Default implementation for the case where there is
|
| - // nothing to clean up.
|
| - return stack_depth;
|
| + // Notify the statement that we are exiting it via break, continue, or
|
| + // return and give it a chance to generate cleanup code. Return the
|
| + // next outer statement in the nesting stack. We accumulate in
|
| + // *stack_depth the amount to drop the stack and in *context_length the
|
| + // number of context chain links to unwind as we traverse the nesting
|
| + // stack from an exit to its target.
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
|
| + return previous_;
|
| }
|
| - NestedStatement* outer() { return previous_; }
|
|
|
| protected:
|
| MacroAssembler* masm() { return codegen_->masm(); }
|
|
|
| - private:
|
| FullCodeGenerator* codegen_;
|
| NestedStatement* previous_;
|
| DISALLOW_COPY_AND_ASSIGN(NestedStatement);
|
| };
|
|
|
| + // A breakable statement such as a block.
|
| class Breakable : public NestedStatement {
|
| public:
|
| - Breakable(FullCodeGenerator* codegen,
|
| - BreakableStatement* break_target)
|
| - : NestedStatement(codegen),
|
| - target_(break_target) {}
|
| + Breakable(FullCodeGenerator* codegen, BreakableStatement* statement)
|
| + : NestedStatement(codegen), statement_(statement) {
|
| + }
|
| virtual ~Breakable() {}
|
| +
|
| virtual Breakable* AsBreakable() { return this; }
|
| - virtual bool IsBreakTarget(Statement* statement) {
|
| - return target_ == statement;
|
| + virtual bool IsBreakTarget(Statement* target) {
|
| + return statement() == target;
|
| }
|
| - BreakableStatement* statement() { return target_; }
|
| - Label* break_target() { return &break_target_label_; }
|
| +
|
| + BreakableStatement* statement() { return statement_; }
|
| + Label* break_label() { return &break_label_; }
|
| +
|
| private:
|
| - BreakableStatement* target_;
|
| - Label break_target_label_;
|
| - DISALLOW_COPY_AND_ASSIGN(Breakable);
|
| + BreakableStatement* statement_;
|
| + Label break_label_;
|
| };
|
|
|
| + // An iteration statement such as a while, for, or do loop.
|
| class Iteration : public Breakable {
|
| public:
|
| - Iteration(FullCodeGenerator* codegen,
|
| - IterationStatement* iteration_statement)
|
| - : Breakable(codegen, iteration_statement) {}
|
| + Iteration(FullCodeGenerator* codegen, IterationStatement* statement)
|
| + : Breakable(codegen, statement) {
|
| + }
|
| virtual ~Iteration() {}
|
| +
|
| virtual Iteration* AsIteration() { return this; }
|
| - virtual bool IsContinueTarget(Statement* statement) {
|
| - return this->statement() == statement;
|
| + virtual bool IsContinueTarget(Statement* target) {
|
| + return statement() == target;
|
| }
|
| - Label* continue_target() { return &continue_target_label_; }
|
| +
|
| + Label* continue_label() { return &continue_label_; }
|
| +
|
| private:
|
| - Label continue_target_label_;
|
| - DISALLOW_COPY_AND_ASSIGN(Iteration);
|
| + Label continue_label_;
|
| };
|
|
|
| - // The environment inside the try block of a try/catch statement.
|
| + // The try block of a try/catch statement.
|
| class TryCatch : public NestedStatement {
|
| public:
|
| - explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry)
|
| - : NestedStatement(codegen), catch_entry_(catch_entry) { }
|
| + explicit TryCatch(FullCodeGenerator* codegen) : NestedStatement(codegen) {
|
| + }
|
| virtual ~TryCatch() {}
|
| - virtual TryCatch* AsTryCatch() { return this; }
|
| - Label* catch_entry() { return catch_entry_; }
|
| - virtual int Exit(int stack_depth);
|
| - private:
|
| - Label* catch_entry_;
|
| - DISALLOW_COPY_AND_ASSIGN(TryCatch);
|
| +
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length);
|
| };
|
|
|
| - // The environment inside the try block of a try/finally statement.
|
| + // The try block of a try/finally statement.
|
| class TryFinally : public NestedStatement {
|
| public:
|
| - explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
|
| - : NestedStatement(codegen), finally_entry_(finally_entry) { }
|
| + TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
|
| + : NestedStatement(codegen), finally_entry_(finally_entry) {
|
| + }
|
| virtual ~TryFinally() {}
|
| - virtual TryFinally* AsTryFinally() { return this; }
|
| - Label* finally_entry() { return finally_entry_; }
|
| - virtual int Exit(int stack_depth);
|
| +
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length);
|
| +
|
| private:
|
| Label* finally_entry_;
|
| - DISALLOW_COPY_AND_ASSIGN(TryFinally);
|
| };
|
|
|
| - // A FinallyEnvironment represents being inside a finally block.
|
| - // Abnormal termination of the finally block needs to clean up
|
| - // the block's parameters from the stack.
|
| + // The finally block of a try/finally statement.
|
| class Finally : public NestedStatement {
|
| public:
|
| + static const int kElementCount = 2;
|
| +
|
| explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { }
|
| virtual ~Finally() {}
|
| - virtual Finally* AsFinally() { return this; }
|
| - virtual int Exit(int stack_depth) {
|
| - return stack_depth + kFinallyStackElementCount;
|
| +
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
|
| + *stack_depth += kElementCount;
|
| + return previous_;
|
| }
|
| - private:
|
| - // Number of extra stack slots occupied during a finally block.
|
| - static const int kFinallyStackElementCount = 2;
|
| - DISALLOW_COPY_AND_ASSIGN(Finally);
|
| };
|
|
|
| - // A ForInEnvironment represents being inside a for-in loop.
|
| - // Abnormal termination of the for-in block needs to clean up
|
| - // the block's temporary storage from the stack.
|
| + // The body of a for/in loop.
|
| class ForIn : public Iteration {
|
| public:
|
| - ForIn(FullCodeGenerator* codegen,
|
| - ForInStatement* statement)
|
| - : Iteration(codegen, statement) { }
|
| + static const int kElementCount = 5;
|
| +
|
| + ForIn(FullCodeGenerator* codegen, ForInStatement* statement)
|
| + : Iteration(codegen, statement) {
|
| + }
|
| virtual ~ForIn() {}
|
| - virtual ForIn* AsForIn() { return this; }
|
| - virtual int Exit(int stack_depth) {
|
| - return stack_depth + kForInStackElementCount;
|
| +
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
|
| + *stack_depth += kElementCount;
|
| + return previous_;
|
| }
|
| - private:
|
| - static const int kForInStackElementCount = 5;
|
| - DISALLOW_COPY_AND_ASSIGN(ForIn);
|
| };
|
|
|
| +
|
| + // The body of a with or catch.
|
| + class WithOrCatch : public NestedStatement {
|
| + public:
|
| + explicit WithOrCatch(FullCodeGenerator* codegen)
|
| + : NestedStatement(codegen) {
|
| + }
|
| + virtual ~WithOrCatch() {}
|
| +
|
| + virtual NestedStatement* Exit(int* stack_depth, int* context_length) {
|
| + ++(*context_length);
|
| + return previous_;
|
| + }
|
| + };
|
| +
|
| // The forward bailout stack keeps track of the expressions that can
|
| // bail out to just before the control flow is split in a child
|
| // node. The stack elements are linked together through the parent
|
|
|