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 if (module_ == nullptr || module_->function_tables.empty()) { |
231 if (!module_->IsValidTable(table_index)) { | |
232 error("function table has to exist to execute call_indirect"); | 228 error("function table has to exist to execute call_indirect"); |
233 return false; | 229 return false; |
234 } | 230 } |
235 if (Complete(pc, operand)) { | 231 if (Complete(pc, operand)) { |
236 return true; | 232 return true; |
237 } | 233 } |
238 error(pc, pc + 1, "invalid signature index: #%u", operand.index); | 234 error(pc, pc + 1, "invalid signature index: #%u", operand.index); |
239 return false; | 235 return false; |
240 } | 236 } |
241 | 237 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 } | 352 } |
357 } | 353 } |
358 default: | 354 default: |
359 return 1; | 355 return 1; |
360 } | 356 } |
361 } | 357 } |
362 }; | 358 }; |
363 | 359 |
364 static const int32_t kNullCatch = -1; | 360 static const int32_t kNullCatch = -1; |
365 | 361 |
366 // The full WASM decoder for bytecode. Both verifies bytecode and generates | 362 // The full WASM decoder for bytecode. Verifies bytecode and, optionally, |
367 // a TurboFan IR graph. | 363 // generates a TurboFan IR graph. |
368 class WasmFullDecoder : public WasmDecoder { | 364 class WasmFullDecoder : public WasmDecoder { |
369 public: | 365 public: |
| 366 WasmFullDecoder(Zone* zone, const FunctionBody& body) |
| 367 : WasmFullDecoder(zone, nullptr, nullptr, body) {} |
| 368 |
| 369 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, |
| 370 const FunctionBody& body) |
| 371 : WasmFullDecoder(zone, module, nullptr, body) {} |
| 372 |
370 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) | 373 WasmFullDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body) |
371 : WasmDecoder(body.module, body.sig, body.start, body.end), | 374 : WasmFullDecoder(zone, builder->module_env() == nullptr |
372 zone_(zone), | 375 ? nullptr |
373 builder_(builder), | 376 : builder->module_env()->module, |
374 base_(body.base), | 377 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 | 378 |
383 bool Decode() { | 379 bool Decode() { |
384 if (FLAG_wasm_code_fuzzer_gen_test) { | 380 if (FLAG_wasm_code_fuzzer_gen_test) { |
385 PrintWasmCodeForDebugging(start_, end_); | 381 PrintWasmCodeForDebugging(start_, end_); |
386 } | 382 } |
387 base::ElapsedTimer decode_timer; | 383 base::ElapsedTimer decode_timer; |
388 if (FLAG_trace_wasm_decode_time) { | 384 if (FLAG_trace_wasm_decode_time) { |
389 decode_timer.Start(); | 385 decode_timer.Start(); |
390 } | 386 } |
391 stack_.clear(); | 387 stack_.clear(); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 total_locals_ = num_locals; | 481 total_locals_ = num_locals; |
486 local_type_vec_.reserve(num_locals); | 482 local_type_vec_.reserve(num_locals); |
487 if (num_locals > local_type_vec_.size()) { | 483 if (num_locals > local_type_vec_.size()) { |
488 local_type_vec_.insert(local_type_vec_.end(), | 484 local_type_vec_.insert(local_type_vec_.end(), |
489 num_locals - local_type_vec_.size(), kWasmI32); | 485 num_locals - local_type_vec_.size(), kWasmI32); |
490 } | 486 } |
491 return AnalyzeLoopAssignment(pc); | 487 return AnalyzeLoopAssignment(pc); |
492 } | 488 } |
493 | 489 |
494 private: | 490 private: |
| 491 WasmFullDecoder(Zone* zone, const wasm::WasmModule* module, |
| 492 TFBuilder* builder, const FunctionBody& body) |
| 493 : WasmDecoder(module, body.sig, body.start, body.end), |
| 494 zone_(zone), |
| 495 builder_(builder), |
| 496 base_(body.base), |
| 497 local_type_vec_(zone), |
| 498 stack_(zone), |
| 499 control_(zone), |
| 500 last_end_found_(false), |
| 501 current_catch_(kNullCatch) { |
| 502 local_types_ = &local_type_vec_; |
| 503 } |
| 504 |
495 static const size_t kErrorMsgSize = 128; | 505 static const size_t kErrorMsgSize = 128; |
496 | 506 |
497 Zone* zone_; | 507 Zone* zone_; |
498 TFBuilder* builder_; | 508 TFBuilder* builder_; |
499 const byte* base_; | 509 const byte* base_; |
500 | 510 |
501 SsaEnv* ssa_env_; | 511 SsaEnv* ssa_env_; |
502 | 512 |
503 ZoneVector<ValueType> local_type_vec_; // types of local variables. | 513 ZoneVector<ValueType> local_type_vec_; // types of local variables. |
504 ZoneVector<Value> stack_; // stack of values. | 514 ZoneVector<Value> stack_; // stack of values. |
(...skipping 24 matching lines...) Expand all Loading... |
529 } | 539 } |
530 while (index < local_type_vec_.size()) { | 540 while (index < local_type_vec_.size()) { |
531 ValueType type = local_type_vec_[index]; | 541 ValueType type = local_type_vec_[index]; |
532 TFNode* node = DefaultValue(type); | 542 TFNode* node = DefaultValue(type); |
533 while (index < local_type_vec_.size() && | 543 while (index < local_type_vec_.size() && |
534 local_type_vec_[index] == type) { | 544 local_type_vec_[index] == type) { |
535 // Do a whole run of like-typed locals at a time. | 545 // Do a whole run of like-typed locals at a time. |
536 ssa_env->locals[index++] = node; | 546 ssa_env->locals[index++] = node; |
537 } | 547 } |
538 } | 548 } |
539 builder_->set_module(module_); | |
540 } | 549 } |
541 ssa_env->control = start; | 550 ssa_env->control = start; |
542 ssa_env->effect = start; | 551 ssa_env->effect = start; |
543 SetEnv("initial", ssa_env); | 552 SetEnv("initial", ssa_env); |
544 if (builder_) { | 553 if (builder_) { |
545 builder_->StackCheck(position()); | 554 builder_->StackCheck(position()); |
546 } | 555 } |
547 } | 556 } |
548 | 557 |
549 TFNode* DefaultValue(ValueType type) { | 558 TFNode* DefaultValue(ValueType type) { |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); | 1120 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); |
1112 break; | 1121 break; |
1113 case kExprF32StoreMem: | 1122 case kExprF32StoreMem: |
1114 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); | 1123 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); |
1115 break; | 1124 break; |
1116 case kExprF64StoreMem: | 1125 case kExprF64StoreMem: |
1117 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); | 1126 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); |
1118 break; | 1127 break; |
1119 case kExprGrowMemory: { | 1128 case kExprGrowMemory: { |
1120 MemoryIndexOperand operand(this, pc_); | 1129 MemoryIndexOperand operand(this, pc_); |
1121 if (module_->module->origin != kAsmJsOrigin) { | 1130 DCHECK_NOT_NULL(module_); |
| 1131 if (module_->origin != kAsmJsOrigin) { |
1122 Value val = Pop(0, kWasmI32); | 1132 Value val = Pop(0, kWasmI32); |
1123 Push(kWasmI32, BUILD(GrowMemory, val.node)); | 1133 Push(kWasmI32, BUILD(GrowMemory, val.node)); |
1124 } else { | 1134 } else { |
1125 error("grow_memory is not supported for asmjs modules"); | 1135 error("grow_memory is not supported for asmjs modules"); |
1126 } | 1136 } |
1127 len = 1 + operand.length; | 1137 len = 1 + operand.length; |
1128 break; | 1138 break; |
1129 } | 1139 } |
1130 case kExprMemorySize: { | 1140 case kExprMemorySize: { |
1131 MemoryIndexOperand operand(this, pc_); | 1141 MemoryIndexOperand operand(this, pc_); |
(...skipping 29 matching lines...) Expand all Loading... |
1161 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); | 1171 CHECK_PROTOTYPE_OPCODE(wasm_simd_prototype); |
1162 len++; | 1172 len++; |
1163 byte simd_index = checked_read_u8(pc_, 1, "simd index"); | 1173 byte simd_index = checked_read_u8(pc_, 1, "simd index"); |
1164 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); | 1174 opcode = static_cast<WasmOpcode>(opcode << 8 | simd_index); |
1165 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, | 1175 TRACE(" @%-4d #%02x #%02x:%-20s|", startrel(pc_), kSimdPrefix, |
1166 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); | 1176 simd_index, WasmOpcodes::ShortOpcodeName(opcode)); |
1167 len += DecodeSimdOpcode(opcode); | 1177 len += DecodeSimdOpcode(opcode); |
1168 break; | 1178 break; |
1169 } | 1179 } |
1170 case kAtomicPrefix: { | 1180 case kAtomicPrefix: { |
1171 if (!module_ || module_->module->origin != kAsmJsOrigin) { | 1181 if (module_ == nullptr || module_->origin != kAsmJsOrigin) { |
1172 error("Atomics are allowed only in AsmJs modules"); | 1182 error("Atomics are allowed only in AsmJs modules"); |
1173 break; | 1183 break; |
1174 } | 1184 } |
1175 if (!FLAG_wasm_atomics_prototype) { | 1185 if (!FLAG_wasm_atomics_prototype) { |
1176 error("Invalid opcode (enable with --wasm_atomics_prototype)"); | 1186 error("Invalid opcode (enable with --wasm_atomics_prototype)"); |
1177 break; | 1187 break; |
1178 } | 1188 } |
1179 len = 2; | 1189 len = 2; |
1180 byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index"); | 1190 byte atomic_opcode = checked_read_u8(pc_, 1, "atomic index"); |
1181 opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode); | 1191 opcode = static_cast<WasmOpcode>(opcode << 8 | atomic_opcode); |
1182 sig = WasmOpcodes::AtomicSignature(opcode); | 1192 sig = WasmOpcodes::AtomicSignature(opcode); |
1183 if (sig) { | 1193 if (sig) { |
1184 BuildAtomicOperator(opcode); | 1194 BuildAtomicOperator(opcode); |
1185 } | 1195 } |
1186 break; | 1196 break; |
1187 } | 1197 } |
1188 default: { | 1198 default: { |
1189 // Deal with special asmjs opcodes. | 1199 // Deal with special asmjs opcodes. |
1190 if (module_ && module_->module->origin == kAsmJsOrigin) { | 1200 if (module_ != nullptr && module_->origin == kAsmJsOrigin) { |
1191 sig = WasmOpcodes::AsmjsSignature(opcode); | 1201 sig = WasmOpcodes::AsmjsSignature(opcode); |
1192 if (sig) { | 1202 if (sig) { |
1193 BuildSimpleOperator(opcode, sig); | 1203 BuildSimpleOperator(opcode, sig); |
1194 } | 1204 } |
1195 } else { | 1205 } else { |
1196 error("Invalid opcode"); | 1206 error("Invalid opcode"); |
1197 return; | 1207 return; |
1198 } | 1208 } |
1199 } | 1209 } |
1200 } | 1210 } |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 break; | 1896 break; |
1887 } | 1897 } |
1888 Push(GetReturnType(sig), node); | 1898 Push(GetReturnType(sig), node); |
1889 } | 1899 } |
1890 }; | 1900 }; |
1891 | 1901 |
1892 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, | 1902 bool DecodeLocalDecls(BodyLocalDecls& decls, const byte* start, |
1893 const byte* end) { | 1903 const byte* end) { |
1894 AccountingAllocator allocator; | 1904 AccountingAllocator allocator; |
1895 Zone tmp(&allocator, ZONE_NAME); | 1905 Zone tmp(&allocator, ZONE_NAME); |
1896 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1906 FunctionBody body = {nullptr, nullptr, start, end}; |
1897 WasmFullDecoder decoder(&tmp, nullptr, body); | 1907 WasmFullDecoder decoder(&tmp, body); |
1898 return decoder.DecodeLocalDecls(decls); | 1908 return decoder.DecodeLocalDecls(decls); |
1899 } | 1909 } |
1900 | 1910 |
1901 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, | 1911 BytecodeIterator::BytecodeIterator(const byte* start, const byte* end, |
1902 BodyLocalDecls* decls) | 1912 BodyLocalDecls* decls) |
1903 : Decoder(start, end) { | 1913 : Decoder(start, end) { |
1904 if (decls != nullptr) { | 1914 if (decls != nullptr) { |
1905 if (DecodeLocalDecls(*decls, start, end)) { | 1915 if (DecodeLocalDecls(*decls, start, end)) { |
1906 pc_ += decls->decls_encoded_size; | 1916 pc_ += decls->decls_encoded_size; |
1907 if (pc_ > end_) pc_ = end_; | 1917 if (pc_ > end_) pc_ = end_; |
1908 } | 1918 } |
1909 } | 1919 } |
1910 } | 1920 } |
1911 | 1921 |
1912 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, | 1922 DecodeResult VerifyWasmCode(AccountingAllocator* allocator, |
| 1923 const wasm::WasmModule* module, |
1913 FunctionBody& body) { | 1924 FunctionBody& body) { |
1914 Zone zone(allocator, ZONE_NAME); | 1925 Zone zone(allocator, ZONE_NAME); |
1915 WasmFullDecoder decoder(&zone, nullptr, body); | 1926 WasmFullDecoder decoder(&zone, module, body); |
1916 decoder.Decode(); | 1927 decoder.Decode(); |
1917 return decoder.toResult<DecodeStruct*>(nullptr); | 1928 return decoder.toResult<DecodeStruct*>(nullptr); |
1918 } | 1929 } |
1919 | 1930 |
1920 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, | 1931 DecodeResult BuildTFGraph(AccountingAllocator* allocator, TFBuilder* builder, |
1921 FunctionBody& body) { | 1932 FunctionBody& body) { |
1922 Zone zone(allocator, ZONE_NAME); | 1933 Zone zone(allocator, ZONE_NAME); |
1923 WasmFullDecoder decoder(&zone, builder, body); | 1934 WasmFullDecoder decoder(&zone, builder, body); |
1924 decoder.Decode(); | 1935 decoder.Decode(); |
1925 return decoder.toResult<DecodeStruct*>(nullptr); | 1936 return decoder.toResult<DecodeStruct*>(nullptr); |
1926 } | 1937 } |
1927 | 1938 |
1928 unsigned OpcodeLength(const byte* pc, const byte* end) { | 1939 unsigned OpcodeLength(const byte* pc, const byte* end) { |
1929 WasmDecoder decoder(nullptr, nullptr, pc, end); | 1940 WasmDecoder decoder(nullptr, nullptr, pc, end); |
1930 return decoder.OpcodeLength(pc); | 1941 return decoder.OpcodeLength(pc); |
1931 } | 1942 } |
1932 | 1943 |
1933 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { | 1944 void PrintWasmCodeForDebugging(const byte* start, const byte* end) { |
1934 AccountingAllocator allocator; | 1945 AccountingAllocator allocator; |
1935 OFStream os(stdout); | 1946 OFStream os(stdout); |
1936 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), os, nullptr); | 1947 PrintWasmCode(&allocator, FunctionBodyForTesting(start, end), nullptr, os, |
| 1948 nullptr); |
1937 } | 1949 } |
1938 | 1950 |
1939 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, | 1951 bool PrintWasmCode(AccountingAllocator* allocator, const FunctionBody& body, |
1940 std::ostream& os, | 1952 const wasm::WasmModule* module, std::ostream& os, |
1941 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { | 1953 std::vector<std::tuple<uint32_t, int, int>>* offset_table) { |
1942 Zone zone(allocator, ZONE_NAME); | 1954 Zone zone(allocator, ZONE_NAME); |
1943 WasmFullDecoder decoder(&zone, nullptr, body); | 1955 WasmFullDecoder decoder(&zone, module, body); |
1944 int line_nr = 0; | 1956 int line_nr = 0; |
1945 | 1957 |
1946 // Print the function signature. | 1958 // Print the function signature. |
1947 if (body.sig) { | 1959 if (body.sig) { |
1948 os << "// signature: " << *body.sig << std::endl; | 1960 os << "// signature: " << *body.sig << std::endl; |
1949 ++line_nr; | 1961 ++line_nr; |
1950 } | 1962 } |
1951 | 1963 |
1952 // Print the local declarations. | 1964 // Print the local declarations. |
1953 BodyLocalDecls decls(&zone); | 1965 BodyLocalDecls decls(&zone); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2051 } | 2063 } |
2052 os << std::endl; | 2064 os << std::endl; |
2053 ++line_nr; | 2065 ++line_nr; |
2054 } | 2066 } |
2055 | 2067 |
2056 return decoder.ok(); | 2068 return decoder.ok(); |
2057 } | 2069 } |
2058 | 2070 |
2059 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2071 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2060 const byte* start, const byte* end) { | 2072 const byte* start, const byte* end) { |
2061 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 2073 FunctionBody body = {nullptr, nullptr, start, end}; |
2062 WasmFullDecoder decoder(zone, nullptr, body); | 2074 WasmFullDecoder decoder(zone, body); |
2063 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 2075 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
2064 } | 2076 } |
2065 | 2077 |
2066 } // namespace wasm | 2078 } // namespace wasm |
2067 } // namespace internal | 2079 } // namespace internal |
2068 } // namespace v8 | 2080 } // namespace v8 |
OLD | NEW |