| Index: src/wasm/asm-wasm-builder.cc
|
| diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc
|
| index d7924926fc5239853785f3d7a51f0d535b42b6a4..88049b8520bc7f07a32dc3761ebbd1ce054d94a3 100644
|
| --- a/src/wasm/asm-wasm-builder.cc
|
| +++ b/src/wasm/asm-wasm-builder.cc
|
| @@ -46,7 +46,9 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| zone_(zone),
|
| cache_(TypeCache::Get()),
|
| breakable_blocks_(zone),
|
| - block_size_(0) {
|
| + block_size_(0),
|
| + init_function_initialized(false),
|
| + init_function_index(0) {
|
| InitializeAstVisitor(isolate);
|
| }
|
|
|
| @@ -79,21 +81,28 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
|
|
| void VisitBlock(Block* stmt) {
|
| - if (in_function_) {
|
| - breakable_blocks_.push_back(
|
| - std::make_pair(stmt->AsBreakableStatement(), false));
|
| - current_function_builder_->Emit(kExprBlock);
|
| - uint32_t index = current_function_builder_->EmitEditableImmediate(0);
|
| - int prev_block_size = block_size_;
|
| - block_size_ = static_cast<byte>(stmt->statements()->length());
|
| - RECURSE(VisitStatements(stmt->statements()));
|
| - DCHECK(block_size_ >= 0);
|
| - current_function_builder_->EditImmediate(index, block_size_);
|
| - block_size_ = prev_block_size;
|
| - breakable_blocks_.pop_back();
|
| - } else {
|
| - RECURSE(VisitStatements(stmt->statements()));
|
| + if (stmt->statements()->length() == 1) {
|
| + ExpressionStatement* expr =
|
| + stmt->statements()->at(0)->AsExpressionStatement();
|
| + if (expr != NULL) {
|
| + if (expr->expression()->IsAssignment()) {
|
| + RECURSE(VisitExpressionStatement(expr));
|
| + return;
|
| + }
|
| + }
|
| }
|
| + DCHECK(in_function_);
|
| + breakable_blocks_.push_back(
|
| + std::make_pair(stmt->AsBreakableStatement(), false));
|
| + current_function_builder_->Emit(kExprBlock);
|
| + uint32_t index = current_function_builder_->EmitEditableImmediate(0);
|
| + int prev_block_size = block_size_;
|
| + block_size_ = static_cast<byte>(stmt->statements()->length());
|
| + RECURSE(VisitStatements(stmt->statements()));
|
| + DCHECK(block_size_ >= 0);
|
| + current_function_builder_->EditImmediate(index, block_size_);
|
| + block_size_ = prev_block_size;
|
| + breakable_blocks_.pop_back();
|
| }
|
|
|
| void VisitExpressionStatement(ExpressionStatement* stmt) {
|
| @@ -368,24 +377,53 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| }
|
| }
|
|
|
| + void LoadInitFunction() {
|
| + if (!init_function_initialized) {
|
| + init_function_initialized = true;
|
| + unsigned char init[] = "__init__";
|
| + init_function_index = builder_->AddFunction(init, 8);
|
| + current_function_builder_ = builder_->FunctionAt(init_function_index);
|
| + current_function_builder_->ReturnType(kAstStmt);
|
| + current_function_builder_->Exported(1);
|
| + in_function_ = true;
|
| + } else {
|
| + current_function_builder_ = builder_->FunctionAt(init_function_index);
|
| + in_function_ = true;
|
| + }
|
| + }
|
| +
|
| + void UnLoadInitFunction() {
|
| + in_function_ = false;
|
| + current_function_builder_ = NULL;
|
| + }
|
| +
|
| void VisitAssignment(Assignment* expr) {
|
| - if (in_function_) {
|
| - BinaryOperation* value_op = expr->value()->AsBinaryOperation();
|
| - if (value_op != NULL && MatchBinaryOperation(value_op) == kAsIs) {
|
| - VariableProxy* target_var = expr->target()->AsVariableProxy();
|
| - VariableProxy* effective_value_var =
|
| - GetLeft(value_op)->AsVariableProxy();
|
| - // TODO(aseemgarg): simplify block_size_ or replace with a kNop
|
| - if (target_var != NULL && effective_value_var != NULL &&
|
| - target_var->var() == effective_value_var->var()) {
|
| - block_size_--;
|
| - return;
|
| - }
|
| + bool in_init = false;
|
| + if (!in_function_) {
|
| + // TODO(bradnelson): Get rid of this.
|
| + if (TypeOf(expr->value()) == kAstStmt) {
|
| + return;
|
| }
|
| - is_set_op_ = true;
|
| - RECURSE(Visit(expr->target()));
|
| - DCHECK(!is_set_op_);
|
| - RECURSE(Visit(expr->value()));
|
| + in_init = true;
|
| + LoadInitFunction();
|
| + }
|
| + BinaryOperation* value_op = expr->value()->AsBinaryOperation();
|
| + if (value_op != NULL && MatchBinaryOperation(value_op) == kAsIs) {
|
| + VariableProxy* target_var = expr->target()->AsVariableProxy();
|
| + VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy();
|
| + // TODO(aseemgarg): simplify block_size_ or replace with a kNop
|
| + if (target_var != NULL && effective_value_var != NULL &&
|
| + target_var->var() == effective_value_var->var()) {
|
| + block_size_--;
|
| + return;
|
| + }
|
| + }
|
| + is_set_op_ = true;
|
| + RECURSE(Visit(expr->target()));
|
| + DCHECK(!is_set_op_);
|
| + RECURSE(Visit(expr->value()));
|
| + if (in_init) {
|
| + UnLoadInitFunction();
|
| }
|
| }
|
|
|
| @@ -914,6 +952,8 @@ class AsmWasmBuilderImpl : public AstVisitor {
|
| TypeCache const& cache_;
|
| ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
|
| int block_size_;
|
| + bool init_function_initialized;
|
| + uint16_t init_function_index;
|
|
|
| DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
|
|
|
|
|