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

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

Issue 1729833002: Add wasm internal opcodes for asm.js stdlib functions we're missing. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: merge Created 4 years, 9 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.h ('k') | test/mjsunit/wasm/asm-wasm.js » ('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 // Required to get M_E etc. in MSVC. 7 // Required to get M_E etc. in MSVC.
8 #if defined(_WIN32) 8 #if defined(_WIN32)
9 #define _USE_MATH_DEFINES 9 #define _USE_MATH_DEFINES
10 #endif 10 #endif
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 void InitializeInitFunction() { 68 void InitializeInitFunction() {
69 unsigned char init[] = "__init__"; 69 unsigned char init[] = "__init__";
70 init_function_index_ = builder_->AddFunction(); 70 init_function_index_ = builder_->AddFunction();
71 current_function_builder_ = builder_->FunctionAt(init_function_index_); 71 current_function_builder_ = builder_->FunctionAt(init_function_index_);
72 current_function_builder_->SetName(init, 8); 72 current_function_builder_->SetName(init, 8);
73 current_function_builder_->ReturnType(kAstStmt); 73 current_function_builder_->ReturnType(kAstStmt);
74 current_function_builder_->Exported(1); 74 current_function_builder_->Exported(1);
75 current_function_builder_ = nullptr; 75 current_function_builder_ = nullptr;
76 } 76 }
77 77
78 void AddStdlibImport(const char* name, int kind, int args) {
79 uint16_t index = builder_->AddFunction();
80 std_function_index_[kind] = index;
81 WasmFunctionBuilder* b = builder_->FunctionAt(index);
82 b->External(1);
83 b->SetName(reinterpret_cast<const unsigned char*>(name),
84 static_cast<int>(strlen(name)));
85 b->ReturnType(kAstF64);
86 for (int i = 0; i < args; ++i) {
87 b->AddParam(kAstF64);
88 }
89 }
90
91 void InitializeStdlibFunctions() {
92 for (int i = 0; i < AsmTyper::kStdlibMax; ++i) {
93 std_function_index_[i] = -1;
94 }
95 }
96
97 void AddStdlibFunction(int kind) {
98 const char* name = nullptr;
99 int args = 0;
100 switch (kind) {
101 case AsmTyper::kMathAcos:
102 name = "_acos";
103 args = 1;
104 break;
105 case AsmTyper::kMathAsin:
106 name = "_asin";
107 args = 1;
108 break;
109 case AsmTyper::kMathAtan:
110 name = "_atan";
111 args = 1;
112 break;
113 case AsmTyper::kMathCos:
114 name = "_cos";
115 args = 1;
116 break;
117 case AsmTyper::kMathSin:
118 name = "_sin";
119 args = 1;
120 break;
121 case AsmTyper::kMathTan:
122 name = "_tan";
123 args = 1;
124 break;
125 case AsmTyper::kMathExp:
126 name = "_exp";
127 args = 1;
128 break;
129 case AsmTyper::kMathLog:
130 name = "_log";
131 args = 1;
132 break;
133 case AsmTyper::kMathAtan2:
134 name = "_atan2";
135 args = 2;
136 break;
137 case AsmTyper::kMathPow:
138 name = "_pow";
139 args = 2;
140 break;
141 }
142 DCHECK(name != nullptr);
143 AddStdlibImport(name, kind, args);
144 }
145
146 void EmitStdlibCall(int kind) {
147 if (std_function_index_[kind] < 0) {
148 AddStdlibFunction(kind);
149 }
150 current_function_builder_->Emit(kExprCallFunction);
151 std::vector<uint8_t> index_arr =
152 UnsignedLEB128From(std_function_index_[kind]);
153 current_function_builder_->EmitCode(
154 &index_arr[0], static_cast<uint32_t>(index_arr.size()));
155 }
156
78 void Compile() { 157 void Compile() {
79 InitializeInitFunction(); 158 InitializeInitFunction();
159 InitializeStdlibFunctions();
80 RECURSE(VisitFunctionLiteral(literal_)); 160 RECURSE(VisitFunctionLiteral(literal_));
81 } 161 }
82 162
83 void VisitVariableDeclaration(VariableDeclaration* decl) {} 163 void VisitVariableDeclaration(VariableDeclaration* decl) {}
84 164
85 void VisitFunctionDeclaration(FunctionDeclaration* decl) { 165 void VisitFunctionDeclaration(FunctionDeclaration* decl) {
86 DCHECK(!in_function_); 166 DCHECK(!in_function_);
87 DCHECK_NULL(current_function_builder_); 167 DCHECK_NULL(current_function_builder_);
88 uint16_t index = LookupOrInsertFunction(decl->proxy()->var()); 168 uint16_t index = LookupOrInsertFunction(decl->proxy()->var());
89 current_function_builder_ = builder_->FunctionAt(index); 169 current_function_builder_ = builder_->FunctionAt(index);
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 Variable* var = expr->var(); 915 Variable* var = expr->var();
836 AsmTyper::StandardMember standard_object = 916 AsmTyper::StandardMember standard_object =
837 typer_->VariableAsStandardMember(var); 917 typer_->VariableAsStandardMember(var);
838 ZoneList<Expression*>* args = call->arguments(); 918 ZoneList<Expression*>* args = call->arguments();
839 LocalType call_type = TypeOf(call); 919 LocalType call_type = TypeOf(call);
840 switch (standard_object) { 920 switch (standard_object) {
841 case AsmTyper::kNone: { 921 case AsmTyper::kNone: {
842 return false; 922 return false;
843 } 923 }
844 case AsmTyper::kMathAcos: { 924 case AsmTyper::kMathAcos: {
845 UNREACHABLE(); 925 EmitStdlibCall(AsmTyper::kMathAcos);
846 break; // TODO(bradnelson): Implement as external. 926 break;
847 } 927 }
848 case AsmTyper::kMathAsin: { 928 case AsmTyper::kMathAsin: {
849 UNREACHABLE(); 929 EmitStdlibCall(AsmTyper::kMathAsin);
850 break; // TODO(bradnelson): Implement as external. 930 break;
851 } 931 }
852 case AsmTyper::kMathAtan: { 932 case AsmTyper::kMathAtan: {
853 UNREACHABLE(); 933 EmitStdlibCall(AsmTyper::kMathAtan);
854 break; // TODO(bradnelson): Implement as external. 934 break;
855 } 935 }
856 case AsmTyper::kMathCos: { 936 case AsmTyper::kMathCos: {
857 UNREACHABLE(); 937 EmitStdlibCall(AsmTyper::kMathCos);
858 break; // TODO(bradnelson): Implement as external. 938 break;
859 } 939 }
860 case AsmTyper::kMathSin: { 940 case AsmTyper::kMathSin: {
861 UNREACHABLE(); 941 EmitStdlibCall(AsmTyper::kMathSin);
862 break; // TODO(bradnelson): Implement as external. 942 break;
863 } 943 }
864 case AsmTyper::kMathTan: { 944 case AsmTyper::kMathTan: {
865 UNREACHABLE(); 945 EmitStdlibCall(AsmTyper::kMathTan);
866 break; // TODO(bradnelson): Implement as external. 946 break;
867 } 947 }
868 case AsmTyper::kMathExp: { 948 case AsmTyper::kMathExp: {
869 UNREACHABLE(); 949 EmitStdlibCall(AsmTyper::kMathExp);
870 break; // TODO(bradnelson): Implement as external. 950 break;
871 } 951 }
872 case AsmTyper::kMathLog: { 952 case AsmTyper::kMathLog: {
873 UNREACHABLE(); 953 EmitStdlibCall(AsmTyper::kMathLog);
874 break; // TODO(bradnelson): Implement as external. 954 break;
875 } 955 }
876 case AsmTyper::kMathCeil: { 956 case AsmTyper::kMathCeil: {
877 if (call_type == kAstF32) { 957 if (call_type == kAstF32) {
878 current_function_builder_->Emit(kExprF32Ceil); 958 current_function_builder_->Emit(kExprF32Ceil);
879 } else if (call_type == kAstF64) { 959 } else if (call_type == kAstF64) {
880 current_function_builder_->Emit(kExprF64Ceil); 960 current_function_builder_->Emit(kExprF64Ceil);
881 } else { 961 } else {
882 UNREACHABLE(); 962 UNREACHABLE();
883 } 963 }
884 break; 964 break;
(...skipping 11 matching lines...) Expand all
896 case AsmTyper::kMathSqrt: { 976 case AsmTyper::kMathSqrt: {
897 if (call_type == kAstF32) { 977 if (call_type == kAstF32) {
898 current_function_builder_->Emit(kExprF32Sqrt); 978 current_function_builder_->Emit(kExprF32Sqrt);
899 } else if (call_type == kAstF64) { 979 } else if (call_type == kAstF64) {
900 current_function_builder_->Emit(kExprF64Sqrt); 980 current_function_builder_->Emit(kExprF64Sqrt);
901 } else { 981 } else {
902 UNREACHABLE(); 982 UNREACHABLE();
903 } 983 }
904 break; 984 break;
905 } 985 }
906 case AsmTyper::kMathAbs: { 986 case AsmTyper::kMathAbs: {
titzer 2016/02/24 17:54:11 We're going to need some more extensive tests for
bradn 2016/02/24 18:07:29 Yeah this one is goofy, Math.abs is supposed to ha
907 // TODO(bradnelson): Handle signed. 987 // TODO(bradnelson): Should this be cast to float?
908 if (call_type == kAstF32) { 988 if (call_type == kAstI32) {
989 current_function_builder_->Emit(kExprIfElse);
990 current_function_builder_->Emit(kExprI32LtS);
991 Visit(args->at(0));
992 byte code[] = {WASM_I32(0)};
titzer 2016/02/24 17:54:11 WASM_I8
bradn 2016/02/24 18:07:29 Done.
993 current_function_builder_->EmitCode(code, sizeof(code));
994 current_function_builder_->Emit(kExprI32Sub);
995 current_function_builder_->EmitCode(code, sizeof(code));
996 Visit(args->at(0));
997 } else if (call_type == kAstF32) {
909 current_function_builder_->Emit(kExprF32Abs); 998 current_function_builder_->Emit(kExprF32Abs);
910 } else if (call_type == kAstF64) { 999 } else if (call_type == kAstF64) {
911 current_function_builder_->Emit(kExprF64Abs); 1000 current_function_builder_->Emit(kExprF64Abs);
912 } else { 1001 } else {
913 UNREACHABLE(); 1002 UNREACHABLE();
914 } 1003 }
915 break; 1004 break;
916 } 1005 }
917 case AsmTyper::kMathMin: { 1006 case AsmTyper::kMathMin: {
918 // TODO(bradnelson): Handle signed.
919 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode. 1007 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode.
920 if (call_type == kAstF32) { 1008 if (call_type == kAstI32) {
1009 current_function_builder_->Emit(kExprIfElse);
bradn 2016/02/24 18:07:29 Min and max have the same -(1<<31) issue it seems
1010 current_function_builder_->Emit(kExprI32LeS);
1011 Visit(args->at(0));
1012 Visit(args->at(1));
1013 } else if (call_type == kAstF32) {
921 current_function_builder_->Emit(kExprF32Min); 1014 current_function_builder_->Emit(kExprF32Min);
922 } else if (call_type == kAstF64) { 1015 } else if (call_type == kAstF64) {
923 current_function_builder_->Emit(kExprF64Min); 1016 current_function_builder_->Emit(kExprF64Min);
924 } else { 1017 } else {
925 UNREACHABLE(); 1018 UNREACHABLE();
926 } 1019 }
927 break; 1020 break;
928 } 1021 }
929 case AsmTyper::kMathMax: { 1022 case AsmTyper::kMathMax: {
930 // TODO(bradnelson): Handle signed.
931 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode. 1023 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode.
932 if (call_type == kAstF32) { 1024 if (call_type == kAstI32) {
1025 current_function_builder_->Emit(kExprIfElse);
1026 current_function_builder_->Emit(kExprI32GtS);
1027 Visit(args->at(0));
1028 Visit(args->at(1));
1029 } else if (call_type == kAstF32) {
933 current_function_builder_->Emit(kExprF32Max); 1030 current_function_builder_->Emit(kExprF32Max);
934 } else if (call_type == kAstF64) { 1031 } else if (call_type == kAstF64) {
935 current_function_builder_->Emit(kExprF64Max); 1032 current_function_builder_->Emit(kExprF64Max);
936 } else { 1033 } else {
937 UNREACHABLE(); 1034 UNREACHABLE();
938 } 1035 }
939 break; 1036 break;
940 } 1037 }
941 case AsmTyper::kMathAtan2: { 1038 case AsmTyper::kMathAtan2: {
942 UNREACHABLE(); 1039 EmitStdlibCall(AsmTyper::kMathAtan2);
943 break; // TODO(bradnelson): Implement as external. 1040 break;
944 } 1041 }
945 case AsmTyper::kMathPow: { 1042 case AsmTyper::kMathPow: {
946 UNREACHABLE(); 1043 EmitStdlibCall(AsmTyper::kMathPow);
947 break; // TODO(bradnelson): Implement as external. 1044 break;
948 } 1045 }
949 case AsmTyper::kMathImul: { 1046 case AsmTyper::kMathImul: {
950 current_function_builder_->Emit(kExprI32Mul); 1047 current_function_builder_->Emit(kExprI32Mul);
951 break; 1048 break;
952 } 1049 }
953 case AsmTyper::kMathFround: { 1050 case AsmTyper::kMathFround: {
954 DCHECK(args->length() == 1); 1051 DCHECK(args->length() == 1);
955 Literal* literal = args->at(0)->AsLiteral(); 1052 Literal* literal = args->at(0)->AsLiteral();
956 if (literal != nullptr) { 1053 if (literal != nullptr) {
957 if (literal->raw_value()->IsNumber()) { 1054 if (literal->raw_value()->IsNumber()) {
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 Zone* zone_; 1577 Zone* zone_;
1481 Handle<Object> foreign_; 1578 Handle<Object> foreign_;
1482 AsmTyper* typer_; 1579 AsmTyper* typer_;
1483 TypeCache const& cache_; 1580 TypeCache const& cache_;
1484 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; 1581 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
1485 int block_size_; 1582 int block_size_;
1486 uint16_t init_function_index_; 1583 uint16_t init_function_index_;
1487 uint32_t next_table_index_; 1584 uint32_t next_table_index_;
1488 ZoneHashMap function_tables_; 1585 ZoneHashMap function_tables_;
1489 ImportedFunctionTable imported_function_table_; 1586 ImportedFunctionTable imported_function_table_;
1587 int std_function_index_[AsmTyper::kStdlibMax];
1490 1588
1491 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 1589 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1492 1590
1493 private: 1591 private:
1494 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); 1592 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl);
1495 }; 1593 };
1496 1594
1497 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, 1595 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone,
1498 FunctionLiteral* literal, Handle<Object> foreign, 1596 FunctionLiteral* literal, Handle<Object> foreign,
1499 AsmTyper* typer) 1597 AsmTyper* typer)
1500 : isolate_(isolate), 1598 : isolate_(isolate),
1501 zone_(zone), 1599 zone_(zone),
1502 literal_(literal), 1600 literal_(literal),
1503 foreign_(foreign), 1601 foreign_(foreign),
1504 typer_(typer) {} 1602 typer_(typer) {}
1505 1603
1506 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so 1604 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so
1507 // that zone in constructor may be thrown away once wasm module is written. 1605 // that zone in constructor may be thrown away once wasm module is written.
1508 WasmModuleIndex* AsmWasmBuilder::Run() { 1606 WasmModuleIndex* AsmWasmBuilder::Run() {
1509 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); 1607 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_);
1510 impl.Compile(); 1608 impl.Compile();
1511 WasmModuleWriter* writer = impl.builder_->Build(zone_); 1609 WasmModuleWriter* writer = impl.builder_->Build(zone_);
1512 return writer->WriteTo(zone_); 1610 return writer->WriteTo(zone_);
1513 } 1611 }
1514 } // namespace wasm 1612 } // namespace wasm
1515 } // namespace internal 1613 } // namespace internal
1516 } // namespace v8 1614 } // namespace v8
OLDNEW
« no previous file with comments | « src/typing-asm.h ('k') | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698