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_MACRO_GEN_H_ | 5 #ifndef V8_WASM_MACRO_GEN_H_ |
6 #define V8_WASM_MACRO_GEN_H_ | 6 #define V8_WASM_MACRO_GEN_H_ |
7 | 7 |
8 #include "src/wasm/wasm-opcodes.h" | 8 #include "src/wasm/wasm-opcodes.h" |
9 | 9 |
| 10 #define U32_LE(v) \ |
| 11 static_cast<byte>(v), static_cast<byte>((v) >> 8), \ |
| 12 static_cast<byte>((v) >> 16), static_cast<byte>((v) >> 24) |
| 13 |
| 14 #define U16_LE(v) static_cast<byte>(v), static_cast<byte>((v) >> 8) |
| 15 |
| 16 #define WASM_MODULE_HEADER U32_LE(kWasmMagic), U32_LE(kWasmVersion) |
| 17 |
| 18 #define SIG_INDEX(v) U16_LE(v) |
| 19 #define FUNC_INDEX(v) U16_LE(v) |
| 20 #define NAME_OFFSET(v) U32_LE(v) |
| 21 #define BR_TARGET(v) U16_LE(v) |
| 22 |
| 23 #define MASK_7 ((1 << 7) - 1) |
| 24 #define MASK_14 ((1 << 14) - 1) |
| 25 #define MASK_21 ((1 << 21) - 1) |
| 26 #define MASK_28 ((1 << 28) - 1) |
| 27 |
| 28 #define U32V_1(x) static_cast<byte>((x)&MASK_7) |
| 29 #define U32V_2(x) \ |
| 30 static_cast<byte>(((x)&MASK_7) | 0x80), static_cast<byte>(((x) >> 7) & MASK_7) |
| 31 #define U32V_3(x) \ |
| 32 static_cast<byte>((((x)) & MASK_7) | 0x80), \ |
| 33 static_cast<byte>((((x) >> 7) & MASK_7) | 0x80), \ |
| 34 static_cast<byte>(((x) >> 14) & MASK_7) |
| 35 #define U32V_4(x) \ |
| 36 static_cast<byte>(((x)&MASK_7) | 0x80), \ |
| 37 static_cast<byte>((((x) >> 7) & MASK_7) | 0x80), \ |
| 38 static_cast<byte>((((x) >> 14) & MASK_7) | 0x80), \ |
| 39 static_cast<byte>(((x) >> 21) & MASK_7) |
| 40 #define U32V_5(x) \ |
| 41 static_cast<byte>(((x)&MASK_7) | 0x80), \ |
| 42 static_cast<byte>((((x) >> 7) & MASK_7) | 0x80), \ |
| 43 static_cast<byte>((((x) >> 14) & MASK_7) | 0x80), \ |
| 44 static_cast<byte>((((x) >> 21) & MASK_7) | 0x80), \ |
| 45 static_cast<byte>((((x) >> 28) & MASK_7)) |
| 46 |
10 // Convenience macros for building Wasm bytecode directly into a byte array. | 47 // Convenience macros for building Wasm bytecode directly into a byte array. |
11 | 48 |
12 //------------------------------------------------------------------------------ | 49 //------------------------------------------------------------------------------ |
13 // Control. | 50 // Control. |
14 //------------------------------------------------------------------------------ | 51 //------------------------------------------------------------------------------ |
15 #define WASM_NOP kExprNop | 52 #define WASM_NOP kExprNop |
16 | 53 |
17 #define WASM_BLOCK(count, ...) kExprBlock, static_cast<byte>(count), __VA_ARGS__ | 54 #define WASM_BLOCK(count, ...) kExprBlock, static_cast<byte>(count), __VA_ARGS__ |
18 #define WASM_INFINITE_LOOP kExprLoop, 1, kExprBr, 0, kExprNop | 55 #define WASM_INFINITE_LOOP kExprLoop, 1, kExprBr, 0, kExprNop |
19 #define WASM_LOOP(count, ...) kExprLoop, static_cast<byte>(count), __VA_ARGS__ | 56 #define WASM_LOOP(count, ...) kExprLoop, static_cast<byte>(count), __VA_ARGS__ |
(...skipping 30 matching lines...) Expand all Loading... |
50 #define I32V_MIN(length) -(1 << (6 + (7 * ((length) - 1)))) | 87 #define I32V_MIN(length) -(1 << (6 + (7 * ((length) - 1)))) |
51 #define I32V_MAX(length) ((1 << (6 + (7 * ((length) - 1)))) - 1) | 88 #define I32V_MAX(length) ((1 << (6 + (7 * ((length) - 1)))) - 1) |
52 #define I64V_MIN(length) -(1LL << (6 + (7 * ((length) - 1)))) | 89 #define I64V_MIN(length) -(1LL << (6 + (7 * ((length) - 1)))) |
53 #define I64V_MAX(length) ((1LL << (6 + 7 * ((length) - 1))) - 1) | 90 #define I64V_MAX(length) ((1LL << (6 + 7 * ((length) - 1))) - 1) |
54 | 91 |
55 #define I32V_IN_RANGE(value, length) \ | 92 #define I32V_IN_RANGE(value, length) \ |
56 ((value) >= I32V_MIN(length) && (value) <= I32V_MAX(length)) | 93 ((value) >= I32V_MIN(length) && (value) <= I32V_MAX(length)) |
57 #define I64V_IN_RANGE(value, length) \ | 94 #define I64V_IN_RANGE(value, length) \ |
58 ((value) >= I64V_MIN(length) && (value) <= I64V_MAX(length)) | 95 ((value) >= I64V_MIN(length) && (value) <= I64V_MAX(length)) |
59 | 96 |
| 97 #define WASM_NO_LOCALS 0 |
| 98 |
60 namespace v8 { | 99 namespace v8 { |
61 namespace internal { | 100 namespace internal { |
62 namespace wasm { | 101 namespace wasm { |
63 | 102 |
64 inline void CheckI32v(int32_t value, int length) { | 103 inline void CheckI32v(int32_t value, int length) { |
65 DCHECK(length >= 1 && length <= 5); | 104 DCHECK(length >= 1 && length <= 5); |
66 DCHECK(length == 5 || I32V_IN_RANGE(value, length)); | 105 DCHECK(length == 5 || I32V_IN_RANGE(value, length)); |
67 DCHECK(length == 1 || !I32V_IN_RANGE(value, length - 1)); | 106 DCHECK(length == 1 || !I32V_IN_RANGE(value, length - 1)); |
68 } | 107 } |
69 | 108 |
70 inline void CheckI64v(int64_t value, int length) { | 109 inline void CheckI64v(int64_t value, int length) { |
71 DCHECK(length >= 1 && length <= 10); | 110 DCHECK(length >= 1 && length <= 10); |
72 DCHECK(length == 10 || I64V_IN_RANGE(value, length)); | 111 DCHECK(length == 10 || I64V_IN_RANGE(value, length)); |
73 DCHECK(length == 1 || !I64V_IN_RANGE(value, length - 1)); | 112 DCHECK(length == 1 || !I64V_IN_RANGE(value, length - 1)); |
74 } | 113 } |
75 | 114 |
| 115 // A helper for encoding local declarations prepended to the body of a |
| 116 // function. |
| 117 class LocalDeclEncoder { |
| 118 public: |
| 119 // Prepend local declarations by creating a new buffer and copying data |
| 120 // over. The new buffer must be delete[]'d by the caller. |
| 121 void Prepend(const byte** start, const byte** end) const { |
| 122 size_t size = (*end - *start); |
| 123 byte* buffer = new byte[Size() + size]; |
| 124 size_t pos = Emit(buffer); |
| 125 memcpy(buffer + pos, *start, size); |
| 126 pos += size; |
| 127 *start = buffer; |
| 128 *end = buffer + pos; |
| 129 } |
| 130 |
| 131 size_t Emit(byte* buffer) const { |
| 132 size_t pos = 0; |
| 133 pos = WriteUint32v(buffer, pos, static_cast<uint32_t>(local_decls.size())); |
| 134 for (size_t i = 0; i < local_decls.size(); i++) { |
| 135 pos = WriteUint32v(buffer, pos, local_decls[i].first); |
| 136 buffer[pos++] = WasmOpcodes::LocalTypeCodeFor(local_decls[i].second); |
| 137 } |
| 138 DCHECK_EQ(Size(), pos); |
| 139 return pos; |
| 140 } |
| 141 |
| 142 // Add locals declarations to this helper. Return the index of the newly added |
| 143 // local(s), with an optional adjustment for the parameters. |
| 144 uint32_t AddLocals(uint32_t count, LocalType type, |
| 145 FunctionSig* sig = nullptr) { |
| 146 if (count == 0) { |
| 147 return static_cast<uint32_t>((sig ? sig->parameter_count() : 0) + |
| 148 local_decls.size()); |
| 149 } |
| 150 size_t pos = local_decls.size(); |
| 151 if (local_decls.size() > 0 && local_decls.back().second == type) { |
| 152 count += local_decls.back().first; |
| 153 local_decls.pop_back(); |
| 154 } |
| 155 local_decls.push_back(std::pair<uint32_t, LocalType>(count, type)); |
| 156 return static_cast<uint32_t>(pos + (sig ? sig->parameter_count() : 0)); |
| 157 } |
| 158 |
| 159 size_t Size() const { |
| 160 size_t size = SizeofUint32v(static_cast<uint32_t>(local_decls.size())); |
| 161 for (auto p : local_decls) size += 1 + SizeofUint32v(p.first); |
| 162 return size; |
| 163 } |
| 164 |
| 165 private: |
| 166 std::vector<std::pair<uint32_t, LocalType>> local_decls; |
| 167 |
| 168 size_t SizeofUint32v(uint32_t val) const { |
| 169 size_t size = 1; |
| 170 while (true) { |
| 171 byte b = val & MASK_7; |
| 172 if (b == val) return size; |
| 173 size++; |
| 174 val = val >> 7; |
| 175 } |
| 176 } |
| 177 |
| 178 // TODO(titzer): lift encoding of u32v to a common place. |
| 179 size_t WriteUint32v(byte* buffer, size_t pos, uint32_t val) const { |
| 180 while (true) { |
| 181 byte b = val & MASK_7; |
| 182 if (b == val) { |
| 183 buffer[pos++] = b; |
| 184 break; |
| 185 } |
| 186 buffer[pos++] = 0x80 | b; |
| 187 val = val >> 7; |
| 188 } |
| 189 return pos; |
| 190 } |
| 191 }; |
76 } // namespace wasm | 192 } // namespace wasm |
77 } // namespace internal | 193 } // namespace internal |
78 } // namespace v8 | 194 } // namespace v8 |
79 | 195 |
80 //------------------------------------------------------------------------------ | 196 //------------------------------------------------------------------------------ |
81 // Int32 Const operations | 197 // Int32 Const operations |
82 //------------------------------------------------------------------------------ | 198 //------------------------------------------------------------------------------ |
83 #define WASM_I32V(val) kExprI32Const, U32V_5(val) | 199 #define WASM_I32V(val) kExprI32Const, U32V_5(val) |
84 | 200 |
85 #define WASM_I32V_1(val) \ | 201 #define WASM_I32V_1(val) \ |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 #define WASM_F32_REINTERPRET_I32(x) kExprF32ReinterpretI32, x | 499 #define WASM_F32_REINTERPRET_I32(x) kExprF32ReinterpretI32, x |
384 #define WASM_F64_SCONVERT_I32(x) kExprF64SConvertI32, x | 500 #define WASM_F64_SCONVERT_I32(x) kExprF64SConvertI32, x |
385 #define WASM_F64_UCONVERT_I32(x) kExprF64UConvertI32, x | 501 #define WASM_F64_UCONVERT_I32(x) kExprF64UConvertI32, x |
386 #define WASM_F64_SCONVERT_I64(x) kExprF64SConvertI64, x | 502 #define WASM_F64_SCONVERT_I64(x) kExprF64SConvertI64, x |
387 #define WASM_F64_UCONVERT_I64(x) kExprF64UConvertI64, x | 503 #define WASM_F64_UCONVERT_I64(x) kExprF64UConvertI64, x |
388 #define WASM_F64_CONVERT_F32(x) kExprF64ConvertF32, x | 504 #define WASM_F64_CONVERT_F32(x) kExprF64ConvertF32, x |
389 #define WASM_F64_REINTERPRET_I64(x) kExprF64ReinterpretI64, x | 505 #define WASM_F64_REINTERPRET_I64(x) kExprF64ReinterpretI64, x |
390 #define WASM_I32_REINTERPRET_F32(x) kExprI32ReinterpretF32, x | 506 #define WASM_I32_REINTERPRET_F32(x) kExprI32ReinterpretF32, x |
391 #define WASM_I64_REINTERPRET_F64(x) kExprI64ReinterpretF64, x | 507 #define WASM_I64_REINTERPRET_F64(x) kExprI64ReinterpretF64, x |
392 | 508 |
393 #define U32_LE(v) \ | |
394 static_cast<byte>(v), static_cast<byte>((v) >> 8), \ | |
395 static_cast<byte>((v) >> 16), static_cast<byte>((v) >> 24) | |
396 | |
397 #define U16_LE(v) static_cast<byte>(v), static_cast<byte>((v) >> 8) | |
398 | |
399 #define WASM_MODULE_HEADER U32_LE(kWasmMagic), U32_LE(kWasmVersion) | |
400 | |
401 #define SIG_INDEX(v) U16_LE(v) | |
402 #define FUNC_INDEX(v) U16_LE(v) | |
403 #define NAME_OFFSET(v) U32_LE(v) | |
404 #define BR_TARGET(v) U16_LE(v) | |
405 | |
406 #define MASK_7 ((1 << 7) - 1) | |
407 #define MASK_14 ((1 << 14) - 1) | |
408 #define MASK_21 ((1 << 21) - 1) | |
409 #define MASK_28 ((1 << 28) - 1) | |
410 | |
411 #define U32V_1(x) static_cast<byte>(x & MASK_7) | |
412 #define U32V_2(x) \ | |
413 static_cast<byte>((x & MASK_7) | 0x80), static_cast<byte>((x >> 7) & MASK_7) | |
414 #define U32V_3(x) \ | |
415 static_cast<byte>((x & MASK_7) | 0x80), \ | |
416 static_cast<byte>(((x >> 7) & MASK_7) | 0x80), \ | |
417 static_cast<byte>((x >> 14) & MASK_7) | |
418 #define U32V_4(x) \ | |
419 static_cast<byte>((x & MASK_7) | 0x80), \ | |
420 static_cast<byte>(((x >> 7) & MASK_7) | 0x80), \ | |
421 static_cast<byte>(((x >> 14) & MASK_7) | 0x80), \ | |
422 static_cast<byte>((x >> 21) & MASK_7) | |
423 #define U32V_5(x) \ | |
424 static_cast<byte>((x & MASK_7) | 0x80), \ | |
425 static_cast<byte>(((x >> 7) & MASK_7) | 0x80), \ | |
426 static_cast<byte>(((x >> 14) & MASK_7) | 0x80), \ | |
427 static_cast<byte>(((x >> 21) & MASK_7) | 0x80), \ | |
428 static_cast<byte>(((x >> 28) & MASK_7)) | |
429 | |
430 #endif // V8_WASM_MACRO_GEN_H_ | 509 #endif // V8_WASM_MACRO_GEN_H_ |
OLD | NEW |