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 |