OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/wasm/wasm-text.h" | 5 #include "src/wasm/wasm-text.h" |
6 | 6 |
7 #include "src/debug/interface-types.h" | 7 #include "src/debug/interface-types.h" |
8 #include "src/ostreams.h" | 8 #include "src/ostreams.h" |
9 #include "src/vector.h" | 9 #include "src/vector.h" |
10 #include "src/wasm/function-body-decoder.h" | 10 #include "src/wasm/function-body-decoder.h" |
11 #include "src/wasm/wasm-module.h" | 11 #include "src/wasm/wasm-module.h" |
12 #include "src/wasm/wasm-opcodes.h" | 12 #include "src/wasm/wasm-opcodes.h" |
13 #include "src/zone/zone.h" | 13 #include "src/zone/zone.h" |
14 | 14 |
15 using namespace v8; | 15 using namespace v8; |
16 using namespace v8::internal; | 16 using namespace v8::internal; |
17 using namespace v8::internal::wasm; | 17 using namespace v8::internal::wasm; |
18 | 18 |
19 namespace { | 19 namespace { |
20 const char *GetOpName(WasmOpcode opcode) { | |
21 #define CASE_OP(name, str) \ | |
22 case kExpr##name: \ | |
23 return str; | |
24 #define CASE_I32_OP(name, str) CASE_OP(I32##name, "i32." str) | |
25 #define CASE_I64_OP(name, str) CASE_OP(I64##name, "i64." str) | |
26 #define CASE_F32_OP(name, str) CASE_OP(F32##name, "f32." str) | |
27 #define CASE_F64_OP(name, str) CASE_OP(F64##name, "f64." str) | |
28 #define CASE_INT_OP(name, str) CASE_I32_OP(name, str) CASE_I64_OP(name, str) | |
29 #define CASE_FLOAT_OP(name, str) CASE_F32_OP(name, str) CASE_F64_OP(name, str) | |
30 #define CASE_ALL_OP(name, str) CASE_FLOAT_OP(name, str) CASE_INT_OP(name, str) | |
31 #define CASE_SIGN_OP(TYPE, name, str) \ | |
32 CASE_##TYPE##_OP(name##S, str "_s") CASE_##TYPE##_OP(name##U, str "_u") | |
33 #define CASE_ALL_SIGN_OP(name, str) \ | |
34 CASE_FLOAT_OP(name, str) CASE_SIGN_OP(INT, name, str) | |
35 #define CASE_CONVERT_OP(name, RES, SRC, src_suffix, str) \ | |
36 CASE_##RES##_OP(U##name##SRC, str "_u/" src_suffix) \ | |
37 CASE_##RES##_OP(S##name##SRC, str "_s/" src_suffix) | |
38 | |
39 switch (opcode) { | |
40 CASE_INT_OP(Eqz, "eqz") | |
41 CASE_ALL_OP(Eq, "eq") | |
42 CASE_ALL_OP(Ne, "ne") | |
43 CASE_ALL_OP(Add, "add") | |
44 CASE_ALL_OP(Sub, "sub") | |
45 CASE_ALL_OP(Mul, "mul") | |
46 CASE_ALL_SIGN_OP(Lt, "lt") | |
47 CASE_ALL_SIGN_OP(Gt, "gt") | |
48 CASE_ALL_SIGN_OP(Le, "le") | |
49 CASE_ALL_SIGN_OP(Ge, "ge") | |
50 CASE_INT_OP(Clz, "clz") | |
51 CASE_INT_OP(Ctz, "ctz") | |
52 CASE_INT_OP(Popcnt, "popcnt") | |
53 CASE_ALL_SIGN_OP(Div, "div") | |
54 CASE_SIGN_OP(INT, Rem, "rem") | |
55 CASE_INT_OP(And, "and") | |
56 CASE_INT_OP(Ior, "or") | |
57 CASE_INT_OP(Xor, "xor") | |
58 CASE_INT_OP(Shl, "shl") | |
59 CASE_SIGN_OP(INT, Shr, "shr") | |
60 CASE_INT_OP(Rol, "rol") | |
61 CASE_INT_OP(Ror, "ror") | |
62 CASE_FLOAT_OP(Abs, "abs") | |
63 CASE_FLOAT_OP(Neg, "neg") | |
64 CASE_FLOAT_OP(Ceil, "ceil") | |
65 CASE_FLOAT_OP(Floor, "floor") | |
66 CASE_FLOAT_OP(Trunc, "trunc") | |
67 CASE_FLOAT_OP(NearestInt, "nearest") | |
68 CASE_FLOAT_OP(Sqrt, "sqrt") | |
69 CASE_FLOAT_OP(Min, "min") | |
70 CASE_FLOAT_OP(Max, "max") | |
71 CASE_FLOAT_OP(CopySign, "copysign") | |
72 CASE_I32_OP(ConvertI64, "wrap/i64") | |
73 CASE_CONVERT_OP(Convert, INT, F32, "f32", "trunc") | |
74 CASE_CONVERT_OP(Convert, INT, F64, "f64", "trunc") | |
75 CASE_CONVERT_OP(Convert, I64, I32, "i32", "extend") | |
76 CASE_CONVERT_OP(Convert, F32, I32, "i32", "convert") | |
77 CASE_CONVERT_OP(Convert, F32, I64, "i64", "convert") | |
78 CASE_F32_OP(ConvertF64, "demote/f64") | |
79 CASE_CONVERT_OP(Convert, F64, I32, "i32", "convert") | |
80 CASE_CONVERT_OP(Convert, F64, I64, "i64", "convert") | |
81 CASE_F64_OP(ConvertF32, "promote/f32") | |
82 CASE_I32_OP(ReinterpretF32, "reinterpret/f32") | |
83 CASE_I64_OP(ReinterpretF64, "reinterpret/f64") | |
84 CASE_F32_OP(ReinterpretI32, "reinterpret/i32") | |
85 CASE_F64_OP(ReinterpretI64, "reinterpret/i64") | |
86 CASE_OP(Unreachable, "unreachable") | |
87 CASE_OP(Nop, "nop") | |
88 CASE_OP(Return, "return") | |
89 CASE_OP(MemorySize, "current_memory") | |
90 CASE_OP(GrowMemory, "grow_memory") | |
91 CASE_OP(Loop, "loop") | |
92 CASE_OP(If, "if") | |
93 CASE_OP(Block, "block") | |
94 CASE_OP(Try, "try") | |
95 CASE_OP(Throw, "throw") | |
96 CASE_OP(Catch, "catch") | |
97 CASE_OP(Drop, "drop") | |
98 CASE_OP(Select, "select") | |
99 CASE_ALL_OP(LoadMem, "load") | |
100 CASE_SIGN_OP(INT, LoadMem8, "load8") | |
101 CASE_SIGN_OP(INT, LoadMem16, "load16") | |
102 CASE_SIGN_OP(I64, LoadMem32, "load32") | |
103 CASE_ALL_OP(StoreMem, "store") | |
104 CASE_INT_OP(StoreMem8, "store8") | |
105 CASE_INT_OP(StoreMem16, "store16") | |
106 CASE_I64_OP(StoreMem32, "store32") | |
107 CASE_OP(SetLocal, "set_local") | |
108 CASE_OP(GetLocal, "get_local") | |
109 CASE_OP(TeeLocal, "tee_local") | |
110 CASE_OP(GetGlobal, "get_global") | |
111 CASE_OP(SetGlobal, "set_global") | |
112 CASE_OP(Br, "br") | |
113 CASE_OP(BrIf, "br_if") | |
114 default: | |
115 UNREACHABLE(); | |
116 return ""; | |
117 } | |
118 } | |
119 | |
120 bool IsValidFunctionName(const Vector<const char> &name) { | 20 bool IsValidFunctionName(const Vector<const char> &name) { |
121 if (name.is_empty()) return false; | 21 if (name.is_empty()) return false; |
122 const char *special_chars = "_.+-*/\\^~=<>!?@#$%&|:'`"; | 22 const char *special_chars = "_.+-*/\\^~=<>!?@#$%&|:'`"; |
123 for (char c : name) { | 23 for (char c : name) { |
124 bool valid_char = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || | 24 bool valid_char = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || |
125 (c >= 'A' && c <= 'Z') || strchr(special_chars, c); | 25 (c >= 'A' && c <= 'Z') || strchr(special_chars, c); |
126 if (!valid_char) return false; | 26 if (!valid_char) return false; |
127 } | 27 } |
128 return true; | 28 return true; |
129 } | 29 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 const char padding[kMaxIndentation + 1] = | 98 const char padding[kMaxIndentation + 1] = |
199 " "; | 99 " "; |
200 os.write(padding, indentation); | 100 os.write(padding, indentation); |
201 | 101 |
202 switch (opcode) { | 102 switch (opcode) { |
203 case kExprLoop: | 103 case kExprLoop: |
204 case kExprIf: | 104 case kExprIf: |
205 case kExprBlock: | 105 case kExprBlock: |
206 case kExprTry: { | 106 case kExprTry: { |
207 BlockTypeOperand operand(&i, i.pc()); | 107 BlockTypeOperand operand(&i, i.pc()); |
208 os << GetOpName(opcode); | 108 os << WasmOpcodes::OpcodeName(opcode); |
209 for (unsigned i = 0; i < operand.arity; i++) { | 109 for (unsigned i = 0; i < operand.arity; i++) { |
210 os << " " << WasmOpcodes::TypeName(operand.read_entry(i)); | 110 os << " " << WasmOpcodes::TypeName(operand.read_entry(i)); |
211 } | 111 } |
212 control_depth++; | 112 control_depth++; |
213 break; | 113 break; |
214 } | 114 } |
215 case kExprBr: | 115 case kExprBr: |
216 case kExprBrIf: { | 116 case kExprBrIf: { |
217 BreakDepthOperand operand(&i, i.pc()); | 117 BreakDepthOperand operand(&i, i.pc()); |
218 os << GetOpName(opcode) << ' ' << operand.depth; | 118 os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.depth; |
219 break; | 119 break; |
220 } | 120 } |
221 case kExprElse: | 121 case kExprElse: |
222 os << "else"; | 122 os << "else"; |
223 control_depth++; | 123 control_depth++; |
224 break; | 124 break; |
225 case kExprEnd: | 125 case kExprEnd: |
226 os << "end"; | 126 os << "end"; |
227 break; | 127 break; |
228 case kExprBrTable: { | 128 case kExprBrTable: { |
(...skipping 12 matching lines...) Expand all Loading... |
241 case kExprCallFunction: { | 141 case kExprCallFunction: { |
242 CallFunctionOperand operand(&i, i.pc()); | 142 CallFunctionOperand operand(&i, i.pc()); |
243 os << "call " << operand.index; | 143 os << "call " << operand.index; |
244 break; | 144 break; |
245 } | 145 } |
246 case kExprGetLocal: | 146 case kExprGetLocal: |
247 case kExprSetLocal: | 147 case kExprSetLocal: |
248 case kExprTeeLocal: | 148 case kExprTeeLocal: |
249 case kExprCatch: { | 149 case kExprCatch: { |
250 LocalIndexOperand operand(&i, i.pc()); | 150 LocalIndexOperand operand(&i, i.pc()); |
251 os << GetOpName(opcode) << ' ' << operand.index; | 151 os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.index; |
252 break; | 152 break; |
253 } | 153 } |
254 case kExprGetGlobal: | 154 case kExprGetGlobal: |
255 case kExprSetGlobal: { | 155 case kExprSetGlobal: { |
256 GlobalIndexOperand operand(&i, i.pc()); | 156 GlobalIndexOperand operand(&i, i.pc()); |
257 os << GetOpName(opcode) << ' ' << operand.index; | 157 os << WasmOpcodes::OpcodeName(opcode) << ' ' << operand.index; |
258 break; | 158 break; |
259 } | 159 } |
260 #define CASE_CONST(type, str, cast_type) \ | 160 #define CASE_CONST(type, str, cast_type) \ |
261 case kExpr##type##Const: { \ | 161 case kExpr##type##Const: { \ |
262 Imm##type##Operand operand(&i, i.pc()); \ | 162 Imm##type##Operand operand(&i, i.pc()); \ |
263 os << #str ".const " << static_cast<cast_type>(operand.value); \ | 163 os << #str ".const " << static_cast<cast_type>(operand.value); \ |
264 break; \ | 164 break; \ |
265 } | 165 } |
266 CASE_CONST(I32, i32, int32_t) | 166 CASE_CONST(I32, i32, int32_t) |
267 CASE_CONST(I64, i64, int64_t) | 167 CASE_CONST(I64, i64, int64_t) |
268 CASE_CONST(F32, f32, float) | 168 CASE_CONST(F32, f32, float) |
269 CASE_CONST(F64, f64, double) | 169 CASE_CONST(F64, f64, double) |
270 | 170 |
271 #define CASE_OPCODE(opcode, _, __) case kExpr##opcode: | 171 #define CASE_OPCODE(opcode, _, __) case kExpr##opcode: |
272 FOREACH_LOAD_MEM_OPCODE(CASE_OPCODE) | 172 FOREACH_LOAD_MEM_OPCODE(CASE_OPCODE) |
273 FOREACH_STORE_MEM_OPCODE(CASE_OPCODE) { | 173 FOREACH_STORE_MEM_OPCODE(CASE_OPCODE) { |
274 MemoryAccessOperand operand(&i, i.pc(), kMaxUInt32); | 174 MemoryAccessOperand operand(&i, i.pc(), kMaxUInt32); |
275 os << GetOpName(opcode) << " offset=" << operand.offset | 175 os << WasmOpcodes::OpcodeName(opcode) << " offset=" << operand.offset |
276 << " align=" << (1ULL << operand.alignment); | 176 << " align=" << (1ULL << operand.alignment); |
277 break; | 177 break; |
278 } | 178 } |
279 | 179 |
280 FOREACH_SIMPLE_OPCODE(CASE_OPCODE) | 180 FOREACH_SIMPLE_OPCODE(CASE_OPCODE) |
281 case kExprUnreachable: | 181 case kExprUnreachable: |
282 case kExprNop: | 182 case kExprNop: |
283 case kExprReturn: | 183 case kExprReturn: |
284 case kExprMemorySize: | 184 case kExprMemorySize: |
285 case kExprGrowMemory: | 185 case kExprGrowMemory: |
286 case kExprDrop: | 186 case kExprDrop: |
287 case kExprSelect: | 187 case kExprSelect: |
288 case kExprThrow: | 188 case kExprThrow: |
289 os << GetOpName(opcode); | 189 os << WasmOpcodes::OpcodeName(opcode); |
290 break; | 190 break; |
291 | 191 |
292 // This group is just printed by their internal opcode name, as they | 192 // This group is just printed by their internal opcode name, as they |
293 // should never be shown to end-users. | 193 // should never be shown to end-users. |
294 FOREACH_ASMJS_COMPAT_OPCODE(CASE_OPCODE) | 194 FOREACH_ASMJS_COMPAT_OPCODE(CASE_OPCODE) |
295 // TODO(wasm): Add correct printing for SIMD and atomic opcodes once | 195 // TODO(wasm): Add correct printing for SIMD and atomic opcodes once |
296 // they are publicly available. | 196 // they are publicly available. |
297 FOREACH_SIMD_0_OPERAND_OPCODE(CASE_OPCODE) | 197 FOREACH_SIMD_0_OPERAND_OPCODE(CASE_OPCODE) |
298 FOREACH_SIMD_1_OPERAND_OPCODE(CASE_OPCODE) | 198 FOREACH_SIMD_1_OPERAND_OPCODE(CASE_OPCODE) |
299 FOREACH_ATOMIC_OPCODE(CASE_OPCODE) | 199 FOREACH_ATOMIC_OPCODE(CASE_OPCODE) |
300 os << WasmOpcodes::OpcodeName(opcode); | 200 os << WasmOpcodes::OpcodeName(opcode); |
301 break; | 201 break; |
302 | 202 |
303 default: | 203 default: |
304 UNREACHABLE(); | 204 UNREACHABLE(); |
305 break; | 205 break; |
306 } | 206 } |
307 os << '\n'; | 207 os << '\n'; |
308 ++line_nr; | 208 ++line_nr; |
309 } | 209 } |
310 DCHECK_EQ(0, control_depth); | 210 DCHECK_EQ(0, control_depth); |
311 DCHECK(i.ok()); | 211 DCHECK(i.ok()); |
312 } | 212 } |
OLD | NEW |