| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_FULL_CODEGEN_H_ | 28 #ifndef V8_FULL_CODEGEN_H_ |
| 29 #define V8_FULL_CODEGEN_H_ | 29 #define V8_FULL_CODEGEN_H_ |
| 30 | 30 |
| 31 #include "v8.h" | 31 #include "v8.h" |
| 32 | 32 |
| 33 #include "ast.h" | 33 #include "ast.h" |
| 34 #include "code-stubs.h" |
| 35 #include "codegen.h" |
| 34 #include "compiler.h" | 36 #include "compiler.h" |
| 35 | 37 |
| 36 namespace v8 { | 38 namespace v8 { |
| 37 namespace internal { | 39 namespace internal { |
| 38 | 40 |
| 39 // AST node visitor which can tell whether a given statement will be breakable | 41 // AST node visitor which can tell whether a given statement will be breakable |
| 40 // when the code is compiled by the full compiler in the debugger. This means | 42 // when the code is compiled by the full compiler in the debugger. This means |
| 41 // that there will be an IC (load/store/call) in the code generated for the | 43 // that there will be an IC (load/store/call) in the code generated for the |
| 42 // debugger to piggybag on. | 44 // debugger to piggybag on. |
| 43 class BreakableStatementChecker: public AstVisitor { | 45 class BreakableStatementChecker: public AstVisitor { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 59 | 61 |
| 60 DISALLOW_COPY_AND_ASSIGN(BreakableStatementChecker); | 62 DISALLOW_COPY_AND_ASSIGN(BreakableStatementChecker); |
| 61 }; | 63 }; |
| 62 | 64 |
| 63 | 65 |
| 64 // ----------------------------------------------------------------------------- | 66 // ----------------------------------------------------------------------------- |
| 65 // Full code generator. | 67 // Full code generator. |
| 66 | 68 |
| 67 class FullCodeGenerator: public AstVisitor { | 69 class FullCodeGenerator: public AstVisitor { |
| 68 public: | 70 public: |
| 71 enum State { |
| 72 NO_REGISTERS, |
| 73 TOS_REG |
| 74 }; |
| 75 |
| 69 explicit FullCodeGenerator(MacroAssembler* masm) | 76 explicit FullCodeGenerator(MacroAssembler* masm) |
| 70 : masm_(masm), | 77 : masm_(masm), |
| 71 info_(NULL), | 78 info_(NULL), |
| 72 nesting_stack_(NULL), | 79 nesting_stack_(NULL), |
| 73 loop_depth_(0), | 80 loop_depth_(0), |
| 74 context_(NULL) { | 81 context_(NULL), |
| 82 bailout_entries_(0), |
| 83 stack_checks_(2), // There's always at least one. |
| 84 forward_bailout_stack_(NULL), |
| 85 forward_bailout_pending_(NULL) { |
| 75 } | 86 } |
| 76 | 87 |
| 77 static bool MakeCode(CompilationInfo* info); | 88 static bool MakeCode(CompilationInfo* info); |
| 78 | 89 |
| 79 void Generate(CompilationInfo* info); | 90 void Generate(CompilationInfo* info); |
| 91 void PopulateDeoptimizationData(Handle<Code> code); |
| 92 |
| 93 class StateField : public BitField<State, 0, 8> { }; |
| 94 class PcField : public BitField<unsigned, 8, 32-8> { }; |
| 95 |
| 96 static const char* State2String(State state) { |
| 97 switch (state) { |
| 98 case NO_REGISTERS: return "NO_REGISTERS"; |
| 99 case TOS_REG: return "TOS_REG"; |
| 100 } |
| 101 UNREACHABLE(); |
| 102 return NULL; |
| 103 } |
| 80 | 104 |
| 81 private: | 105 private: |
| 82 class Breakable; | 106 class Breakable; |
| 83 class Iteration; | 107 class Iteration; |
| 84 class TryCatch; | 108 class TryCatch; |
| 85 class TryFinally; | 109 class TryFinally; |
| 86 class Finally; | 110 class Finally; |
| 87 class ForIn; | 111 class ForIn; |
| 88 | 112 |
| 89 class NestedStatement BASE_EMBEDDED { | 113 class NestedStatement BASE_EMBEDDED { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 virtual ~ForIn() {} | 246 virtual ~ForIn() {} |
| 223 virtual ForIn* AsForIn() { return this; } | 247 virtual ForIn* AsForIn() { return this; } |
| 224 virtual int Exit(int stack_depth) { | 248 virtual int Exit(int stack_depth) { |
| 225 return stack_depth + kForInStackElementCount; | 249 return stack_depth + kForInStackElementCount; |
| 226 } | 250 } |
| 227 private: | 251 private: |
| 228 static const int kForInStackElementCount = 5; | 252 static const int kForInStackElementCount = 5; |
| 229 DISALLOW_COPY_AND_ASSIGN(ForIn); | 253 DISALLOW_COPY_AND_ASSIGN(ForIn); |
| 230 }; | 254 }; |
| 231 | 255 |
| 256 // The forward bailout stack keeps track of the expressions that can |
| 257 // bail out to just before the control flow is split in a child |
| 258 // node. The stack elements are linked together through the parent |
| 259 // link when visiting expressions in test contexts after requesting |
| 260 // bailout in child forwarding. |
| 261 class ForwardBailoutStack BASE_EMBEDDED { |
| 262 public: |
| 263 ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent) |
| 264 : expr_(expr), parent_(parent) { } |
| 265 |
| 266 Expression* expr() const { return expr_; } |
| 267 ForwardBailoutStack* parent() const { return parent_; } |
| 268 |
| 269 private: |
| 270 Expression* const expr_; |
| 271 ForwardBailoutStack* const parent_; |
| 272 }; |
| 273 |
| 232 enum ConstantOperand { | 274 enum ConstantOperand { |
| 233 kNoConstants, | 275 kNoConstants, |
| 234 kLeftConstant, | 276 kLeftConstant, |
| 235 kRightConstant | 277 kRightConstant |
| 236 }; | 278 }; |
| 237 | 279 |
| 238 // Type of a member function that generates inline code for a native function. | 280 // Type of a member function that generates inline code for a native function. |
| 239 typedef void (FullCodeGenerator::*InlineFunctionGenerator) | 281 typedef void (FullCodeGenerator::*InlineFunctionGenerator) |
| 240 (ZoneList<Expression*>*); | 282 (ZoneList<Expression*>*); |
| 241 | 283 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 267 Label* fall_through); | 309 Label* fall_through); |
| 268 | 310 |
| 269 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); | 311 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); |
| 270 void Move(Register dst, Slot* source); | 312 void Move(Register dst, Slot* source); |
| 271 | 313 |
| 272 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. | 314 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. |
| 273 // May emit code to traverse the context chain, destroying the scratch | 315 // May emit code to traverse the context chain, destroying the scratch |
| 274 // register. | 316 // register. |
| 275 MemOperand EmitSlotSearch(Slot* slot, Register scratch); | 317 MemOperand EmitSlotSearch(Slot* slot, Register scratch); |
| 276 | 318 |
| 319 // Forward the bailout responsibility for the given expression to |
| 320 // the next child visited (which must be in a test context). |
| 321 void ForwardBailoutToChild(Expression* expr); |
| 322 |
| 277 void VisitForEffect(Expression* expr) { | 323 void VisitForEffect(Expression* expr) { |
| 278 EffectContext context(this); | 324 EffectContext context(this); |
| 279 Visit(expr); | 325 HandleInNonTestContext(expr, NO_REGISTERS); |
| 280 } | 326 } |
| 281 | 327 |
| 282 void VisitForAccumulatorValue(Expression* expr) { | 328 void VisitForAccumulatorValue(Expression* expr) { |
| 283 AccumulatorValueContext context(this); | 329 AccumulatorValueContext context(this); |
| 284 Visit(expr); | 330 HandleInNonTestContext(expr, TOS_REG); |
| 285 } | 331 } |
| 286 | 332 |
| 287 void VisitForStackValue(Expression* expr) { | 333 void VisitForStackValue(Expression* expr) { |
| 288 StackValueContext context(this); | 334 StackValueContext context(this); |
| 289 Visit(expr); | 335 HandleInNonTestContext(expr, NO_REGISTERS); |
| 290 } | 336 } |
| 291 | 337 |
| 292 void VisitForControl(Expression* expr, | 338 void VisitForControl(Expression* expr, |
| 293 Label* if_true, | 339 Label* if_true, |
| 294 Label* if_false, | 340 Label* if_false, |
| 295 Label* fall_through) { | 341 Label* fall_through) { |
| 296 TestContext context(this, if_true, if_false, fall_through); | 342 TestContext context(this, if_true, if_false, fall_through); |
| 297 Visit(expr); | 343 VisitInTestContext(expr); |
| 344 // Forwarding bailouts to children is a one shot operation. It |
| 345 // should have been processed at this point. |
| 346 ASSERT(forward_bailout_pending_ == NULL); |
| 298 } | 347 } |
| 299 | 348 |
| 349 void HandleInNonTestContext(Expression* expr, State state); |
| 350 void VisitInTestContext(Expression* expr); |
| 351 |
| 300 void VisitDeclarations(ZoneList<Declaration*>* declarations); | 352 void VisitDeclarations(ZoneList<Declaration*>* declarations); |
| 301 void DeclareGlobals(Handle<FixedArray> pairs); | 353 void DeclareGlobals(Handle<FixedArray> pairs); |
| 302 | 354 |
| 303 // Try to perform a comparison as a fast inlined literal compare if | 355 // Try to perform a comparison as a fast inlined literal compare if |
| 304 // the operands allow it. Returns true if the compare operations | 356 // the operands allow it. Returns true if the compare operations |
| 305 // has been matched and all code generated; false otherwise. | 357 // has been matched and all code generated; false otherwise. |
| 306 bool TryLiteralCompare(Token::Value op, | 358 bool TryLiteralCompare(Token::Value op, |
| 307 Expression* left, | 359 Expression* left, |
| 308 Expression* right, | 360 Expression* right, |
| 309 Label* if_true, | 361 Label* if_true, |
| 310 Label* if_false, | 362 Label* if_false, |
| 311 Label* fall_through); | 363 Label* fall_through); |
| 312 | 364 |
| 365 // Bailout support. |
| 366 void PrepareForBailout(AstNode* node, State state); |
| 367 void PrepareForBailoutForId(int id, State state); |
| 368 |
| 369 // Record a call's return site offset, used to rebuild the frame if the |
| 370 // called function was inlined at the site. |
| 371 void RecordJSReturnSite(Call* call); |
| 372 |
| 373 // Prepare for bailout before a test (or compare) and branch. If |
| 374 // should_normalize, then the following comparison will not handle the |
| 375 // canonical JS true value so we will insert a (dead) test against true at |
| 376 // the actual bailout target from the optimized code. If not |
| 377 // should_normalize, the true and false labels are ignored. |
| 378 void PrepareForBailoutBeforeSplit(State state, |
| 379 bool should_normalize, |
| 380 Label* if_true, |
| 381 Label* if_false); |
| 382 |
| 313 // Platform-specific code for a variable, constant, or function | 383 // Platform-specific code for a variable, constant, or function |
| 314 // declaration. Functions have an initial value. | 384 // declaration. Functions have an initial value. |
| 315 void EmitDeclaration(Variable* variable, | 385 void EmitDeclaration(Variable* variable, |
| 316 Variable::Mode mode, | 386 Variable::Mode mode, |
| 317 FunctionLiteral* function); | 387 FunctionLiteral* function); |
| 318 | 388 |
| 389 // Platform-specific code for checking the stack limit at the back edge of |
| 390 // a loop. |
| 391 void EmitStackCheck(IterationStatement* stmt); |
| 392 // Record the OSR AST id corresponding to a stack check in the code. |
| 393 void RecordStackCheck(int osr_ast_id); |
| 394 // Emit a table of stack check ids and pcs into the code stream. Return |
| 395 // the offset of the start of the table. |
| 396 unsigned EmitStackCheckTable(); |
| 397 |
| 319 // Platform-specific return sequence | 398 // Platform-specific return sequence |
| 320 void EmitReturnSequence(); | 399 void EmitReturnSequence(); |
| 321 | 400 |
| 322 // Platform-specific code sequences for calls | 401 // Platform-specific code sequences for calls |
| 323 void EmitCallWithStub(Call* expr); | 402 void EmitCallWithStub(Call* expr); |
| 324 void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode); | 403 void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode); |
| 325 void EmitKeyedCallWithIC(Call* expr, Expression* key, RelocInfo::Mode mode); | 404 void EmitKeyedCallWithIC(Call* expr, Expression* key, RelocInfo::Mode mode); |
| 326 | 405 |
| 327 // Platform-specific code for inline runtime calls. | 406 // Platform-specific code for inline runtime calls. |
| 328 InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id); | 407 InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 543 |
| 465 // AST node visit functions. | 544 // AST node visit functions. |
| 466 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 545 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
| 467 AST_NODE_LIST(DECLARE_VISIT) | 546 AST_NODE_LIST(DECLARE_VISIT) |
| 468 #undef DECLARE_VISIT | 547 #undef DECLARE_VISIT |
| 469 // Handles the shortcutted logical binary operations in VisitBinaryOperation. | 548 // Handles the shortcutted logical binary operations in VisitBinaryOperation. |
| 470 void EmitLogicalOperation(BinaryOperation* expr); | 549 void EmitLogicalOperation(BinaryOperation* expr); |
| 471 | 550 |
| 472 void VisitForTypeofValue(Expression* expr); | 551 void VisitForTypeofValue(Expression* expr); |
| 473 | 552 |
| 474 MacroAssembler* masm_; | 553 struct BailoutEntry { |
| 475 CompilationInfo* info_; | 554 unsigned id; |
| 555 unsigned pc_and_state; |
| 556 }; |
| 476 | 557 |
| 477 Label return_label_; | |
| 478 NestedStatement* nesting_stack_; | |
| 479 int loop_depth_; | |
| 480 | 558 |
| 481 class ExpressionContext { | 559 class ExpressionContext BASE_EMBEDDED { |
| 482 public: | 560 public: |
| 483 explicit ExpressionContext(FullCodeGenerator* codegen) | 561 explicit ExpressionContext(FullCodeGenerator* codegen) |
| 484 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { | 562 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { |
| 485 codegen->set_new_context(this); | 563 codegen->set_new_context(this); |
| 486 } | 564 } |
| 487 | 565 |
| 488 virtual ~ExpressionContext() { | 566 virtual ~ExpressionContext() { |
| 489 codegen_->set_new_context(old_); | 567 codegen_->set_new_context(old_); |
| 490 } | 568 } |
| 491 | 569 |
| 492 // Convert constant control flow (true or false) to the result expected for | 570 // Convert constant control flow (true or false) to the result expected for |
| 493 // this expression context. | 571 // this expression context. |
| 494 virtual void Plug(bool flag) const = 0; | 572 virtual void Plug(bool flag) const = 0; |
| 495 | 573 |
| 496 // Emit code to convert a pure value (in a register, slot, as a literal, | 574 // Emit code to convert a pure value (in a register, slot, as a literal, |
| 497 // or on top of the stack) into the result expected according to this | 575 // or on top of the stack) into the result expected according to this |
| 498 // expression context. | 576 // expression context. |
| 499 virtual void Plug(Register reg) const = 0; | 577 virtual void Plug(Register reg) const = 0; |
| 500 virtual void Plug(Slot* slot) const = 0; | 578 virtual void Plug(Slot* slot) const = 0; |
| 501 virtual void Plug(Handle<Object> lit) const = 0; | 579 virtual void Plug(Handle<Object> lit) const = 0; |
| 502 virtual void Plug(Heap::RootListIndex index) const = 0; | 580 virtual void Plug(Heap::RootListIndex index) const = 0; |
| 503 virtual void PlugTOS() const = 0; | 581 virtual void PlugTOS() const = 0; |
| 504 | 582 |
| 505 // Emit code to convert pure control flow to a pair of unbound labels into | 583 // Emit code to convert pure control flow to a pair of unbound labels into |
| 506 // the result expected according to this expression context. The | 584 // the result expected according to this expression context. The |
| 507 // implementation may decide to bind either of the labels. | 585 // implementation will bind both labels unless it's a TestContext, which |
| 586 // won't bind them at this point. |
| 508 virtual void Plug(Label* materialize_true, | 587 virtual void Plug(Label* materialize_true, |
| 509 Label* materialize_false) const = 0; | 588 Label* materialize_false) const = 0; |
| 510 | 589 |
| 511 // Emit code to discard count elements from the top of stack, then convert | 590 // Emit code to discard count elements from the top of stack, then convert |
| 512 // a pure value into the result expected according to this expression | 591 // a pure value into the result expected according to this expression |
| 513 // context. | 592 // context. |
| 514 virtual void DropAndPlug(int count, Register reg) const = 0; | 593 virtual void DropAndPlug(int count, Register reg) const = 0; |
| 515 | 594 |
| 516 // For shortcutting operations || and &&. | 595 // For shortcutting operations || and &&. |
| 517 virtual void EmitLogicalLeft(BinaryOperation* expr, | 596 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 518 Label* eval_right, | 597 Label* eval_right, |
| 519 Label* done) const = 0; | 598 Label* done) const = 0; |
| 520 | 599 |
| 521 // Set up branch labels for a test expression. The three Label** parameters | 600 // Set up branch labels for a test expression. The three Label** parameters |
| 522 // are output parameters. | 601 // are output parameters. |
| 523 virtual void PrepareTest(Label* materialize_true, | 602 virtual void PrepareTest(Label* materialize_true, |
| 524 Label* materialize_false, | 603 Label* materialize_false, |
| 525 Label** if_true, | 604 Label** if_true, |
| 526 Label** if_false, | 605 Label** if_false, |
| 527 Label** fall_through) const = 0; | 606 Label** fall_through) const = 0; |
| 528 | 607 |
| 608 virtual void HandleExpression(Expression* expr) const = 0; |
| 609 |
| 529 // Returns true if we are evaluating only for side effects (ie if the result | 610 // Returns true if we are evaluating only for side effects (ie if the result |
| 530 // will be discarded. | 611 // will be discarded). |
| 531 virtual bool IsEffect() const { return false; } | 612 virtual bool IsEffect() const { return false; } |
| 532 | 613 |
| 533 // Returns true if we are branching on the value rather than materializing | 614 // Returns true if we are branching on the value rather than materializing |
| 534 // it. | 615 // it. Only used for asserts. |
| 535 virtual bool IsTest() const { return false; } | 616 virtual bool IsTest() const { return false; } |
| 536 | 617 |
| 537 protected: | 618 protected: |
| 538 FullCodeGenerator* codegen() const { return codegen_; } | 619 FullCodeGenerator* codegen() const { return codegen_; } |
| 539 MacroAssembler* masm() const { return masm_; } | 620 MacroAssembler* masm() const { return masm_; } |
| 540 MacroAssembler* masm_; | 621 MacroAssembler* masm_; |
| 541 | 622 |
| 542 private: | 623 private: |
| 543 const ExpressionContext* old_; | 624 const ExpressionContext* old_; |
| 544 FullCodeGenerator* codegen_; | 625 FullCodeGenerator* codegen_; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 558 virtual void PlugTOS() const; | 639 virtual void PlugTOS() const; |
| 559 virtual void DropAndPlug(int count, Register reg) const; | 640 virtual void DropAndPlug(int count, Register reg) const; |
| 560 virtual void EmitLogicalLeft(BinaryOperation* expr, | 641 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 561 Label* eval_right, | 642 Label* eval_right, |
| 562 Label* done) const; | 643 Label* done) const; |
| 563 virtual void PrepareTest(Label* materialize_true, | 644 virtual void PrepareTest(Label* materialize_true, |
| 564 Label* materialize_false, | 645 Label* materialize_false, |
| 565 Label** if_true, | 646 Label** if_true, |
| 566 Label** if_false, | 647 Label** if_false, |
| 567 Label** fall_through) const; | 648 Label** fall_through) const; |
| 649 virtual void HandleExpression(Expression* expr) const; |
| 568 }; | 650 }; |
| 569 | 651 |
| 570 class StackValueContext : public ExpressionContext { | 652 class StackValueContext : public ExpressionContext { |
| 571 public: | 653 public: |
| 572 explicit StackValueContext(FullCodeGenerator* codegen) | 654 explicit StackValueContext(FullCodeGenerator* codegen) |
| 573 : ExpressionContext(codegen) { } | 655 : ExpressionContext(codegen) { } |
| 574 | 656 |
| 575 virtual void Plug(bool flag) const; | 657 virtual void Plug(bool flag) const; |
| 576 virtual void Plug(Register reg) const; | 658 virtual void Plug(Register reg) const; |
| 577 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 659 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 578 virtual void Plug(Slot* slot) const; | 660 virtual void Plug(Slot* slot) const; |
| 579 virtual void Plug(Handle<Object> lit) const; | 661 virtual void Plug(Handle<Object> lit) const; |
| 580 virtual void Plug(Heap::RootListIndex) const; | 662 virtual void Plug(Heap::RootListIndex) const; |
| 581 virtual void PlugTOS() const; | 663 virtual void PlugTOS() const; |
| 582 virtual void DropAndPlug(int count, Register reg) const; | 664 virtual void DropAndPlug(int count, Register reg) const; |
| 583 virtual void EmitLogicalLeft(BinaryOperation* expr, | 665 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 584 Label* eval_right, | 666 Label* eval_right, |
| 585 Label* done) const; | 667 Label* done) const; |
| 586 virtual void PrepareTest(Label* materialize_true, | 668 virtual void PrepareTest(Label* materialize_true, |
| 587 Label* materialize_false, | 669 Label* materialize_false, |
| 588 Label** if_true, | 670 Label** if_true, |
| 589 Label** if_false, | 671 Label** if_false, |
| 590 Label** fall_through) const; | 672 Label** fall_through) const; |
| 673 virtual void HandleExpression(Expression* expr) const; |
| 591 }; | 674 }; |
| 592 | 675 |
| 593 class TestContext : public ExpressionContext { | 676 class TestContext : public ExpressionContext { |
| 594 public: | 677 public: |
| 595 explicit TestContext(FullCodeGenerator* codegen, | 678 explicit TestContext(FullCodeGenerator* codegen, |
| 596 Label* true_label, | 679 Label* true_label, |
| 597 Label* false_label, | 680 Label* false_label, |
| 598 Label* fall_through) | 681 Label* fall_through) |
| 599 : ExpressionContext(codegen), | 682 : ExpressionContext(codegen), |
| 600 true_label_(true_label), | 683 true_label_(true_label), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 619 virtual void PlugTOS() const; | 702 virtual void PlugTOS() const; |
| 620 virtual void DropAndPlug(int count, Register reg) const; | 703 virtual void DropAndPlug(int count, Register reg) const; |
| 621 virtual void EmitLogicalLeft(BinaryOperation* expr, | 704 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 622 Label* eval_right, | 705 Label* eval_right, |
| 623 Label* done) const; | 706 Label* done) const; |
| 624 virtual void PrepareTest(Label* materialize_true, | 707 virtual void PrepareTest(Label* materialize_true, |
| 625 Label* materialize_false, | 708 Label* materialize_false, |
| 626 Label** if_true, | 709 Label** if_true, |
| 627 Label** if_false, | 710 Label** if_false, |
| 628 Label** fall_through) const; | 711 Label** fall_through) const; |
| 712 virtual void HandleExpression(Expression* expr) const; |
| 629 virtual bool IsTest() const { return true; } | 713 virtual bool IsTest() const { return true; } |
| 630 | 714 |
| 631 private: | 715 private: |
| 632 Label* true_label_; | 716 Label* true_label_; |
| 633 Label* false_label_; | 717 Label* false_label_; |
| 634 Label* fall_through_; | 718 Label* fall_through_; |
| 635 }; | 719 }; |
| 636 | 720 |
| 637 class EffectContext : public ExpressionContext { | 721 class EffectContext : public ExpressionContext { |
| 638 public: | 722 public: |
| 639 explicit EffectContext(FullCodeGenerator* codegen) | 723 explicit EffectContext(FullCodeGenerator* codegen) |
| 640 : ExpressionContext(codegen) { } | 724 : ExpressionContext(codegen) { } |
| 641 | 725 |
| 642 virtual void Plug(bool flag) const; | 726 virtual void Plug(bool flag) const; |
| 643 virtual void Plug(Register reg) const; | 727 virtual void Plug(Register reg) const; |
| 644 virtual void Plug(Label* materialize_true, Label* materialize_false) const; | 728 virtual void Plug(Label* materialize_true, Label* materialize_false) const; |
| 645 virtual void Plug(Slot* slot) const; | 729 virtual void Plug(Slot* slot) const; |
| 646 virtual void Plug(Handle<Object> lit) const; | 730 virtual void Plug(Handle<Object> lit) const; |
| 647 virtual void Plug(Heap::RootListIndex) const; | 731 virtual void Plug(Heap::RootListIndex) const; |
| 648 virtual void PlugTOS() const; | 732 virtual void PlugTOS() const; |
| 649 virtual void DropAndPlug(int count, Register reg) const; | 733 virtual void DropAndPlug(int count, Register reg) const; |
| 650 virtual void EmitLogicalLeft(BinaryOperation* expr, | 734 virtual void EmitLogicalLeft(BinaryOperation* expr, |
| 651 Label* eval_right, | 735 Label* eval_right, |
| 652 Label* done) const; | 736 Label* done) const; |
| 653 virtual void PrepareTest(Label* materialize_true, | 737 virtual void PrepareTest(Label* materialize_true, |
| 654 Label* materialize_false, | 738 Label* materialize_false, |
| 655 Label** if_true, | 739 Label** if_true, |
| 656 Label** if_false, | 740 Label** if_false, |
| 657 Label** fall_through) const; | 741 Label** fall_through) const; |
| 742 virtual void HandleExpression(Expression* expr) const; |
| 658 virtual bool IsEffect() const { return true; } | 743 virtual bool IsEffect() const { return true; } |
| 659 }; | 744 }; |
| 660 | 745 |
| 746 MacroAssembler* masm_; |
| 747 CompilationInfo* info_; |
| 748 Label return_label_; |
| 749 NestedStatement* nesting_stack_; |
| 750 int loop_depth_; |
| 661 const ExpressionContext* context_; | 751 const ExpressionContext* context_; |
| 752 ZoneList<BailoutEntry> bailout_entries_; |
| 753 ZoneList<BailoutEntry> stack_checks_; |
| 754 ForwardBailoutStack* forward_bailout_stack_; |
| 755 ForwardBailoutStack* forward_bailout_pending_; |
| 662 | 756 |
| 663 friend class NestedStatement; | 757 friend class NestedStatement; |
| 664 | 758 |
| 665 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 759 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
| 666 }; | 760 }; |
| 667 | 761 |
| 668 | 762 |
| 669 } } // namespace v8::internal | 763 } } // namespace v8::internal |
| 670 | 764 |
| 671 #endif // V8_FULL_CODEGEN_H_ | 765 #endif // V8_FULL_CODEGEN_H_ |
| OLD | NEW |