Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 1a89942

Browse files
committed
[WebAssembly] Read prefixed opcodes as ULEB128s
Summary: Depends on D54126. Reviewers: aheejin, dschuff, aardappel Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D54138 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346465 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c562714 commit 1a89942

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,34 @@ extern "C" void LLVMInitializeWebAssemblyDisassembler() {
6666
createWebAssemblyDisassembler);
6767
}
6868

69-
static int nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) {
69+
static uint8_t nextByte(ArrayRef<uint8_t> Bytes, uint64_t &Size) {
7070
if (Size >= Bytes.size())
7171
return -1;
7272
auto V = Bytes[Size];
7373
Size++;
7474
return V;
7575
}
7676

77-
static bool parseLEBImmediate(MCInst &MI, uint64_t &Size,
78-
ArrayRef<uint8_t> Bytes, bool Signed) {
77+
static bool nextLEB(int64_t &Val, ArrayRef<uint8_t> Bytes, uint64_t &Size,
78+
bool Signed = false) {
7979
unsigned N = 0;
8080
const char *Error = nullptr;
81-
auto Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N,
82-
Bytes.data() + Bytes.size(), &Error)
83-
: static_cast<int64_t>(
84-
decodeULEB128(Bytes.data() + Size, &N,
85-
Bytes.data() + Bytes.size(), &Error));
81+
Val = Signed ? decodeSLEB128(Bytes.data() + Size, &N,
82+
Bytes.data() + Bytes.size(), &Error)
83+
: static_cast<int64_t>(decodeULEB128(Bytes.data() + Size, &N,
84+
Bytes.data() + Bytes.size(),
85+
&Error));
8686
if (Error)
8787
return false;
8888
Size += N;
89+
return true;
90+
}
91+
92+
static bool parseLEBImmediate(MCInst &MI, uint64_t &Size,
93+
ArrayRef<uint8_t> Bytes, bool Signed) {
94+
int64_t Val;
95+
if (!nextLEB(Val, Bytes, Size, Signed))
96+
return false;
8997
MI.addOperand(MCOperand::createImm(Val));
9098
return true;
9199
}
@@ -127,10 +135,12 @@ MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
127135
}
128136
if (!WasmInst)
129137
return MCDisassembler::Fail;
130-
Opc = nextByte(Bytes, Size);
131-
if (Opc < 0)
138+
int64_t PrefixedOpc;
139+
if (!nextLEB(PrefixedOpc, Bytes, Size))
140+
return MCDisassembler::Fail;
141+
if (PrefixedOpc < 0 || PrefixedOpc >= WebAssemblyInstructionTableSize)
132142
return MCDisassembler::Fail;
133-
WasmInst += Opc;
143+
WasmInst += PrefixedOpc;
134144
}
135145
if (WasmInst->ET == ET_Unused)
136146
return MCDisassembler::Fail;

test/MC/Disassembler/WebAssembly/wasm.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,12 @@
3737

3838
# CHECK: v8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
3939
0xFD 0x03 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
40+
41+
# Check LEB128 encoding of SIMD instructions
42+
# CHECK: i64x2.all_true
43+
0xFD 0x86 0x01
44+
45+
# Including non-canonical LEB128 encodings
46+
# CHECK: i64x2.any_true
47+
# CHECK-NOT: i64.div_u
48+
0xFD 0x85 0x81 0x80 0x80 0x80 0x80 0x00

utils/TableGen/WebAssemblyDisassemblerEmitter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
namespace llvm {
2121

22+
static constexpr int WebAssemblyInstructionTableSize = 256;
23+
2224
void emitWebAssemblyDisassemblerTables(
2325
raw_ostream &OS,
2426
const ArrayRef<const CodeGenInstruction *> &NumberedInstructions) {
@@ -59,6 +61,8 @@ void emitWebAssemblyDisassemblerTables(
5961
OS << "#include \"MCTargetDesc/WebAssemblyMCTargetDesc.h\"\n";
6062
OS << "\n";
6163
OS << "namespace llvm {\n\n";
64+
OS << "static constexpr int WebAssemblyInstructionTableSize = ";
65+
OS << WebAssemblyInstructionTableSize << ";\n\n";
6266
OS << "enum EntryType : uint8_t { ";
6367
OS << "ET_Unused, ET_Prefix, ET_Instruction };\n\n";
6468
OS << "struct WebAssemblyInstruction {\n";
@@ -74,7 +78,7 @@ void emitWebAssemblyDisassemblerTables(
7478
continue;
7579
OS << "WebAssemblyInstruction InstructionTable" << PrefixPair.first;
7680
OS << "[] = {\n";
77-
for (unsigned I = 0; I <= 0xFF; I++) {
81+
for (unsigned I = 0; I < WebAssemblyInstructionTableSize; I++) {
7882
auto InstIt = PrefixPair.second.find(I);
7983
if (InstIt != PrefixPair.second.end()) {
8084
// Regular instruction.

0 commit comments

Comments
 (0)