| 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 |