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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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_index_(0), | 50 init_function_index_(0), |
51 next_table_index_(0), | 51 next_table_index_(0), |
52 function_tables_(HashMap::PointersMatch, | 52 function_tables_(HashMap::PointersMatch, |
53 ZoneHashMap::kDefaultHashMapCapacity, | 53 ZoneHashMap::kDefaultHashMapCapacity, |
54 ZoneAllocationPolicy(zone)) { | 54 ZoneAllocationPolicy(zone)), |
55 imported_function_table_(this) { | |
55 InitializeAstVisitor(isolate); | 56 InitializeAstVisitor(isolate); |
56 } | 57 } |
57 | 58 |
58 void InitializeInitFunction() { | 59 void InitializeInitFunction() { |
59 unsigned char init[] = "__init__"; | 60 unsigned char init[] = "__init__"; |
60 init_function_index_ = builder_->AddFunction(); | 61 init_function_index_ = builder_->AddFunction(); |
61 current_function_builder_ = builder_->FunctionAt(init_function_index_); | 62 current_function_builder_ = builder_->FunctionAt(init_function_index_); |
62 current_function_builder_->SetName(init, 8); | 63 current_function_builder_->SetName(init, 8); |
63 current_function_builder_->ReturnType(kAstStmt); | 64 current_function_builder_->ReturnType(kAstStmt); |
64 current_function_builder_->Exported(1); | 65 current_function_builder_->Exported(1); |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 DCHECK(in_function_); | 361 DCHECK(in_function_); |
361 current_function_builder_->Emit(kExprIfElse); | 362 current_function_builder_->Emit(kExprIfElse); |
362 RECURSE(Visit(expr->condition())); | 363 RECURSE(Visit(expr->condition())); |
363 RECURSE(Visit(expr->then_expression())); | 364 RECURSE(Visit(expr->then_expression())); |
364 RECURSE(Visit(expr->else_expression())); | 365 RECURSE(Visit(expr->else_expression())); |
365 } | 366 } |
366 | 367 |
367 void VisitVariableProxy(VariableProxy* expr) { | 368 void VisitVariableProxy(VariableProxy* expr) { |
368 if (in_function_) { | 369 if (in_function_) { |
369 Variable* var = expr->var(); | 370 Variable* var = expr->var(); |
370 if (var->is_function()) { | 371 if (is_set_op_) { |
371 DCHECK(!is_set_op_); | 372 if (var->IsContextSlot()) { |
372 std::vector<uint8_t> index = | 373 current_function_builder_->Emit(kExprStoreGlobal); |
373 UnsignedLEB128From(LookupOrInsertFunction(var)); | 374 } else { |
374 current_function_builder_->EmitCode( | 375 current_function_builder_->Emit(kExprSetLocal); |
375 &index[0], static_cast<uint32_t>(index.size())); | 376 } |
377 is_set_op_ = false; | |
376 } else { | 378 } else { |
377 if (is_set_op_) { | 379 if (var->IsContextSlot()) { |
378 if (var->IsContextSlot()) { | 380 current_function_builder_->Emit(kExprLoadGlobal); |
379 current_function_builder_->Emit(kExprStoreGlobal); | |
380 } else { | |
381 current_function_builder_->Emit(kExprSetLocal); | |
382 } | |
383 is_set_op_ = false; | |
384 } else { | 381 } else { |
385 if (var->IsContextSlot()) { | 382 current_function_builder_->Emit(kExprGetLocal); |
386 current_function_builder_->Emit(kExprLoadGlobal); | |
387 } else { | |
388 current_function_builder_->Emit(kExprGetLocal); | |
389 } | |
390 } | 383 } |
391 LocalType var_type = TypeOf(expr); | 384 } |
392 DCHECK(var_type != kAstStmt); | 385 LocalType var_type = TypeOf(expr); |
393 if (var->IsContextSlot()) { | 386 DCHECK(var_type != kAstStmt); |
394 AddLeb128(LookupOrInsertGlobal(var, var_type), false); | 387 if (var->IsContextSlot()) { |
395 } else { | 388 AddLeb128(LookupOrInsertGlobal(var, var_type), false); |
396 AddLeb128(LookupOrInsertLocal(var, var_type), true); | 389 } else { |
397 } | 390 AddLeb128(LookupOrInsertLocal(var, var_type), true); |
398 } | 391 } |
399 } | 392 } |
400 } | 393 } |
401 | 394 |
402 void VisitLiteral(Literal* expr) { | 395 void VisitLiteral(Literal* expr) { |
403 if (in_function_) { | 396 if (in_function_) { |
404 if (expr->raw_value()->IsNumber()) { | 397 if (expr->raw_value()->IsNumber()) { |
405 LocalType type = TypeOf(expr); | 398 LocalType type = TypeOf(expr); |
406 switch (type) { | 399 switch (type) { |
407 case kAstI32: { | 400 case kAstI32: { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
501 entry->value = container; | 494 entry->value = container; |
502 } | 495 } |
503 | 496 |
504 FunctionTableIndices* LookupFunctionTable(Variable* v) { | 497 FunctionTableIndices* LookupFunctionTable(Variable* v) { |
505 ZoneHashMap::Entry* entry = | 498 ZoneHashMap::Entry* entry = |
506 function_tables_.Lookup(v, ComputePointerHash(v)); | 499 function_tables_.Lookup(v, ComputePointerHash(v)); |
507 DCHECK(entry != nullptr); | 500 DCHECK(entry != nullptr); |
508 return reinterpret_cast<FunctionTableIndices*>(entry->value); | 501 return reinterpret_cast<FunctionTableIndices*>(entry->value); |
509 } | 502 } |
510 | 503 |
504 class ImportedFunctionTable { | |
505 public: | |
506 class ImportedFunctionIndices : public ZoneObject { | |
507 public: | |
508 const unsigned char* name_; | |
509 int name_length_; | |
510 WasmModuleBuilder::SignatureMap signature_to_index_; | |
511 | |
512 ImportedFunctionIndices(const unsigned char* name, int name_length, | |
513 Zone* zone) | |
514 : name_(name), name_length_(name_length), signature_to_index_(zone) {} | |
515 }; | |
516 ZoneHashMap table_; | |
bradnelson
2016/02/05 01:19:43
Make these private
aseemgarg
2016/02/05 01:33:18
Done. Though seems like if not exposed in .h file,
| |
517 AsmWasmBuilderImpl* builder_; | |
518 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) | |
519 : table_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity, | |
520 ZoneAllocationPolicy(builder->zone())), | |
521 builder_(builder) {} | |
522 | |
523 void AddImport(Variable* v, const unsigned char* name, int name_length) { | |
524 ImportedFunctionIndices* indices = new (builder_->zone()) | |
525 ImportedFunctionIndices(name, name_length, builder_->zone()); | |
526 ZoneHashMap::Entry* entry = table_.LookupOrInsert( | |
bradnelson
2016/02/05 01:19:43
Huh, hadn't considered that you need to track the
| |
527 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); | |
528 entry->value = indices; | |
529 } | |
530 | |
531 uint16_t GetFunctionIndex(Variable* v, FunctionSig* sig) { | |
532 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); | |
533 DCHECK(entry != nullptr); | |
534 ImportedFunctionIndices* indices = | |
535 reinterpret_cast<ImportedFunctionIndices*>(entry->value); | |
536 WasmModuleBuilder::SignatureMap::iterator pos = | |
537 indices->signature_to_index_.find(sig); | |
538 if (pos != indices->signature_to_index_.end()) { | |
539 return pos->second; | |
540 } else { | |
541 uint16_t index = builder_->builder_->AddFunction(); | |
542 indices->signature_to_index_[sig] = index; | |
543 WasmFunctionBuilder* function = builder_->builder_->FunctionAt(index); | |
544 function->External(1); | |
545 function->SetName(indices->name_, indices->name_length_); | |
546 if (sig->return_count() > 0) { | |
547 function->ReturnType(sig->GetReturn()); | |
548 } | |
549 for (size_t i = 0; i < sig->parameter_count(); i++) { | |
550 function->AddParam(sig->GetParam(i)); | |
551 } | |
552 return index; | |
553 } | |
554 } | |
555 }; | |
556 | |
511 void VisitAssignment(Assignment* expr) { | 557 void VisitAssignment(Assignment* expr) { |
512 bool in_init = false; | 558 bool in_init = false; |
513 if (!in_function_) { | 559 if (!in_function_) { |
514 // TODO(bradnelson): Get rid of this. | 560 // TODO(bradnelson): Get rid of this. |
515 if (TypeOf(expr->value()) == kAstStmt) { | 561 if (TypeOf(expr->value()) == kAstStmt) { |
562 Property* prop = expr->value()->AsProperty(); | |
563 if (prop != nullptr) { | |
564 VariableProxy* vp = prop->obj()->AsVariableProxy(); | |
565 if (vp != nullptr && vp->var()->IsParameter() && | |
566 (vp->var()->index() == 1)) { | |
bradnelson
2016/02/05 01:19:43
drop extra parens
aseemgarg
2016/02/05 01:33:18
Done.
| |
567 VariableProxy* target = expr->target()->AsVariableProxy(); | |
568 if (target->bounds().lower->Is(Type::Function())) { | |
569 const AstRawString* name = | |
570 prop->key()->AsLiteral()->AsRawPropertyName(); | |
571 imported_function_table_.AddImport( | |
572 target->var(), name->raw_data(), name->length()); | |
573 } | |
574 } | |
575 } | |
516 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); | 576 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); |
517 if (funcs != nullptr && | 577 if (funcs != nullptr && |
518 funcs->bounds().lower->AsArray()->Element()->IsFunction()) { | 578 funcs->bounds().lower->AsArray()->Element()->IsFunction()) { |
519 VariableProxy* target = expr->target()->AsVariableProxy(); | 579 VariableProxy* target = expr->target()->AsVariableProxy(); |
520 DCHECK(target != nullptr); | 580 DCHECK(target != nullptr); |
521 AddFunctionTable(target, funcs); | 581 AddFunctionTable(target, funcs); |
522 } | 582 } |
523 return; | 583 return; |
524 } | 584 } |
525 in_init = true; | 585 in_init = true; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
613 return; | 673 return; |
614 } | 674 } |
615 UNREACHABLE(); | 675 UNREACHABLE(); |
616 } | 676 } |
617 | 677 |
618 void VisitCall(Call* expr) { | 678 void VisitCall(Call* expr) { |
619 Call::CallType call_type = expr->GetCallType(isolate_); | 679 Call::CallType call_type = expr->GetCallType(isolate_); |
620 switch (call_type) { | 680 switch (call_type) { |
621 case Call::OTHER_CALL: { | 681 case Call::OTHER_CALL: { |
622 DCHECK(in_function_); | 682 DCHECK(in_function_); |
683 uint16_t index; | |
684 VariableProxy* vp = expr->expression()->AsVariableProxy(); | |
685 if (vp != nullptr && | |
686 Type::Any()->Is(vp->bounds().lower->AsFunction()->Result())) { | |
687 LocalType return_type = TypeOf(expr); | |
688 ZoneList<Expression*>* args = expr->arguments(); | |
689 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, | |
690 args->length()); | |
691 if (return_type != kAstStmt) { | |
692 sig.AddReturn(return_type); | |
693 } | |
694 for (int i = 0; i < args->length(); i++) { | |
695 sig.AddParam(TypeOf(args->at(i))); | |
696 } | |
697 index = | |
698 imported_function_table_.GetFunctionIndex(vp->var(), sig.Build()); | |
699 } else { | |
700 index = LookupOrInsertFunction(vp->var()); | |
701 } | |
623 current_function_builder_->Emit(kExprCallFunction); | 702 current_function_builder_->Emit(kExprCallFunction); |
624 RECURSE(Visit(expr->expression())); | 703 std::vector<uint8_t> index_arr = UnsignedLEB128From(index); |
704 current_function_builder_->EmitCode( | |
705 &index_arr[0], static_cast<uint32_t>(index_arr.size())); | |
625 break; | 706 break; |
626 } | 707 } |
627 case Call::KEYED_PROPERTY_CALL: { | 708 case Call::KEYED_PROPERTY_CALL: { |
628 DCHECK(in_function_); | 709 DCHECK(in_function_); |
629 Property* p = expr->expression()->AsProperty(); | 710 Property* p = expr->expression()->AsProperty(); |
630 DCHECK(p != nullptr); | 711 DCHECK(p != nullptr); |
631 VariableProxy* var = p->obj()->AsVariableProxy(); | 712 VariableProxy* var = p->obj()->AsVariableProxy(); |
632 DCHECK(var != nullptr); | 713 DCHECK(var != nullptr); |
633 FunctionTableIndices* indices = LookupFunctionTable(var->var()); | 714 FunctionTableIndices* indices = LookupFunctionTable(var->var()); |
634 current_function_builder_->EmitWithU8(kExprCallIndirect, | 715 current_function_builder_->EmitWithU8(kExprCallIndirect, |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1087 WasmFunctionBuilder* current_function_builder_; | 1168 WasmFunctionBuilder* current_function_builder_; |
1088 FunctionLiteral* literal_; | 1169 FunctionLiteral* literal_; |
1089 Isolate* isolate_; | 1170 Isolate* isolate_; |
1090 Zone* zone_; | 1171 Zone* zone_; |
1091 TypeCache const& cache_; | 1172 TypeCache const& cache_; |
1092 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; | 1173 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
1093 int block_size_; | 1174 int block_size_; |
1094 uint16_t init_function_index_; | 1175 uint16_t init_function_index_; |
1095 uint32_t next_table_index_; | 1176 uint32_t next_table_index_; |
1096 ZoneHashMap function_tables_; | 1177 ZoneHashMap function_tables_; |
1178 ImportedFunctionTable imported_function_table_; | |
1097 | 1179 |
1098 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 1180 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
1099 | 1181 |
1100 private: | 1182 private: |
1101 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); | 1183 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); |
1102 }; | 1184 }; |
1103 | 1185 |
1104 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, | 1186 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
1105 FunctionLiteral* literal) | 1187 FunctionLiteral* literal) |
1106 : isolate_(isolate), zone_(zone), literal_(literal) {} | 1188 : isolate_(isolate), zone_(zone), literal_(literal) {} |
1107 | 1189 |
1108 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so | 1190 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so |
1109 // that zone in constructor may be thrown away once wasm module is written. | 1191 // that zone in constructor may be thrown away once wasm module is written. |
1110 WasmModuleIndex* AsmWasmBuilder::Run() { | 1192 WasmModuleIndex* AsmWasmBuilder::Run() { |
1111 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); | 1193 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); |
1112 impl.Compile(); | 1194 impl.Compile(); |
1113 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 1195 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
1114 return writer->WriteTo(zone_); | 1196 return writer->WriteTo(zone_); |
1115 } | 1197 } |
1116 } // namespace wasm | 1198 } // namespace wasm |
1117 } // namespace internal | 1199 } // namespace internal |
1118 } // namespace v8 | 1200 } // namespace v8 |
OLD | NEW |