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 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 Variable* var = expr->var(); | 839 Variable* var = expr->var(); |
840 AsmTyper::StandardMember standard_object = | 840 AsmTyper::StandardMember standard_object = |
841 typer_->VariableAsStandardMember(var); | 841 typer_->VariableAsStandardMember(var); |
842 ZoneList<Expression*>* args = call->arguments(); | 842 ZoneList<Expression*>* args = call->arguments(); |
843 LocalType call_type = TypeOf(call); | 843 LocalType call_type = TypeOf(call); |
844 switch (standard_object) { | 844 switch (standard_object) { |
845 case AsmTyper::kNone: { | 845 case AsmTyper::kNone: { |
846 return false; | 846 return false; |
847 } | 847 } |
848 case AsmTyper::kMathAcos: { | 848 case AsmTyper::kMathAcos: { |
849 UNREACHABLE(); | 849 DCHECK_EQ(kAstF64, call_type); |
850 break; // TODO(bradnelson): Implement as external. | 850 current_function_builder_->Emit(kExprF64Acos); |
| 851 break; |
851 } | 852 } |
852 case AsmTyper::kMathAsin: { | 853 case AsmTyper::kMathAsin: { |
853 UNREACHABLE(); | 854 DCHECK_EQ(kAstF64, call_type); |
854 break; // TODO(bradnelson): Implement as external. | 855 current_function_builder_->Emit(kExprF64Asin); |
| 856 break; |
855 } | 857 } |
856 case AsmTyper::kMathAtan: { | 858 case AsmTyper::kMathAtan: { |
857 UNREACHABLE(); | 859 DCHECK_EQ(kAstF64, call_type); |
858 break; // TODO(bradnelson): Implement as external. | 860 current_function_builder_->Emit(kExprF64Atan); |
| 861 break; |
859 } | 862 } |
860 case AsmTyper::kMathCos: { | 863 case AsmTyper::kMathCos: { |
861 UNREACHABLE(); | 864 DCHECK_EQ(kAstF64, call_type); |
862 break; // TODO(bradnelson): Implement as external. | 865 current_function_builder_->Emit(kExprF64Cos); |
| 866 break; |
863 } | 867 } |
864 case AsmTyper::kMathSin: { | 868 case AsmTyper::kMathSin: { |
865 UNREACHABLE(); | 869 DCHECK_EQ(kAstF64, call_type); |
866 break; // TODO(bradnelson): Implement as external. | 870 current_function_builder_->Emit(kExprF64Sin); |
| 871 break; |
867 } | 872 } |
868 case AsmTyper::kMathTan: { | 873 case AsmTyper::kMathTan: { |
869 UNREACHABLE(); | 874 DCHECK_EQ(kAstF64, call_type); |
870 break; // TODO(bradnelson): Implement as external. | 875 current_function_builder_->Emit(kExprF64Tan); |
| 876 break; |
871 } | 877 } |
872 case AsmTyper::kMathExp: { | 878 case AsmTyper::kMathExp: { |
873 UNREACHABLE(); | 879 DCHECK_EQ(kAstF64, call_type); |
874 break; // TODO(bradnelson): Implement as external. | 880 current_function_builder_->Emit(kExprF64Exp); |
| 881 break; |
875 } | 882 } |
876 case AsmTyper::kMathLog: { | 883 case AsmTyper::kMathLog: { |
877 UNREACHABLE(); | 884 DCHECK_EQ(kAstF64, call_type); |
878 break; // TODO(bradnelson): Implement as external. | 885 current_function_builder_->Emit(kExprF64Log); |
| 886 break; |
879 } | 887 } |
880 case AsmTyper::kMathCeil: { | 888 case AsmTyper::kMathCeil: { |
881 if (call_type == kAstF32) { | 889 if (call_type == kAstF32) { |
882 current_function_builder_->Emit(kExprF32Ceil); | 890 current_function_builder_->Emit(kExprF32Ceil); |
883 } else if (call_type == kAstF64) { | 891 } else if (call_type == kAstF64) { |
884 current_function_builder_->Emit(kExprF64Ceil); | 892 current_function_builder_->Emit(kExprF64Ceil); |
885 } else { | 893 } else { |
886 UNREACHABLE(); | 894 UNREACHABLE(); |
887 } | 895 } |
888 break; | 896 break; |
(...skipping 12 matching lines...) Expand all Loading... |
901 if (call_type == kAstF32) { | 909 if (call_type == kAstF32) { |
902 current_function_builder_->Emit(kExprF32Sqrt); | 910 current_function_builder_->Emit(kExprF32Sqrt); |
903 } else if (call_type == kAstF64) { | 911 } else if (call_type == kAstF64) { |
904 current_function_builder_->Emit(kExprF64Sqrt); | 912 current_function_builder_->Emit(kExprF64Sqrt); |
905 } else { | 913 } else { |
906 UNREACHABLE(); | 914 UNREACHABLE(); |
907 } | 915 } |
908 break; | 916 break; |
909 } | 917 } |
910 case AsmTyper::kMathAbs: { | 918 case AsmTyper::kMathAbs: { |
911 // TODO(bradnelson): Handle signed. | 919 // TODO(bradnelson): Should this be cast to float? |
912 if (call_type == kAstF32) { | 920 if (call_type == kAstI32) { |
| 921 current_function_builder_->Emit(kExprIfElse); |
| 922 current_function_builder_->Emit(kExprI32LtS); |
| 923 Visit(args->at(0)); |
| 924 byte code[] = {WASM_I8(0)}; |
| 925 current_function_builder_->EmitCode(code, sizeof(code)); |
| 926 current_function_builder_->Emit(kExprI32Sub); |
| 927 current_function_builder_->EmitCode(code, sizeof(code)); |
| 928 Visit(args->at(0)); |
| 929 } else if (call_type == kAstF32) { |
913 current_function_builder_->Emit(kExprF32Abs); | 930 current_function_builder_->Emit(kExprF32Abs); |
914 } else if (call_type == kAstF64) { | 931 } else if (call_type == kAstF64) { |
915 current_function_builder_->Emit(kExprF64Abs); | 932 current_function_builder_->Emit(kExprF64Abs); |
916 } else { | 933 } else { |
917 UNREACHABLE(); | 934 UNREACHABLE(); |
918 } | 935 } |
919 break; | 936 break; |
920 } | 937 } |
921 case AsmTyper::kMathMin: { | 938 case AsmTyper::kMathMin: { |
922 // TODO(bradnelson): Handle signed. | |
923 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode. | 939 // TODO(bradnelson): Change wasm to match Math.min in asm.js mode. |
924 if (call_type == kAstF32) { | 940 if (call_type == kAstI32) { |
| 941 current_function_builder_->Emit(kExprIfElse); |
| 942 current_function_builder_->Emit(kExprI32LeS); |
| 943 Visit(args->at(0)); |
| 944 Visit(args->at(1)); |
| 945 } else if (call_type == kAstF32) { |
925 current_function_builder_->Emit(kExprF32Min); | 946 current_function_builder_->Emit(kExprF32Min); |
926 } else if (call_type == kAstF64) { | 947 } else if (call_type == kAstF64) { |
927 current_function_builder_->Emit(kExprF64Min); | 948 current_function_builder_->Emit(kExprF64Min); |
928 } else { | 949 } else { |
929 UNREACHABLE(); | 950 UNREACHABLE(); |
930 } | 951 } |
931 break; | 952 break; |
932 } | 953 } |
933 case AsmTyper::kMathMax: { | 954 case AsmTyper::kMathMax: { |
934 // TODO(bradnelson): Handle signed. | |
935 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode. | 955 // TODO(bradnelson): Change wasm to match Math.max in asm.js mode. |
936 if (call_type == kAstF32) { | 956 if (call_type == kAstI32) { |
| 957 current_function_builder_->Emit(kExprIfElse); |
| 958 current_function_builder_->Emit(kExprI32GtS); |
| 959 Visit(args->at(0)); |
| 960 Visit(args->at(1)); |
| 961 } else if (call_type == kAstF32) { |
937 current_function_builder_->Emit(kExprF32Max); | 962 current_function_builder_->Emit(kExprF32Max); |
938 } else if (call_type == kAstF64) { | 963 } else if (call_type == kAstF64) { |
939 current_function_builder_->Emit(kExprF64Max); | 964 current_function_builder_->Emit(kExprF64Max); |
940 } else { | 965 } else { |
941 UNREACHABLE(); | 966 UNREACHABLE(); |
942 } | 967 } |
943 break; | 968 break; |
944 } | 969 } |
945 case AsmTyper::kMathAtan2: { | 970 case AsmTyper::kMathAtan2: { |
946 UNREACHABLE(); | 971 DCHECK_EQ(kAstF64, call_type); |
947 break; // TODO(bradnelson): Implement as external. | 972 current_function_builder_->Emit(kExprF64Atan2); |
| 973 break; |
948 } | 974 } |
949 case AsmTyper::kMathPow: { | 975 case AsmTyper::kMathPow: { |
950 UNREACHABLE(); | 976 DCHECK_EQ(kAstF64, call_type); |
951 break; // TODO(bradnelson): Implement as external. | 977 current_function_builder_->Emit(kExprF64Pow); |
| 978 break; |
952 } | 979 } |
953 case AsmTyper::kMathImul: { | 980 case AsmTyper::kMathImul: { |
954 current_function_builder_->Emit(kExprI32Mul); | 981 current_function_builder_->Emit(kExprI32Mul); |
955 break; | 982 break; |
956 } | 983 } |
957 case AsmTyper::kMathFround: { | 984 case AsmTyper::kMathFround: { |
958 DCHECK(args->length() == 1); | 985 DCHECK(args->length() == 1); |
959 Literal* literal = args->at(0)->AsLiteral(); | 986 Literal* literal = args->at(0)->AsLiteral(); |
960 if (literal != nullptr) { | 987 if (literal != nullptr) { |
961 if (literal->raw_value()->IsNumber()) { | 988 if (literal->raw_value()->IsNumber()) { |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true); | 1263 BINOP_CASE(Token::SHL, Shl, NON_SIGNED_INT_BINOP, true); |
1237 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true); | 1264 BINOP_CASE(Token::SAR, ShrS, NON_SIGNED_INT_BINOP, true); |
1238 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true); | 1265 BINOP_CASE(Token::SHR, ShrU, NON_SIGNED_INT_BINOP, true); |
1239 case Token::MOD: { | 1266 case Token::MOD: { |
1240 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false); | 1267 TypeIndex type = TypeIndexOf(expr->left(), expr->right(), false); |
1241 if (type == kInt32) { | 1268 if (type == kInt32) { |
1242 current_function_builder_->Emit(kExprI32RemS); | 1269 current_function_builder_->Emit(kExprI32RemS); |
1243 } else if (type == kUint32) { | 1270 } else if (type == kUint32) { |
1244 current_function_builder_->Emit(kExprI32RemU); | 1271 current_function_builder_->Emit(kExprI32RemU); |
1245 } else if (type == kFloat64) { | 1272 } else if (type == kFloat64) { |
1246 ModF64(expr); | 1273 current_function_builder_->Emit(kExprF64Mod); |
1247 return; | 1274 return; |
1248 } else { | 1275 } else { |
1249 UNREACHABLE(); | 1276 UNREACHABLE(); |
1250 } | 1277 } |
1251 break; | 1278 break; |
1252 } | 1279 } |
1253 case Token::COMMA: { | 1280 case Token::COMMA: { |
1254 current_function_builder_->EmitWithU8(kExprBlock, 2); | 1281 current_function_builder_->EmitWithU8(kExprBlock, 2); |
1255 break; | 1282 break; |
1256 } | 1283 } |
1257 default: | 1284 default: |
1258 UNREACHABLE(); | 1285 UNREACHABLE(); |
1259 } | 1286 } |
1260 RECURSE(Visit(expr->left())); | 1287 RECURSE(Visit(expr->left())); |
1261 RECURSE(Visit(expr->right())); | 1288 RECURSE(Visit(expr->right())); |
1262 } | 1289 } |
1263 } | 1290 } |
1264 | 1291 |
1265 void ModF64(BinaryOperation* expr) { | |
1266 current_function_builder_->EmitWithU8(kExprBlock, 3); | |
1267 uint16_t index_0 = current_function_builder_->AddLocal(kAstF64); | |
1268 uint16_t index_1 = current_function_builder_->AddLocal(kAstF64); | |
1269 current_function_builder_->Emit(kExprSetLocal); | |
1270 AddLeb128(index_0, true); | |
1271 RECURSE(Visit(expr->left())); | |
1272 current_function_builder_->Emit(kExprSetLocal); | |
1273 AddLeb128(index_1, true); | |
1274 RECURSE(Visit(expr->right())); | |
1275 current_function_builder_->Emit(kExprF64Sub); | |
1276 current_function_builder_->Emit(kExprGetLocal); | |
1277 AddLeb128(index_0, true); | |
1278 current_function_builder_->Emit(kExprF64Mul); | |
1279 current_function_builder_->Emit(kExprGetLocal); | |
1280 AddLeb128(index_1, true); | |
1281 // Use trunc instead of two casts | |
1282 current_function_builder_->Emit(kExprF64SConvertI32); | |
1283 current_function_builder_->Emit(kExprI32SConvertF64); | |
1284 current_function_builder_->Emit(kExprF64Div); | |
1285 current_function_builder_->Emit(kExprGetLocal); | |
1286 AddLeb128(index_0, true); | |
1287 current_function_builder_->Emit(kExprGetLocal); | |
1288 AddLeb128(index_1, true); | |
1289 } | |
1290 | |
1291 void AddLeb128(uint32_t index, bool is_local) { | 1292 void AddLeb128(uint32_t index, bool is_local) { |
1292 std::vector<uint8_t> index_vec = UnsignedLEB128From(index); | 1293 std::vector<uint8_t> index_vec = UnsignedLEB128From(index); |
1293 if (is_local) { | 1294 if (is_local) { |
1294 uint32_t pos_of_index[1] = {0}; | 1295 uint32_t pos_of_index[1] = {0}; |
1295 current_function_builder_->EmitCode( | 1296 current_function_builder_->EmitCode( |
1296 &index_vec[0], static_cast<uint32_t>(index_vec.size()), pos_of_index, | 1297 &index_vec[0], static_cast<uint32_t>(index_vec.size()), pos_of_index, |
1297 1); | 1298 1); |
1298 } else { | 1299 } else { |
1299 current_function_builder_->EmitCode( | 1300 current_function_builder_->EmitCode( |
1300 &index_vec[0], static_cast<uint32_t>(index_vec.size())); | 1301 &index_vec[0], static_cast<uint32_t>(index_vec.size())); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1511 // that zone in constructor may be thrown away once wasm module is written. | 1512 // that zone in constructor may be thrown away once wasm module is written. |
1512 WasmModuleIndex* AsmWasmBuilder::Run() { | 1513 WasmModuleIndex* AsmWasmBuilder::Run() { |
1513 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); | 1514 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); |
1514 impl.Compile(); | 1515 impl.Compile(); |
1515 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 1516 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
1516 return writer->WriteTo(zone_); | 1517 return writer->WriteTo(zone_); |
1517 } | 1518 } |
1518 } // namespace wasm | 1519 } // namespace wasm |
1519 } // namespace internal | 1520 } // namespace internal |
1520 } // namespace v8 | 1521 } // namespace v8 |
OLD | NEW |