| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/wasm/asm-wasm-builder.h" | 7 #include "src/wasm/asm-wasm-builder.h" |
| 8 #include "src/wasm/wasm-macro-gen.h" | 8 #include "src/wasm/wasm-macro-gen.h" |
| 9 #include "src/wasm/wasm-opcodes.h" | 9 #include "src/wasm/wasm-opcodes.h" |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 in_function_(false), | 39 in_function_(false), |
| 40 is_set_op_(false), | 40 is_set_op_(false), |
| 41 marking_exported(false), | 41 marking_exported(false), |
| 42 builder_(new (zone) WasmModuleBuilder(zone)), | 42 builder_(new (zone) WasmModuleBuilder(zone)), |
| 43 current_function_builder_(NULL), | 43 current_function_builder_(NULL), |
| 44 literal_(literal), | 44 literal_(literal), |
| 45 isolate_(isolate), | 45 isolate_(isolate), |
| 46 zone_(zone), | 46 zone_(zone), |
| 47 cache_(TypeCache::Get()), | 47 cache_(TypeCache::Get()), |
| 48 breakable_blocks_(zone), | 48 breakable_blocks_(zone), |
| 49 block_size_(0) { | 49 block_size_(0), |
| 50 init_function_initialized(false), |
| 51 init_function_index(0) { |
| 50 InitializeAstVisitor(isolate); | 52 InitializeAstVisitor(isolate); |
| 51 } | 53 } |
| 52 | 54 |
| 53 void Compile() { RECURSE(VisitFunctionLiteral(literal_)); } | 55 void Compile() { RECURSE(VisitFunctionLiteral(literal_)); } |
| 54 | 56 |
| 55 void VisitVariableDeclaration(VariableDeclaration* decl) {} | 57 void VisitVariableDeclaration(VariableDeclaration* decl) {} |
| 56 | 58 |
| 57 void VisitFunctionDeclaration(FunctionDeclaration* decl) { | 59 void VisitFunctionDeclaration(FunctionDeclaration* decl) { |
| 58 DCHECK(!in_function_); | 60 DCHECK(!in_function_); |
| 59 DCHECK(current_function_builder_ == NULL); | 61 DCHECK(current_function_builder_ == NULL); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 72 | 74 |
| 73 void VisitStatements(ZoneList<Statement*>* stmts) { | 75 void VisitStatements(ZoneList<Statement*>* stmts) { |
| 74 for (int i = 0; i < stmts->length(); ++i) { | 76 for (int i = 0; i < stmts->length(); ++i) { |
| 75 Statement* stmt = stmts->at(i); | 77 Statement* stmt = stmts->at(i); |
| 76 RECURSE(Visit(stmt)); | 78 RECURSE(Visit(stmt)); |
| 77 if (stmt->IsJump()) break; | 79 if (stmt->IsJump()) break; |
| 78 } | 80 } |
| 79 } | 81 } |
| 80 | 82 |
| 81 void VisitBlock(Block* stmt) { | 83 void VisitBlock(Block* stmt) { |
| 82 if (in_function_) { | 84 if (stmt->statements()->length() == 1) { |
| 83 breakable_blocks_.push_back( | 85 ExpressionStatement* expr = |
| 84 std::make_pair(stmt->AsBreakableStatement(), false)); | 86 stmt->statements()->at(0)->AsExpressionStatement(); |
| 85 current_function_builder_->Emit(kExprBlock); | 87 if (expr != NULL) { |
| 86 uint32_t index = current_function_builder_->EmitEditableImmediate(0); | 88 if (expr->expression()->IsAssignment()) { |
| 87 int prev_block_size = block_size_; | 89 RECURSE(VisitExpressionStatement(expr)); |
| 88 block_size_ = static_cast<byte>(stmt->statements()->length()); | 90 return; |
| 89 RECURSE(VisitStatements(stmt->statements())); | 91 } |
| 90 DCHECK(block_size_ >= 0); | 92 } |
| 91 current_function_builder_->EditImmediate(index, block_size_); | |
| 92 block_size_ = prev_block_size; | |
| 93 breakable_blocks_.pop_back(); | |
| 94 } else { | |
| 95 RECURSE(VisitStatements(stmt->statements())); | |
| 96 } | 93 } |
| 94 DCHECK(in_function_); |
| 95 breakable_blocks_.push_back( |
| 96 std::make_pair(stmt->AsBreakableStatement(), false)); |
| 97 current_function_builder_->Emit(kExprBlock); |
| 98 uint32_t index = current_function_builder_->EmitEditableImmediate(0); |
| 99 int prev_block_size = block_size_; |
| 100 block_size_ = static_cast<byte>(stmt->statements()->length()); |
| 101 RECURSE(VisitStatements(stmt->statements())); |
| 102 DCHECK(block_size_ >= 0); |
| 103 current_function_builder_->EditImmediate(index, block_size_); |
| 104 block_size_ = prev_block_size; |
| 105 breakable_blocks_.pop_back(); |
| 97 } | 106 } |
| 98 | 107 |
| 99 void VisitExpressionStatement(ExpressionStatement* stmt) { | 108 void VisitExpressionStatement(ExpressionStatement* stmt) { |
| 100 RECURSE(Visit(stmt->expression())); | 109 RECURSE(Visit(stmt->expression())); |
| 101 } | 110 } |
| 102 | 111 |
| 103 void VisitEmptyStatement(EmptyStatement* stmt) {} | 112 void VisitEmptyStatement(EmptyStatement* stmt) {} |
| 104 | 113 |
| 105 void VisitEmptyParentheses(EmptyParentheses* paren) { UNREACHABLE(); } | 114 void VisitEmptyParentheses(EmptyParentheses* paren) { UNREACHABLE(); } |
| 106 | 115 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 370 } |
| 362 | 371 |
| 363 void VisitArrayLiteral(ArrayLiteral* expr) { | 372 void VisitArrayLiteral(ArrayLiteral* expr) { |
| 364 ZoneList<Expression*>* values = expr->values(); | 373 ZoneList<Expression*>* values = expr->values(); |
| 365 for (int i = 0; i < values->length(); ++i) { | 374 for (int i = 0; i < values->length(); ++i) { |
| 366 Expression* value = values->at(i); | 375 Expression* value = values->at(i); |
| 367 RECURSE(Visit(value)); | 376 RECURSE(Visit(value)); |
| 368 } | 377 } |
| 369 } | 378 } |
| 370 | 379 |
| 371 void VisitAssignment(Assignment* expr) { | 380 void LoadInitFunction() { |
| 372 if (in_function_) { | 381 if (!init_function_initialized) { |
| 373 BinaryOperation* value_op = expr->value()->AsBinaryOperation(); | 382 init_function_initialized = true; |
| 374 if (value_op != NULL && MatchBinaryOperation(value_op) == kAsIs) { | 383 unsigned char init[] = "__init__"; |
| 375 VariableProxy* target_var = expr->target()->AsVariableProxy(); | 384 init_function_index = builder_->AddFunction(init, 8); |
| 376 VariableProxy* effective_value_var = | 385 current_function_builder_ = builder_->FunctionAt(init_function_index); |
| 377 GetLeft(value_op)->AsVariableProxy(); | 386 current_function_builder_->ReturnType(kAstStmt); |
| 378 // TODO(aseemgarg): simplify block_size_ or replace with a kNop | 387 current_function_builder_->Exported(1); |
| 379 if (target_var != NULL && effective_value_var != NULL && | 388 in_function_ = true; |
| 380 target_var->var() == effective_value_var->var()) { | 389 } else { |
| 381 block_size_--; | 390 current_function_builder_ = builder_->FunctionAt(init_function_index); |
| 382 return; | 391 in_function_ = true; |
| 383 } | |
| 384 } | |
| 385 is_set_op_ = true; | |
| 386 RECURSE(Visit(expr->target())); | |
| 387 DCHECK(!is_set_op_); | |
| 388 RECURSE(Visit(expr->value())); | |
| 389 } | 392 } |
| 390 } | 393 } |
| 391 | 394 |
| 395 void UnLoadInitFunction() { |
| 396 in_function_ = false; |
| 397 current_function_builder_ = NULL; |
| 398 } |
| 399 |
| 400 void VisitAssignment(Assignment* expr) { |
| 401 bool in_init = false; |
| 402 if (!in_function_) { |
| 403 // TODO(bradnelson): Get rid of this. |
| 404 if (TypeOf(expr->value()) == kAstStmt) { |
| 405 return; |
| 406 } |
| 407 in_init = true; |
| 408 LoadInitFunction(); |
| 409 } |
| 410 BinaryOperation* value_op = expr->value()->AsBinaryOperation(); |
| 411 if (value_op != NULL && MatchBinaryOperation(value_op) == kAsIs) { |
| 412 VariableProxy* target_var = expr->target()->AsVariableProxy(); |
| 413 VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy(); |
| 414 // TODO(aseemgarg): simplify block_size_ or replace with a kNop |
| 415 if (target_var != NULL && effective_value_var != NULL && |
| 416 target_var->var() == effective_value_var->var()) { |
| 417 block_size_--; |
| 418 return; |
| 419 } |
| 420 } |
| 421 is_set_op_ = true; |
| 422 RECURSE(Visit(expr->target())); |
| 423 DCHECK(!is_set_op_); |
| 424 RECURSE(Visit(expr->value())); |
| 425 if (in_init) { |
| 426 UnLoadInitFunction(); |
| 427 } |
| 428 } |
| 429 |
| 392 void VisitYield(Yield* expr) { | 430 void VisitYield(Yield* expr) { |
| 393 RECURSE(Visit(expr->generator_object())); | 431 RECURSE(Visit(expr->generator_object())); |
| 394 RECURSE(Visit(expr->expression())); | 432 RECURSE(Visit(expr->expression())); |
| 395 } | 433 } |
| 396 | 434 |
| 397 void VisitThrow(Throw* expr) { RECURSE(Visit(expr->exception())); } | 435 void VisitThrow(Throw* expr) { RECURSE(Visit(expr->exception())); } |
| 398 | 436 |
| 399 void VisitProperty(Property* expr) { | 437 void VisitProperty(Property* expr) { |
| 400 Expression* obj = expr->obj(); | 438 Expression* obj = expr->obj(); |
| 401 DCHECK(obj->bounds().lower == obj->bounds().upper); | 439 DCHECK(obj->bounds().lower == obj->bounds().upper); |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 907 bool is_set_op_; | 945 bool is_set_op_; |
| 908 bool marking_exported; | 946 bool marking_exported; |
| 909 WasmModuleBuilder* builder_; | 947 WasmModuleBuilder* builder_; |
| 910 WasmFunctionBuilder* current_function_builder_; | 948 WasmFunctionBuilder* current_function_builder_; |
| 911 FunctionLiteral* literal_; | 949 FunctionLiteral* literal_; |
| 912 Isolate* isolate_; | 950 Isolate* isolate_; |
| 913 Zone* zone_; | 951 Zone* zone_; |
| 914 TypeCache const& cache_; | 952 TypeCache const& cache_; |
| 915 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; | 953 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
| 916 int block_size_; | 954 int block_size_; |
| 955 bool init_function_initialized; |
| 956 uint16_t init_function_index; |
| 917 | 957 |
| 918 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 958 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| 919 | 959 |
| 920 private: | 960 private: |
| 921 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); | 961 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); |
| 922 }; | 962 }; |
| 923 | 963 |
| 924 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, | 964 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
| 925 FunctionLiteral* literal) | 965 FunctionLiteral* literal) |
| 926 : isolate_(isolate), zone_(zone), literal_(literal) {} | 966 : isolate_(isolate), zone_(zone), literal_(literal) {} |
| 927 | 967 |
| 928 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so | 968 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so |
| 929 // that zone in constructor may be thrown away once wasm module is written. | 969 // that zone in constructor may be thrown away once wasm module is written. |
| 930 WasmModuleIndex* AsmWasmBuilder::Run() { | 970 WasmModuleIndex* AsmWasmBuilder::Run() { |
| 931 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); | 971 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); |
| 932 impl.Compile(); | 972 impl.Compile(); |
| 933 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 973 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
| 934 return writer->WriteTo(zone_); | 974 return writer->WriteTo(zone_); |
| 935 } | 975 } |
| 936 } // namespace wasm | 976 } // namespace wasm |
| 937 } // namespace internal | 977 } // namespace internal |
| 938 } // namespace v8 | 978 } // namespace v8 |
| OLD | NEW |