5 #include "src/wasm/function-body-decoder.h" 8 #include "src/handles.h" 9 #include "src/objects-inl.h" 10 #include "src/ostreams.h" 11 #include "src/wasm/decoder.h" 12 #include "src/wasm/function-body-decoder-impl.h" 13 #include "src/wasm/wasm-limits.h" 14 #include "src/wasm/wasm-linkage.h" 15 #include "src/wasm/wasm-module.h" 16 #include "src/wasm/wasm-opcodes.h" 22 bool DecodeLocalDecls(
const WasmFeatures& enabled, BodyLocalDecls* decls,
23 const byte* start,
const byte* end) {
24 Decoder decoder(start, end);
25 if (WasmDecoder<Decoder::kValidate>::DecodeLocals(enabled, &decoder,
nullptr,
28 decls->encoded_size = decoder.pc_offset();
34 BytecodeIterator::BytecodeIterator(
const byte* start,
const byte* end,
35 BodyLocalDecls* decls)
36 : Decoder(start, end) {
37 if (decls !=
nullptr) {
38 if (DecodeLocalDecls(kAllWasmFeatures, decls, start, end)) {
39 pc_ += decls->encoded_size;
40 if (pc_ > end_) pc_ = end_;
45 DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
46 const WasmFeatures& enabled,
47 const WasmModule* module, WasmFeatures* detected,
49 Zone zone(allocator, ZONE_NAME);
50 WasmFullDecoder<Decoder::kValidate, EmptyInterface> decoder(
51 &zone, module, enabled, detected, body);
53 return decoder.toResult(
nullptr);
56 unsigned OpcodeLength(
const byte* pc,
const byte* end) {
57 Decoder decoder(pc, end);
58 return WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder, pc);
61 std::pair<uint32_t, uint32_t> StackEffect(
const WasmModule* module,
62 FunctionSig* sig,
const byte* pc,
64 WasmFeatures unused_detected_features;
65 WasmDecoder<Decoder::kNoValidate> decoder(
66 module, kAllWasmFeatures, &unused_detected_features, sig, pc, end);
67 return decoder.StackEffect(pc);
70 void PrintRawWasmCode(
const byte* start,
const byte* end) {
71 AccountingAllocator allocator;
72 PrintRawWasmCode(&allocator, FunctionBody{
nullptr, 0, start, end},
nullptr,
77 const char* RawOpcodeName(WasmOpcode opcode) {
79 #define DECLARE_NAME_CASE(name, opcode, sig) \ 82 FOREACH_OPCODE(DECLARE_NAME_CASE)
83 #undef DECLARE_NAME_CASE 91 bool PrintRawWasmCode(AccountingAllocator* allocator,
const FunctionBody& body,
92 const WasmModule* module, PrintLocals print_locals) {
94 return PrintRawWasmCode(allocator, body, module, print_locals, os);
97 bool PrintRawWasmCode(AccountingAllocator* allocator,
const FunctionBody& body,
98 const WasmModule* module, PrintLocals print_locals,
99 std::ostream& os, std::vector<int>* line_numbers) {
100 Zone zone(allocator, ZONE_NAME);
101 WasmFeatures unused_detected_features;
102 WasmDecoder<Decoder::kNoValidate> decoder(module, kAllWasmFeatures,
103 &unused_detected_features, body.sig,
104 body.start, body.end);
106 constexpr
int kNoByteCode = -1;
110 os <<
"// signature: " << *body.sig << std::endl;
111 if (line_numbers) line_numbers->push_back(kNoByteCode);
116 BodyLocalDecls decls(&zone);
117 BytecodeIterator
i(body.start, body.end, &decls);
118 if (body.start !=
i.pc() && print_locals == kPrintLocals) {
120 if (!decls.type_list.empty()) {
121 ValueType type = decls.type_list[0];
123 for (
size_t pos = 0; pos < decls.type_list.size(); ++pos) {
124 if (decls.type_list[pos] == type) {
127 os <<
" " << count <<
" " << ValueTypes::TypeName(type);
128 type = decls.type_list[pos];
134 if (line_numbers) line_numbers->push_back(kNoByteCode);
137 for (
const byte* locals = body.start; locals <
i.pc(); locals++) {
138 os << (locals == body.start ?
"0x" :
" 0x") << AsHex(*locals, 2) <<
",";
141 if (line_numbers) line_numbers->push_back(kNoByteCode);
145 os <<
"// body: " << std::endl;
146 if (line_numbers) line_numbers->push_back(kNoByteCode);
148 unsigned control_depth = 0;
149 for (;
i.has_next();
i.next()) {
151 WasmDecoder<Decoder::kNoValidate>::OpcodeLength(&decoder,
i.pc());
153 WasmOpcode opcode =
i.current();
154 if (line_numbers) line_numbers->push_back(
i.position());
155 if (opcode == kExprElse) control_depth--;
157 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
160 const char* padding =
162 os.write(padding, num_whitespaces);
164 os << RawOpcodeName(opcode) <<
",";
166 if (opcode == kExprLoop || opcode == kExprIf || opcode == kExprBlock ||
167 opcode == kExprTry) {
168 DCHECK_EQ(2, length);
171 #define CASE_LOCAL_TYPE(local_name, type_name) \ 172 case kLocal##local_name: \ 173 os << " kWasm" #type_name ","; \ 176 CASE_LOCAL_TYPE(I32, I32)
177 CASE_LOCAL_TYPE(I64, I64)
178 CASE_LOCAL_TYPE(F32, F32)
179 CASE_LOCAL_TYPE(F64, F64)
180 CASE_LOCAL_TYPE(S128, S128)
181 CASE_LOCAL_TYPE(Void, Stmt)
183 os <<
" 0x" << AsHex(
i.pc()[1], 2) <<
",";
186 #undef CASE_LOCAL_TYPE 188 for (
unsigned j = 1; j < length; ++j) {
189 os <<
" 0x" << AsHex(
i.pc()[j], 2) <<
",";
195 os <<
" // @" <<
i.pc_offset();
202 BlockTypeImmediate<Decoder::kNoValidate> imm(kAllWasmFeatures, &
i,
204 os <<
" // @" <<
i.pc_offset();
205 if (decoder.Complete(imm)) {
207 os <<
" " << ValueTypes::TypeName(imm.out_type(
i));
214 os <<
" // @" <<
i.pc_offset();
218 BreakDepthImmediate<Decoder::kNoValidate> imm(&
i,
i.pc());
219 os <<
" // depth=" << imm.depth;
223 BreakDepthImmediate<Decoder::kNoValidate> imm(&
i,
i.pc());
224 os <<
" // depth=" << imm.depth;
228 BranchTableImmediate<Decoder::kNoValidate> imm(&
i,
i.pc());
229 os <<
" // entries=" << imm.table_count;
232 case kExprCallIndirect: {
233 CallIndirectImmediate<Decoder::kNoValidate> imm(&
i,
i.pc());
234 os <<
" // sig #" << imm.sig_index;
235 if (decoder.Complete(
i.pc(), imm)) {
236 os <<
": " << *imm.sig;
240 case kExprCallFunction: {
241 CallFunctionImmediate<Decoder::kNoValidate> imm(&
i,
i.pc());
242 os <<
" // function #" << imm.index;
243 if (decoder.Complete(
i.pc(), imm)) {
244 os <<
": " << *imm.sig;
254 DCHECK(!line_numbers || line_numbers->size() ==
static_cast<size_t>(line_nr));
259 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone,
size_t num_locals,
260 const byte* start,
const byte* end) {
261 Decoder decoder(start, end);
262 return WasmDecoder<Decoder::kValidate>::AnalyzeLoopAssignment(
263 &decoder, start, static_cast<uint32_t>(num_locals), zone);