| Index: runtime/vm/ast_transformer.h
|
| diff --git a/runtime/vm/ast_transformer.h b/runtime/vm/ast_transformer.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d0d4c8262f263ab04f352437778c950bb5f6c762
|
| --- /dev/null
|
| +++ b/runtime/vm/ast_transformer.h
|
| @@ -0,0 +1,84 @@
|
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +#ifndef VM_AST_TRANSFORMER_H_
|
| +#define VM_AST_TRANSFORMER_H_
|
| +
|
| +#include "platform/assert.h"
|
| +#include "vm/ast.h"
|
| +
|
| +namespace dart {
|
| +
|
| +class ParsedFunction;
|
| +
|
| +// Translate an AstNode containing an expression (that itself contains one or
|
| +// more awaits) into a sequential representation where subexpressions are
|
| +// evaluated sequentially into intermediates. Those intermediates are stored
|
| +// within a context.
|
| +//
|
| +// This allows a function to be suspended and resumed from within evaluating an
|
| +// expression. The evaluation is split among a so-called preamble and the
|
| +// evaluation of the resulting expression (which is only a single load).
|
| +//
|
| +// Example (minimalistic):
|
| +//
|
| +// var a = (await bar()) + foo();
|
| +//
|
| +// This translates to a premable similar to:
|
| +//
|
| +// var t_1, t_2, t_3, t_4; // All stored in a context.
|
| +// t_1 = bar();
|
| +// :result_param = t_1;
|
| +// <continuation logic>
|
| +// t_2 = :result_param;
|
| +// t_3 = foo();
|
| +// t_4 = t_2.operator+(t_3);
|
| +//
|
| +// and a resulting expression of a load of t_4.
|
| +//
|
| +class AwaitTransformer : public AstNodeVisitor {
|
| + public:
|
| + AwaitTransformer(SequenceNode* preamble,
|
| + const Library& library,
|
| + ParsedFunction* const parsed_function)
|
| + : preamble_(preamble),
|
| + temp_cnt_(0),
|
| + library_(library),
|
| + parsed_function_(parsed_function),
|
| + isolate_(Isolate::Current()) {}
|
| +
|
| +#define DECLARE_VISIT(BaseName) \
|
| + virtual void Visit##BaseName##Node(BaseName##Node* node);
|
| +
|
| + FOR_EACH_NODE(DECLARE_VISIT)
|
| +#undef DECLARE_VISIT
|
| +
|
| + AstNode* Transform(AstNode* expr);
|
| +
|
| + private:
|
| + LocalVariable* EnsureCurrentTempVar();
|
| + LocalVariable* AddToPreambleNewTempVar(AstNode* node);
|
| + ArgumentListNode* TransformArguments(ArgumentListNode* node);
|
| + AstNode* LazyTransform(const Token::Kind kind,
|
| + AstNode* new_left,
|
| + AstNode* right);
|
| +
|
| + void NextTempVar() { temp_cnt_++; }
|
| +
|
| + Isolate* isolate() const { return isolate_; }
|
| +
|
| + SequenceNode* preamble_;
|
| + int temp_cnt_;
|
| + AstNode* result_;
|
| + const Library& library_;
|
| + ParsedFunction* const parsed_function_;
|
| +
|
| + Isolate* isolate_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AwaitTransformer);
|
| +};
|
| +
|
| +} // namespace dart
|
| +
|
| +#endif // VM_AST_TRANSFORMER_H_
|
|
|