| Index: src/interpreter/control-flow-builders.h
|
| diff --git a/src/interpreter/control-flow-builders.h b/src/interpreter/control-flow-builders.h
|
| index 3ef800c1cfe78a195f1d88b62f5e512f8ec86c54..c9be6dcdc73ef57a59de53f78aaac99b227f80f2 100644
|
| --- a/src/interpreter/control-flow-builders.h
|
| +++ b/src/interpreter/control-flow-builders.h
|
| @@ -28,48 +28,97 @@ class ControlFlowBuilder BASE_EMBEDDED {
|
| DISALLOW_COPY_AND_ASSIGN(ControlFlowBuilder);
|
| };
|
|
|
| -// A class to help with co-ordinating break and continue statements with
|
| -// their loop.
|
| -// TODO(oth): add support for TF branch/merge info.
|
| -class LoopBuilder : public ControlFlowBuilder {
|
| +class BreakableControlFlowBuilder : public ControlFlowBuilder {
|
| public:
|
| - explicit LoopBuilder(BytecodeArrayBuilder* builder)
|
| + explicit BreakableControlFlowBuilder(BytecodeArrayBuilder* builder)
|
| : ControlFlowBuilder(builder),
|
| - continue_sites_(builder->zone()),
|
| break_sites_(builder->zone()) {}
|
| - ~LoopBuilder();
|
| + virtual ~BreakableControlFlowBuilder();
|
|
|
| - // These methods should be called by the LoopBuilder owner before
|
| - // destruction to update sites that emit jumps for break/continue.
|
| - void SetContinueTarget(const BytecodeLabel& continue_target);
|
| + // This method should be called by the control flow owner before
|
| + // destruction to update sites that emit jumps for break.
|
| void SetBreakTarget(const BytecodeLabel& break_target);
|
|
|
| - // These methods are called when visiting break and continue
|
| - // statements in the AST. Inserts a jump to a unbound label that is
|
| - // patched when the corresponding SetContinueTarget/SetBreakTarget
|
| - // is called.
|
| + // This method is called when visiting break statements in the AST.
|
| + // Inserts a jump to a unbound label that is patched when the corresponding
|
| + // SetBreakTarget is called.
|
| void Break() { EmitJump(&break_sites_); }
|
| void BreakIfTrue() { EmitJumpIfTrue(&break_sites_); }
|
| void BreakIfUndefined() { EmitJumpIfUndefined(&break_sites_); }
|
| void BreakIfNull() { EmitJumpIfNull(&break_sites_); }
|
| - void Continue() { EmitJump(&continue_sites_); }
|
| - void ContinueIfTrue() { EmitJumpIfTrue(&continue_sites_); }
|
| - void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_sites_); }
|
| - void ContinueIfNull() { EmitJumpIfNull(&continue_sites_); }
|
|
|
| - private:
|
| - void BindLabels(const BytecodeLabel& target, ZoneVector<BytecodeLabel>* site);
|
| + protected:
|
| void EmitJump(ZoneVector<BytecodeLabel>* labels);
|
| + void EmitJump(ZoneVector<BytecodeLabel>* labels, int index);
|
| void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels);
|
| + void EmitJumpIfTrue(ZoneVector<BytecodeLabel>* labels, int index);
|
| void EmitJumpIfUndefined(ZoneVector<BytecodeLabel>* labels);
|
| void EmitJumpIfNull(ZoneVector<BytecodeLabel>* labels);
|
|
|
| - // Unbound labels that identify jumps for continue/break statements
|
| - // in the code.
|
| - ZoneVector<BytecodeLabel> continue_sites_;
|
| + void BindLabels(const BytecodeLabel& target, ZoneVector<BytecodeLabel>* site);
|
| +
|
| + private:
|
| + // Unbound labels that identify jumps for break statements in the code.
|
| ZoneVector<BytecodeLabel> break_sites_;
|
| };
|
|
|
| +// A class to help with co-ordinating break and continue statements with
|
| +// their loop.
|
| +// TODO(oth): add support for TF branch/merge info.
|
| +class LoopBuilder final : public BreakableControlFlowBuilder {
|
| + public:
|
| + explicit LoopBuilder(BytecodeArrayBuilder* builder)
|
| + : BreakableControlFlowBuilder(builder),
|
| + continue_sites_(builder->zone()) {}
|
| + ~LoopBuilder();
|
| +
|
| + // This methods should be called by the LoopBuilder owner before
|
| + // destruction to update sites that emit jumps for continue.
|
| + void SetContinueTarget(const BytecodeLabel& continue_target);
|
| +
|
| + // This method is called when visiting continue statements in the AST.
|
| + // Inserts a jump to a unbound label that is patched when the corresponding
|
| + // SetContinueTarget is called.
|
| + void Continue() { EmitJump(&continue_sites_); }
|
| + void ContinueIfTrue() { EmitJumpIfTrue(&continue_sites_); }
|
| + void ContinueIfUndefined() { EmitJumpIfUndefined(&continue_sites_); }
|
| + void ContinueIfNull() { EmitJumpIfNull(&continue_sites_); }
|
| +
|
| + private:
|
| + // Unbound labels that identify jumps for continue statements in the code.
|
| + ZoneVector<BytecodeLabel> continue_sites_;
|
| +};
|
| +
|
| +// A class to help with co-ordinating break statements with their switch.
|
| +// TODO(oth): add support for TF branch/merge info.
|
| +class SwitchBuilder final : public BreakableControlFlowBuilder {
|
| + public:
|
| + explicit SwitchBuilder(BytecodeArrayBuilder* builder, int number_of_cases)
|
| + : BreakableControlFlowBuilder(builder),
|
| + case_sites_(builder->zone()) {
|
| + case_sites_.resize(number_of_cases);
|
| + }
|
| + ~SwitchBuilder();
|
| +
|
| + // This method should be called by the SwitchBuilder owner when the case
|
| + // statement with |index| is emitted to update the case jump site.
|
| + void SetCaseTarget(int index);
|
| +
|
| + // This method is called when visiting case comparison operation for |index|.
|
| + // Inserts a JumpIfTrue to a unbound label that is patched when the
|
| + // corresponding SetCaseTarget is called.
|
| + void Case(int index) { EmitJumpIfTrue(&case_sites_, index); }
|
| +
|
| + // This method is called when all cases comparisons have been emitted if there
|
| + // is a default case statement. Inserts a Jump to a unbound label that is
|
| + // patched when the corresponding SetCaseTarget is called.
|
| + void DefaultAt(int index) { EmitJump(&case_sites_, index); }
|
| +
|
| + private:
|
| + // Unbound labels that identify jumps for case statements in the code.
|
| + ZoneVector<BytecodeLabel> case_sites_;
|
| +};
|
| +
|
| } // namespace interpreter
|
| } // namespace internal
|
| } // namespace v8
|
|
|