Skip to content

Commit 502949d

Browse files
committed
Implement decoding of data segments
- Account for in-line data segments - Allocate WasmDataSegments one time only - Use LEB128 for segment size - Switch to char16 decode errors
1 parent 0950f53 commit 502949d

9 files changed

Lines changed: 140 additions & 9 deletions

lib/WasmReader/Chakra.WasmReader.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
<ClCompile Include="$(MSBuildThisFileDirectory)SExprParser.cpp" />
3838
<ClCompile Include="ModuleInfo.cpp" />
3939
<ClCompile Include="WasmBytecodeGenerator.cpp" />
40+
<ClCompile Include="WasmDataSegment.cpp" />
4041
<ClCompile Include="WasmFunctionInfo.cpp" />
4142
<ClCompile Include="WasmReaderPch.cpp">
4243
<PrecompiledHeader>Create</PrecompiledHeader>
@@ -53,6 +54,7 @@
5354
<ClInclude Include="SExprParser.h" />
5455
<ClInclude Include="SExprScanner.h" />
5556
<ClInclude Include="WasmBytecodeGenerator.h" />
57+
<ClInclude Include="WasmDataSegment.h" />
5658
<ClInclude Include="WasmFunctionInfo.h" />
5759
<ClInclude Include="WasmKeywordSwitch.h" />
5860
<ClInclude Include="WasmReader.h" />

lib/WasmReader/Chakra.WasmReader.vcxproj.filters

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<ClInclude Include="WasmSignature.h" />
2020
<ClInclude Include="WasmSections.h" />
2121
<ClInclude Include="WasmSection.h" />
22+
<ClInclude Include="WasmDataSegment.h" />
2223
</ItemGroup>
2324
<ItemGroup>
2425
<ClCompile Include="$(MSBuildThisFileDirectory)SExprParser.cpp" />
@@ -31,8 +32,10 @@
3132
<ClCompile Include="ModuleInfo.cpp" />
3233
<ClCompile Include="WasmSignature.cpp" />
3334
<ClCompile Include="WasmSection.cpp" />
35+
<ClCompile Include="WasmDataSegment.cpp" />
3436
</ItemGroup>
3537
<ItemGroup>
3638
<None Include="SExprScan.js" />
3739
</ItemGroup>
38-
</Project>
40+
</Project>
41+

lib/WasmReader/ModuleInfo.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ ModuleInfo::SetFunctionImport(uint32 i, uint32 sigId, wchar_t* modName, uint32 m
192192
m_imports[i].fnName = fnName;
193193
}
194194

195-
Wasm::WasmImport* ModuleInfo::GetFunctionImport(uint32 i) const
195+
Wasm::WasmImport*
196+
ModuleInfo::GetFunctionImport(uint32 i) const
196197
{
197198
if (i >= m_importCount)
198199
{
@@ -201,6 +202,35 @@ Wasm::WasmImport* ModuleInfo::GetFunctionImport(uint32 i) const
201202
return &m_imports[i];
202203
}
203204

205+
void
206+
ModuleInfo::AllocateDataSegs(uint32 count)
207+
{
208+
Assert(count != 0);
209+
m_datasegCount = count;
210+
m_datasegs = AnewArray(m_alloc, WasmDataSegment*, count);
211+
}
212+
213+
bool
214+
ModuleInfo::AddDataSeg(WasmDataSegment* seg, uint32 index)
215+
{
216+
if (index >= m_datasegCount)
217+
{
218+
return false;
219+
}
220+
m_datasegs[index] = seg;
221+
return true;
222+
}
223+
224+
WasmDataSegment*
225+
ModuleInfo::GetDataSeg(uint32 index) const
226+
{
227+
if (index >= m_datasegCount)
228+
{
229+
return nullptr;
230+
}
231+
return m_datasegs[index];
232+
}
233+
204234
} // namespace Wasm
205235

206236
#endif // ENABLE_WASM

lib/WasmReader/ModuleInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class ModuleInfo
4343
void AllocateFunctions(uint32 count);
4444
bool SetFunSig(WasmFunctionInfo* funsig, uint32 index);
4545
WasmFunctionInfo * GetFunSig(uint index) const;
46+
4647
void AllocateFunctionExports(uint32 entries);
4748
uint GetExportCount() const { return m_exportCount; }
4849
void SetFunctionExport(uint32 iExport, uint32 funcIndex, char16* exportName, uint32 nameLength);
@@ -53,6 +54,10 @@ class ModuleInfo
5354
void SetFunctionImport(uint32 i, uint32 sigId, wchar_t* modName, uint32 modNameLen, wchar_t* fnName, uint32 fnNameLen);
5455
WasmImport* GetFunctionImport(uint32 i) const;
5556

57+
void AllocateDataSegs(uint32 count);
58+
bool AddDataSeg(WasmDataSegment* seg, uint32 index);
59+
WasmDataSegment * GetDataSeg(uint32 index) const;
60+
5661
private:
5762
typedef JsUtil::GrowingArray<WasmSignature*, ArenaAllocator> WasmSignatureArray;
5863

@@ -61,11 +66,13 @@ class ModuleInfo
6166
WasmFunctionInfo** m_funsigs;
6267
WasmExport* m_exports;
6368
WasmImport* m_imports;
69+
WasmDataSegment** m_datasegs;
6470

6571
uint m_funcCount;
6672
uint m_indirectFuncCount;
6773
uint m_exportCount;
6874
uint32 m_importCount;
75+
uint32 m_datasegCount;
6976

7077
ArenaAllocator * m_alloc;
7178
};

lib/WasmReader/WasmBinaryReader.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,18 @@ WasmBinaryReader::ProcessSection(SectionCode sectionId, bool isEntry /*= true*/)
166166
break; // This section is not used by bytecode generator, stay in decoder
167167
}
168168
case bSectDataSegments:
169-
// TODO: Populate Data entry info
170-
ReadConst<UINT32>(); // dest addr in module memory
171-
ReadConst<UINT32>(); // source offset (?)
172-
ReadConst<UINT32>(); // size
173-
ReadConst<UINT8>(); // init
174-
m_moduleState.count++;
169+
m_moduleState.size = LEB128(length);
170+
if (m_moduleState.size == 0)
171+
{
172+
// TODO: Probably can factor this out and validate all count fields.
173+
ThrowDecodingError(_u("Illegal data segment entry count"));
174+
}
175+
m_moduleInfo->AllocateDataSegs(m_moduleState.size);
176+
for (m_moduleState.count = 0; m_moduleState.count < m_moduleState.size; m_moduleState.count++)
177+
{
178+
TRACE_WASM_DECODER(L"Data Segment #%u", m_moduleState.count);
179+
DataSegment();
180+
}
175181
break; // This section is not used by bytecode generator, stay in decoder
176182

177183
case bSectFunctionSignatures:
@@ -641,6 +647,18 @@ WasmBinaryReader::FunctionBodyHeader()
641647
}
642648
}
643649

650+
void
651+
WasmBinaryReader::DataSegment()
652+
{
653+
UINT len = 0;
654+
UINT32 offset = LEB128(len);
655+
UINT32 dataByteLen = LEB128(len);
656+
WasmDataSegment *dseg = Anew(&m_alloc, WasmDataSegment, &m_alloc, offset, dataByteLen, m_pc);
657+
CheckBytesLeft(dataByteLen);
658+
m_pc += dataByteLen;
659+
m_moduleInfo->AddDataSeg(dseg, m_moduleState.count);
660+
}
661+
644662
char16* WasmBinaryReader::ReadInlineName(uint32& length, uint32& nameLength)
645663
{
646664
nameLength = LEB128(length);
@@ -671,7 +689,7 @@ WasmBinaryReader::ImportEntry()
671689

672690
if (sigId >= m_moduleInfo->GetSignatureCount())
673691
{
674-
ThrowDecodingError(L"Function signature is out of bound");
692+
ThrowDecodingError(_u("Function signature is out of bound"));
675693
}
676694

677695
wchar_t* modName = ReadInlineName(len, modNameLen);

lib/WasmReader/WasmBinaryReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace Wasm
5353
#include "WasmBinaryOpcodes.h"
5454
bSigLimit
5555
};
56+
5657
} // namespace WasmTypes
5758

5859
// binary opcodes
@@ -120,6 +121,7 @@ namespace Wasm
120121
void ReadExportTable();
121122
void ReadIndirectFunctionTable();
122123
void FunctionBodyHeader();
124+
void DataSegment();
123125

124126
char16* ReadInlineName(uint32& length, uint32& nameLength);
125127
void ImportEntry();

lib/WasmReader/WasmDataSegment.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
#include "WasmReaderPch.h"
7+
8+
#ifdef ENABLE_WASM
9+
10+
namespace Wasm
11+
{
12+
13+
WasmDataSegment::WasmDataSegment(ArenaAllocator * alloc, uint32 _dest_addr, uint32 _source_size, byte* _data) :
14+
m_alloc(alloc),
15+
dest_addr(_dest_addr),
16+
source_size(_source_size),
17+
data(_data)
18+
{
19+
}
20+
21+
uint32
22+
WasmDataSegment::getDestAddr() const
23+
{
24+
return dest_addr;
25+
}
26+
27+
uint32
28+
WasmDataSegment::getSourceSize() const
29+
{
30+
return source_size;
31+
}
32+
33+
byte*
34+
WasmDataSegment::getData() const
35+
{
36+
return data;
37+
}
38+
39+
} // namespace Wasm
40+
41+
#endif // ENABLE_WASM

lib/WasmReader/WasmDataSegment.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
#pragma once
7+
8+
namespace Wasm
9+
{
10+
11+
class WasmDataSegment
12+
{
13+
public:
14+
WasmDataSegment(ArenaAllocator * alloc, uint32 _dest_addr, uint32 _source_size, byte* _data);
15+
uint32 getDestAddr() const;
16+
uint32 getSourceSize() const;
17+
byte* getData() const;
18+
19+
private:
20+
ArenaAllocator * m_alloc;
21+
22+
uint32 dest_addr; // offset in linear memory at which to store data
23+
uint32 source_size;
24+
byte* data;
25+
};
26+
27+
} // namespace Wasm

lib/WasmReader/WasmReader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace Wasm
3030
}
3131

3232
#include "WasmSignature.h"
33+
#include "WasmDataSegment.h"
3334
#include "ModuleInfo.h"
3435
#include "WasmFunctionInfo.h"
3536

0 commit comments

Comments
 (0)