Skip to content

Commit c9e6892

Browse files
committed
Fix: handle decodeExpr correctly
1 parent c78fb7b commit c9e6892

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

source/binary/mod.d

+37-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import binary.types;
99
import std.algorithm : each;
1010
import std.bitmanip : read;
1111
import std.exception : enforce;
12-
import std.range : popFrontExactly;
12+
import std.range : front, popFront, popFrontExactly;
1313
import std.system : Endian;
1414
import std.typecons : Tuple, tuple;
1515

@@ -116,12 +116,19 @@ Limits decodeLimits(ref const(ubyte)[] input)
116116
}
117117

118118
///
119-
uint decodeExpr(ref const(ubyte)[] input)
119+
const(Instruction)[] decodeExpr(ref const(ubyte)[] input)
120120
{
121-
input.leb128!uint(); // i32.const
122-
auto offset = input.leb128!uint();
123-
input.leb128!uint(); // end
124-
return offset;
121+
typeof(return) insns = [];
122+
while (true)
123+
{
124+
if (0x0b == input.front)
125+
{
126+
input.popFront();
127+
return insns;
128+
}
129+
insns ~= input.decodeInstruction();
130+
}
131+
assert(false);
125132
}
126133

127134
///
@@ -219,6 +226,15 @@ Function decodeFunctionBody(ref const(ubyte)[] input, ref uint remaining)
219226
return body;
220227
}
221228

229+
///
230+
Instruction decodeInstruction(ref const(ubyte)[] input)
231+
{
232+
// FIXME: use @("nolint(dscanner.could_be_immutable_check)")
233+
// once it works someday...
234+
uint dummy;
235+
return decodeInstruction(input, dummy);
236+
}
237+
222238
///
223239
Instruction decodeInstruction(ref const(ubyte)[] input, ref uint remaining)
224240
{
@@ -586,14 +602,26 @@ unittest
586602
tuple(
587603
"source/fixtures/data.wat",
588604
[
589-
Data(memoryIndex: 0, offset: 0, bytes: cast(ubyte[]) "hello")
605+
Data(
606+
memoryIndex: 0,
607+
offset: [Instruction(I32Const(0))],
608+
bytes: cast(ubyte[]) "hello"
609+
)
590610
]
591611
),
592612
tuple(
593613
"source/fixtures/memory.wat",
594614
[
595-
Data(memoryIndex: 0, offset: 0, bytes: cast(ubyte[]) "hello"),
596-
Data(memoryIndex: 0, offset: 5, bytes: cast(ubyte[]) "world")
615+
Data(
616+
memoryIndex: 0,
617+
offset: [Instruction(I32Const(0))],
618+
bytes: cast(ubyte[]) "hello"
619+
),
620+
Data(
621+
memoryIndex: 0,
622+
offset: [Instruction(I32Const(5))],
623+
bytes: cast(ubyte[]) "world"
624+
)
597625
]
598626

599627
)

source/binary/types.d

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
module binary.types;
22

3+
import binary.instruction;
4+
35
import std.sumtype;
46

57
///
@@ -80,7 +82,7 @@ struct Data
8082
///
8183
uint memoryIndex;
8284
///
83-
uint offset;
85+
const(Instruction)[] offset;
8486
///
8587
const(ubyte)[] bytes;
8688
}

source/execution/store.d

+7-4
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,14 @@ struct Store
137137
);
138138
}
139139

140-
foreach (data; mod.dataSection)
140+
foreach (segment; mod.dataSection)
141141
{
142-
auto memory = memories[data.memoryIndex];
143-
size_t offset = data.offset;
144-
auto bytes = data.bytes;
142+
auto memory = memories[segment.memoryIndex];
143+
const offset = segment.offset[$-1].match!(
144+
(I32Const i32const) => size_t(i32const.value),
145+
_ => enforce(false, "unexpected instrcution for offset")
146+
);
147+
auto bytes = segment.bytes;
145148
enforce(
146149
offset + bytes.length <= memory.data.length,
147150
"data is too large to fit in memory"

0 commit comments

Comments
 (0)