Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: src/wasm/asm-wasm-builder.cc

Issue 1667253003: Add Foreign Functions to asm to wasm (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/wasm/encoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 private:
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_;
517 AsmWasmBuilderImpl* builder_;
518
519 public:
520 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder)
521 : table_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity,
522 ZoneAllocationPolicy(builder->zone())),
523 builder_(builder) {}
524
525 void AddImport(Variable* v, const unsigned char* name, int name_length) {
526 ImportedFunctionIndices* indices = new (builder_->zone())
527 ImportedFunctionIndices(name, name_length, builder_->zone());
528 ZoneHashMap::Entry* entry = table_.LookupOrInsert(
529 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
530 entry->value = indices;
531 }
532
533 uint16_t GetFunctionIndex(Variable* v, FunctionSig* sig) {
534 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v));
535 DCHECK(entry != nullptr);
536 ImportedFunctionIndices* indices =
537 reinterpret_cast<ImportedFunctionIndices*>(entry->value);
538 WasmModuleBuilder::SignatureMap::iterator pos =
539 indices->signature_to_index_.find(sig);
540 if (pos != indices->signature_to_index_.end()) {
541 return pos->second;
542 } else {
543 uint16_t index = builder_->builder_->AddFunction();
544 indices->signature_to_index_[sig] = index;
545 WasmFunctionBuilder* function = builder_->builder_->FunctionAt(index);
546 function->External(1);
547 function->SetName(indices->name_, indices->name_length_);
548 if (sig->return_count() > 0) {
549 function->ReturnType(sig->GetReturn());
550 }
551 for (size_t i = 0; i < sig->parameter_count(); i++) {
552 function->AddParam(sig->GetParam(i));
553 }
554 return index;
555 }
556 }
557 };
558
511 void VisitAssignment(Assignment* expr) { 559 void VisitAssignment(Assignment* expr) {
512 bool in_init = false; 560 bool in_init = false;
513 if (!in_function_) { 561 if (!in_function_) {
514 // TODO(bradnelson): Get rid of this. 562 // TODO(bradnelson): Get rid of this.
515 if (TypeOf(expr->value()) == kAstStmt) { 563 if (TypeOf(expr->value()) == kAstStmt) {
564 Property* prop = expr->value()->AsProperty();
565 if (prop != nullptr) {
566 VariableProxy* vp = prop->obj()->AsVariableProxy();
567 if (vp != nullptr && vp->var()->IsParameter() &&
568 vp->var()->index() == 1) {
569 VariableProxy* target = expr->target()->AsVariableProxy();
570 if (target->bounds().lower->Is(Type::Function())) {
571 const AstRawString* name =
572 prop->key()->AsLiteral()->AsRawPropertyName();
573 imported_function_table_.AddImport(
574 target->var(), name->raw_data(), name->length());
575 }
576 }
577 }
516 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); 578 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
517 if (funcs != nullptr && 579 if (funcs != nullptr &&
518 funcs->bounds().lower->AsArray()->Element()->IsFunction()) { 580 funcs->bounds().lower->AsArray()->Element()->IsFunction()) {
519 VariableProxy* target = expr->target()->AsVariableProxy(); 581 VariableProxy* target = expr->target()->AsVariableProxy();
520 DCHECK(target != nullptr); 582 DCHECK(target != nullptr);
521 AddFunctionTable(target, funcs); 583 AddFunctionTable(target, funcs);
522 } 584 }
523 return; 585 return;
524 } 586 }
525 in_init = true; 587 in_init = true;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 return; 675 return;
614 } 676 }
615 UNREACHABLE(); 677 UNREACHABLE();
616 } 678 }
617 679
618 void VisitCall(Call* expr) { 680 void VisitCall(Call* expr) {
619 Call::CallType call_type = expr->GetCallType(isolate_); 681 Call::CallType call_type = expr->GetCallType(isolate_);
620 switch (call_type) { 682 switch (call_type) {
621 case Call::OTHER_CALL: { 683 case Call::OTHER_CALL: {
622 DCHECK(in_function_); 684 DCHECK(in_function_);
685 uint16_t index;
686 VariableProxy* vp = expr->expression()->AsVariableProxy();
687 if (vp != nullptr &&
688 Type::Any()->Is(vp->bounds().lower->AsFunction()->Result())) {
689 LocalType return_type = TypeOf(expr);
690 ZoneList<Expression*>* args = expr->arguments();
691 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
692 args->length());
693 if (return_type != kAstStmt) {
694 sig.AddReturn(return_type);
695 }
696 for (int i = 0; i < args->length(); i++) {
697 sig.AddParam(TypeOf(args->at(i)));
698 }
699 index =
700 imported_function_table_.GetFunctionIndex(vp->var(), sig.Build());
701 } else {
702 index = LookupOrInsertFunction(vp->var());
703 }
623 current_function_builder_->Emit(kExprCallFunction); 704 current_function_builder_->Emit(kExprCallFunction);
624 RECURSE(Visit(expr->expression())); 705 std::vector<uint8_t> index_arr = UnsignedLEB128From(index);
706 current_function_builder_->EmitCode(
707 &index_arr[0], static_cast<uint32_t>(index_arr.size()));
625 break; 708 break;
626 } 709 }
627 case Call::KEYED_PROPERTY_CALL: { 710 case Call::KEYED_PROPERTY_CALL: {
628 DCHECK(in_function_); 711 DCHECK(in_function_);
629 Property* p = expr->expression()->AsProperty(); 712 Property* p = expr->expression()->AsProperty();
630 DCHECK(p != nullptr); 713 DCHECK(p != nullptr);
631 VariableProxy* var = p->obj()->AsVariableProxy(); 714 VariableProxy* var = p->obj()->AsVariableProxy();
632 DCHECK(var != nullptr); 715 DCHECK(var != nullptr);
633 FunctionTableIndices* indices = LookupFunctionTable(var->var()); 716 FunctionTableIndices* indices = LookupFunctionTable(var->var());
634 current_function_builder_->EmitWithU8(kExprCallIndirect, 717 current_function_builder_->EmitWithU8(kExprCallIndirect,
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 WasmFunctionBuilder* current_function_builder_; 1170 WasmFunctionBuilder* current_function_builder_;
1088 FunctionLiteral* literal_; 1171 FunctionLiteral* literal_;
1089 Isolate* isolate_; 1172 Isolate* isolate_;
1090 Zone* zone_; 1173 Zone* zone_;
1091 TypeCache const& cache_; 1174 TypeCache const& cache_;
1092 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1175 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1093 int block_size_; 1176 int block_size_;
1094 uint16_t init_function_index_; 1177 uint16_t init_function_index_;
1095 uint32_t next_table_index_; 1178 uint32_t next_table_index_;
1096 ZoneHashMap function_tables_; 1179 ZoneHashMap function_tables_;
1180 ImportedFunctionTable imported_function_table_;
1097 1181
1098 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1182 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1099 1183
1100 private: 1184 private:
1101 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1185 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1102 }; 1186 };
1103 1187
1104 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1188 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1105 FunctionLiteral* literal) 1189 FunctionLiteral* literal)
1106 : isolate_(isolate), zone_(zone), literal_(literal) {} 1190 : isolate_(isolate), zone_(zone), literal_(literal) {}
1107 1191
1108 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1192 // 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. 1193 // that zone in constructor may be thrown away once wasm module is written.
1110 WasmModuleIndex* AsmWasmBuilder::Run() { 1194 WasmModuleIndex* AsmWasmBuilder::Run() {
1111 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); 1195 AsmWasmBuilderImpl impl(isolate_, zone_, literal_);
1112 impl.Compile(); 1196 impl.Compile();
1113 WasmModuleWriter* writer = impl.builder_->Build(zone_); 1197 WasmModuleWriter* writer = impl.builder_->Build(zone_);
1114 return writer->WriteTo(zone_); 1198 return writer->WriteTo(zone_);
1115 } 1199 }
1116 } // namespace wasm 1200 } // namespace wasm
1117 } // namespace internal 1201 } // namespace internal
1118 } // namespace v8 1202 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/encoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698