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

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
« no previous file with comments | « src/typing-asm.cc ('k') | 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 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 (int i = 0; i < func_type->Arity(); i++) {
477 sig.AddParam(TypeFrom(func_type->Parameter(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 (int i = 0; i < funcs->values()->length(); i++) {
483 VariableProxy* func = funcs->values()->at(i)->AsVariableProxy();
484 DCHECK(func != nullptr);
485 builder_->AddIndirectFunction(LookupOrInsertFunction(func->var()));
486 }
487 }
488
489 struct FunctionTableIndices : public ZoneObject {
490 uint32_t start_index;
491 uint16_t signature_index;
492 };
493
494 void InsertFunctionTable(Variable* v, uint32_t start_index,
495 uint16_t signature_index) {
496 FunctionTableIndices* container = new (zone()) FunctionTableIndices();
497 container->start_index = start_index;
498 container->signature_index = signature_index;
499 ZoneHashMap::Entry* entry = function_tables_.LookupOrInsert(
500 v, ComputePointerHash(v), ZoneAllocationPolicy(zone()));
501 entry->value = container;
502 }
503
504 FunctionTableIndices* LookupFunctionTable(Variable* v) {
505 ZoneHashMap::Entry* entry =
506 function_tables_.Lookup(v, ComputePointerHash(v));
507 DCHECK(entry != nullptr);
508 return reinterpret_cast<FunctionTableIndices*>(entry->value);
509 }
510
463 void VisitAssignment(Assignment* expr) { 511 void VisitAssignment(Assignment* expr) {
464 bool in_init = false; 512 bool in_init = false;
465 if (!in_function_) { 513 if (!in_function_) {
466 // TODO(bradnelson): Get rid of this. 514 // TODO(bradnelson): Get rid of this.
467 if (TypeOf(expr->value()) == kAstStmt) { 515 if (TypeOf(expr->value()) == kAstStmt) {
516 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
517 if (funcs != nullptr &&
518 funcs->bounds().lower->AsArray()->Element()->IsFunction()) {
519 VariableProxy* target = expr->target()->AsVariableProxy();
520 DCHECK(target != nullptr);
521 AddFunctionTable(target, funcs);
522 }
468 return; 523 return;
469 } 524 }
470 in_init = true; 525 in_init = true;
471 LoadInitFunction(); 526 LoadInitFunction();
472 } 527 }
473 BinaryOperation* value_op = expr->value()->AsBinaryOperation(); 528 BinaryOperation* value_op = expr->value()->AsBinaryOperation();
474 if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) { 529 if (value_op != nullptr && MatchBinaryOperation(value_op) == kAsIs) {
475 VariableProxy* target_var = expr->target()->AsVariableProxy(); 530 VariableProxy* target_var = expr->target()->AsVariableProxy();
476 VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy(); 531 VariableProxy* effective_value_var = GetLeft(value_op)->AsVariableProxy();
477 if (target_var != nullptr && effective_value_var != nullptr && 532 if (target_var != nullptr && effective_value_var != nullptr &&
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 UNREACHABLE(); 615 UNREACHABLE();
561 } 616 }
562 617
563 void VisitCall(Call* expr) { 618 void VisitCall(Call* expr) {
564 Call::CallType call_type = expr->GetCallType(isolate_); 619 Call::CallType call_type = expr->GetCallType(isolate_);
565 switch (call_type) { 620 switch (call_type) {
566 case Call::OTHER_CALL: { 621 case Call::OTHER_CALL: {
567 DCHECK(in_function_); 622 DCHECK(in_function_);
568 current_function_builder_->Emit(kExprCallFunction); 623 current_function_builder_->Emit(kExprCallFunction);
569 RECURSE(Visit(expr->expression())); 624 RECURSE(Visit(expr->expression()));
570 ZoneList<Expression*>* args = expr->arguments(); 625 break;
571 for (int i = 0; i < args->length(); ++i) { 626 }
572 Expression* arg = args->at(i); 627 case Call::KEYED_PROPERTY_CALL: {
573 RECURSE(Visit(arg)); 628 DCHECK(in_function_);
574 } 629 Property* p = expr->expression()->AsProperty();
630 DCHECK(p != nullptr);
631 VariableProxy* var = p->obj()->AsVariableProxy();
632 DCHECK(var != nullptr);
633 FunctionTableIndices* indices = LookupFunctionTable(var->var());
634 current_function_builder_->EmitWithU8(kExprCallIndirect,
635 indices->signature_index);
636 current_function_builder_->Emit(kExprI32Add);
637 byte code[] = {WASM_I32(indices->start_index)};
638 current_function_builder_->EmitCode(code, sizeof(code));
639 RECURSE(Visit(p->key()));
575 break; 640 break;
576 } 641 }
577 default: 642 default:
578 UNREACHABLE(); 643 UNREACHABLE();
579 } 644 }
645 ZoneList<Expression*>* args = expr->arguments();
646 for (int i = 0; i < args->length(); ++i) {
647 Expression* arg = args->at(i);
648 RECURSE(Visit(arg));
649 }
580 } 650 }
581 651
582 void VisitCallNew(CallNew* expr) { UNREACHABLE(); } 652 void VisitCallNew(CallNew* expr) { UNREACHABLE(); }
583 653
584 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); } 654 void VisitCallRuntime(CallRuntime* expr) { UNREACHABLE(); }
585 655
586 void VisitUnaryOperation(UnaryOperation* expr) { 656 void VisitUnaryOperation(UnaryOperation* expr) {
587 switch (expr->op()) { 657 switch (expr->op()) {
588 case Token::NOT: { 658 case Token::NOT: {
589 DCHECK(TypeOf(expr->expression()) == kAstI32); 659 DCHECK(TypeOf(expr->expression()) == kAstI32);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 RECURSE(Visit(GetLeft(expr))); 831 RECURSE(Visit(GetLeft(expr)));
762 } else if (convertOperation == kAsIs) { 832 } else if (convertOperation == kAsIs) {
763 RECURSE(Visit(GetLeft(expr))); 833 RECURSE(Visit(GetLeft(expr)));
764 } else { 834 } else {
765 switch (expr->op()) { 835 switch (expr->op()) {
766 BINOP_CASE(Token::ADD, Add, NON_SIGNED_BINOP, true); 836 BINOP_CASE(Token::ADD, Add, NON_SIGNED_BINOP, true);
767 BINOP_CASE(Token::SUB, Sub, NON_SIGNED_BINOP, true); 837 BINOP_CASE(Token::SUB, Sub, NON_SIGNED_BINOP, true);
768 BINOP_CASE(Token::MUL, Mul, NON_SIGNED_BINOP, true); 838 BINOP_CASE(Token::MUL, Mul, NON_SIGNED_BINOP, true);
769 BINOP_CASE(Token::DIV, Div, SIGNED_BINOP, false); 839 BINOP_CASE(Token::DIV, Div, SIGNED_BINOP, false);
770 BINOP_CASE(Token::BIT_OR, Ior, NON_SIGNED_INT_BINOP, true); 840 BINOP_CASE(Token::BIT_OR, Ior, NON_SIGNED_INT_BINOP, true);
841 BINOP_CASE(Token::BIT_AND, And, NON_SIGNED_INT_BINOP, true);
771 BINOP_CASE(Token::BIT_XOR, Xor, NON_SIGNED_INT_BINOP, true); 842 BINOP_CASE(Token::BIT_XOR, Xor, NON_SIGNED_INT_BINOP, true);
772 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true); 843 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true);
773 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true); 844 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true);
774 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true); 845 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true);
775 case Token::MOD: { 846 case Token::MOD: {
776 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false); 847 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false);
777 if (type == kInt32) { 848 if (type == kInt32) {
778 current_function_builder_->Emit(kExprI32RemS); 849 current_function_builder_->Emit(kExprI32RemS);
779 } else if (type == kUint32) { 850 } else if (type == kUint32) {
780 current_function_builder_->Emit(kExprI32RemU); 851 current_function_builder_->Emit(kExprI32RemU);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 bool is_set_op_; 1084 bool is_set_op_;
1014 bool marking_exported; 1085 bool marking_exported;
1015 WasmModuleBuilder* builder_; 1086 WasmModuleBuilder* builder_;
1016 WasmFunctionBuilder* current_function_builder_; 1087 WasmFunctionBuilder* current_function_builder_;
1017 FunctionLiteral* literal_; 1088 FunctionLiteral* literal_;
1018 Isolate* isolate_; 1089 Isolate* isolate_;
1019 Zone* zone_; 1090 Zone* zone_;
1020 TypeCache const& cache_; 1091 TypeCache const& cache_;
1021 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1092 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1022 int block_size_; 1093 int block_size_;
1023 uint16_t init_function_index; 1094 uint16_t init_function_index_;
1095 uint32_t next_table_index_;
1096 ZoneHashMap function_tables_;
1024 1097
1025 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1098 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1026 1099
1027 private: 1100 private:
1028 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1101 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1029 }; 1102 };
1030 1103
1031 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1104 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1032 FunctionLiteral* literal) 1105 FunctionLiteral* literal)
1033 : isolate_(isolate), zone_(zone), literal_(literal) {} 1106 : isolate_(isolate), zone_(zone), literal_(literal) {}
1034 1107
1035 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1108 // 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. 1109 // that zone in constructor may be thrown away once wasm module is written.
1037 WasmModuleIndex* AsmWasmBuilder::Run() { 1110 WasmModuleIndex* AsmWasmBuilder::Run() {
1038 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); 1111 AsmWasmBuilderImpl impl(isolate_, zone_, literal_);
1039 impl.Compile(); 1112 impl.Compile();
1040 WasmModuleWriter* writer = impl.builder_->Build(zone_); 1113 WasmModuleWriter* writer = impl.builder_->Build(zone_);
1041 return writer->WriteTo(zone_); 1114 return writer->WriteTo(zone_);
1042 } 1115 }
1043 } // namespace wasm 1116 } // namespace wasm
1044 } // namespace internal 1117 } // namespace internal
1045 } // namespace v8 1118 } // namespace v8
OLDNEW
« no previous file with comments | « src/typing-asm.cc ('k') | src/wasm/encoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698