Chromium Code Reviews| 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 |