Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit edc3af3

Browse files
author
Dan Gohman
committed
[WebAssembly] Import the linear memory and function table.
Instead of having .o files contain linear-memory and function table definitions, use imports. This is more consistent with the stack pointer being imported, and it's consistent with the linker being the one to decide whether linear memory and function table are imported or defined in the linked output. This implements tool-conventions #23. Differential Revision: https://reviews.llvm.org/D40875 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319989 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 72671d6 commit edc3af3

File tree

9 files changed

+81
-72
lines changed

9 files changed

+81
-72
lines changed

lib/MC/WasmObjectWriter.cpp

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,9 @@ class WasmObjectWriter : public MCObjectWriter {
270270
}
271271

272272
void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
273-
void writeImportSection(ArrayRef<WasmImport> Imports);
273+
void writeImportSection(ArrayRef<WasmImport> Imports, uint32_t DataSize,
274+
uint32_t NumElements);
274275
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
275-
void writeTableSection(uint32_t NumElements);
276-
void writeMemorySection(uint32_t DataSize);
277276
void writeGlobalSection();
278277
void writeExportSection(ArrayRef<WasmExport> Exports);
279278
void writeElemSection(ArrayRef<uint32_t> TableElems);
@@ -661,10 +660,14 @@ void WasmObjectWriter::writeTypeSection(
661660
endSection(Section);
662661
}
663662

664-
void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
663+
void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports,
664+
uint32_t DataSize,
665+
uint32_t NumElements) {
665666
if (Imports.empty())
666667
return;
667668

669+
uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;
670+
668671
SectionBookkeeping Section;
669672
startSection(Section, wasm::WASM_SEC_IMPORT);
670673

@@ -683,6 +686,15 @@ void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
683686
encodeSLEB128(int32_t(Import.Type), getStream());
684687
encodeULEB128(int32_t(Import.IsMutable), getStream());
685688
break;
689+
case wasm::WASM_EXTERNAL_MEMORY:
690+
encodeULEB128(0, getStream()); // flags
691+
encodeULEB128(NumPages, getStream()); // initial
692+
break;
693+
case wasm::WASM_EXTERNAL_TABLE:
694+
encodeSLEB128(int32_t(Import.Type), getStream());
695+
encodeULEB128(0, getStream()); // flags
696+
encodeULEB128(NumElements, getStream()); // initial
697+
break;
686698
default:
687699
llvm_unreachable("unsupported import kind");
688700
}
@@ -705,39 +717,6 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
705717
endSection(Section);
706718
}
707719

708-
void WasmObjectWriter::writeTableSection(uint32_t NumElements) {
709-
// For now, always emit the table section, since indirect calls are not
710-
// valid without it. In the future, we could perhaps be more clever and omit
711-
// it if there are no indirect calls.
712-
713-
SectionBookkeeping Section;
714-
startSection(Section, wasm::WASM_SEC_TABLE);
715-
716-
encodeULEB128(1, getStream()); // The number of tables.
717-
// Fixed to 1 for now.
718-
encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream()); // Type of table
719-
encodeULEB128(0, getStream()); // flags
720-
encodeULEB128(NumElements, getStream()); // initial
721-
722-
endSection(Section);
723-
}
724-
725-
void WasmObjectWriter::writeMemorySection(uint32_t DataSize) {
726-
// For now, always emit the memory section, since loads and stores are not
727-
// valid without it. In the future, we could perhaps be more clever and omit
728-
// it if there are no loads or stores.
729-
SectionBookkeeping Section;
730-
uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;
731-
732-
startSection(Section, wasm::WASM_SEC_MEMORY);
733-
encodeULEB128(1, getStream()); // number of memory spaces
734-
735-
encodeULEB128(0, getStream()); // flags
736-
encodeULEB128(NumPages, getStream()); // initial
737-
738-
endSection(Section);
739-
}
740-
741720
void WasmObjectWriter::writeGlobalSection() {
742721
if (Globals.empty())
743722
return;
@@ -1085,6 +1064,29 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
10851064
}
10861065
}
10871066

1067+
// For now, always emit the memory import, since loads and stores are not
1068+
// valid without it. In the future, we could perhaps be more clever and omit
1069+
// it if there are no loads or stores.
1070+
MCSymbolWasm *MemorySym =
1071+
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory"));
1072+
WasmImport MemImport;
1073+
MemImport.ModuleName = MemorySym->getModuleName();
1074+
MemImport.FieldName = MemorySym->getName();
1075+
MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
1076+
Imports.push_back(MemImport);
1077+
1078+
// For now, always emit the table section, since indirect calls are not
1079+
// valid without it. In the future, we could perhaps be more clever and omit
1080+
// it if there are no indirect calls.
1081+
MCSymbolWasm *TableSym =
1082+
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table"));
1083+
WasmImport TableImport;
1084+
TableImport.ModuleName = TableSym->getModuleName();
1085+
TableImport.FieldName = TableSym->getName();
1086+
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
1087+
TableImport.Type = wasm::WASM_TYPE_ANYFUNC;
1088+
Imports.push_back(TableImport);
1089+
10881090
// Populate FunctionTypeIndices and Imports.
10891091
for (const MCSymbol &S : Asm.symbols()) {
10901092
const auto &WS = static_cast<const MCSymbolWasm &>(S);
@@ -1295,10 +1297,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
12951297
writeHeader(Asm);
12961298

12971299
writeTypeSection(FunctionTypes);
1298-
writeImportSection(Imports);
1300+
writeImportSection(Imports, DataSize, TableElems.size());
12991301
writeFunctionSection(Functions);
1300-
writeTableSection(TableElems.size());
1301-
writeMemorySection(DataSize);
1302+
// Skip the "table" section; we import the table instead.
1303+
// Skip the "memory" section; we import the memory instead.
13021304
writeGlobalSection();
13031305
writeExportSection(Exports);
13041306
// TODO: Start Section

test/MC/WebAssembly/external-func-address.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ declare void @f1(i32) #1
1717
; CHECK-NEXT: - I32
1818
; CHECK: - Type: IMPORT
1919
; CHECK-NEXT: Imports:
20-
; CHECK-NEXT: - Module: env
20+
; CHECK: - Module: env
21+
; CHECK-NEXT: Field: __linear_memory
22+
; CHECK: - Module: env
23+
; CHECK-NEXT: Field: __indirect_function_table
24+
; CHECK: - Module: env
2125
; CHECK-NEXT: Field: f1
2226
; CHECK-NEXT: Kind: FUNCTION
2327
; CHECK-NEXT: SigIndex: 0

test/MC/WebAssembly/func-address.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ entry:
2828
; CHECK: }
2929

3030
; CHECK: Relocations [
31-
; CHECK: Section (8) CODE {
31+
; CHECK: Section (6) CODE {
3232
; CHECK: Relocation {
3333
; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
3434
; CHECK: Offset: 0x4

test/MC/WebAssembly/init-fini-array.ll

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,25 @@ declare void @func2()
1414
; CHECK: - Type: IMPORT
1515
; CHECK-NEXT: Imports:
1616
; CHECK-NEXT: - Module: env
17+
; CHECK-NEXT: Field: __linear_memory
18+
; CHECK-NEXT: Kind: MEMORY
19+
; CHECK-NEXT: Memory:
20+
; CHECK-NEXT: Initial: 0x00000001
21+
; CHECK-NEXT: - Module: env
22+
; CHECK-NEXT: Field: __indirect_function_table
23+
; CHECK-NEXT: Kind: TABLE
24+
; CHECK-NEXT: Table:
25+
; CHECK-NEXT: ElemType: ANYFUNC
26+
; CHECK-NEXT: Limits:
27+
; CHECK-NEXT: Initial: 0x00000002
28+
; CHECK-NEXT: - Module: env
1729
; CHECK-NEXT: Field: func1
1830
; CHECK-NEXT: Kind: FUNCTION
1931
; CHECK-NEXT: SigIndex: 0
2032
; CHECK-NEXT: - Module: env
2133
; CHECK-NEXT: Field: func2
2234
; CHECK-NEXT: Kind: FUNCTION
2335
; CHECK-NEXT: SigIndex: 0
24-
; CHECK-NEXT: - Type: TABLE
25-
; CHECK-NEXT: Tables:
26-
; CHECK-NEXT: - ElemType: ANYFUNC
27-
; CHECK-NEXT: Limits:
28-
; CHECK-NEXT: Initial: 0x00000002
29-
; CHECK-NEXT: - Type: MEMORY
30-
; CHECK-NEXT: Memories:
31-
; CHECK-NEXT: - Initial: 0x00000001
3236
; CHECK-NEXT: - Type: GLOBAL
3337
; CHECK-NEXT: Globals:
3438
; CHECK-NEXT: - Type: I32

test/MC/WebAssembly/reloc-code.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ entry:
2222

2323
; CHECK: Format: WASM
2424
; CHECK: Relocations [
25-
; CHECK-NEXT: Section (8) CODE {
25+
; CHECK-NEXT: Section (6) CODE {
2626
; CHECK-NEXT: Relocation {
2727
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
2828
; CHECK-NEXT: Offset: 0x9

test/MC/WebAssembly/reloc-data.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
; CHECK: Format: WASM
1212
; CHECK: Relocations [
13-
; CHECK-NEXT: Section (6) DATA {
13+
; CHECK-NEXT: Section (4) DATA {
1414
; CHECK-NEXT: Relocation {
1515
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5)
1616
; CHECK-NEXT: Offset: 0x13

test/MC/WebAssembly/sections.ll

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,6 @@ entry:
2828
; CHECK: Type: FUNCTION (0x3)
2929
; CHECK: }
3030
; CHECK: Section {
31-
; CHECK: Type: TABLE (0x4)
32-
; CHECK: }
33-
; CHECK: Section {
34-
; CHECK: Type: MEMORY (0x5)
35-
; CHECK: Memories [
36-
; CHECK: Memory {
37-
; CHECK: InitialPages: 1
38-
; CHECK: }
39-
; CHECK: ]
40-
; CHECK: }
41-
; CHECK: Section {
4231
; CHECK: Type: GLOBAL (0x6)
4332
; CHECK: }
4433
; CHECK: Section {

test/MC/WebAssembly/weak-alias.ll

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,22 @@ entry:
2929
; CHECK-NEXT: - Index: 0
3030
; CHECK-NEXT: ReturnType: I32
3131
; CHECK-NEXT: ParamTypes:
32+
; CHECK-NEXT: - Type: IMPORT
33+
; CHECK-NEXT: Imports:
34+
; CHECK-NEXT: - Module: env
35+
; CHECK-NEXT: Field: __linear_memory
36+
; CHECK-NEXT: Kind: MEMORY
37+
; CHECK-NEXT: Memory:
38+
; CHECK-NEXT: Initial: 0x00000001
39+
; CHECK-NEXT: - Module: env
40+
; CHECK-NEXT: Field: __indirect_function_table
41+
; CHECK-NEXT: Kind: TABLE
42+
; CHECK-NEXT: Table:
43+
; CHECK-NEXT: ElemType: ANYFUNC
44+
; CHECK-NEXT: Limits:
45+
; CHECK-NEXT: Initial: 0x00000000
3246
; CHECK-NEXT: - Type: FUNCTION
3347
; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
34-
; CHECK-NEXT: - Type: TABLE
35-
; CHECK-NEXT: Tables:
36-
; CHECK-NEXT: - ElemType: ANYFUNC
37-
; CHECK-NEXT: Limits:
38-
; CHECK-NEXT: Initial: 0x00000000
39-
; CHECK-NEXT: - Type: MEMORY
40-
; CHECK-NEXT: Memories:
41-
; CHECK-NEXT: - Initial: 0x00000001
4248
; CHECK-NEXT: - Type: GLOBAL
4349
; CHECK-NEXT: Globals:
4450
; CHECK-NEXT: - Type: I32

test/MC/WebAssembly/weak.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ entry:
1212

1313
; CHECK: - Type: IMPORT
1414
; CHECK-NEXT: Imports:
15-
; CHECK-NEXT: - Module: env
15+
; CHECK: - Module: env
16+
; CHECK-NEXT: Field: __linear_memory
17+
; CHECK: - Module: env
18+
; CHECK-NEXT: Field: __indirect_function_table
19+
; CHECK: - Module: env
1620
; CHECK-NEXT: Field: weak_external_data
1721
; CHECK-NEXT: Kind: GLOBAL
1822
; CHECK-NEXT: GlobalType: I32

0 commit comments

Comments
 (0)