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/signature.h" | 5 #include "src/signature.h" |
6 | 6 |
7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
8 #include "src/flags.h" | 8 #include "src/flags.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/zone/zone-containers.h" | 10 #include "src/zone/zone-containers.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 } | 143 } |
144 }; | 144 }; |
145 | 145 |
146 // Macros that build nodes only if there is a graph and the current SSA | 146 // Macros that build nodes only if there is a graph and the current SSA |
147 // environment is reachable from start. This avoids problems with malformed | 147 // environment is reachable from start. This avoids problems with malformed |
148 // TF graphs when decoding inputs that have unreachable code. | 148 // TF graphs when decoding inputs that have unreachable code. |
149 #define BUILD(func, ...) \ | 149 #define BUILD(func, ...) \ |
150 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr) | 150 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr) |
151 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr) | 151 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr) |
152 | 152 |
| 153 struct LaneOperand { |
| 154 uint8_t lane; |
| 155 unsigned length; |
| 156 |
| 157 inline LaneOperand(Decoder* decoder, const byte* pc) { |
| 158 lane = decoder->checked_read_u8(pc, 2, "lane"); |
| 159 length = 1; |
| 160 } |
| 161 }; |
| 162 |
153 // Generic Wasm bytecode decoder with utilities for decoding operands, | 163 // Generic Wasm bytecode decoder with utilities for decoding operands, |
154 // lengths, etc. | 164 // lengths, etc. |
155 class WasmDecoder : public Decoder { | 165 class WasmDecoder : public Decoder { |
156 public: | 166 public: |
157 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start, | 167 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start, |
158 const byte* end) | 168 const byte* end) |
159 : Decoder(start, end), | 169 : Decoder(start, end), |
160 module_(module), | 170 module_(module), |
161 sig_(sig), | 171 sig_(sig), |
162 total_locals_(0), | 172 total_locals_(0), |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 error(pc, pc + 1, "invalid break depth: %u", operand.depth); | 243 error(pc, pc + 1, "invalid break depth: %u", operand.depth); |
234 return false; | 244 return false; |
235 } | 245 } |
236 | 246 |
237 bool Validate(const byte* pc, BranchTableOperand& operand, | 247 bool Validate(const byte* pc, BranchTableOperand& operand, |
238 size_t block_depth) { | 248 size_t block_depth) { |
239 // TODO(titzer): add extra redundant validation for br_table here? | 249 // TODO(titzer): add extra redundant validation for br_table here? |
240 return true; | 250 return true; |
241 } | 251 } |
242 | 252 |
| 253 inline bool Validate(const byte* pc, LaneOperand& operand) { |
| 254 if (operand.lane < 0 || operand.lane > 3) { |
| 255 error(pc_, pc_ + 2, "invalid extract lane value"); |
| 256 return false; |
| 257 } else { |
| 258 return true; |
| 259 } |
| 260 } |
| 261 |
243 unsigned OpcodeLength(const byte* pc) { | 262 unsigned OpcodeLength(const byte* pc) { |
244 switch (static_cast<WasmOpcode>(*pc)) { | 263 switch (static_cast<byte>(*pc)) { |
245 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: | 264 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
246 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) | 265 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) |
247 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) | 266 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) |
248 #undef DECLARE_OPCODE_CASE | 267 #undef DECLARE_OPCODE_CASE |
249 { | 268 { |
250 MemoryAccessOperand operand(this, pc, UINT32_MAX); | 269 MemoryAccessOperand operand(this, pc, UINT32_MAX); |
251 return 1 + operand.length; | 270 return 1 + operand.length; |
252 } | 271 } |
253 case kExprBr: | 272 case kExprBr: |
254 case kExprBrIf: { | 273 case kExprBrIf: { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 case kExprI64Const: { | 316 case kExprI64Const: { |
298 ImmI64Operand operand(this, pc); | 317 ImmI64Operand operand(this, pc); |
299 return 1 + operand.length; | 318 return 1 + operand.length; |
300 } | 319 } |
301 case kExprI8Const: | 320 case kExprI8Const: |
302 return 2; | 321 return 2; |
303 case kExprF32Const: | 322 case kExprF32Const: |
304 return 5; | 323 return 5; |
305 case kExprF64Const: | 324 case kExprF64Const: |
306 return 9; | 325 return 9; |
| 326 case kSimdPrefix: { |
| 327 byte simd_index = *(pc + 1); |
| 328 WasmOpcode opcode = |
| 329 static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index); |
| 330 switch (opcode) { |
| 331 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
| 332 FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
| 333 #undef DECLARE_OPCODE_CASE |
| 334 { |
| 335 return 2; |
| 336 } |
| 337 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
| 338 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
| 339 #undef DECLARE_OPCODE_CASE |
| 340 { |
| 341 return 3; |
| 342 } |
| 343 default: |
| 344 UNREACHABLE(); |
| 345 } |
| 346 } |
307 default: | 347 default: |
308 return 1; | 348 return 1; |
309 } | 349 } |
310 } | 350 } |
311 }; | 351 }; |
312 | 352 |
313 static const int32_t kNullCatch = -1; | 353 static const int32_t kNullCatch = -1; |
314 | 354 |
315 // The full WASM decoder for bytecode. Both verifies bytecode and generates | 355 // The full WASM decoder for bytecode. Both verifies bytecode and generates |
316 // a TurboFan IR graph. | 356 // a TurboFan IR graph. |
(...skipping 925 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 int DecodeStoreMem(LocalType type, MachineType mem_type) { | 1282 int DecodeStoreMem(LocalType type, MachineType mem_type) { |
1243 MemoryAccessOperand operand(this, pc_, | 1283 MemoryAccessOperand operand(this, pc_, |
1244 ElementSizeLog2Of(mem_type.representation())); | 1284 ElementSizeLog2Of(mem_type.representation())); |
1245 Value val = Pop(1, type); | 1285 Value val = Pop(1, type); |
1246 Value index = Pop(0, kAstI32); | 1286 Value index = Pop(0, kAstI32); |
1247 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, | 1287 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, |
1248 val.node, position()); | 1288 val.node, position()); |
1249 return 1 + operand.length; | 1289 return 1 + operand.length; |
1250 } | 1290 } |
1251 | 1291 |
| 1292 unsigned ExtractLane(WasmOpcode opcode, LocalType type) { |
| 1293 LaneOperand operand(this, pc_); |
| 1294 if (Validate(pc_, operand)) { |
| 1295 TFNode* input = Pop(0, LocalType::kSimd128).node; |
| 1296 TFNode* node = BUILD(SimdExtractLane, opcode, operand.lane, input); |
| 1297 Push(type, node); |
| 1298 } |
| 1299 return operand.length; |
| 1300 } |
| 1301 |
1252 unsigned DecodeSimdOpcode(WasmOpcode opcode) { | 1302 unsigned DecodeSimdOpcode(WasmOpcode opcode) { |
1253 unsigned len = 0; | 1303 unsigned len = 0; |
1254 switch (opcode) { | 1304 switch (opcode) { |
1255 case kExprI32x4ExtractLane: { | 1305 case kExprI32x4ExtractLane: { |
1256 uint8_t lane = this->checked_read_u8(pc_, 2, "lane number"); | 1306 len = ExtractLane(opcode, LocalType::kWord32); |
1257 if (lane < 0 || lane > 3) { | 1307 break; |
1258 error(pc_, pc_ + 2, "invalid extract lane value"); | 1308 } |
1259 } | 1309 case kExprF32x4ExtractLane: { |
1260 TFNode* input = Pop(0, LocalType::kSimd128).node; | 1310 len = ExtractLane(opcode, LocalType::kFloat32); |
1261 TFNode* node = BUILD(SimdExtractLane, opcode, lane, input); | |
1262 Push(LocalType::kWord32, node); | |
1263 len++; | |
1264 break; | 1311 break; |
1265 } | 1312 } |
1266 default: { | 1313 default: { |
1267 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 1314 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
1268 if (sig != nullptr) { | 1315 if (sig != nullptr) { |
1269 compiler::NodeVector inputs(sig->parameter_count(), zone_); | 1316 compiler::NodeVector inputs(sig->parameter_count(), zone_); |
1270 for (size_t i = sig->parameter_count(); i > 0; i--) { | 1317 for (size_t i = sig->parameter_count(); i > 0; i--) { |
1271 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); | 1318 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); |
1272 inputs[i - 1] = val.node; | 1319 inputs[i - 1] = val.node; |
1273 } | 1320 } |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1951 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1998 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1952 const byte* start, const byte* end) { | 1999 const byte* start, const byte* end) { |
1953 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2000 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1954 WasmFullDecoder decoder(zone, nullptr, body); | 2001 WasmFullDecoder decoder(zone, nullptr, body); |
1955 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2002 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1956 } | 2003 } |
1957 | 2004 |
1958 } // namespace wasm | 2005 } // namespace wasm |
1959 } // namespace internal | 2006 } // namespace internal |
1960 } // namespace v8 | 2007 } // namespace v8 |
OLD | NEW |