Skip to content

Commit da419bd

Browse files
committed
[WebAssembly] Add support for the event section
Summary: This adds support for the 'event section' specified in the exception handling proposal. (This was named 'exception section' first, but later renamed to 'event section' to take possibilities of other kinds of events into consideration. But currently we only store exception info in this section.) The event section is added between the global section and the export section. This is for ease of validation per request of the V8 team. This patch: - Creates the event symbol type, which is a weak symbol - Makes 'throw' instruction take the event symbol '__cpp_exception' - Adds relocation support for events - Adds WasmObjectWriter / WasmObjectFile (Reader) support - Adds obj2yaml / yaml2obj support - Adds '.eventtype' printing support Reviewers: dschuff, sbc100, aardappel Subscribers: jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D54096 llvm-svn: 346825
1 parent 6a3c279 commit da419bd

34 files changed

+708
-116
lines changed

llvm/include/llvm/BinaryFormat/Wasm.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ struct WasmGlobal {
7575
StringRef SymbolName; // from the "linking" section
7676
};
7777

78+
struct WasmEventType {
79+
// Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible.
80+
uint32_t Attribute;
81+
uint32_t SigIndex;
82+
};
83+
84+
struct WasmEvent {
85+
uint32_t Index;
86+
WasmEventType Type;
87+
StringRef SymbolName; // from the "linking" section
88+
};
89+
7890
struct WasmImport {
7991
StringRef Module;
8092
StringRef Field;
@@ -84,6 +96,7 @@ struct WasmImport {
8496
WasmGlobalType Global;
8597
WasmTable Table;
8698
WasmLimits Memory;
99+
WasmEventType Event;
87100
};
88101
};
89102

@@ -178,7 +191,8 @@ enum : unsigned {
178191
WASM_SEC_START = 8, // Start function declaration
179192
WASM_SEC_ELEM = 9, // Elements section
180193
WASM_SEC_CODE = 10, // Function bodies (code)
181-
WASM_SEC_DATA = 11 // Data segments
194+
WASM_SEC_DATA = 11, // Data segments
195+
WASM_SEC_EVENT = 12 // Event declarations
182196
};
183197

184198
// Type immediate encodings used in various contexts.
@@ -200,6 +214,7 @@ enum : unsigned {
200214
WASM_EXTERNAL_TABLE = 0x1,
201215
WASM_EXTERNAL_MEMORY = 0x2,
202216
WASM_EXTERNAL_GLOBAL = 0x3,
217+
WASM_EXTERNAL_EVENT = 0x4,
203218
};
204219

205220
// Opcodes used in initializer expressions.
@@ -243,6 +258,12 @@ enum WasmSymbolType : unsigned {
243258
WASM_SYMBOL_TYPE_DATA = 0x1,
244259
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
245260
WASM_SYMBOL_TYPE_SECTION = 0x3,
261+
WASM_SYMBOL_TYPE_EVENT = 0x4,
262+
};
263+
264+
// Kinds of event attributes.
265+
enum WasmEventAttribute : unsigned {
266+
WASM_EVENT_ATTRIBUTE_EXCEPTION = 0x0,
246267
};
247268

248269
const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;

llvm/include/llvm/BinaryFormat/WasmRelocs.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#ifndef WASM_RELOC
32
#error "WASM_RELOC must be defined"
43
#endif
@@ -13,3 +12,4 @@ WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
1312
WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB, 7)
1413
WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32, 8)
1514
WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32, 9)
15+
WASM_RELOC(R_WEBASSEMBLY_EVENT_INDEX_LEB, 10)

llvm/include/llvm/CodeGen/WasmEHFuncInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
namespace llvm {
2323

24+
enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };
25+
2426
using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
2527

2628
struct WasmEHFuncInfo {

llvm/include/llvm/MC/MCExpr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ class MCSymbolRefExpr : public MCExpr {
288288
VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
289289
VK_WebAssembly_GLOBAL, // Global object index
290290
VK_WebAssembly_TYPEINDEX,// Type table index
291+
VK_WebAssembly_EVENT, // Event index
291292

292293
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
293294
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi

llvm/include/llvm/MC/MCSymbolWasm.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class MCSymbolWasm : public MCSymbol {
2121
bool IsComdat = false;
2222
std::string ModuleName;
2323
wasm::WasmSignature *Signature = nullptr;
24-
wasm::WasmGlobalType GlobalType;
25-
bool GlobalTypeSet = false;
24+
Optional<wasm::WasmGlobalType> GlobalType;
25+
Optional<wasm::WasmEventType> EventType;
2626

2727
/// An expression describing how to calculate the size of a symbol. If a
2828
/// symbol has no size this field will be NULL.
@@ -42,6 +42,7 @@ class MCSymbolWasm : public MCSymbol {
4242
bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
4343
bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
4444
bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
45+
bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
4546
wasm::WasmSymbolType getType() const { return Type; }
4647
void setType(wasm::WasmSymbolType type) { Type = type; }
4748

@@ -61,14 +62,16 @@ class MCSymbolWasm : public MCSymbol {
6162
void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
6263

6364
const wasm::WasmGlobalType &getGlobalType() const {
64-
assert(GlobalTypeSet);
65-
return GlobalType;
65+
assert(GlobalType.hasValue());
66+
return GlobalType.getValue();
6667
}
68+
void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
6769

68-
void setGlobalType(wasm::WasmGlobalType GT) {
69-
GlobalTypeSet = true;
70-
GlobalType = GT;
70+
const wasm::WasmEventType &getEventType() const {
71+
assert(EventType.hasValue());
72+
return EventType.getValue();
7173
}
74+
void setEventType(wasm::WasmEventType ET) { EventType = ET; }
7275
};
7376

7477
} // end namespace llvm

llvm/include/llvm/Object/RelocVisitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ class RelocVisitor {
333333
case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
334334
case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
335335
case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
336+
case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
336337
// For wasm section, its offset at 0 -- ignoring Value
337338
return 0;
338339
}

llvm/include/llvm/Object/Wasm.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,15 @@ class WasmSymbol {
3838
public:
3939
WasmSymbol(const wasm::WasmSymbolInfo &Info,
4040
const wasm::WasmSignature *FunctionType,
41-
const wasm::WasmGlobalType *GlobalType)
42-
: Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {}
41+
const wasm::WasmGlobalType *GlobalType,
42+
const wasm::WasmEventType *EventType)
43+
: Info(Info), FunctionType(FunctionType), GlobalType(GlobalType),
44+
EventType(EventType) {}
4345

4446
const wasm::WasmSymbolInfo &Info;
4547
const wasm::WasmSignature *FunctionType;
4648
const wasm::WasmGlobalType *GlobalType;
49+
const wasm::WasmEventType *EventType;
4750

4851
bool isTypeFunction() const {
4952
return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
@@ -59,6 +62,8 @@ class WasmSymbol {
5962
return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
6063
}
6164

65+
bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
66+
6267
bool isDefined() const { return !isUndefined(); }
6368

6469
bool isUndefined() const {
@@ -130,6 +135,7 @@ class WasmObjectFile : public ObjectFile {
130135
ArrayRef<wasm::WasmTable> tables() const { return Tables; }
131136
ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
132137
ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
138+
ArrayRef<wasm::WasmEvent> events() const { return Events; }
133139
ArrayRef<wasm::WasmExport> exports() const { return Exports; }
134140
ArrayRef<WasmSymbol> syms() const { return Symbols; }
135141
const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
@@ -141,6 +147,7 @@ class WasmObjectFile : public ObjectFile {
141147
uint32_t startFunction() const { return StartFunction; }
142148
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
143149
uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
150+
uint32_t getNumImportedEvents() const { return NumImportedEvents; }
144151

145152
void moveSymbolNext(DataRefImpl &Symb) const override;
146153

@@ -205,12 +212,16 @@ class WasmObjectFile : public ObjectFile {
205212
bool isDefinedFunctionIndex(uint32_t Index) const;
206213
bool isValidGlobalIndex(uint32_t Index) const;
207214
bool isDefinedGlobalIndex(uint32_t Index) const;
215+
bool isValidEventIndex(uint32_t Index) const;
216+
bool isDefinedEventIndex(uint32_t Index) const;
208217
bool isValidFunctionSymbol(uint32_t Index) const;
209218
bool isValidGlobalSymbol(uint32_t Index) const;
219+
bool isValidEventSymbol(uint32_t Index) const;
210220
bool isValidDataSymbol(uint32_t Index) const;
211221
bool isValidSectionSymbol(uint32_t Index) const;
212222
wasm::WasmFunction &getDefinedFunction(uint32_t Index);
213223
wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
224+
wasm::WasmEvent &getDefinedEvent(uint32_t Index);
214225

215226
const WasmSection &getWasmSection(DataRefImpl Ref) const;
216227
const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
@@ -226,6 +237,7 @@ class WasmObjectFile : public ObjectFile {
226237
Error parseTableSection(ReadContext &Ctx);
227238
Error parseMemorySection(ReadContext &Ctx);
228239
Error parseGlobalSection(ReadContext &Ctx);
240+
Error parseEventSection(ReadContext &Ctx);
229241
Error parseExportSection(ReadContext &Ctx);
230242
Error parseStartSection(ReadContext &Ctx);
231243
Error parseElemSection(ReadContext &Ctx);
@@ -246,6 +258,7 @@ class WasmObjectFile : public ObjectFile {
246258
std::vector<wasm::WasmTable> Tables;
247259
std::vector<wasm::WasmLimits> Memories;
248260
std::vector<wasm::WasmGlobal> Globals;
261+
std::vector<wasm::WasmEvent> Events;
249262
std::vector<wasm::WasmImport> Imports;
250263
std::vector<wasm::WasmExport> Exports;
251264
std::vector<wasm::WasmElemSegment> ElemSegments;
@@ -258,9 +271,11 @@ class WasmObjectFile : public ObjectFile {
258271
wasm::WasmLinkingData LinkingData;
259272
uint32_t NumImportedGlobals = 0;
260273
uint32_t NumImportedFunctions = 0;
274+
uint32_t NumImportedEvents = 0;
261275
uint32_t CodeSection = 0;
262276
uint32_t DataSection = 0;
263277
uint32_t GlobalSection = 0;
278+
uint32_t EventSection = 0;
264279
};
265280

266281
} // end namespace object

llvm/include/llvm/ObjectYAML/WasmYAML.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ struct Global {
7474
wasm::WasmInitExpr InitExpr;
7575
};
7676

77+
struct Event {
78+
uint32_t Index;
79+
uint32_t Attribute;
80+
uint32_t SigIndex;
81+
};
82+
7783
struct Import {
7884
StringRef Module;
7985
StringRef Field;
@@ -83,6 +89,7 @@ struct Import {
8389
Global GlobalImport;
8490
Table TableImport;
8591
Limits Memory;
92+
Event EventImport;
8693
};
8794
};
8895

@@ -262,6 +269,16 @@ struct GlobalSection : Section {
262269
std::vector<Global> Globals;
263270
};
264271

272+
struct EventSection : Section {
273+
EventSection() : Section(wasm::WASM_SEC_EVENT) {}
274+
275+
static bool classof(const Section *S) {
276+
return S->Type == wasm::WASM_SEC_EVENT;
277+
}
278+
279+
std::vector<Event> Events;
280+
};
281+
265282
struct ExportSection : Section {
266283
ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
267284

@@ -339,6 +356,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
339356
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
340357
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
341358
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
359+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Event)
342360

343361
namespace llvm {
344362
namespace yaml {
@@ -471,6 +489,10 @@ template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
471489
static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
472490
};
473491

492+
template <> struct MappingTraits<WasmYAML::Event> {
493+
static void mapping(IO &IO, WasmYAML::Event &Event);
494+
};
495+
474496
} // end namespace yaml
475497
} // end namespace llvm
476498

llvm/lib/BinaryFormat/Wasm.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ std::string llvm::wasm::toString(wasm::WasmSymbolType type) {
1919
return "WASM_SYMBOL_TYPE_DATA";
2020
case wasm::WASM_SYMBOL_TYPE_SECTION:
2121
return "WASM_SYMBOL_TYPE_SECTION";
22+
case wasm::WASM_SYMBOL_TYPE_EVENT:
23+
return "WASM_SYMBOL_TYPE_EVENT";
2224
}
2325
llvm_unreachable("unknown symbol type");
2426
}

llvm/lib/CodeGen/AsmPrinter/WasmException.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,25 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "WasmException.h"
16+
#include "llvm/IR/Mangler.h"
17+
#include "llvm/MC/MCContext.h"
1618
#include "llvm/MC/MCStreamer.h"
1719
using namespace llvm;
1820

21+
void WasmException::endModule() {
22+
// This is the symbol used in 'throw' and 'if_except' instruction to denote
23+
// this is a C++ exception. This symbol has to be emitted somewhere once in
24+
// the module. Check if the symbol has already been created, i.e., we have at
25+
// least one 'throw' or 'if_except' instruction in the module, and emit the
26+
// symbol only if so.
27+
SmallString<60> NameStr;
28+
Mangler::getNameWithPrefix(NameStr, "__cpp_exception", Asm->getDataLayout());
29+
if (Asm->OutContext.lookupSymbol(NameStr)) {
30+
MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol("__cpp_exception");
31+
Asm->OutStreamer->EmitLabel(ExceptionSym);
32+
}
33+
}
34+
1935
void WasmException::markFunctionEnd() {
2036
// Get rid of any dead landing pads.
2137
if (!Asm->MF->getLandingPads().empty()) {

llvm/lib/CodeGen/AsmPrinter/WasmException.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {
2424
public:
2525
WasmException(AsmPrinter *A) : EHStreamer(A) {}
2626

27-
void endModule() override {}
27+
void endModule() override;
2828
void beginFunction(const MachineFunction *MF) override {}
2929
virtual void markFunctionEnd() override;
3030
void endFunction(const MachineFunction *MF) override;

llvm/lib/MC/MCExpr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
306306
case VK_WebAssembly_FUNCTION: return "FUNCTION";
307307
case VK_WebAssembly_GLOBAL: return "GLOBAL";
308308
case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
309+
case VK_WebAssembly_EVENT: return "EVENT";
309310
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
310311
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
311312
case VK_AMDGPU_REL32_LO: return "rel32@lo";
@@ -421,6 +422,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
421422
.Case("function", VK_WebAssembly_FUNCTION)
422423
.Case("global", VK_WebAssembly_GLOBAL)
423424
.Case("typeindex", VK_WebAssembly_TYPEINDEX)
425+
.Case("event", VK_WebAssembly_EVENT)
424426
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
425427
.Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
426428
.Case("rel32@lo", VK_AMDGPU_REL32_LO)

0 commit comments

Comments
 (0)