| 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 #ifndef V8_WASM_FUNCTION_BODY_DECODER_H_ | 5 #ifndef V8_WASM_FUNCTION_BODY_DECODER_H_ |
| 6 #define V8_WASM_FUNCTION_BODY_DECODER_H_ | 6 #define V8_WASM_FUNCTION_BODY_DECODER_H_ |
| 7 | 7 |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "src/base/compiler-specific.h" | 10 #include "src/base/compiler-specific.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 } | 25 } |
| 26 | 26 |
| 27 namespace wasm { | 27 namespace wasm { |
| 28 | 28 |
| 29 const uint32_t kMaxNumWasmLocals = 8000000; | 29 const uint32_t kMaxNumWasmLocals = 8000000; |
| 30 struct WasmGlobal; | 30 struct WasmGlobal; |
| 31 | 31 |
| 32 // Helpers for decoding different kinds of operands which follow bytecodes. | 32 // Helpers for decoding different kinds of operands which follow bytecodes. |
| 33 struct LocalIndexOperand { | 33 struct LocalIndexOperand { |
| 34 uint32_t index; | 34 uint32_t index; |
| 35 LocalType type; | 35 ValueType type; |
| 36 unsigned length; | 36 unsigned length; |
| 37 | 37 |
| 38 inline LocalIndexOperand(Decoder* decoder, const byte* pc) { | 38 inline LocalIndexOperand(Decoder* decoder, const byte* pc) { |
| 39 index = decoder->checked_read_u32v(pc, 1, &length, "local index"); | 39 index = decoder->checked_read_u32v(pc, 1, &length, "local index"); |
| 40 type = kAstStmt; | 40 type = kWasmStmt; |
| 41 } | 41 } |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 struct ImmI8Operand { | 44 struct ImmI8Operand { |
| 45 int8_t value; | 45 int8_t value; |
| 46 unsigned length; | 46 unsigned length; |
| 47 inline ImmI8Operand(Decoder* decoder, const byte* pc) { | 47 inline ImmI8Operand(Decoder* decoder, const byte* pc) { |
| 48 value = bit_cast<int8_t>(decoder->checked_read_u8(pc, 1, "immi8")); | 48 value = bit_cast<int8_t>(decoder->checked_read_u8(pc, 1, "immi8")); |
| 49 length = 1; | 49 length = 1; |
| 50 } | 50 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 79 double value; | 79 double value; |
| 80 unsigned length; | 80 unsigned length; |
| 81 inline ImmF64Operand(Decoder* decoder, const byte* pc) { | 81 inline ImmF64Operand(Decoder* decoder, const byte* pc) { |
| 82 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64")); | 82 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64")); |
| 83 length = 8; | 83 length = 8; |
| 84 } | 84 } |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 struct GlobalIndexOperand { | 87 struct GlobalIndexOperand { |
| 88 uint32_t index; | 88 uint32_t index; |
| 89 LocalType type; | 89 ValueType type; |
| 90 const WasmGlobal* global; | 90 const WasmGlobal* global; |
| 91 unsigned length; | 91 unsigned length; |
| 92 | 92 |
| 93 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) { | 93 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) { |
| 94 index = decoder->checked_read_u32v(pc, 1, &length, "global index"); | 94 index = decoder->checked_read_u32v(pc, 1, &length, "global index"); |
| 95 global = nullptr; | 95 global = nullptr; |
| 96 type = kAstStmt; | 96 type = kWasmStmt; |
| 97 } | 97 } |
| 98 }; | 98 }; |
| 99 | 99 |
| 100 struct BlockTypeOperand { | 100 struct BlockTypeOperand { |
| 101 uint32_t arity; | 101 uint32_t arity; |
| 102 const byte* types; // pointer to encoded types for the block. | 102 const byte* types; // pointer to encoded types for the block. |
| 103 unsigned length; | 103 unsigned length; |
| 104 | 104 |
| 105 inline BlockTypeOperand(Decoder* decoder, const byte* pc) { | 105 inline BlockTypeOperand(Decoder* decoder, const byte* pc) { |
| 106 uint8_t val = decoder->checked_read_u8(pc, 1, "block type"); | 106 uint8_t val = decoder->checked_read_u8(pc, 1, "block type"); |
| 107 LocalType type = kAstStmt; | 107 ValueType type = kWasmStmt; |
| 108 length = 1; | 108 length = 1; |
| 109 arity = 0; | 109 arity = 0; |
| 110 types = nullptr; | 110 types = nullptr; |
| 111 if (decode_local_type(val, &type)) { | 111 if (decode_local_type(val, &type)) { |
| 112 arity = type == kAstStmt ? 0 : 1; | 112 arity = type == kWasmStmt ? 0 : 1; |
| 113 types = pc + 1; | 113 types = pc + 1; |
| 114 } else { | 114 } else { |
| 115 // Handle multi-value blocks. | 115 // Handle multi-value blocks. |
| 116 if (!FLAG_wasm_mv_prototype) { | 116 if (!FLAG_wasm_mv_prototype) { |
| 117 decoder->error(pc, pc + 1, "invalid block arity > 1"); | 117 decoder->error(pc, pc + 1, "invalid block arity > 1"); |
| 118 return; | 118 return; |
| 119 } | 119 } |
| 120 if (val != kMultivalBlock) { | 120 if (val != kMultivalBlock) { |
| 121 decoder->error(pc, pc + 1, "invalid block type"); | 121 decoder->error(pc, pc + 1, "invalid block type"); |
| 122 return; | 122 return; |
| 123 } | 123 } |
| 124 // Decode and check the types vector of the block. | 124 // Decode and check the types vector of the block. |
| 125 unsigned len = 0; | 125 unsigned len = 0; |
| 126 uint32_t count = decoder->checked_read_u32v(pc, 2, &len, "block arity"); | 126 uint32_t count = decoder->checked_read_u32v(pc, 2, &len, "block arity"); |
| 127 // {count} is encoded as {arity-2}, so that a {0} count here corresponds | 127 // {count} is encoded as {arity-2}, so that a {0} count here corresponds |
| 128 // to a block with 2 values. This makes invalid/redundant encodings | 128 // to a block with 2 values. This makes invalid/redundant encodings |
| 129 // impossible. | 129 // impossible. |
| 130 arity = count + 2; | 130 arity = count + 2; |
| 131 length = 1 + len + arity; | 131 length = 1 + len + arity; |
| 132 types = pc + 1 + 1 + len; | 132 types = pc + 1 + 1 + len; |
| 133 | 133 |
| 134 for (uint32_t i = 0; i < arity; i++) { | 134 for (uint32_t i = 0; i < arity; i++) { |
| 135 uint32_t offset = 1 + 1 + len + i; | 135 uint32_t offset = 1 + 1 + len + i; |
| 136 val = decoder->checked_read_u8(pc, offset, "block type"); | 136 val = decoder->checked_read_u8(pc, offset, "block type"); |
| 137 decode_local_type(val, &type); | 137 decode_local_type(val, &type); |
| 138 if (type == kAstStmt) { | 138 if (type == kWasmStmt) { |
| 139 decoder->error(pc, pc + offset, "invalid block type"); | 139 decoder->error(pc, pc + offset, "invalid block type"); |
| 140 return; | 140 return; |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 // Decode a byte representing a local type. Return {false} if the encoded | 145 // Decode a byte representing a local type. Return {false} if the encoded |
| 146 // byte was invalid or {kMultivalBlock}. | 146 // byte was invalid or {kMultivalBlock}. |
| 147 bool decode_local_type(uint8_t val, LocalType* result) { | 147 bool decode_local_type(uint8_t val, ValueType* result) { |
| 148 switch (static_cast<LocalTypeCode>(val)) { | 148 switch (static_cast<ValueTypeCode>(val)) { |
| 149 case kLocalVoid: | 149 case kLocalVoid: |
| 150 *result = kAstStmt; | 150 *result = kWasmStmt; |
| 151 return true; | 151 return true; |
| 152 case kLocalI32: | 152 case kLocalI32: |
| 153 *result = kAstI32; | 153 *result = kWasmI32; |
| 154 return true; | 154 return true; |
| 155 case kLocalI64: | 155 case kLocalI64: |
| 156 *result = kAstI64; | 156 *result = kWasmI64; |
| 157 return true; | 157 return true; |
| 158 case kLocalF32: | 158 case kLocalF32: |
| 159 *result = kAstF32; | 159 *result = kWasmF32; |
| 160 return true; | 160 return true; |
| 161 case kLocalF64: | 161 case kLocalF64: |
| 162 *result = kAstF64; | 162 *result = kWasmF64; |
| 163 return true; | 163 return true; |
| 164 case kLocalS128: | 164 case kLocalS128: |
| 165 *result = kAstS128; | 165 *result = kWasmS128; |
| 166 return true; | 166 return true; |
| 167 default: | 167 default: |
| 168 *result = kAstStmt; | 168 *result = kWasmStmt; |
| 169 return false; | 169 return false; |
| 170 } | 170 } |
| 171 } | 171 } |
| 172 LocalType read_entry(unsigned index) { | 172 ValueType read_entry(unsigned index) { |
| 173 DCHECK_LT(index, arity); | 173 DCHECK_LT(index, arity); |
| 174 LocalType result; | 174 ValueType result; |
| 175 CHECK(decode_local_type(types[index], &result)); | 175 CHECK(decode_local_type(types[index], &result)); |
| 176 return result; | 176 return result; |
| 177 } | 177 } |
| 178 }; | 178 }; |
| 179 | 179 |
| 180 struct Control; | 180 struct Control; |
| 181 struct BreakDepthOperand { | 181 struct BreakDepthOperand { |
| 182 uint32_t depth; | 182 uint32_t depth; |
| 183 Control* target; | 183 Control* target; |
| 184 unsigned length; | 184 unsigned length; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 } | 359 } |
| 360 | 360 |
| 361 struct BodyLocalDecls { | 361 struct BodyLocalDecls { |
| 362 // The size of the encoded declarations. | 362 // The size of the encoded declarations. |
| 363 uint32_t decls_encoded_size; // size of encoded declarations | 363 uint32_t decls_encoded_size; // size of encoded declarations |
| 364 | 364 |
| 365 // Total number of locals. | 365 // Total number of locals. |
| 366 uint32_t total_local_count; | 366 uint32_t total_local_count; |
| 367 | 367 |
| 368 // List of {local type, count} pairs. | 368 // List of {local type, count} pairs. |
| 369 ZoneVector<std::pair<LocalType, uint32_t>> local_types; | 369 ZoneVector<std::pair<ValueType, uint32_t>> local_types; |
| 370 | 370 |
| 371 // Constructor initializes the vector. | 371 // Constructor initializes the vector. |
| 372 explicit BodyLocalDecls(Zone* zone) | 372 explicit BodyLocalDecls(Zone* zone) |
| 373 : decls_encoded_size(0), total_local_count(0), local_types(zone) {} | 373 : decls_encoded_size(0), total_local_count(0), local_types(zone) {} |
| 374 }; | 374 }; |
| 375 | 375 |
| 376 V8_EXPORT_PRIVATE bool DecodeLocalDecls(BodyLocalDecls& decls, | 376 V8_EXPORT_PRIVATE bool DecodeLocalDecls(BodyLocalDecls& decls, |
| 377 const byte* start, const byte* end); | 377 const byte* start, const byte* end); |
| 378 V8_EXPORT_PRIVATE BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, | 378 V8_EXPORT_PRIVATE BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, |
| 379 size_t num_locals, | 379 size_t num_locals, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 } | 470 } |
| 471 | 471 |
| 472 bool has_next() { return pc_ < end_; } | 472 bool has_next() { return pc_ < end_; } |
| 473 }; | 473 }; |
| 474 | 474 |
| 475 } // namespace wasm | 475 } // namespace wasm |
| 476 } // namespace internal | 476 } // namespace internal |
| 477 } // namespace v8 | 477 } // namespace v8 |
| 478 | 478 |
| 479 #endif // V8_WASM_FUNCTION_BODY_DECODER_H_ | 479 #endif // V8_WASM_FUNCTION_BODY_DECODER_H_ |
| OLD | NEW |