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

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

Issue 1609893002: Add function tables to asm to wasm (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 11 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
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 29 matching lines...) Expand all
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_(nullptr), 43 current_function_builder_(nullptr),
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),
52 function_tables_(HashMap::PointersMatch,
53 ZoneHashMap::kDefaultHashMapCapacity,
54 ZoneAllocationPolicy(zone)) {
51 InitializeAstVisitor(isolate); 55 InitializeAstVisitor(isolate);
52 } 56 }
53 57
54 void InitializeInitFunction() { 58 void InitializeInitFunction() {
55 unsigned char init[] = "__init__"; 59 unsigned char init[] = "__init__";
56 init_function_index = builder_->AddFunction(); 60 init_function_index_ = builder_->AddFunction();
57 current_function_builder_ = builder_->FunctionAt(init_function_index); 61 current_function_builder_ = builder_->FunctionAt(init_function_index_);
58 current_function_builder_->SetName(init, 8); 62 current_function_builder_->SetName(init, 8);
59 current_function_builder_->ReturnType(kAstStmt); 63 current_function_builder_->ReturnType(kAstStmt);
60 current_function_builder_->Exported(1); 64 current_function_builder_->Exported(1);
61 current_function_builder_ = nullptr; 65 current_function_builder_ = nullptr;
62 } 66 }
63 67
64 void Compile() { 68 void Compile() {
65 InitializeInitFunction(); 69 InitializeInitFunction();
66 RECURSE(VisitFunctionLiteral(literal_)); 70 RECURSE(VisitFunctionLiteral(literal_));
67 } 71 }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 current_function_builder_->ReturnType(return_type); 341 current_function_builder_->ReturnType(return_type);
338 for (int i = 0; i < expr->parameter_count(); i++) { 342 for (int i = 0; i < expr->parameter_count(); i++) {
339 LocalType type = TypeFrom(func_type->Parameter(i)); 343 LocalType type = TypeFrom(func_type->Parameter(i));
340 DCHECK(type != kAstStmt); 344 DCHECK(type != kAstStmt);
341 LookupOrInsertLocal(scope->parameter(i), type); 345 LookupOrInsertLocal(scope->parameter(i), type);
342 } 346 }
343 } else { 347 } else {
344 UNREACHABLE(); 348 UNREACHABLE();
345 } 349 }
346 } 350 }
351 RECURSE(VisitStatements(expr->body()));
347 RECURSE(VisitDeclarations(scope->declarations())); 352 RECURSE(VisitDeclarations(scope->declarations()));
348 RECURSE(VisitStatements(expr->body()));
349 } 353 }
350 354
351 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { 355 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
352 UNREACHABLE(); 356 UNREACHABLE();
353 } 357 }
354 358
355 void VisitConditional(Conditional* expr) { 359 void VisitConditional(Conditional* expr) {
356 DCHECK(in_function_); 360 DCHECK(in_function_);
357 current_function_builder_->Emit(kExprIfElse); 361 current_function_builder_->Emit(kExprIfElse);
358 RECURSE(Visit(expr->condition())); 362 RECURSE(Visit(expr->condition()));
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 builder_->FunctionAt(index)->Exported(1); 448 builder_->FunctionAt(index)->Exported(1);
445 builder_->FunctionAt(index) 449 builder_->FunctionAt(index)
446 ->SetName(raw_name->raw_data(), raw_name->length()); 450 ->SetName(raw_name->raw_data(), raw_name->length());
447 } 451 }
448 } 452 }
449 } 453 }
450 454
451 void VisitArrayLiteral(ArrayLiteral* expr) { UNREACHABLE(); } 455 void VisitArrayLiteral(ArrayLiteral* expr) { UNREACHABLE(); }
452 456
453 void LoadInitFunction() { 457 void LoadInitFunction() {
454 current_function_builder_ = builder_->FunctionAt(init_function_index); 458 current_function_builder_ = builder_->FunctionAt(init_function_index_);
455 in_function_ = true; 459 in_function_ = true;
456 } 460 }
457 461
458 void UnLoadInitFunction() { 462 void UnLoadInitFunction() {
459 in_function_ = false; 463 in_function_ = false;
460 current_function_builder_ = nullptr; 464 current_function_builder_ = nullptr;
461 } 465 }
462 466
467 void AddFunctionTable(VariableProxy* table, ArrayLiteral* funcs) {
468 Type::FunctionType* func_type =
469 funcs->bounds().lower->AsArray()->Element()->AsFunction();
470 LocalType return_type = TypeFrom(func_type->Result());
471 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
472 func_type->Arity());
473 if (return_type != kAstStmt) {
474 sig.AddReturn(static_cast<LocalType>(return_type));
475 }
476 for (size_t i = 0; i < func_type->Arity(); i++) {
477 sig.AddParam(TypeFrom(func_type->Parameter(static_cast<int>(i))));
478 }
479 uint16_t signature_index = builder_->AddSignature(sig.Build());
480 InsertFunctionTable(table->var(), next_table_index_, signature_index);
481 next_table_index_ += funcs->values()->length();
482 for (size_t i = 0; i < funcs->values()->length(); i++) {
483 VariableProxy* func =
484 funcs->values()->at(static_cast<int>(i))->AsVariableProxy();
485 DCHECK(func != nullptr);
486 builder_->AddIndirectFunction(LookupOrInsertFunction(func->var()));
487 }
488 }
489
490 struct FunctionTableIndices : public ZoneObject {
491 uint16_t start_index;
492 uint16_t signature_index;
493 };
494
495 void InsertFunctionTable(Variable* v, uint16_t start_index,
496 uint16_t signature_index) {
497 FunctionTableIndices* container = new (zone()) FunctionTableIndices();
498 container->start_index = start_index;
499 container->signature_index = signature_index;
500 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
501 v, ComputePointerHash(v), ZoneAllocationPolicy(zone()));
502 entry->value = container;
503 }
504
505 FunctionTableIndices* LookupFunctionTable(Variable* v) {
506 ZoneHashMap::Entry* entry =
507 function_tables_.Lookup(v, ComputePointerHash(v));
508 DCHECK(entry != nullptr);
509 return reinterpret_cast<FunctionTableIndices*>(entry->value);
510 }
511
463 void VisitAssignment(Assignment* expr) { 512 void VisitAssignment(Assignment* expr) {
464 bool in_init = false; 513 bool in_init = false;
465 if (!in_function_) { 514 if (!in_function_) {
466 // TODO(bradnelson): Get rid of this. 515 // TODO(bradnelson): Get rid of this.
467 if (TypeOf(expr->value()) == kAstStmt) { 516 if (TypeOf(expr->value()) == kAstStmt) {
517 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
518 if (funcs != nullptr &&
519 funcs->bounds().lower->AsArray()->Element()->IsFunction()) {
520 VariableProxy* target = expr->target()->AsVariableProxy();
521 DCHECK(target != nullptr);
522 AddFunctionTable(target, funcs);
523 }
468 return; 524 return;
469 } 525 }
470 in_init = true; 526 in_init = true;
471 LoadInitFunction(); 527 LoadInitFunction();
472 } 528 }
473 BinaryOperation* value_op = expr->value()->AsBinaryOperation(); 529 BinaryOperation* value_op = expr->value()->AsBinaryOperation();
474 if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) { 530 if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) {
475 VariableProxy* target_var = expr->target()->AsVariableProxy(); 531 VariableProxy* target_var = expr->target()->AsVariableProxy();
476 VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy(); 532 VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy();
477 if (target_var != nullptr && effective_value_var != nullptr && 533 if (target_var != nullptr && effective_value_var != nullptr &&
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 UNREACHABLE(); 616 UNREACHABLE();
561 } 617 }
562 618
563 void VisitCall(Call* expr) { 619 void VisitCall(Call* expr) {
564 Call::CallType call_type = expr->GetCallType(isolate_); 620 Call::CallType call_type = expr->GetCallType(isolate_);
565 switch (call_type) { 621 switch (call_type) {
566 case Call::OTHER_CALL: { 622 case Call::OTHER_CALL: {
567 DCHECK(in_function_); 623 DCHECK(in_function_);
568 current_function_builder_->Emit(kExprCallFunction); 624 current_function_builder_->Emit(kExprCallFunction);
569 RECURSE(Visit(expr->expression())); 625 RECURSE(Visit(expr->expression()));
570 ZoneList<Expression*>* args = expr->arguments(); 626 break;
571 for (int i = 0; i < args->length(); ++i) { 627 }
572 Expression* arg = args->at(i); 628 case Call::KEYED_PROPERTY_CALL: {
573 RECURSE(Visit(arg)); 629 DCHECK(in_function_);
574 } 630 Property* p = expr->expression()->AsProperty();
631 DCHECK(p != nullptr);
632 VariableProxy* var = p->obj()->AsVariableProxy();
633 DCHECK(var != nullptr);
634 FunctionTableIndices* indices = LookupFunctionTable(var->var());
635 current_function_builder_->EmitWithU8(kExprCallIndirect,
636 indices->signature_index);
637 current_function_builder_->Emit(kExprI32Add);
638 byte code[] = {WASM_I32(indices->start_index)};
639 current_function_builder_->EmitCode(code, sizeof(code));
640 RECURSE(Visit(p->key()));
575 break; 641 break;
576 } 642 }
577 default: 643 default:
578 UNREACHABLE(); 644 UNREACHABLE();
579 } 645 }
646 ZoneList<Expression*>* args = expr->arguments();
647 for (int i = 0; i < args->length(); ++i) {
648 Expression* arg = args->at(i);
649 RECURSE(Visit(arg));
650 }
580 } 651 }
581 652
582 void VisitCallNew(CallNew* expr) { UNREACHABLE(); } 653 void VisitCallNew(CallNew* expr) { UNREACHABLE(); }
583 654
584 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); } 655 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); }
585 656
586 void VisitUnaryOperation(UnaryOperation* expr) { 657 void VisitUnaryOperation(UnaryOperation* expr) {
587 switch (expr->op()) { 658 switch (expr->op()) {
588 case Token::NOT: { 659 case Token::NOT: {
589 DCHECK(TypeOf(expr->expression()) == kAstI32); 660 DCHECK(TypeOf(expr->expression()) == kAstI32);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 RECURSE(Visit(GetLeft(expr))); 832 RECURSE(Visit(GetLeft(expr)));
762 } else if (convertOperation == kAsIs) { 833 } else if (convertOperation == kAsIs) {
763 RECURSE(Visit(GetLeft(expr))); 834 RECURSE(Visit(GetLeft(expr)));
764 } else { 835 } else {
765 switch (expr->op()) { 836 switch (expr->op()) {
766 BINOP_CASE(Token::ADD, Add, NON_SIGNED_BINOP, true); 837 BINOP_CASE(Token::ADD, Add, NON_SIGNED_BINOP, true);
767 BINOP_CASE(Token::SUB, Sub, NON_SIGNED_BINOP, true); 838 BINOP_CASE(Token::SUB, Sub, NON_SIGNED_BINOP, true);
768 BINOP_CASE(Token::MUL, Mul, NON_SIGNED_BINOP, true); 839 BINOP_CASE(Token::MUL, Mul, NON_SIGNED_BINOP, true);
769 BINOP_CASE(Token::DIV, Div, SIGNED_BINOP, false); 840 BINOP_CASE(Token::DIV, Div, SIGNED_BINOP, false);
770 BINOP_CASE(Token::BIT_OR, Ior, NON_SIGNED_INT_BINOP, true); 841 BINOP_CASE(Token::BIT_OR, Ior, NON_SIGNED_INT_BINOP, true);
842 BINOP_CASE(Token::BIT_AND, And, NON_SIGNED_INT_BINOP, true);
771 BINOP_CASE(Token::BIT_XOR, Xor, NON_SIGNED_INT_BINOP, true); 843 BINOP_CASE(Token::BIT_XOR, Xor, NON_SIGNED_INT_BINOP, true);
772 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true); 844 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true);
773 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true); 845 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true);
774 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true); 846 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true);
775 case Token::MOD: { 847 case Token::MOD: {
776 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false); 848 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false);
777 if (type == kInt32) { 849 if (type == kInt32) {
778 current_function_builder_->Emit(kExprI32RemS); 850 current_function_builder_->Emit(kExprI32RemS);
779 } else if (type == kUint32) { 851 } else if (type == kUint32) {
780 current_function_builder_->Emit(kExprI32RemU); 852 current_function_builder_->Emit(kExprI32RemU);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 bool is_set_op_; 1085 bool is_set_op_;
1014 bool marking_exported; 1086 bool marking_exported;
1015 WasmModuleBuilder* builder_; 1087 WasmModuleBuilder* builder_;
1016 WasmFunctionBuilder* current_function_builder_; 1088 WasmFunctionBuilder* current_function_builder_;
1017 FunctionLiteral* literal_; 1089 FunctionLiteral* literal_;
1018 Isolate* isolate_; 1090 Isolate* isolate_;
1019 Zone* zone_; 1091 Zone* zone_;
1020 TypeCache const& cache_; 1092 TypeCache const& cache_;
1021 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1093 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1022 int block_size_; 1094 int block_size_;
1023 uint16_t init_function_index; 1095 uint16_t init_function_index_;
1096 uint16_t next_table_index_;
1097 ZoneHashMap function_tables_;
1024 1098
1025 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1099 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1026 1100
1027 private: 1101 private:
1028 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1102 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1029 }; 1103 };
1030 1104
1031 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1105 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1032 FunctionLiteral* literal) 1106 FunctionLiteral* literal)
1033 : isolate_(isolate), zone_(zone), literal_(literal) {} 1107 : isolate_(isolate), zone_(zone), literal_(literal) {}
1034 1108
1035 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1109 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so
1036 // that zone in constructor may be thrown away once wasm module is written. 1110 // that zone in constructor may be thrown away once wasm module is written.
1037 WasmModuleIndex* AsmWasmBuilder::Run() { 1111 WasmModuleIndex* AsmWasmBuilder::Run() {
1038 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); 1112 AsmWasmBuilderImpl impl(isolate_, zone_, literal_);
1039 impl.Compile(); 1113 impl.Compile();
1040 WasmModuleWriter* writer = impl.builder_->Build(zone_); 1114 WasmModuleWriter* writer = impl.builder_->Build(zone_);
1041 return writer->WriteTo(zone_); 1115 return writer->WriteTo(zone_);
1042 } 1116 }
1043 } // namespace wasm 1117 } // namespace wasm
1044 } // namespace internal 1118 } // namespace internal
1045 } // namespace v8 1119 } // namespace v8
OLDNEW
« src/typing-asm.cc ('K') | « src/typing-asm.cc ('k') | src/wasm/encoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698