| 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_AST_DECODER_H_ | 5 #ifndef V8_WASM_AST_DECODER_H_ |
| 6 #define V8_WASM_AST_DECODER_H_ | 6 #define V8_WASM_AST_DECODER_H_ |
| 7 | 7 |
| 8 #include "src/signature.h" | 8 #include "src/signature.h" |
| 9 #include "src/wasm/decoder.h" |
| 9 #include "src/wasm/wasm-opcodes.h" | 10 #include "src/wasm/wasm-opcodes.h" |
| 10 #include "src/wasm/wasm-result.h" | 11 #include "src/wasm/wasm-result.h" |
| 11 | 12 |
| 12 namespace v8 { | 13 namespace v8 { |
| 13 namespace internal { | 14 namespace internal { |
| 14 | 15 |
| 15 class BitVector; // forward declaration | 16 class BitVector; // forward declaration |
| 16 | 17 |
| 17 namespace compiler { // external declarations from compiler. | 18 namespace compiler { // external declarations from compiler. |
| 18 class WasmGraphBuilder; | 19 class WasmGraphBuilder; |
| 19 } | 20 } |
| 20 | 21 |
| 21 namespace wasm { | 22 namespace wasm { |
| 22 | 23 |
| 24 // Helpers for decoding different kinds of operands which follow bytecodes. |
| 25 struct LocalIndexOperand { |
| 26 uint32_t index; |
| 27 LocalType type; |
| 28 int length; |
| 29 |
| 30 inline LocalIndexOperand(Decoder* decoder, const byte* pc) { |
| 31 index = decoder->checked_read_u32v(pc, 1, &length, "local index"); |
| 32 type = kAstStmt; |
| 33 } |
| 34 }; |
| 35 |
| 36 struct ImmI8Operand { |
| 37 int8_t value; |
| 38 int length; |
| 39 inline ImmI8Operand(Decoder* decoder, const byte* pc) { |
| 40 value = bit_cast<int8_t>(decoder->checked_read_u8(pc, 1, "immi8")); |
| 41 length = 1; |
| 42 } |
| 43 }; |
| 44 |
| 45 struct ImmI32Operand { |
| 46 int32_t value; |
| 47 int length; |
| 48 inline ImmI32Operand(Decoder* decoder, const byte* pc) { |
| 49 value = bit_cast<int32_t>(decoder->checked_read_u32(pc, 1, "immi32")); |
| 50 length = 4; |
| 51 } |
| 52 }; |
| 53 |
| 54 struct ImmI64Operand { |
| 55 int64_t value; |
| 56 int length; |
| 57 inline ImmI64Operand(Decoder* decoder, const byte* pc) { |
| 58 value = bit_cast<int64_t>(decoder->checked_read_u64(pc, 1, "immi64")); |
| 59 length = 8; |
| 60 } |
| 61 }; |
| 62 |
| 63 struct ImmF32Operand { |
| 64 float value; |
| 65 int length; |
| 66 inline ImmF32Operand(Decoder* decoder, const byte* pc) { |
| 67 value = bit_cast<float>(decoder->checked_read_u32(pc, 1, "immf32")); |
| 68 length = 4; |
| 69 } |
| 70 }; |
| 71 |
| 72 struct ImmF64Operand { |
| 73 double value; |
| 74 int length; |
| 75 inline ImmF64Operand(Decoder* decoder, const byte* pc) { |
| 76 value = bit_cast<double>(decoder->checked_read_u64(pc, 1, "immf64")); |
| 77 length = 8; |
| 78 } |
| 79 }; |
| 80 |
| 81 struct GlobalIndexOperand { |
| 82 uint32_t index; |
| 83 LocalType type; |
| 84 MachineType machine_type; |
| 85 int length; |
| 86 |
| 87 inline GlobalIndexOperand(Decoder* decoder, const byte* pc) { |
| 88 index = decoder->checked_read_u32v(pc, 1, &length, "global index"); |
| 89 type = kAstStmt; |
| 90 machine_type = MachineType::None(); |
| 91 } |
| 92 }; |
| 93 |
| 94 struct Block; |
| 95 struct BreakDepthOperand { |
| 96 uint32_t depth; |
| 97 Block* target; |
| 98 int length; |
| 99 inline BreakDepthOperand(Decoder* decoder, const byte* pc) { |
| 100 depth = decoder->checked_read_u8(pc, 1, "break depth"); |
| 101 length = 1; |
| 102 target = nullptr; |
| 103 } |
| 104 }; |
| 105 |
| 106 struct BlockCountOperand { |
| 107 uint32_t count; |
| 108 int length; |
| 109 inline BlockCountOperand(Decoder* decoder, const byte* pc) { |
| 110 count = decoder->checked_read_u8(pc, 1, "block count"); |
| 111 length = 1; |
| 112 } |
| 113 }; |
| 114 |
| 115 struct SignatureIndexOperand { |
| 116 uint32_t index; |
| 117 FunctionSig* sig; |
| 118 int length; |
| 119 inline SignatureIndexOperand(Decoder* decoder, const byte* pc) { |
| 120 index = decoder->checked_read_u32v(pc, 1, &length, "signature index"); |
| 121 sig = nullptr; |
| 122 } |
| 123 }; |
| 124 |
| 125 struct FunctionIndexOperand { |
| 126 uint32_t index; |
| 127 FunctionSig* sig; |
| 128 int length; |
| 129 inline FunctionIndexOperand(Decoder* decoder, const byte* pc) { |
| 130 index = decoder->checked_read_u32v(pc, 1, &length, "function index"); |
| 131 sig = nullptr; |
| 132 } |
| 133 }; |
| 134 |
| 135 struct TableSwitchOperand { |
| 136 uint32_t case_count; |
| 137 uint32_t table_count; |
| 138 const byte* table; |
| 139 int length; |
| 140 inline TableSwitchOperand(Decoder* decoder, const byte* pc) { |
| 141 case_count = decoder->checked_read_u16(pc, 1, "expected #cases"); |
| 142 table_count = decoder->checked_read_u16(pc, 3, "expected #entries"); |
| 143 length = 4 + table_count * 2; |
| 144 |
| 145 if (decoder->check(pc, 5, table_count * 2, "expected <table entries>")) { |
| 146 table = pc + 5; |
| 147 } else { |
| 148 table = nullptr; |
| 149 } |
| 150 } |
| 151 inline uint16_t read_entry(Decoder* decoder, int i) { |
| 152 DCHECK(i >= 0 && static_cast<uint32_t>(i) < table_count); |
| 153 return table ? decoder->read_u16(table + i * sizeof(uint16_t)) : 0; |
| 154 } |
| 155 }; |
| 156 |
| 157 struct MemoryAccessOperand { |
| 158 bool aligned; |
| 159 uint32_t offset; |
| 160 int length; |
| 161 inline MemoryAccessOperand(Decoder* decoder, const byte* pc) { |
| 162 byte bitfield = decoder->checked_read_u8(pc, 1, "memory access byte"); |
| 163 aligned = MemoryAccess::AlignmentField::decode(bitfield); |
| 164 if (MemoryAccess::OffsetField::decode(bitfield)) { |
| 165 offset = decoder->checked_read_u32v(pc, 2, &length, "memory offset"); |
| 166 length++; |
| 167 } else { |
| 168 offset = 0; |
| 169 length = 1; |
| 170 } |
| 171 } |
| 172 }; |
| 173 |
| 23 typedef compiler::WasmGraphBuilder TFBuilder; | 174 typedef compiler::WasmGraphBuilder TFBuilder; |
| 24 struct ModuleEnv; // forward declaration of module interface. | 175 struct ModuleEnv; // forward declaration of module interface. |
| 25 | 176 |
| 26 // Interface the function environment during decoding, include the signature | 177 // Interface the function environment during decoding, include the signature |
| 27 // and number of locals. | 178 // and number of locals. |
| 28 struct FunctionEnv { | 179 struct FunctionEnv { |
| 29 ModuleEnv* module; // module environment | 180 ModuleEnv* module; // module environment |
| 30 FunctionSig* sig; // signature of this function | 181 FunctionSig* sig; // signature of this function |
| 31 uint32_t local_int32_count; // number of int32 locals | 182 uint32_t local_int32_count; // number of int32 locals |
| 32 uint32_t local_int64_count; // number of int64 locals | 183 uint32_t local_int64_count; // number of int64 locals |
| 33 uint32_t local_float32_count; // number of float32 locals | 184 uint32_t local_float32_count; // number of float32 locals |
| 34 uint32_t local_float64_count; // number of float64 locals | 185 uint32_t local_float64_count; // number of float64 locals |
| 35 uint32_t total_locals; // sum of parameters and all locals | 186 uint32_t total_locals; // sum of parameters and all locals |
| 36 | 187 |
| 37 bool IsValidLocal(uint32_t index) { return index < total_locals; } | |
| 38 uint32_t GetLocalCount() { return total_locals; } | 188 uint32_t GetLocalCount() { return total_locals; } |
| 39 LocalType GetLocalType(uint32_t index) { | 189 LocalType GetLocalType(uint32_t index) { |
| 40 if (index < static_cast<uint32_t>(sig->parameter_count())) { | 190 if (index < static_cast<uint32_t>(sig->parameter_count())) { |
| 41 return sig->GetParam(index); | 191 return sig->GetParam(index); |
| 42 } | 192 } |
| 43 index -= static_cast<uint32_t>(sig->parameter_count()); | 193 index -= static_cast<uint32_t>(sig->parameter_count()); |
| 44 if (index < local_int32_count) return kAstI32; | 194 if (index < local_int32_count) return kAstI32; |
| 45 index -= local_int32_count; | 195 index -= local_int32_count; |
| 46 if (index < local_int64_count) return kAstI64; | 196 if (index < local_int64_count) return kAstI64; |
| 47 index -= local_int64_count; | 197 index -= local_int64_count; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 255 |
| 106 enum ReadUnsignedLEB128ErrorCode { kNoError, kInvalidLEB128, kMissingLEB128 }; | 256 enum ReadUnsignedLEB128ErrorCode { kNoError, kInvalidLEB128, kMissingLEB128 }; |
| 107 | 257 |
| 108 ReadUnsignedLEB128ErrorCode ReadUnsignedLEB128Operand(const byte*, const byte*, | 258 ReadUnsignedLEB128ErrorCode ReadUnsignedLEB128Operand(const byte*, const byte*, |
| 109 int*, uint32_t*); | 259 int*, uint32_t*); |
| 110 | 260 |
| 111 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, | 261 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, FunctionEnv* env, |
| 112 const byte* start, const byte* end); | 262 const byte* start, const byte* end); |
| 113 | 263 |
| 114 // Computes the length of the opcode at the given address. | 264 // Computes the length of the opcode at the given address. |
| 115 int OpcodeLength(const byte* pc); | 265 int OpcodeLength(const byte* pc, const byte* end); |
| 116 | 266 |
| 117 // Computes the arity (number of sub-nodes) of the opcode at the given address. | 267 // Computes the arity (number of sub-nodes) of the opcode at the given address. |
| 118 int OpcodeArity(FunctionEnv* env, const byte* pc); | 268 int OpcodeArity(FunctionEnv* env, const byte* pc, const byte* end); |
| 119 } // namespace wasm | 269 } // namespace wasm |
| 120 } // namespace internal | 270 } // namespace internal |
| 121 } // namespace v8 | 271 } // namespace v8 |
| 122 | 272 |
| 123 #endif // V8_WASM_AST_DECODER_H_ | 273 #endif // V8_WASM_AST_DECODER_H_ |
| OLD | NEW |