diff options
Diffstat (limited to 'deps/v8/src/fast-codegen.h')
-rw-r--r-- | deps/v8/src/fast-codegen.h | 195 |
1 files changed, 193 insertions, 2 deletions
diff --git a/deps/v8/src/fast-codegen.h b/deps/v8/src/fast-codegen.h index 9b262a7393..54f0df1152 100644 --- a/deps/v8/src/fast-codegen.h +++ b/deps/v8/src/fast-codegen.h @@ -35,6 +35,8 @@ namespace v8 { namespace internal { +// ----------------------------------------------------------------------------- +// Fast code generator. class FastCodeGenerator: public AstVisitor { public: @@ -43,6 +45,7 @@ class FastCodeGenerator: public AstVisitor { function_(NULL), script_(script), is_eval_(is_eval), + nesting_stack_(NULL), loop_depth_(0), true_label_(NULL), false_label_(NULL) { @@ -55,6 +58,159 @@ class FastCodeGenerator: public AstVisitor { void Generate(FunctionLiteral* fun); private: + class Breakable; + class Iteration; + class TryCatch; + class TryFinally; + class Finally; + class ForIn; + + class NestedStatement BASE_EMBEDDED { + public: + explicit NestedStatement(FastCodeGenerator* codegen) : codegen_(codegen) { + // Link into codegen's nesting stack. + previous_ = codegen->nesting_stack_; + codegen->nesting_stack_ = this; + } + virtual ~NestedStatement() { + // Unlink from codegen's nesting stack. + ASSERT_EQ(this, codegen_->nesting_stack_); + codegen_->nesting_stack_ = previous_; + } + + 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; + } + NestedStatement* outer() { return previous_; } + protected: + MacroAssembler* masm() { return codegen_->masm(); } + private: + FastCodeGenerator* codegen_; + NestedStatement* previous_; + DISALLOW_COPY_AND_ASSIGN(NestedStatement); + }; + + class Breakable : public NestedStatement { + public: + Breakable(FastCodeGenerator* codegen, + BreakableStatement* break_target) + : NestedStatement(codegen), + target_(break_target) {} + virtual ~Breakable() {} + virtual Breakable* AsBreakable() { return this; } + virtual bool IsBreakTarget(Statement* statement) { + return target_ == statement; + } + BreakableStatement* statement() { return target_; } + Label* break_target() { return &break_target_label_; } + private: + BreakableStatement* target_; + Label break_target_label_; + DISALLOW_COPY_AND_ASSIGN(Breakable); + }; + + class Iteration : public Breakable { + public: + Iteration(FastCodeGenerator* codegen, + IterationStatement* iteration_statement) + : Breakable(codegen, iteration_statement) {} + virtual ~Iteration() {} + virtual Iteration* AsIteration() { return this; } + virtual bool IsContinueTarget(Statement* statement) { + return this->statement() == statement; + } + Label* continue_target() { return &continue_target_label_; } + private: + Label continue_target_label_; + DISALLOW_COPY_AND_ASSIGN(Iteration); + }; + + // The environment inside the try block of a try/catch statement. + class TryCatch : public NestedStatement { + public: + explicit TryCatch(FastCodeGenerator* codegen, Label* catch_entry) + : NestedStatement(codegen), catch_entry_(catch_entry) { } + 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); + }; + + // The environment inside the try block of a try/finally statement. + class TryFinally : public NestedStatement { + public: + explicit TryFinally(FastCodeGenerator* 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); + 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. + class Finally : public NestedStatement { + public: + explicit Finally(FastCodeGenerator* codegen) : NestedStatement(codegen) { } + virtual ~Finally() {} + virtual Finally* AsFinally() { return this; } + virtual int Exit(int stack_depth) { + return stack_depth + kFinallyStackElementCount; + } + 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. + class ForIn : public Iteration { + public: + ForIn(FastCodeGenerator* codegen, + ForInStatement* statement) + : Iteration(codegen, statement) { } + virtual ~ForIn() {} + virtual ForIn* AsForIn() { return this; } + virtual int Exit(int stack_depth) { + return stack_depth + kForInStackElementCount; + } + private: + // TODO(lrn): Check that this value is correct when implementing + // for-in. + static const int kForInStackElementCount = 5; + DISALLOW_COPY_AND_ASSIGN(ForIn); + }; + + int SlotOffset(Slot* slot); void Move(Expression::Context destination, Register source); void Move(Expression::Context destination, Slot* source, Register scratch); @@ -84,10 +240,25 @@ class FastCodeGenerator: public AstVisitor { // Platform-specific code sequences for calls void EmitCallWithStub(Call* expr); - void EmitCallWithIC(Call* expr, RelocInfo::Mode reloc_info); + void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode); + + // Platform-specific code for loading variables. + void EmitVariableLoad(Variable* expr, Expression::Context context); // Platform-specific support for compiling assignments. + // Load a value from a named property and push the result on the stack. + // The receiver is left on the stack by the IC. + void EmitNamedPropertyLoad(Property* expr, Expression::Context context); + + // Load a value from a named property and push the result on the stack. + // The receiver and the key is left on the stack by the IC. + void EmitKeyedPropertyLoad(Expression::Context context); + + // Apply the compound assignment operator. Expects both operands on top + // of the stack. + void EmitCompoundAssignmentOp(Token::Value op, Expression::Context context); + // Complete a variable assignment. The right-hand-side value is expected // on top of the stack. void EmitVariableAssignment(Assignment* expr); @@ -105,6 +276,12 @@ class FastCodeGenerator: public AstVisitor { void SetStatementPosition(Statement* stmt); void SetSourcePosition(int pos); + // Non-local control flow support. + void EnterFinallyBlock(); + void ExitFinallyBlock(); + void ThrowException(); + + // Loop nesting counter. int loop_depth() { return loop_depth_; } void increment_loop_depth() { loop_depth_++; } void decrement_loop_depth() { @@ -112,11 +289,22 @@ class FastCodeGenerator: public AstVisitor { loop_depth_--; } + MacroAssembler* masm() { return masm_; } + static Register result_register(); + static Register context_register(); + + // Set fields in the stack frame. Offsets are the frame pointer relative + // offsets defined in, e.g., StandardFrameConstants. + void StoreToFrameField(int frame_offset, Register value); + + // Load a value from the current context. Indices are defined as an enum + // in v8::internal::Context. + void LoadContextField(Register dst, int context_index); + // AST node visit functions. #define DECLARE_VISIT(type) virtual void Visit##type(type* node); AST_NODE_LIST(DECLARE_VISIT) #undef DECLARE_VISIT - // Handles the shortcutted logical binary operations in VisitBinaryOperation. void EmitLogicalOperation(BinaryOperation* expr); @@ -125,11 +313,14 @@ class FastCodeGenerator: public AstVisitor { Handle<Script> script_; bool is_eval_; Label return_label_; + NestedStatement* nesting_stack_; int loop_depth_; Label* true_label_; Label* false_label_; + friend class NestedStatement; + DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator); }; |