| Index: runtime/vm/kernel_binary.cc
|
| diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
|
| index 350690d6b474d252ce97590143f3066a0ecbae9f..11ae16f8f09165a7c30717dd566c316af981541e 100644
|
| --- a/runtime/vm/kernel_binary.cc
|
| +++ b/runtime/vm/kernel_binary.cc
|
| @@ -294,25 +294,45 @@ class SwitchCaseScope {
|
| };
|
|
|
|
|
| +// Unlike other scopes, labels from enclosing functions are not visible in
|
| +// nested functions. The LabelScope class is used to hide outer labels.
|
| +template<typename Builder, typename Block>
|
| +class LabelScope {
|
| + public:
|
| + explicit LabelScope(Builder* builder) : builder_(builder) {
|
| + outer_block_ = builder_->labels();
|
| + builder_->set_labels(&block_);
|
| + }
|
| + ~LabelScope() {
|
| + builder_->set_labels(outer_block_);
|
| + }
|
| +
|
| + private:
|
| + Builder* builder_;
|
| + Block block_;
|
| + Block* outer_block_;
|
| +};
|
| +
|
| class ReaderHelper {
|
| public:
|
| - ReaderHelper() : program_(NULL) {}
|
| - ~ReaderHelper() {}
|
| + ReaderHelper() : program_(NULL), labels_(NULL) {}
|
|
|
| Program* program() { return program_; }
|
| void set_program(Program* program) { program_ = program; }
|
|
|
| BlockStack<VariableDeclaration>& variables() { return scope_; }
|
| BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
|
| - BlockStack<LabeledStatement>& lables() { return labels_; }
|
| BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
|
|
|
| + BlockStack<LabeledStatement>* labels() { return labels_; }
|
| + void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; }
|
| +
|
| private:
|
| Program* program_;
|
| BlockStack<VariableDeclaration> scope_;
|
| BlockStack<TypeParameter> type_parameters_;
|
| - BlockStack<LabeledStatement> labels_;
|
| BlockStack<SwitchCase> switch_cases_;
|
| + BlockStack<LabeledStatement>* labels_;
|
| };
|
|
|
|
|
| @@ -423,6 +443,8 @@ class Reader {
|
|
|
| class WriterHelper {
|
| public:
|
| + WriterHelper() : labels_(NULL) {}
|
| +
|
| void SetProgram(Program* program) {
|
| program_ = program;
|
| for (int i = 0; i < program->libraries().length(); i++) {
|
| @@ -470,9 +492,11 @@ class WriterHelper {
|
|
|
| BlockMap<VariableDeclaration>& variables() { return scope_; }
|
| BlockMap<TypeParameter>& type_parameters() { return type_parameters_; }
|
| - BlockMap<LabeledStatement>& lables() { return labels_; }
|
| BlockMap<SwitchCase>& switch_cases() { return switch_cases_; }
|
|
|
| + BlockMap<LabeledStatement>* labels() { return labels_; }
|
| + void set_labels(BlockMap<LabeledStatement>* labels) { labels_ = labels; }
|
| +
|
| private:
|
| Program* program_;
|
|
|
| @@ -485,8 +509,8 @@ class WriterHelper {
|
|
|
| BlockMap<VariableDeclaration> scope_;
|
| BlockMap<TypeParameter> type_parameters_;
|
| - BlockMap<LabeledStatement> labels_;
|
| BlockMap<SwitchCase> switch_cases_;
|
| + BlockMap<LabeledStatement>* labels_;
|
| };
|
|
|
|
|
| @@ -2241,9 +2265,9 @@ void AssertStatement::WriteTo(Writer* writer) {
|
| LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
|
| TRACE_READ_OFFSET();
|
| LabeledStatement* stmt = new LabeledStatement();
|
| - reader->helper()->lables().Push(stmt);
|
| + reader->helper()->labels()->Push(stmt);
|
| stmt->body_ = Statement::ReadFrom(reader);
|
| - reader->helper()->lables().Pop(stmt);
|
| + reader->helper()->labels()->Pop(stmt);
|
| return stmt;
|
| }
|
|
|
| @@ -2251,16 +2275,16 @@ LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
|
| void LabeledStatement::WriteTo(Writer* writer) {
|
| TRACE_WRITE_OFFSET();
|
| writer->WriteTag(kLabeledStatement);
|
| - writer->helper()->lables().Push(this);
|
| + writer->helper()->labels()->Push(this);
|
| body_->WriteTo(writer);
|
| - writer->helper()->lables().Pop(this);
|
| + writer->helper()->labels()->Pop(this);
|
| }
|
|
|
|
|
| BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
|
| TRACE_READ_OFFSET();
|
| BreakStatement* stmt = new BreakStatement();
|
| - stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt());
|
| + stmt->target_ = reader->helper()->labels()->Lookup(reader->ReadUInt());
|
| return stmt;
|
| }
|
|
|
| @@ -2268,7 +2292,7 @@ BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
|
| void BreakStatement::WriteTo(Writer* writer) {
|
| TRACE_WRITE_OFFSET();
|
| writer->WriteTag(kBreakStatement);
|
| - writer->WriteUInt(writer->helper()->lables().Lookup(target_));
|
| + writer->WriteUInt(writer->helper()->labels()->Lookup(target_));
|
| }
|
|
|
|
|
| @@ -2845,6 +2869,8 @@ FunctionNode* FunctionNode::ReadFrom(Reader* reader) {
|
| function->return_type_ = DartType::ReadFrom(reader);
|
| function->inferred_return_value_ = reader->ReadOptional<InferredValue>();
|
|
|
| + LabelScope<ReaderHelper, BlockStack<LabeledStatement> > labels(
|
| + reader->helper());
|
| VariableScope<ReaderHelper> vars(reader->helper());
|
| function->body_ = reader->ReadOptional<Statement>();
|
| return function;
|
| @@ -2863,6 +2889,8 @@ void FunctionNode::WriteTo(Writer* writer) {
|
| return_type_->WriteTo(writer);
|
| writer->WriteOptional<InferredValue>(inferred_return_value_);
|
|
|
| + LabelScope<WriterHelper, BlockMap<LabeledStatement> > labels(
|
| + writer->helper());
|
| VariableScope<WriterHelper> vars(writer->helper());
|
| writer->WriteOptional<Statement>(body_);
|
| }
|
|
|