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 13 matching lines...) Expand all Loading... | |
24 | 24 |
25 #if DEBUG | 25 #if DEBUG |
26 #define TRACE(...) \ | 26 #define TRACE(...) \ |
27 do { \ | 27 do { \ |
28 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ | 28 if (FLAG_trace_wasm_decoder) PrintF(__VA_ARGS__); \ |
29 } while (false) | 29 } while (false) |
30 #else | 30 #else |
31 #define TRACE(...) | 31 #define TRACE(...) |
32 #endif | 32 #endif |
33 | 33 |
34 #define CHECK_PROTOTYPE_OPCODE(flag) \ | 34 #define CHECK_PROTOTYPE_OPCODE(flag) \ |
35 if (module_ && module_->module->origin == kAsmJsOrigin) { \ | 35 if (module_ != nullptr && module_->origin == kAsmJsOrigin) { \ |
36 error("Opcode not supported for asmjs modules"); \ | 36 error("Opcode not supported for asmjs modules"); \ |
37 } \ | 37 } \ |
38 if (!FLAG_##flag) { \ | 38 if (!FLAG_##flag) { \ |
39 error("Invalid opcode (enable with --" #flag ")"); \ | 39 error("Invalid opcode (enable with --" #flag ")"); \ |
40 break; \ | 40 break; \ |
41 } | 41 } |
42 // TODO(titzer): this is only for intermediate migration. | 42 // TODO(titzer): this is only for intermediate migration. |
43 #define IMPLICIT_FUNCTION_END 1 | 43 #define IMPLICIT_FUNCTION_END 1 |
44 | 44 |
45 // An SsaEnv environment carries the current local variable renaming | 45 // An SsaEnv environment carries the current local variable renaming |
46 // as well as the current effect and control dependency in the TF graph. | 46 // as well as the current effect and control dependency in the TF graph. |
47 // It maintains a control state that tracks whether the environment | 47 // It maintains a control state that tracks whether the environment |
48 // is reachable, has reached a control end, or has been merged. | 48 // is reachable, has reached a control end, or has been merged. |
49 struct SsaEnv { | 49 struct SsaEnv { |
50 enum State { kControlEnd, kUnreachable, kReached, kMerged }; | 50 enum State { kControlEnd, kUnreachable, kReached, kMerged }; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 inline LaneOperand(Decoder* decoder, const byte* pc) { | 157 inline LaneOperand(Decoder* decoder, const byte* pc) { |
158 lane = decoder->checked_read_u8(pc, 2, "lane"); | 158 lane = decoder->checked_read_u8(pc, 2, "lane"); |
159 length = 1; | 159 length = 1; |
160 } | 160 } |
161 }; | 161 }; |
162 | 162 |
163 // Generic Wasm bytecode decoder with utilities for decoding operands, | 163 // Generic Wasm bytecode decoder with utilities for decoding operands, |
164 // lengths, etc. | 164 // lengths, etc. |
165 class WasmDecoder : public Decoder { | 165 class WasmDecoder : public Decoder { |
166 public: | 166 public: |
167 WasmDecoder(ModuleEnv* module, FunctionSig* sig, const byte* start, | 167 WasmDecoder(const WasmModule* module, FunctionSig* sig, const byte* start, |
168 const byte* end) | 168 const byte* end) |
169 : Decoder(start, end), | 169 : Decoder(start, end), |
170 module_(module), | 170 module_(module), |
171 sig_(sig), | 171 sig_(sig), |
172 total_locals_(0), | 172 total_locals_(0), |
173 local_types_(nullptr) {} | 173 local_types_(nullptr) {} |
174 ModuleEnv* module_; | 174 const WasmModule* module_; |
175 FunctionSig* sig_; | 175 FunctionSig* sig_; |
176 size_t total_locals_; | 176 size_t total_locals_; |
177 ZoneVector<ValueType>* local_types_; | 177 ZoneVector<ValueType>* local_types_; |
178 | 178 |
179 inline bool Validate(const byte* pc, LocalIndexOperand& operand) { | 179 inline bool Validate(const byte* pc, LocalIndexOperand& operand) { |
180 if (operand.index < total_locals_) { | 180 if (operand.index < total_locals_) { |
181 if (local_types_) { | 181 if (local_types_) { |
182 operand.type = local_types_->at(operand.index); | 182 operand.type = local_types_->at(operand.index); |
183 } else { | 183 } else { |
184 operand.type = kWasmStmt; | 184 operand.type = kWasmStmt; |
185 } | 185 } |
186 return true; | 186 return true; |
187 } | 187 } |
188 error(pc, pc + 1, "invalid local index: %u", operand.index); | 188 error(pc, pc + 1, "invalid local index: %u", operand.index); |
189 return false; | 189 return false; |
190 } | 190 } |
191 | 191 |
192 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) { | 192 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) { |
193 ModuleEnv* m = module_; | 193 if (module_ != nullptr && operand.index < module_->globals.size()) { |
194 if (m && m->module && operand.index < m->module->globals.size()) { | 194 operand.global = &module_->globals[operand.index]; |
195 operand.global = &m->module->globals[operand.index]; | |
196 operand.type = operand.global->type; | 195 operand.type = operand.global->type; |
197 return true; | 196 return true; |
198 } | 197 } |
199 error(pc, pc + 1, "invalid global index: %u", operand.index); | 198 error(pc, pc + 1, "invalid global index: %u", operand.index); |
200 return false; | 199 return false; |
201 } | 200 } |
202 | 201 |
203 inline bool Complete(const byte* pc, CallFunctionOperand& operand) { | 202 inline bool Complete(const byte* pc, CallFunctionOperand& operand) { |
204 ModuleEnv* m = module_; | 203 if (module_ != nullptr && operand.index < module_->functions.size()) { |
205 if (m && m->module && operand.index < m->module->functions.size()) { | 204 operand.sig = module_->functions[operand.index].sig; |
206 operand.sig = m->module->functions[operand.index].sig; | |
207 return true; | 205 return true; |
208 } | 206 } |
209 return false; | 207 return false; |
210 } | 208 } |
211 | 209 |
212 inline bool Validate(const byte* pc, CallFunctionOperand& operand) { | 210 inline bool Validate(const byte* pc, CallFunctionOperand& operand) { |
213 if (Complete(pc, operand)) { | 211 if (Complete(pc, operand)) { |
214 return true; | 212 return true; |
215 } | 213 } |
216 error(pc, pc + 1, "invalid function index: %u", operand.index); | 214 error(pc, pc + 1, "invalid function index: %u", operand.index); |
217 return false; | 215 return false; |
218 } | 216 } |
219 | 217 |
220 inline bool Complete(const byte* pc, CallIndirectOperand& operand) { | 218 inline bool Complete(const byte* pc, CallIndirectOperand& operand) { |
221 ModuleEnv* m = module_; | 219 if (module_ != nullptr && operand.index < module_->signatures.size()) { |
222 if (m && m->module && operand.index < m->module->signatures.size()) { | 220 operand.sig = module_->signatures[operand.index]; |
223 operand.sig = m->module->signatures[operand.index]; | |
224 return true; | 221 return true; |
225 } | 222 } |
226 return false; | 223 return false; |
227 } | 224 } |
228 | 225 |
229 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { | 226 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { |
230 uint32_t table_index = 0; | 227 uint32_t table_index = 0; |
231 if (!module_->IsValidTable(table_index)) { | 228 if (module_ == nullptr || module_->function_tables.empty()) { |
232 error("function table has to exist to execute call_indirect"); | 229 error("function table has to exist to execute call_indirect"); |
233 return false; | 230 return false; |
234 } | 231 } |
235 if (Complete(pc, operand)) { | 232 if (Complete(pc, operand)) { |
236 return true; | 233 return true; |
237 } | 234 } |
238 error(pc, pc + 1, "invalid signature index: #%u", operand.index); | 235 error(pc, pc + 1, "invalid signature index: #%u", operand.index); |
239 return false; | 236 return false; |
240 } | 237 } |
241 | 238 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
356 } | 353 } |
357 } | 354 } |
358 default: | 355 default: |
359 return 1; | 356 return 1; |
360 } | 357 } |
361 } | 358 } |
362 }; | 359 }; |
363 | 360 |
364 static const int32_t kNullCatch = -1; | 361 static const int32_t kNullCatch = -1; |
365 | 362 |
366 // The full WASM decoder for bytecode. Both verifies bytecode and generates | 363 // The full WASM decoder for bytecode. Verifies bytecode or generates |
titzer
2017/01/04 03:32:41
The comment should reflect that in the later case,
Mircea Trofin
2017/01/04 04:55:33
Good point - done.
| |
367 // a TurboFan IR graph. | 364 // a TurboFan IR graph. |
368 class WasmFullDecoder : public WasmDecoder { | 365 class WasmFullDecoder : public WasmDecoder { |
369 public: | 366 public: |
367 WasmFullDecoder(Zone* zone, const FunctionBody& body) | |
titzer
2017/01/04 03:32:41
I think it's better to have only a single construc
Mircea Trofin
2017/01/04 04:55:33
I tend to agree. I will make more changes in the u
| |
368 : WasmFullDecoder(zone, nullptr, nullptr, body) {} | |
369 | |
370 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, | |
371 const FunctionBody& body) | |
372 : WasmFullDecoder(zone, module, nullptr, body) {} | |
373 | |
370 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) | 374 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) |
371 : WasmDecoder(body.module, body.sig, body.start, body.end), | 375 : WasmFullDecoder(zone, builder->module_env() == nullptr |
372 zone_(zone), | 376 ? nullptr |
373 builder_(builder), | 377 : builder->module_env()->module, |
374 base_(body.base), | 378 builder, body) {} |
375 local_type_vec_(zone), | |
376 stack_(zone), | |
377 control_(zone), | |
378 last_end_found_(false), | |
379 current_catch_(kNullCatch) { | |
380 local_types_ = &local_type_vec_; | |
381 } | |
382 | 379 |
383 bool Decode() { | 380 bool Decode() { |
384 if (FLAG_wasm_code_fuzzer_gen_test) { | 381 if (FLAG_wasm_code_fuzzer_gen_test) { |
385 PrintWasmCodeForDebugging(start_, end_); | 382 PrintWasmCodeForDebugging(start_, end_); |
386 } | 383 } |
387 base::ElapsedTimer decode_timer; | 384 base::ElapsedTimer decode_timer; |
388 if (FLAG_trace_wasm_decode_time) { | 385 if (FLAG_trace_wasm_decode_time) { |
389 decode_timer.Start(); | 386 decode_timer.Start(); |
390 } | 387 } |
391 stack_.clear(); | 388 stack_.clear(); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 total_locals_ = num_locals; | 482 total_locals_ = num_locals; |
486 local_type_vec_.reserve(num_locals); | 483 local_type_vec_.reserve(num_locals); |
487 if (num_locals > local_type_vec_.size()) { | 484 if (num_locals > local_type_vec_.size()) { |
488 local_type_vec_.insert(local_type_vec_.end(), | 485 local_type_vec_.insert(local_type_vec_.end(), |
489 num_locals - local_type_vec_.size(), kWasmI32); | 486 num_locals - local_type_vec_.size(), kWasmI32); |
490 } | 487 } |
491 return AnalyzeLoopAssignment(pc); | 488 return AnalyzeLoopAssignment(pc); |
492 } | 489 } |
493 | 490 |
494 private: | 491 private: |
492 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, | |
493 TFBuilder* builder, const FunctionBody& body) | |
494 : WasmDecoder(module, body.sig, body.start, body.end), | |
495 zone_(zone), | |
496 builder_(builder), | |
497 base_(body.base), | |
498 local_type_vec_(zone), | |
499 stack_(zone), | |
500 control_(zone), | |
501 last_end_found_(false), | |
502 current_catch_(kNullCatch) { | |
503 local_types_ = &local_type_vec_; | |
504 } | |
505 | |
495 static const size_t kErrorMsgSize = 128; | 506 static const size_t kErrorMsgSize = 128; |
496 | 507 |
497 Zone* zone_; | 508 Zone* zone_; |
498 TFBuilder* builder_; | 509 TFBuilder* builder_; |
499 const byte* base_; | 510 const byte* base_; |
500 | 511 |
501 SsaEnv* ssa_env_; | 512 SsaEnv* ssa_env_; |
502 | 513 |
503 ZoneVector<ValueType> local_type_vec_; // types of local variables. | 514 ZoneVector<ValueType> local_type_vec_; // types of local variables. |
504 ZoneVector<Value> stack_; // stack of values. | 515 ZoneVector<Value> stack_; // stack of values. |
(...skipping 24 matching lines...) Expand all Loading... | |
529 } | 540 } |
530 while (index < local_type_vec_.size()) { | 541 while (index < local_type_vec_.size()) { |
531 ValueType type = local_type_vec_[index]; | 542 ValueType type = local_type_vec_[index]; |
532 TFNode* node = DefaultValue(type); | 543 TFNode* node = DefaultValue(type); |
533 while (index < local_type_vec_.size() && | 544 while (index < local_type_vec_.size() && |
534 local_type_vec_[index] == type) { | 545 local_type_vec_[index] == type) { |
535 // Do a whole run of like-typed locals at a time. | 546 // Do a whole run of like-typed locals at a time. |
536 ssa_env->locals[index++] = node; | 547 ssa_env->locals[index++] = node; |
537 } | 548 } |
538 } | 549 } |
539 builder_->set_module(module_); | |
540 } | 550 } |
541 ssa_env->control = start; | 551 ssa_env->control = start; |
542 ssa_env->effect = start; | 552 ssa_env->effect = start; |
543 SetEnv("initial", ssa_env); | 553 SetEnv("initial", ssa_env); |
544 if (builder_) { | 554 if (builder_) { |
545 builder_->StackCheck(position()); | 555 builder_->StackCheck(position()); |
546 } | 556 } |
547 } | 557 } |
548 | 558 |
549 TFNode* DefaultValue(ValueType type) { | 559 TFNode* DefaultValue(ValueType type) { |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1111 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); | 1121 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); |
1112 break; | 1122 break; |
1113 case kExprF32StoreMem: | 1123 case kExprF32StoreMem: |
1114 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); | 1124 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); |
1115 break; | 1125 break; |
1116 case kExprF64StoreMem: | 1126 case kExprF64StoreMem: |
1117 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); | 1127 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); |
1118 break; | 1128 break; |
1119 case kExprGrowMemory: { | 1129 case kExprGrowMemory: { |
1120 MemoryIndexOperand operand(this, pc_); | 1130 MemoryIndexOperand operand(this, pc_); |
1121 if (module_->module->origin != kAsmJsOrigin) { | 1131 DCHECK_NOT_NULL(module_); |
1132 if (module_->origin != kAsmJsOrigin) { | |
1122 Value val = Pop(0, kWasmI32); | 1133 Value val = Pop(0, kWasmI32); |
1123 Push(kWasmI32, BUILD(GrowMemory, val.node)); | 1134 Push(kWasmI32, BUILD(GrowMemory, val.node)); |
1124 } else { | 1135 } else { |
1125 error("grow_memory is not supported for asmjs modules"); | 1136 error("grow_memory is not supported for asmjs modules"); |
1126 } | 1137 } |
1127 len = 1 + operand.length; | 1138 len = 1 + operand.length; |
1128 break; | 1139 break; |
1129 } | 1140 } |
1130 case kExprMemorySize: { | 1141 case kExprMemorySize: { |
1131 MemoryIndexOperand operand(this, pc_); | 1142 MemoryIndexOperand operand(this, pc_); |
(...skipping 29 matching lines...) Expand all Loading... | |
1161 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); | 1172 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); |
1162 len++; | 1173 len++; |
1163 byte simd_index = checked_read_u8(pc_, 1, "simd index"); | 1174 byte simd_index = checked_read_u8(pc_, 1, "simd index"); |
1164 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | 1175 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); |
1165 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, | 1176 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, |
1166 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); | 1177 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); |
1167 len += DecodeSimdOpcode(opcode); | 1178 len += DecodeSimdOpcode(opcode); |
1168 break; | 1179 break; |
1169 } | 1180 } |
1170 case kAtomicPrefix: { | 1181 case kAtomicPrefix: { |
1171 if (!module_ || module_->module->origin != kAsmJsOrigin) { | 1182 if (module_ == nullptr || module_->origin != kAsmJsOrigin) { |
1172 error("Atomics are allowed only in AsmJs modules"); | 1183 error("Atomics are allowed only in AsmJs modules"); |
1173 break; | 1184 break; |
1174 } | 1185 } |
1175 if (!FLAG_wasm_atomics_prototype) { | 1186 if (!FLAG_wasm_atomics_prototype) { |
1176 error("Invalid opcode (enable with --wasm_atomics_prototype)"); | 1187 error("Invalid opcode (enable with --wasm_atomics_prototype)"); |
1177 break; | 1188 break; |
1178 } | 1189 } |
1179 len = 2; | 1190 len = 2; |
1180 byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index"); | 1191 byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index"); |
1181 opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode); | 1192 opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode); |
1182 sig = WasmOpcodes::AtomicSignature(opcode); | 1193 sig = WasmOpcodes::AtomicSignature(opcode); |
1183 if (sig) { | 1194 if (sig) { |
1184 BuildAtomicOperator(opcode); | 1195 BuildAtomicOperator(opcode); |
1185 } | 1196 } |
1186 break; | 1197 break; |
1187 } | 1198 } |
1188 default: { | 1199 default: { |
1189 // Deal with special asmjs opcodes. | 1200 // Deal with special asmjs opcodes. |
1190 if (module_ && module_->module->origin == kAsmJsOrigin) { | 1201 if (module_ != nullptr && module_->origin == kAsmJsOrigin) { |
1191 sig = WasmOpcodes::AsmjsSignature(opcode); | 1202 sig = WasmOpcodes::AsmjsSignature(opcode); |
1192 if (sig) { | 1203 if (sig) { |
1193 BuildSimpleOperator(opcode, sig); | 1204 BuildSimpleOperator(opcode, sig); |
1194 } | 1205 } |
1195 } else { | 1206 } else { |
1196 error("Invalid opcode"); | 1207 error("Invalid opcode"); |
1197 return; | 1208 return; |
1198 } | 1209 } |
1199 } | 1210 } |
1200 } | 1211 } |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1886 break; | 1897 break; |
1887 } | 1898 } |
1888 Push(GetReturnType(sig), node); | 1899 Push(GetReturnType(sig), node); |
1889 } | 1900 } |
1890 }; | 1901 }; |
1891 | 1902 |
1892 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, | 1903 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, |
1893 const byte* end) { | 1904 const byte* end) { |
1894 AccountingAllocator allocator; | 1905 AccountingAllocator allocator; |
1895 Zone tmp(&allocator, ZONE_NAME); | 1906 Zone tmp(&allocator, ZONE_NAME); |
1896 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1907 FunctionBody body = {nullptr, nullptr, start, end}; |
1897 WasmFullDecoder decoder(&tmp, nullptr, body); | 1908 WasmFullDecoder decoder(&tmp, body); |
1898 return decoder.DecodeLocalDecls(decls); | 1909 return decoder.DecodeLocalDecls(decls); |
1899 } | 1910 } |
1900 | 1911 |
1901 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, | 1912 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, |
1902 BodyLocalDecls* decls) | 1913 BodyLocalDecls* decls) |
1903 : Decoder(start, end) { | 1914 : Decoder(start, end) { |
1904 if (decls != nullptr) { | 1915 if (decls != nullptr) { |
1905 if (DecodeLocalDecls(*decls, start, end)) { | 1916 if (DecodeLocalDecls(*decls, start, end)) { |
1906 pc_ += decls->decls_encoded_size; | 1917 pc_ += decls->decls_encoded_size; |
1907 if (pc_ > end_) pc_ = end_; | 1918 if (pc_ > end_) pc_ = end_; |
1908 } | 1919 } |
1909 } | 1920 } |
1910 } | 1921 } |
1911 | 1922 |
1912 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, | 1923 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, |
1924 const wasm::WasmModule* module, | |
1913 FunctionBody& body) { | 1925 FunctionBody& body) { |
1914 Zone zone(allocator, ZONE_NAME); | 1926 Zone zone(allocator, ZONE_NAME); |
1915 WasmFullDecoder decoder(&zone, nullptr, body); | 1927 WasmFullDecoder decoder(&zone, module, body); |
1916 decoder.Decode(); | 1928 decoder.Decode(); |
1917 return decoder.toResult<DecodeStruct*>(nullptr); | 1929 return decoder.toResult<DecodeStruct*>(nullptr); |
1918 } | 1930 } |
1919 | 1931 |
1920 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, | 1932 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, |
1921 FunctionBody& body) { | 1933 FunctionBody& body) { |
1922 Zone zone(allocator, ZONE_NAME); | 1934 Zone zone(allocator, ZONE_NAME); |
1923 WasmFullDecoder decoder(&zone, builder, body); | 1935 WasmFullDecoder decoder(&zone, builder, body); |
1924 decoder.Decode(); | 1936 decoder.Decode(); |
1925 return decoder.toResult<DecodeStruct*>(nullptr); | 1937 return decoder.toResult<DecodeStruct*>(nullptr); |
1926 } | 1938 } |
1927 | 1939 |
1928 unsigned OpcodeLength(const byte* pc, const byte* end) { | 1940 unsigned OpcodeLength(const byte* pc, const byte* end) { |
1929 WasmDecoder decoder(nullptr, nullptr, pc, end); | 1941 WasmDecoder decoder(nullptr, nullptr, pc, end); |
1930 return decoder.OpcodeLength(pc); | 1942 return decoder.OpcodeLength(pc); |
1931 } | 1943 } |
1932 | 1944 |
1933 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { | 1945 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { |
1934 AccountingAllocator allocator; | 1946 AccountingAllocator allocator; |
1935 OFStream os(stdout); | 1947 OFStream os(stdout); |
1936 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), os, nullptr); | 1948 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr, os, |
1949 nullptr); | |
1937 } | 1950 } |
1938 | 1951 |
1939 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, | 1952 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, |
1940 std::ostream& os, | 1953 const wasm::WasmModule* module, std::ostream& os, |
1941 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { | 1954 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { |
1942 Zone zone(allocator, ZONE_NAME); | 1955 Zone zone(allocator, ZONE_NAME); |
1943 WasmFullDecoder decoder(&zone, nullptr, body); | 1956 WasmFullDecoder decoder(&zone, module, body); |
1944 int line_nr = 0; | 1957 int line_nr = 0; |
1945 | 1958 |
1946 // Print the function signature. | 1959 // Print the function signature. |
1947 if (body.sig) { | 1960 if (body.sig) { |
1948 os << "// signature: " << *body.sig << std::endl; | 1961 os << "// signature: " << *body.sig << std::endl; |
1949 ++line_nr; | 1962 ++line_nr; |
1950 } | 1963 } |
1951 | 1964 |
1952 // Print the local declarations. | 1965 // Print the local declarations. |
1953 BodyLocalDecls decls(&zone); | 1966 BodyLocalDecls decls(&zone); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2051 } | 2064 } |
2052 os << std::endl; | 2065 os << std::endl; |
2053 ++line_nr; | 2066 ++line_nr; |
2054 } | 2067 } |
2055 | 2068 |
2056 return decoder.ok(); | 2069 return decoder.ok(); |
2057 } | 2070 } |
2058 | 2071 |
2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2072 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2060 const byte* start, const byte* end) { | 2073 const byte* start, const byte* end) { |
2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2074 FunctionBody body = {nullptr, nullptr, start, end}; |
2062 WasmFullDecoder decoder(zone, nullptr, body); | 2075 WasmFullDecoder decoder(zone, body); |
2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2076 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
2064 } | 2077 } |
2065 | 2078 |
2066 } // namespace wasm | 2079 } // namespace wasm |
2067 } // namespace internal | 2080 } // namespace internal |
2068 } // namespace v8 | 2081 } // namespace v8 |
OLD | NEW |