Skip to content

Commit

Permalink
[WebAssembly] Import the linear memory and function table.
Browse files Browse the repository at this point in the history
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 llvm-mirror#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
  • Loading branch information
Dan Gohman committed Dec 6, 2017
1 parent 72671d6 commit edc3af3
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 72 deletions.
82 changes: 42 additions & 40 deletions lib/MC/WasmObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,9 @@ class WasmObjectWriter : public MCObjectWriter {
}

void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
void writeImportSection(ArrayRef<WasmImport> Imports);
void writeImportSection(ArrayRef<WasmImport> Imports, uint32_t DataSize,
uint32_t NumElements);
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
void writeTableSection(uint32_t NumElements);
void writeMemorySection(uint32_t DataSize);
void writeGlobalSection();
void writeExportSection(ArrayRef<WasmExport> Exports);
void writeElemSection(ArrayRef<uint32_t> TableElems);
Expand Down Expand Up @@ -661,10 +660,14 @@ void WasmObjectWriter::writeTypeSection(
endSection(Section);
}

void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports,
uint32_t DataSize,
uint32_t NumElements) {
if (Imports.empty())
return;

uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;

SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_IMPORT);

Expand All @@ -683,6 +686,15 @@ void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
encodeSLEB128(int32_t(Import.Type), getStream());
encodeULEB128(int32_t(Import.IsMutable), getStream());
break;
case wasm::WASM_EXTERNAL_MEMORY:
encodeULEB128(0, getStream()); // flags
encodeULEB128(NumPages, getStream()); // initial
break;
case wasm::WASM_EXTERNAL_TABLE:
encodeSLEB128(int32_t(Import.Type), getStream());
encodeULEB128(0, getStream()); // flags
encodeULEB128(NumElements, getStream()); // initial
break;
default:
llvm_unreachable("unsupported import kind");
}
Expand All @@ -705,39 +717,6 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
endSection(Section);
}

void WasmObjectWriter::writeTableSection(uint32_t NumElements) {
// For now, always emit the table section, since indirect calls are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no indirect calls.

SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_TABLE);

encodeULEB128(1, getStream()); // The number of tables.
// Fixed to 1 for now.
encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream()); // Type of table
encodeULEB128(0, getStream()); // flags
encodeULEB128(NumElements, getStream()); // initial

endSection(Section);
}

void WasmObjectWriter::writeMemorySection(uint32_t DataSize) {
// For now, always emit the memory section, since loads and stores are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no loads or stores.
SectionBookkeeping Section;
uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;

startSection(Section, wasm::WASM_SEC_MEMORY);
encodeULEB128(1, getStream()); // number of memory spaces

encodeULEB128(0, getStream()); // flags
encodeULEB128(NumPages, getStream()); // initial

endSection(Section);
}

void WasmObjectWriter::writeGlobalSection() {
if (Globals.empty())
return;
Expand Down Expand Up @@ -1085,6 +1064,29 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
}
}

// For now, always emit the memory import, since loads and stores are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no loads or stores.
MCSymbolWasm *MemorySym =
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory"));
WasmImport MemImport;
MemImport.ModuleName = MemorySym->getModuleName();
MemImport.FieldName = MemorySym->getName();
MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
Imports.push_back(MemImport);

// For now, always emit the table section, since indirect calls are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no indirect calls.
MCSymbolWasm *TableSym =
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table"));
WasmImport TableImport;
TableImport.ModuleName = TableSym->getModuleName();
TableImport.FieldName = TableSym->getName();
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
TableImport.Type = wasm::WASM_TYPE_ANYFUNC;
Imports.push_back(TableImport);

// Populate FunctionTypeIndices and Imports.
for (const MCSymbol &S : Asm.symbols()) {
const auto &WS = static_cast<const MCSymbolWasm &>(S);
Expand Down Expand Up @@ -1295,10 +1297,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
writeHeader(Asm);

writeTypeSection(FunctionTypes);
writeImportSection(Imports);
writeImportSection(Imports, DataSize, TableElems.size());
writeFunctionSection(Functions);
writeTableSection(TableElems.size());
writeMemorySection(DataSize);
// Skip the "table" section; we import the table instead.
// Skip the "memory" section; we import the memory instead.
writeGlobalSection();
writeExportSection(Exports);
// TODO: Start Section
Expand Down
6 changes: 5 additions & 1 deletion test/MC/WebAssembly/external-func-address.ll
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ declare void @f1(i32) #1
; CHECK-NEXT: - I32
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK: - Module: env
; CHECK-NEXT: Field: __linear_memory
; CHECK: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
; CHECK: - Module: env
; CHECK-NEXT: Field: f1
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
Expand Down
2 changes: 1 addition & 1 deletion test/MC/WebAssembly/func-address.ll
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ entry:
; CHECK: }

; CHECK: Relocations [
; CHECK: Section (8) CODE {
; CHECK: Section (6) CODE {
; CHECK: Relocation {
; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
; CHECK: Offset: 0x4
Expand Down
20 changes: 12 additions & 8 deletions test/MC/WebAssembly/init-fini-array.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@ declare void @func2()
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __linear_memory
; CHECK-NEXT: Kind: MEMORY
; CHECK-NEXT: Memory:
; CHECK-NEXT: Initial: 0x00000001
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
; CHECK-NEXT: Kind: TABLE
; CHECK-NEXT: Table:
; CHECK-NEXT: ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000002
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: func1
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: func2
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
; CHECK-NEXT: - ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000002
; CHECK-NEXT: - Type: MEMORY
; CHECK-NEXT: Memories:
; CHECK-NEXT: - Initial: 0x00000001
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
Expand Down
2 changes: 1 addition & 1 deletion test/MC/WebAssembly/reloc-code.ll
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ entry:

; CHECK: Format: WASM
; CHECK: Relocations [
; CHECK-NEXT: Section (8) CODE {
; CHECK-NEXT: Section (6) CODE {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
; CHECK-NEXT: Offset: 0x9
Expand Down
2 changes: 1 addition & 1 deletion test/MC/WebAssembly/reloc-data.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

; CHECK: Format: WASM
; CHECK: Relocations [
; CHECK-NEXT: Section (6) DATA {
; CHECK-NEXT: Section (4) DATA {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5)
; CHECK-NEXT: Offset: 0x13
Expand Down
11 changes: 0 additions & 11 deletions test/MC/WebAssembly/sections.ll
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ entry:
; CHECK: Type: FUNCTION (0x3)
; CHECK: }
; CHECK: Section {
; CHECK: Type: TABLE (0x4)
; CHECK: }
; CHECK: Section {
; CHECK: Type: MEMORY (0x5)
; CHECK: Memories [
; CHECK: Memory {
; CHECK: InitialPages: 1
; CHECK: }
; CHECK: ]
; CHECK: }
; CHECK: Section {
; CHECK: Type: GLOBAL (0x6)
; CHECK: }
; CHECK: Section {
Expand Down
22 changes: 14 additions & 8 deletions test/MC/WebAssembly/weak-alias.ll
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,22 @@ entry:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __linear_memory
; CHECK-NEXT: Kind: MEMORY
; CHECK-NEXT: Memory:
; CHECK-NEXT: Initial: 0x00000001
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
; CHECK-NEXT: Kind: TABLE
; CHECK-NEXT: Table:
; CHECK-NEXT: ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000000
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
; CHECK-NEXT: - ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Initial: 0x00000000
; CHECK-NEXT: - Type: MEMORY
; CHECK-NEXT: Memories:
; CHECK-NEXT: - Initial: 0x00000001
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
Expand Down
6 changes: 5 additions & 1 deletion test/MC/WebAssembly/weak.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ entry:

; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK: - Module: env
; CHECK-NEXT: Field: __linear_memory
; CHECK: - Module: env
; CHECK-NEXT: Field: __indirect_function_table
; CHECK: - Module: env
; CHECK-NEXT: Field: weak_external_data
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: GlobalType: I32
Expand Down

0 comments on commit edc3af3

Please sign in to comment.