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 // 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |