| 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/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" | 
| 6 | 6 | 
| 7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" | 
| 8 | 8 | 
| 9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" | 
| 10 | 10 | 
| (...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1146           wasm::kAstF64, right, | 1146           wasm::kAstF64, right, | 
| 1147           left_is_not_nan.Phi( | 1147           left_is_not_nan.Phi( | 
| 1148               wasm::kAstF64, | 1148               wasm::kAstF64, | 
| 1149               Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), | 1149               Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), | 
| 1150               Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); | 1150               Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); | 
| 1151 } | 1151 } | 
| 1152 | 1152 | 
| 1153 | 1153 | 
| 1154 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { | 1154 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { | 
| 1155   MachineOperatorBuilder* m = jsgraph()->machine(); | 1155   MachineOperatorBuilder* m = jsgraph()->machine(); | 
|  | 1156   if (module_ && module_->asm_js()) { | 
|  | 1157     // asm.js must use the wacky JS semantics. | 
|  | 1158     input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | 
|  | 1159     return graph()->NewNode( | 
|  | 1160         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 
|  | 1161   } | 
|  | 1162 | 
| 1156   // Truncation of the input value is needed for the overflow check later. | 1163   // Truncation of the input value is needed for the overflow check later. | 
| 1157   Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1164   Node* trunc = Unop(wasm::kExprF32Trunc, input); | 
| 1158   Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); | 1165   Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); | 
| 1159 | 1166 | 
| 1160   // Convert the result back to f64. If we end up at a different value than the | 1167   // Convert the result back to f64. If we end up at a different value than the | 
| 1161   // truncated input value, then there has been an overflow and we trap. | 1168   // truncated input value, then there has been an overflow and we trap. | 
| 1162   Node* check = Unop(wasm::kExprF32SConvertI32, result); | 1169   Node* check = Unop(wasm::kExprF32SConvertI32, result); | 
| 1163   Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1170   Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 
| 1164   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 1171   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 
| 1165 | 1172 | 
| 1166   return result; | 1173   return result; | 
| 1167 } | 1174 } | 
| 1168 | 1175 | 
| 1169 | 1176 | 
| 1170 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { | 1177 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { | 
| 1171   MachineOperatorBuilder* m = jsgraph()->machine(); | 1178   MachineOperatorBuilder* m = jsgraph()->machine(); | 
| 1172   if (module_ && module_->asm_js) { | 1179   if (module_ && module_->asm_js()) { | 
|  | 1180     // asm.js must use the wacky JS semantics. | 
| 1173     return graph()->NewNode( | 1181     return graph()->NewNode( | 
| 1174         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 1182         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 
| 1175   } | 1183   } | 
| 1176   // Truncation of the input value is needed for the overflow check later. | 1184   // Truncation of the input value is needed for the overflow check later. | 
| 1177   Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1185   Node* trunc = Unop(wasm::kExprF64Trunc, input); | 
| 1178   Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); | 1186   Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); | 
| 1179 | 1187 | 
| 1180   // Convert the result back to f64. If we end up at a different value than the | 1188   // Convert the result back to f64. If we end up at a different value than the | 
| 1181   // truncated input value, then there has been an overflow and we trap. | 1189   // truncated input value, then there has been an overflow and we trap. | 
| 1182   Node* check = Unop(wasm::kExprF64SConvertI32, result); | 1190   Node* check = Unop(wasm::kExprF64SConvertI32, result); | 
| 1183   Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 1191   Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 
| 1184   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 1192   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 
| 1185 | 1193 | 
| 1186   return result; | 1194   return result; | 
| 1187 } | 1195 } | 
| 1188 | 1196 | 
| 1189 | 1197 | 
| 1190 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { | 1198 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { | 
| 1191   MachineOperatorBuilder* m = jsgraph()->machine(); | 1199   MachineOperatorBuilder* m = jsgraph()->machine(); | 
|  | 1200   if (module_ && module_->asm_js()) { | 
|  | 1201     // asm.js must use the wacky JS semantics. | 
|  | 1202     input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | 
|  | 1203     return graph()->NewNode( | 
|  | 1204         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 
|  | 1205   } | 
|  | 1206 | 
| 1192   // Truncation of the input value is needed for the overflow check later. | 1207   // Truncation of the input value is needed for the overflow check later. | 
| 1193   Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1208   Node* trunc = Unop(wasm::kExprF32Trunc, input); | 
| 1194   Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); | 1209   Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); | 
| 1195 | 1210 | 
| 1196   // Convert the result back to f32. If we end up at a different value than the | 1211   // Convert the result back to f32. If we end up at a different value than the | 
| 1197   // truncated input value, then there has been an overflow and we trap. | 1212   // truncated input value, then there has been an overflow and we trap. | 
| 1198   Node* check = Unop(wasm::kExprF32UConvertI32, result); | 1213   Node* check = Unop(wasm::kExprF32UConvertI32, result); | 
| 1199   Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1214   Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 
| 1200   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 1215   trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow); | 
| 1201 | 1216 | 
| 1202   return result; | 1217   return result; | 
| 1203 } | 1218 } | 
| 1204 | 1219 | 
| 1205 | 1220 | 
| 1206 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { | 1221 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { | 
| 1207   MachineOperatorBuilder* m = jsgraph()->machine(); | 1222   MachineOperatorBuilder* m = jsgraph()->machine(); | 
| 1208   if (module_ && module_->asm_js) { | 1223   if (module_ && module_->asm_js()) { | 
|  | 1224     // asm.js must use the wacky JS semantics. | 
| 1209     return graph()->NewNode( | 1225     return graph()->NewNode( | 
| 1210         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 1226         m->TruncateFloat64ToInt32(TruncationMode::kJavaScript), input); | 
| 1211   } | 1227   } | 
| 1212   // Truncation of the input value is needed for the overflow check later. | 1228   // Truncation of the input value is needed for the overflow check later. | 
| 1213   Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1229   Node* trunc = Unop(wasm::kExprF64Trunc, input); | 
| 1214   Node* result = graph()->NewNode(m->ChangeFloat64ToUint32(), trunc); | 1230   Node* result = graph()->NewNode(m->ChangeFloat64ToUint32(), trunc); | 
| 1215 | 1231 | 
| 1216   // Convert the result back to f64. If we end up at a different value than the | 1232   // Convert the result back to f64. If we end up at a different value than the | 
| 1217   // truncated input value, then there has been an overflow and we trap. | 1233   // truncated input value, then there has been an overflow and we trap. | 
| 1218   Node* check = Unop(wasm::kExprF64UConvertI32, result); | 1234   Node* check = Unop(wasm::kExprF64UConvertI32, result); | 
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1882   } | 1898   } | 
| 1883 | 1899 | 
| 1884   trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); | 1900   trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond); | 
| 1885 } | 1901 } | 
| 1886 | 1902 | 
| 1887 | 1903 | 
| 1888 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, | 1904 Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, | 
| 1889                                 Node* index, uint32_t offset) { | 1905                                 Node* index, uint32_t offset) { | 
| 1890   Node* load; | 1906   Node* load; | 
| 1891 | 1907 | 
| 1892   if (module_ && module_->asm_js) { | 1908   if (module_ && module_->asm_js()) { | 
| 1893     // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). | 1909     // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish). | 
| 1894     DCHECK_EQ(0, offset); | 1910     DCHECK_EQ(0, offset); | 
| 1895     const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); | 1911     const Operator* op = jsgraph()->machine()->CheckedLoad(memtype); | 
| 1896     load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, | 1912     load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_, | 
| 1897                             *control_); | 1913                             *control_); | 
| 1898   } else { | 1914   } else { | 
| 1899     // WASM semantics throw on OOB. Introduce explicit bounds check. | 1915     // WASM semantics throw on OOB. Introduce explicit bounds check. | 
| 1900     BoundsCheckMem(memtype, index, offset); | 1916     BoundsCheckMem(memtype, index, offset); | 
| 1901     load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 1917     load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 
| 1902                             MemBuffer(offset), index, *effect_, *control_); | 1918                             MemBuffer(offset), index, *effect_, *control_); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 1917     } | 1933     } | 
| 1918   } | 1934   } | 
| 1919 | 1935 | 
| 1920   return load; | 1936   return load; | 
| 1921 } | 1937 } | 
| 1922 | 1938 | 
| 1923 | 1939 | 
| 1924 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 1940 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 
| 1925                                  uint32_t offset, Node* val) { | 1941                                  uint32_t offset, Node* val) { | 
| 1926   Node* store; | 1942   Node* store; | 
| 1927   if (module_ && module_->asm_js) { | 1943   if (module_ && module_->asm_js()) { | 
| 1928     // asm.js semantics use CheckedStore (i.e. ignore OOB writes). | 1944     // asm.js semantics use CheckedStore (i.e. ignore OOB writes). | 
| 1929     DCHECK_EQ(0, offset); | 1945     DCHECK_EQ(0, offset); | 
| 1930     const Operator* op = | 1946     const Operator* op = | 
| 1931         jsgraph()->machine()->CheckedStore(memtype.representation()); | 1947         jsgraph()->machine()->CheckedStore(memtype.representation()); | 
| 1932     store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, | 1948     store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_, | 
| 1933                              *control_); | 1949                              *control_); | 
| 1934   } else { | 1950   } else { | 
| 1935     // WASM semantics throw on OOB. Introduce explicit bounds check. | 1951     // WASM semantics throw on OOB. Introduce explicit bounds check. | 
| 1936     BoundsCheckMem(memtype, index, offset); | 1952     BoundsCheckMem(memtype, index, offset); | 
| 1937     StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 1953     StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2247         module_env->module->GetName(function.name_offset)); | 2263         module_env->module->GetName(function.name_offset)); | 
| 2248   } | 2264   } | 
| 2249 | 2265 | 
| 2250   return code; | 2266   return code; | 
| 2251 } | 2267 } | 
| 2252 | 2268 | 
| 2253 | 2269 | 
| 2254 }  // namespace compiler | 2270 }  // namespace compiler | 
| 2255 }  // namespace internal | 2271 }  // namespace internal | 
| 2256 }  // namespace v8 | 2272 }  // namespace v8 | 
| OLD | NEW | 
|---|