Skip to content

Commit da419bd

Browse files
committedNov 14, 2018
[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)

‎llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 140 additions & 51 deletions
Large diffs are not rendered by default.

‎llvm/lib/Object/WasmObjectFile.cpp

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ Error WasmObjectFile::parseSection(WasmSection &Sec) {
295295
return parseMemorySection(Ctx);
296296
case wasm::WASM_SEC_GLOBAL:
297297
return parseGlobalSection(Ctx);
298+
case wasm::WASM_SEC_EVENT:
299+
return parseEventSection(Ctx);
298300
case wasm::WASM_SEC_EXPORT:
299301
return parseExportSection(Ctx);
300302
case wasm::WASM_SEC_START:
@@ -439,19 +441,24 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
439441

440442
std::vector<wasm::WasmImport *> ImportedGlobals;
441443
std::vector<wasm::WasmImport *> ImportedFunctions;
444+
std::vector<wasm::WasmImport *> ImportedEvents;
442445
ImportedGlobals.reserve(Imports.size());
443446
ImportedFunctions.reserve(Imports.size());
447+
ImportedEvents.reserve(Imports.size());
444448
for (auto &I : Imports) {
445449
if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
446450
ImportedFunctions.emplace_back(&I);
447451
else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
448452
ImportedGlobals.emplace_back(&I);
453+
else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
454+
ImportedEvents.emplace_back(&I);
449455
}
450456

451457
while (Count--) {
452458
wasm::WasmSymbolInfo Info;
453459
const wasm::WasmSignature *FunctionType = nullptr;
454460
const wasm::WasmGlobalType *GlobalType = nullptr;
461+
const wasm::WasmEventType *EventType = nullptr;
455462

456463
Info.Kind = readUint8(Ctx);
457464
Info.Flags = readVaruint32(Ctx);
@@ -532,6 +539,32 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
532539
break;
533540
}
534541

542+
case wasm::WASM_SYMBOL_TYPE_EVENT: {
543+
Info.ElementIndex = readVaruint32(Ctx);
544+
if (!isValidEventIndex(Info.ElementIndex) ||
545+
IsDefined != isDefinedEventIndex(Info.ElementIndex))
546+
return make_error<GenericBinaryError>("invalid event symbol index",
547+
object_error::parse_failed);
548+
if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
549+
wasm::WASM_SYMBOL_BINDING_WEAK)
550+
return make_error<GenericBinaryError>("undefined weak global symbol",
551+
object_error::parse_failed);
552+
if (IsDefined) {
553+
Info.Name = readString(Ctx);
554+
unsigned EventIndex = Info.ElementIndex - NumImportedEvents;
555+
wasm::WasmEvent &Event = Events[EventIndex];
556+
EventType = &Event.Type;
557+
if (Event.SymbolName.empty())
558+
Event.SymbolName = Info.Name;
559+
560+
} else {
561+
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
562+
EventType = &Import.Event;
563+
Info.Name = Import.Field;
564+
}
565+
break;
566+
}
567+
535568
default:
536569
return make_error<GenericBinaryError>("Invalid symbol type",
537570
object_error::parse_failed);
@@ -545,7 +578,7 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
545578
object_error::parse_failed);
546579
LinkingData.SymbolTable.emplace_back(Info);
547580
Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
548-
GlobalType);
581+
GlobalType, EventType);
549582
LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
550583
}
551584

@@ -635,6 +668,11 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
635668
return make_error<GenericBinaryError>("Bad relocation global index",
636669
object_error::parse_failed);
637670
break;
671+
case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
672+
if (!isValidEventSymbol(Reloc.Index))
673+
return make_error<GenericBinaryError>("Bad relocation event index",
674+
object_error::parse_failed);
675+
break;
638676
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
639677
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
640678
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
@@ -755,6 +793,11 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
755793
return make_error<GenericBinaryError>("Invalid table element type",
756794
object_error::parse_failed);
757795
break;
796+
case wasm::WASM_EXTERNAL_EVENT:
797+
NumImportedEvents++;
798+
Im.Event.Attribute = readVarint32(Ctx);
799+
Im.Event.SigIndex = readVarint32(Ctx);
800+
break;
758801
default:
759802
return make_error<GenericBinaryError>("Unexpected import kind",
760803
object_error::parse_failed);
@@ -831,6 +874,24 @@ Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
831874
return Error::success();
832875
}
833876

877+
Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
878+
EventSection = Sections.size();
879+
uint32_t Count = readVarint32(Ctx);
880+
Events.reserve(Count);
881+
while (Count--) {
882+
wasm::WasmEvent Event;
883+
Event.Index = NumImportedEvents + Events.size();
884+
Event.Type.Attribute = readVaruint32(Ctx);
885+
Event.Type.SigIndex = readVarint32(Ctx);
886+
Events.push_back(Event);
887+
}
888+
889+
if (Ctx.Ptr != Ctx.End)
890+
return make_error<GenericBinaryError>("Event section ended prematurely",
891+
object_error::parse_failed);
892+
return Error::success();
893+
}
894+
834895
Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
835896
uint32_t Count = readVaruint32(Ctx);
836897
Exports.reserve(Count);
@@ -850,6 +911,11 @@ Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
850911
return make_error<GenericBinaryError>("Invalid global export",
851912
object_error::parse_failed);
852913
break;
914+
case wasm::WASM_EXTERNAL_EVENT:
915+
if (!isValidEventIndex(Ex.Index))
916+
return make_error<GenericBinaryError>("Invalid event export",
917+
object_error::parse_failed);
918+
break;
853919
case wasm::WASM_EXTERNAL_MEMORY:
854920
case wasm::WASM_EXTERNAL_TABLE:
855921
break;
@@ -881,6 +947,14 @@ bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
881947
return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
882948
}
883949

950+
bool WasmObjectFile::isValidEventIndex(uint32_t Index) const {
951+
return Index < NumImportedEvents + Events.size();
952+
}
953+
954+
bool WasmObjectFile::isDefinedEventIndex(uint32_t Index) const {
955+
return Index >= NumImportedEvents && isValidEventIndex(Index);
956+
}
957+
884958
bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
885959
return Index < Symbols.size() && Symbols[Index].isTypeFunction();
886960
}
@@ -889,6 +963,10 @@ bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
889963
return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
890964
}
891965

966+
bool WasmObjectFile::isValidEventSymbol(uint32_t Index) const {
967+
return Index < Symbols.size() && Symbols[Index].isTypeEvent();
968+
}
969+
892970
bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
893971
return Index < Symbols.size() && Symbols[Index].isTypeData();
894972
}
@@ -907,6 +985,11 @@ wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
907985
return Globals[Index - NumImportedGlobals];
908986
}
909987

988+
wasm::WasmEvent &WasmObjectFile::getDefinedEvent(uint32_t Index) {
989+
assert(isDefinedEventIndex(Index));
990+
return Events[Index - NumImportedEvents];
991+
}
992+
910993
Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
911994
StartFunction = readVaruint32(Ctx);
912995
if (!isValidFunctionIndex(StartFunction))
@@ -1070,6 +1153,7 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
10701153
switch (Sym.Info.Kind) {
10711154
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
10721155
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
1156+
case wasm::WASM_SYMBOL_TYPE_EVENT:
10731157
return Sym.Info.ElementIndex;
10741158
case wasm::WASM_SYMBOL_TYPE_DATA: {
10751159
// The value of a data symbol is the segment offset, plus the symbol
@@ -1112,6 +1196,8 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
11121196
return SymbolRef::ST_Data;
11131197
case wasm::WASM_SYMBOL_TYPE_SECTION:
11141198
return SymbolRef::ST_Debug;
1199+
case wasm::WASM_SYMBOL_TYPE_EVENT:
1200+
return SymbolRef::ST_Other;
11151201
}
11161202

11171203
llvm_unreachable("Unknown WasmSymbol::SymbolType");
@@ -1135,10 +1221,12 @@ WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
11351221
case wasm::WASM_SYMBOL_TYPE_DATA:
11361222
Ref.d.a = DataSection;
11371223
break;
1138-
case wasm::WASM_SYMBOL_TYPE_SECTION: {
1224+
case wasm::WASM_SYMBOL_TYPE_SECTION:
11391225
Ref.d.a = Sym.Info.ElementIndex;
11401226
break;
1141-
}
1227+
case wasm::WASM_SYMBOL_TYPE_EVENT:
1228+
Ref.d.a = EventSection;
1229+
break;
11421230
default:
11431231
llvm_unreachable("Unknown WasmSymbol::SymbolType");
11441232
}
@@ -1161,6 +1249,7 @@ std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
11611249
ECase(TABLE);
11621250
ECase(MEMORY);
11631251
ECase(GLOBAL);
1252+
ECase(EVENT);
11641253
ECase(EXPORT);
11651254
ECase(START);
11661255
ECase(ELEM);

‎llvm/lib/ObjectYAML/WasmYAML.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) {
100100
IO.mapOptional("Globals", Section.Globals);
101101
}
102102

103+
static void sectionMapping(IO &IO, WasmYAML::EventSection &Section) {
104+
commonSectionMapping(IO, Section);
105+
IO.mapOptional("Events", Section.Events);
106+
}
107+
103108
static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) {
104109
commonSectionMapping(IO, Section);
105110
IO.mapOptional("Exports", Section.Exports);
@@ -187,6 +192,11 @@ void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
187192
Section.reset(new WasmYAML::GlobalSection());
188193
sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
189194
break;
195+
case wasm::WASM_SEC_EVENT:
196+
if (!IO.outputting())
197+
Section.reset(new WasmYAML::EventSection());
198+
sectionMapping(IO, *cast<WasmYAML::EventSection>(Section.get()));
199+
break;
190200
case wasm::WASM_SEC_EXPORT:
191201
if (!IO.outputting())
192202
Section.reset(new WasmYAML::ExportSection());
@@ -227,6 +237,7 @@ void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
227237
ECase(TABLE);
228238
ECase(MEMORY);
229239
ECase(GLOBAL);
240+
ECase(EVENT);
230241
ECase(EXPORT);
231242
ECase(START);
232243
ECase(ELEM);
@@ -307,6 +318,9 @@ void MappingTraits<WasmYAML::Import>::mapping(IO &IO,
307318
} else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
308319
IO.mapRequired("GlobalType", Import.GlobalImport.Type);
309320
IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
321+
} else if (Import.Kind == wasm::WASM_EXTERNAL_EVENT) {
322+
IO.mapRequired("EventAttribute", Import.EventImport.Attribute);
323+
IO.mapRequired("EventSigIndex", Import.EventImport.SigIndex);
310324
} else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
311325
IO.mapRequired("Table", Import.TableImport);
312326
} else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) {
@@ -399,6 +413,8 @@ void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
399413
IO.mapRequired("Function", Info.ElementIndex);
400414
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
401415
IO.mapRequired("Global", Info.ElementIndex);
416+
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
417+
IO.mapRequired("Event", Info.ElementIndex);
402418
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
403419
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
404420
IO.mapRequired("Segment", Info.DataRef.Segment);
@@ -412,6 +428,12 @@ void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
412428
}
413429
}
414430

431+
void MappingTraits<WasmYAML::Event>::mapping(IO &IO, WasmYAML::Event &Event) {
432+
IO.mapRequired("Index", Event.Index);
433+
IO.mapRequired("Attribute", Event.Attribute);
434+
IO.mapRequired("SigIndex", Event.SigIndex);
435+
}
436+
415437
void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
416438
IO &IO, WasmYAML::LimitFlags &Value) {
417439
#define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
@@ -443,6 +465,7 @@ void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
443465
ECase(DATA);
444466
ECase(GLOBAL);
445467
ECase(SECTION);
468+
ECase(EVENT);
446469
#undef ECase
447470
}
448471

@@ -467,6 +490,7 @@ void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration(
467490
ECase(TABLE);
468491
ECase(MEMORY);
469492
ECase(GLOBAL);
493+
ECase(EVENT);
470494
#undef ECase
471495
}
472496

‎llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
8686
const MCOperand &MO = MI.getOperand(i);
8787
if (MO.isReg()) {
8888
/* nothing to encode */
89+
8990
} else if (MO.isImm()) {
9091
if (i < Desc.getNumOperands()) {
9192
assert(Desc.TSFlags == 0 &&
@@ -128,6 +129,7 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
128129
WebAssemblyII::VariableOpImmediateIsLabel));
129130
encodeULEB128(uint64_t(MO.getImm()), OS);
130131
}
132+
131133
} else if (MO.isFPImm()) {
132134
assert(i < Desc.getNumOperands() &&
133135
"Unexpected floating-point immediate as a non-fixed operand");
@@ -144,22 +146,27 @@ void WebAssemblyMCCodeEmitter::encodeInstruction(
144146
double d = MO.getFPImm();
145147
support::endian::write<double>(OS, d, support::little);
146148
}
149+
147150
} else if (MO.isExpr()) {
148151
const MCOperandInfo &Info = Desc.OpInfo[i];
149152
llvm::MCFixupKind FixupKind;
150153
size_t PaddedSize = 5;
151-
if (Info.OperandType == WebAssembly::OPERAND_I32IMM) {
154+
switch (Info.OperandType) {
155+
case WebAssembly::OPERAND_I32IMM:
152156
FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i32);
153-
} else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) {
157+
break;
158+
case WebAssembly::OPERAND_I64IMM:
154159
FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i64);
155160
PaddedSize = 10;
156-
} else if (Info.OperandType == WebAssembly::OPERAND_FUNCTION32 ||
157-
Info.OperandType == WebAssembly::OPERAND_OFFSET32 ||
158-
Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) {
161+
break;
162+
case WebAssembly::OPERAND_FUNCTION32:
163+
case WebAssembly::OPERAND_OFFSET32:
164+
case WebAssembly::OPERAND_TYPEINDEX:
165+
case WebAssembly::OPERAND_GLOBAL:
166+
case WebAssembly::OPERAND_EVENT:
159167
FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32);
160-
} else if (Info.OperandType == WebAssembly::OPERAND_GLOBAL) {
161-
FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32);
162-
} else {
168+
break;
169+
default:
163170
llvm_unreachable("unexpected symbolic operand kind");
164171
}
165172
Fixups.push_back(MCFixup::create(OS.tell() - Start, MO.getExpr(),

‎llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ enum OperandType {
7777
OPERAND_SIGNATURE,
7878
/// type signature immediate for call_indirect.
7979
OPERAND_TYPEINDEX,
80+
/// Event index.
81+
OPERAND_EVENT,
8082
};
8183
} // end namespace WebAssembly
8284

@@ -97,7 +99,8 @@ enum TOF {
9799
// Flags to indicate the type of the symbol being referenced
98100
MO_SYMBOL_FUNCTION = 0x1,
99101
MO_SYMBOL_GLOBAL = 0x2,
100-
MO_SYMBOL_MASK = 0x3,
102+
MO_SYMBOL_EVENT = 0x4,
103+
MO_SYMBOL_MASK = 0x7,
101104
};
102105
} // end namespace WebAssemblyII
103106

‎llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,28 @@ void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
100100
}
101101

102102
void WebAssemblyTargetAsmStreamer::emitGlobalType(MCSymbolWasm *Sym) {
103+
assert(Sym->isGlobal());
103104
OS << "\t.globaltype\t" << Sym->getName() << ", " <<
104105
WebAssembly::TypeToString(
105106
static_cast<wasm::ValType>(Sym->getGlobalType().Type)) <<
106107
'\n';
107108
}
108109

110+
void WebAssemblyTargetAsmStreamer::emitEventType(MCSymbolWasm *Sym) {
111+
assert(Sym->isEvent());
112+
OS << "\t.eventtype\t" << Sym->getName();
113+
if (Sym->getSignature()->Returns.empty())
114+
OS << ", void";
115+
else {
116+
assert(Sym->getSignature()->Returns.size() == 1);
117+
OS << ", "
118+
<< WebAssembly::TypeToString(Sym->getSignature()->Returns.front());
119+
}
120+
for (auto Ty : Sym->getSignature()->Params)
121+
OS << ", " << WebAssembly::TypeToString(Ty);
122+
OS << '\n';
123+
}
124+
109125
void WebAssemblyTargetAsmStreamer::emitImportModule(MCSymbolWasm *Sym,
110126
StringRef ModuleName) {
111127
OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n';
@@ -159,6 +175,9 @@ void WebAssemblyTargetWasmStreamer::emitGlobalType(MCSymbolWasm *Sym) {
159175
// Not needed.
160176
}
161177

178+
void WebAssemblyTargetWasmStreamer::emitEventType(MCSymbolWasm *Sym) {
179+
// Not needed.
180+
}
162181
void WebAssemblyTargetWasmStreamer::emitImportModule(MCSymbolWasm *Sym,
163182
StringRef ModuleName) {
164183
Sym->setModuleName(ModuleName);

‎llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class WebAssemblyTargetStreamer : public MCTargetStreamer {
4545
virtual void emitIndIdx(const MCExpr *Value) = 0;
4646
/// .globaltype
4747
virtual void emitGlobalType(MCSymbolWasm *Sym) = 0;
48+
/// .eventtype
49+
virtual void emitEventType(MCSymbolWasm *Sym) = 0;
4850
/// .import_module
4951
virtual void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) = 0;
5052

@@ -66,6 +68,7 @@ class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
6668
void emitIndirectFunctionType(MCSymbolWasm *Symbol) override;
6769
void emitIndIdx(const MCExpr *Value) override;
6870
void emitGlobalType(MCSymbolWasm *Sym) override;
71+
void emitEventType(MCSymbolWasm *Sym) override;
6972
void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
7073
};
7174

@@ -81,6 +84,7 @@ class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer {
8184
void emitIndirectFunctionType(MCSymbolWasm *Symbol) override;
8285
void emitIndIdx(const MCExpr *Value) override;
8386
void emitGlobalType(MCSymbolWasm *Sym) override;
87+
void emitEventType(MCSymbolWasm *Sym) override;
8488
void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
8589
};
8690

‎llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ static bool IsGlobalType(const MCValue &Target) {
8686
return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_GLOBAL;
8787
}
8888

89+
static bool IsEventType(const MCValue &Target) {
90+
const MCSymbolRefExpr *RefA = Target.getSymA();
91+
return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_EVENT;
92+
}
93+
8994
unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
9095
const MCFixup &Fixup) const {
9196
// WebAssembly functions are not allocated in the data address space. To
@@ -106,6 +111,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
106111
return wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB;
107112
if (IsFunction)
108113
return wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB;
114+
if (IsEventType(Target))
115+
return wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB;
109116
return wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB;
110117
case FK_Data_4:
111118
if (IsFunction)

‎llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,12 @@ WebAssemblyTargetStreamer *WebAssemblyAsmPrinter::getTargetStreamer() {
7979

8080
void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
8181
for (auto &It : OutContext.getSymbols()) {
82-
// Emit a .globaltype declaration.
82+
// Emit a .globaltype and .eventtype declaration.
8383
auto Sym = cast<MCSymbolWasm>(It.getValue());
84-
if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
84+
if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL)
8585
getTargetStreamer()->emitGlobalType(Sym);
86-
}
86+
else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
87+
getTargetStreamer()->emitEventType(Sym);
8788
}
8889

8990
for (const auto &F : M) {

‎llvm/lib/Target/WebAssembly/WebAssemblyISD.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ HANDLE_NODETYPE(SHUFFLE)
2525
HANDLE_NODETYPE(VEC_SHL)
2626
HANDLE_NODETYPE(VEC_SHR_S)
2727
HANDLE_NODETYPE(VEC_SHR_U)
28+
HANDLE_NODETYPE(THROW)
2829

2930
// add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...

‎llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/CodeGen/MachineModuleInfo.h"
2525
#include "llvm/CodeGen/MachineRegisterInfo.h"
2626
#include "llvm/CodeGen/SelectionDAG.h"
27+
#include "llvm/CodeGen/WasmEHFuncInfo.h"
2728
#include "llvm/IR/DiagnosticInfo.h"
2829
#include "llvm/IR/DiagnosticPrinter.h"
2930
#include "llvm/IR/Function.h"
@@ -234,6 +235,7 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
234235

235236
// Exception handling intrinsics
236237
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
238+
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
237239

238240
setMaxAtomicSizeInBitsSupported(64);
239241
}
@@ -882,6 +884,8 @@ SDValue WebAssemblyTargetLowering::LowerOperation(SDValue Op,
882884
case ISD::EXTRACT_VECTOR_ELT:
883885
case ISD::INSERT_VECTOR_ELT:
884886
return LowerAccessVectorElement(Op, DAG);
887+
case ISD::INTRINSIC_VOID:
888+
return LowerINTRINSIC_VOID(Op, DAG);
885889
case ISD::VECTOR_SHUFFLE:
886890
return LowerVECTOR_SHUFFLE(Op, DAG);
887891
case ISD::SHL:
@@ -1045,6 +1049,44 @@ WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
10451049
}
10461050
}
10471051

1052+
SDValue
1053+
WebAssemblyTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
1054+
SelectionDAG &DAG) const {
1055+
MachineFunction &MF = DAG.getMachineFunction();
1056+
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
1057+
SDLoc DL(Op);
1058+
1059+
switch (IntNo) {
1060+
default:
1061+
return {}; // Don't custom lower most intrinsics.
1062+
1063+
case Intrinsic::wasm_throw: {
1064+
int Tag = cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
1065+
switch (Tag) {
1066+
case CPP_EXCEPTION: {
1067+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
1068+
MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
1069+
const char *SymName = MF.createExternalSymbolName("__cpp_exception");
1070+
SDValue SymNode =
1071+
DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
1072+
DAG.getTargetExternalSymbol(
1073+
SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT));
1074+
return DAG.getNode(WebAssemblyISD::THROW, DL,
1075+
MVT::Other, // outchain type
1076+
{
1077+
Op.getOperand(0), // inchain
1078+
SymNode, // exception symbol
1079+
Op.getOperand(3) // thrown value
1080+
});
1081+
}
1082+
default:
1083+
llvm_unreachable("Invalid tag!");
1084+
}
1085+
break;
1086+
}
1087+
}
1088+
}
1089+
10481090
SDValue
10491091
WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,
10501092
SelectionDAG &DAG) const {

‎llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ class WebAssemblyTargetLowering final : public TargetLowering {
9898
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
9999
SDValue LowerCopyToReg(SDValue Op, SelectionDAG &DAG) const;
100100
SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
101+
SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
101102
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
102103
SDValue LowerAccessVectorElement(SDValue Op, SelectionDAG &DAG) const;
103104
SDValue LowerShift(SDValue Op, SelectionDAG &DAG) const;

‎llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,16 @@ let Predicates = [HasExceptionHandling] in {
146146

147147
// Throwing an exception: throw / rethrow
148148
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
149-
defm THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
150-
(outs), (ins i32imm:$tag),
151-
[(int_wasm_throw imm:$tag, I32:$val)],
149+
defm THROW_I32 : I<(outs), (ins event_op:$tag, I32:$val),
150+
(outs), (ins event_op:$tag),
151+
[(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag),
152+
I32:$val)],
152153
"throw \t$tag, $val", "throw \t$tag",
153154
0x08>;
154-
defm THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
155-
(outs), (ins i32imm:$tag),
156-
[(int_wasm_throw imm:$tag, I64:$val)],
155+
defm THROW_I64 : I<(outs), (ins event_op:$tag, I64:$val),
156+
(outs), (ins event_op:$tag),
157+
[(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag),
158+
I64:$val)],
157159
"throw \t$tag, $val", "throw \t$tag",
158160
0x08>;
159161
defm RETHROW : NRI<(outs), (ins bb_op:$dst), [], "rethrow \t$dst", 0x09>;

‎llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def SDT_WebAssemblyArgument : SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>;
6464
def SDT_WebAssemblyReturn : SDTypeProfile<0, -1, []>;
6565
def SDT_WebAssemblyWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
6666
SDTCisPtrTy<0>]>;
67+
def SDT_WebAssemblyThrow : SDTypeProfile<0, 2, [SDTCisPtrTy<0>]>;
6768

6869
//===----------------------------------------------------------------------===//
6970
// WebAssembly-specific DAG Nodes.
@@ -90,6 +91,8 @@ def WebAssemblyreturn : SDNode<"WebAssemblyISD::RETURN",
9091
SDT_WebAssemblyReturn, [SDNPHasChain]>;
9192
def WebAssemblywrapper : SDNode<"WebAssemblyISD::Wrapper",
9293
SDT_WebAssemblyWrapper>;
94+
def WebAssemblythrow : SDNode<"WebAssemblyISD::THROW", SDT_WebAssemblyThrow,
95+
[SDNPHasChain]>;
9396

9497
//===----------------------------------------------------------------------===//
9598
// WebAssembly-specific Operands.
@@ -140,6 +143,10 @@ let OperandType = "OPERAND_P2ALIGN" in {
140143
def P2Align : Operand<i32> {
141144
let PrintMethod = "printWebAssemblyP2AlignOperand";
142145
}
146+
147+
let OperandType = "OPERAND_EVENT" in
148+
def event_op : Operand<i32>;
149+
143150
} // OperandType = "OPERAND_P2ALIGN"
144151

145152
let OperandType = "OPERAND_SIGNATURE" in {

‎llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
7575
cast<MCSymbolWasm>(Printer.GetExternalSymbolSymbol(Name));
7676
const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
7777

78-
// __stack_pointer is a global variable; all other external symbols used by
79-
// CodeGen are functions. It's OK to hardcode knowledge of specific symbols
80-
// here; this method is precisely there for fetching the signatures of known
81-
// Clang-provided symbols.
78+
// Except for the two exceptions (__stack_pointer and __cpp_exception), all
79+
// other external symbols used by CodeGen are functions. It's OK to hardcode
80+
// knowledge of specific symbols here; this method is precisely there for
81+
// fetching the signatures of known Clang-provided symbols.
8282
if (strcmp(Name, "__stack_pointer") == 0) {
8383
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
8484
WasmSym->setGlobalType(wasm::WasmGlobalType{
@@ -90,24 +90,45 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
9090

9191
SmallVector<wasm::ValType, 4> Returns;
9292
SmallVector<wasm::ValType, 4> Params;
93-
GetLibcallSignature(Subtarget, Name, Returns, Params);
93+
if (strcmp(Name, "__cpp_exception") == 0) {
94+
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT);
95+
// We can't confirm its signature index for now because there can be
96+
// imported exceptions. Set it to be 0 for now.
97+
WasmSym->setEventType(
98+
{wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION, /* SigIndex */ 0});
99+
// We may have multiple C++ compilation units to be linked together, each of
100+
// which defines the exception symbol. To resolve them, we declare them as
101+
// weak.
102+
WasmSym->setWeak(true);
103+
WasmSym->setExternal(true);
104+
105+
// All C++ exceptions are assumed to have a single i32 (for wasm32) or i64
106+
// (for wasm64) param type and void return type. The reaon is, all C++
107+
// exception values are pointers, and to share the type section with
108+
// functions, exceptions are assumed to have void return type.
109+
Params.push_back(Subtarget.hasAddr64() ? wasm::ValType::I64
110+
: wasm::ValType::I32);
111+
} else { // Function symbols
112+
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
113+
GetLibcallSignature(Subtarget, Name, Returns, Params);
114+
}
94115
auto Signature =
95116
make_unique<wasm::WasmSignature>(std::move(Returns), std::move(Params));
96117
WasmSym->setSignature(Signature.get());
97118
Printer.addSignature(std::move(Signature));
98-
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
99119

100120
return WasmSym;
101121
}
102122

103123
MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
104124
int64_t Offset,
105-
bool IsFunc,
106-
bool IsGlob) const {
125+
bool IsFunc, bool IsGlob,
126+
bool IsEvent) const {
107127
MCSymbolRefExpr::VariantKind VK =
108128
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
109129
: IsGlob ? MCSymbolRefExpr::VK_WebAssembly_GLOBAL
110-
: MCSymbolRefExpr::VK_None;
130+
: IsEvent ? MCSymbolRefExpr::VK_WebAssembly_EVENT
131+
: MCSymbolRefExpr::VK_None;
111132

112133
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);
113134

@@ -116,6 +137,8 @@ MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
116137
report_fatal_error("Function addresses with offsets not supported");
117138
if (IsGlob)
118139
report_fatal_error("Global indexes with offsets not supported");
140+
if (IsEvent)
141+
report_fatal_error("Event indexes with offsets not supported");
119142
Expr =
120143
MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx);
121144
}
@@ -218,7 +241,7 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
218241
"WebAssembly does not use target flags on GlobalAddresses");
219242
MCOp = LowerSymbolOperand(GetGlobalAddressSymbol(MO), MO.getOffset(),
220243
MO.getGlobal()->getValueType()->isFunctionTy(),
221-
false);
244+
false, false);
222245
break;
223246
case MachineOperand::MO_ExternalSymbol:
224247
// The target flag indicates whether this is a symbol for a
@@ -228,14 +251,16 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
228251
MCOp = LowerSymbolOperand(
229252
GetExternalSymbolSymbol(MO), /*Offset=*/0,
230253
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_FUNCTION) != 0,
231-
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0);
254+
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0,
255+
(MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_EVENT) != 0);
232256
break;
233257
case MachineOperand::MO_MCSymbol:
234258
// This is currently used only for LSDA symbols (GCC_except_table),
235259
// because global addresses or other external symbols are handled above.
236260
assert(MO.getTargetFlags() == 0 &&
237261
"WebAssembly does not use target flags on MCSymbol");
238-
MCOp = LowerSymbolOperand(MO.getMCSymbol(), /*Offset=*/0, false, false);
262+
MCOp = LowerSymbolOperand(MO.getMCSymbol(), /*Offset=*/0, false, false,
263+
false);
239264
break;
240265
}
241266

‎llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyMCInstLower {
3434
MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
3535
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
3636
MCOperand LowerSymbolOperand(MCSymbol *Sym, int64_t Offset, bool IsFunc,
37-
bool IsGlob) const;
37+
bool IsGlob, bool IsEvent) const;
3838

3939
public:
4040
WebAssemblyMCInstLower(MCContext &ctx, WebAssemblyAsmPrinter &printer)

‎llvm/test/CodeGen/WebAssembly/exception.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ declare void @llvm.wasm.throw(i32, i8*)
1313

1414
; CHECK-LABEL: test_throw:
1515
; CHECK-NEXT: i32.const $push0=, 0
16-
; CHECK-NEXT: throw 0, $pop0
16+
; CHECK-NEXT: throw __cpp_exception@EVENT, $pop0
1717
define void @test_throw() {
1818
call void @llvm.wasm.throw(i32 0, i8* null)
1919
ret void
@@ -259,3 +259,6 @@ declare void @__cxa_rethrow()
259259
declare void @__clang_call_terminate(i8*)
260260
declare void @_ZSt9terminatev()
261261
declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned)
262+
263+
; CHECK: __cpp_exception:
264+
; CHECK: .eventtype __cpp_exception, void, i32
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %s -o - | obj2yaml | FileCheck %s
2+
; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %s -o - | llvm-readobj -s | FileCheck -check-prefix=SEC %s
3+
4+
target triple = "wasm32-unknown-unknown"
5+
6+
declare void @llvm.wasm.throw(i32, i8*)
7+
8+
define i32 @test_throw0(i8* %p) {
9+
call void @llvm.wasm.throw(i32 0, i8* %p)
10+
ret i32 0
11+
}
12+
13+
define i32 @test_throw1(i8* %p) {
14+
call void @llvm.wasm.throw(i32 0, i8* %p)
15+
ret i32 1
16+
}
17+
18+
; CHECK: Sections:
19+
; CHECK-NEXT: - Type: TYPE
20+
; CHECK-NEXT: Signatures:
21+
; CHECK-NEXT: - Index: 0
22+
; CHECK-NEXT: ReturnType: I32
23+
; CHECK-NEXT: ParamTypes:
24+
; CHECK-NEXT: - I32
25+
; CHECK-NEXT: - Index: 1
26+
; CHECK-NEXT: ReturnType: NORESULT
27+
; CHECK-NEXT: ParamTypes:
28+
; CHECK-NEXT: - I32
29+
30+
; CHECK: - Type: EVENT
31+
; CHECK-NEXT: Events:
32+
; CHECK-NEXT: - Index: 0
33+
; CHECK-NEXT: Attribute: 0
34+
; CHECK-NEXT: SigIndex: 1
35+
36+
; CHECK-NEXT: - Type: CODE
37+
; CHECK-NEXT: Relocations:
38+
; CHECK-NEXT: - Type: R_WEBASSEMBLY_EVENT_INDEX_LEB
39+
; CHECK-NEXT: Index: 1
40+
; CHECK-NEXT: Offset: 0x00000006
41+
; CHECK-NEXT: - Type: R_WEBASSEMBLY_EVENT_INDEX_LEB
42+
; CHECK-NEXT: Index: 1
43+
; CHECK-NEXT: Offset: 0x00000013
44+
45+
; CHECK: - Type: CUSTOM
46+
; CHECK-NEXT: Name: linking
47+
; CHECK-NEXT: Version: 1
48+
; CHECK-NEXT: SymbolTable:
49+
50+
; CHECK: - Index: 1
51+
; CHECK-NEXT: Kind: EVENT
52+
; CHECK-NEXT: Name: __cpp_exception
53+
; CHECK-NEXT: Flags: [ BINDING_WEAK ]
54+
; CHECK-NEXT: Event: 0
55+
56+
; SEC: Type: EVENT (0xC)
57+
; SEC-NEXT: Size: 3
58+
; SEC-NEXT: Offset: 97
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
2+
3+
--- !WASM
4+
FileHeader:
5+
Version: 0x00000001
6+
Sections:
7+
- Type: TYPE
8+
Signatures:
9+
- Index: 0
10+
ReturnType: I32
11+
ParamTypes:
12+
- I32
13+
- Index: 1
14+
ReturnType: NORESULT
15+
ParamTypes:
16+
- I32
17+
- Type: FUNCTION
18+
FunctionTypes: [ 0 ]
19+
- Type: EVENT
20+
Events:
21+
- Index: 0
22+
Attribute: 0
23+
SigIndex: 1
24+
- Type: CODE
25+
Relocations:
26+
- Type: R_WEBASSEMBLY_EVENT_INDEX_LEB
27+
Index: 1
28+
Offset: 0x00000006
29+
Functions:
30+
- Index: 0
31+
Locals:
32+
Body: 200008808080800041000B
33+
- Type: CUSTOM
34+
Name: linking
35+
Version: 1
36+
SymbolTable:
37+
- Index: 0
38+
Kind: FUNCTION
39+
Name: test_throw0
40+
Flags: [ ]
41+
Function: 0
42+
- Index: 1
43+
Kind: EVENT
44+
Name: __cpp_exception
45+
Flags: [ BINDING_WEAK ]
46+
Event: 0
47+
...
48+
49+
# CHECK: --- !WASM
50+
# CHECK-NEXT: FileHeader:
51+
# CHECK-NEXT: Version: 0x00000001
52+
# CHECK-NEXT: Sections:
53+
# CHECK-NEXT: - Type: TYPE
54+
# CHECK-NEXT: Signatures:
55+
# CHECK-NEXT: - Index: 0
56+
# CHECK-NEXT: ReturnType: I32
57+
# CHECK-NEXT: ParamTypes:
58+
# CHECK-NEXT: - I32
59+
# CHECK-NEXT: - Index: 1
60+
# CHECK-NEXT: ReturnType: NORESULT
61+
# CHECK-NEXT: ParamTypes:
62+
# CHECK-NEXT: - I32
63+
# CHECK-NEXT: - Type: FUNCTION
64+
# CHECK-NEXT: FunctionTypes: [ 0 ]
65+
# CHECK-NEXT: - Type: EVENT
66+
# CHECK-NEXT: Events:
67+
# CHECK-NEXT: - Index: 0
68+
# CHECK-NEXT: Attribute: 0
69+
# CHECK-NEXT: SigIndex: 1
70+
# CHECK-NEXT: - Type: CODE
71+
# CHECK-NEXT: Relocations:
72+
# CHECK-NEXT: - Type: R_WEBASSEMBLY_EVENT_INDEX_LEB
73+
# CHECK-NEXT: Index: 1
74+
# CHECK-NEXT: Offset: 0x00000006
75+
# CHECK-NEXT: Functions:
76+
# CHECK-NEXT: - Index: 0
77+
# CHECK-NEXT: Locals:
78+
# CHECK-NEXT: Body: 200008808080800041000B
79+
# CHECK-NEXT: - Type: CUSTOM
80+
# CHECK-NEXT: Name: linking
81+
# CHECK-NEXT: Version: 1
82+
# CHECK-NEXT: SymbolTable:
83+
# CHECK-NEXT: - Index: 0
84+
# CHECK-NEXT: Kind: FUNCTION
85+
# CHECK-NEXT: Name: test_throw0
86+
# CHECK-NEXT: Flags: [ ]
87+
# CHECK-NEXT: Function: 0
88+
# CHECK-NEXT: - Index: 1
89+
# CHECK-NEXT: Kind: EVENT
90+
# CHECK-NEXT: Name: __cpp_exception
91+
# CHECK-NEXT: Flags: [ BINDING_WEAK ]
92+
# CHECK-NEXT: Event: 0

‎llvm/tools/llvm-readobj/WasmDumper.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,19 @@ namespace {
2525
static const EnumEntry<unsigned> WasmSymbolTypes[] = {
2626
#define ENUM_ENTRY(X) \
2727
{ #X, wasm::WASM_SYMBOL_TYPE_##X }
28-
ENUM_ENTRY(FUNCTION),
29-
ENUM_ENTRY(DATA),
30-
ENUM_ENTRY(GLOBAL),
31-
ENUM_ENTRY(SECTION),
28+
ENUM_ENTRY(FUNCTION), ENUM_ENTRY(DATA), ENUM_ENTRY(GLOBAL),
29+
ENUM_ENTRY(SECTION), ENUM_ENTRY(EVENT),
3230
#undef ENUM_ENTRY
3331
};
3432

3533
static const EnumEntry<uint32_t> WasmSectionTypes[] = {
3634
#define ENUM_ENTRY(X) \
3735
{ #X, wasm::WASM_SEC_##X }
38-
ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
39-
ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
40-
ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EXPORT), ENUM_ENTRY(START),
41-
ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE), ENUM_ENTRY(DATA),
36+
ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
37+
ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
38+
ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
39+
ENUM_ENTRY(START), ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE),
40+
ENUM_ENTRY(DATA),
4241
#undef ENUM_ENTRY
4342
};
4443

‎llvm/tools/obj2yaml/wasm2yaml.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
107107
break;
108108
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
109109
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
110+
case wasm::WASM_SYMBOL_TYPE_EVENT:
110111
Info.ElementIndex = Symbol.ElementIndex;
111112
break;
112113
case wasm::WASM_SYMBOL_TYPE_SECTION:
@@ -182,6 +183,10 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
182183
Im.GlobalImport.Type = Import.Global.Type;
183184
Im.GlobalImport.Mutable = Import.Global.Mutable;
184185
break;
186+
case wasm::WASM_EXTERNAL_EVENT:
187+
Im.EventImport.Attribute = Import.Event.Attribute;
188+
Im.EventImport.SigIndex = Import.Event.SigIndex;
189+
break;
185190
case wasm::WASM_EXTERNAL_TABLE:
186191
Im.TableImport = make_table(Import.Table);
187192
break;
@@ -231,6 +236,18 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
231236
S = std::move(GlobalSec);
232237
break;
233238
}
239+
case wasm::WASM_SEC_EVENT: {
240+
auto EventSec = make_unique<WasmYAML::EventSection>();
241+
for (auto &Event : Obj.events()) {
242+
WasmYAML::Event E;
243+
E.Index = Event.Index;
244+
E.Attribute = Event.Type.Attribute;
245+
E.SigIndex = Event.Type.SigIndex;
246+
EventSec->Events.push_back(E);
247+
}
248+
S = std::move(EventSec);
249+
break;
250+
}
234251
case wasm::WASM_SEC_START: {
235252
auto StartSec = make_unique<WasmYAML::StartSection>();
236253
StartSec->StartFunction = Obj.startFunction();

‎llvm/tools/yaml2obj/yaml2wasm.cpp

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class WasmWriter {
3737
int writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section);
3838
int writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section);
3939
int writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section);
40+
int writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section);
4041
int writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section);
4142
int writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section);
4243
int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
@@ -49,6 +50,7 @@ class WasmWriter {
4950
WasmYAML::Object &Obj;
5051
uint32_t NumImportedFunctions = 0;
5152
uint32_t NumImportedGlobals = 0;
53+
uint32_t NumImportedEvents = 0;
5254
};
5355

5456
static int writeUint64(raw_ostream &OS, uint64_t Value) {
@@ -152,6 +154,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
152154
switch (Info.Kind) {
153155
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
154156
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
157+
case wasm::WASM_SYMBOL_TYPE_EVENT:
155158
encodeULEB128(Info.ElementIndex, SubSection.GetStream());
156159
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
157160
writeStringRef(Info.Name, SubSection.GetStream());
@@ -292,6 +295,11 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
292295
writeUint8(OS, Import.GlobalImport.Mutable);
293296
NumImportedGlobals++;
294297
break;
298+
case wasm::WASM_EXTERNAL_EVENT:
299+
writeUint32(OS, Import.EventImport.Attribute);
300+
writeUint32(OS, Import.EventImport.SigIndex);
301+
NumImportedGlobals++;
302+
break;
295303
case wasm::WASM_EXTERNAL_MEMORY:
296304
writeLimits(Import.Memory, OS);
297305
break;
@@ -369,6 +377,22 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
369377
return 0;
370378
}
371379

380+
int WasmWriter::writeSectionContent(raw_ostream &OS,
381+
WasmYAML::EventSection &Section) {
382+
encodeULEB128(Section.Events.size(), OS);
383+
uint32_t ExpectedIndex = NumImportedEvents;
384+
for (auto &Event : Section.Events) {
385+
if (Event.Index != ExpectedIndex) {
386+
errs() << "Unexpected event index: " << Event.Index << "\n";
387+
return 1;
388+
}
389+
++ExpectedIndex;
390+
encodeULEB128(Event.Attribute, OS);
391+
encodeULEB128(Event.SigIndex, OS);
392+
}
393+
return 0;
394+
}
395+
372396
int WasmWriter::writeSectionContent(raw_ostream &OS,
373397
WasmYAML::ElemSection &Section) {
374398
encodeULEB128(Section.Segments.size(), OS);
@@ -474,17 +498,7 @@ int WasmWriter::writeWasm(raw_ostream &OS) {
474498
writeUint32(OS, Obj.Header.Version);
475499

476500
// Write each section
477-
uint32_t LastType = 0;
478501
for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
479-
uint32_t Type = Sec->Type;
480-
if (Type != wasm::WASM_SEC_CUSTOM) {
481-
if (Type < LastType) {
482-
errs() << "Out of order section type: " << Type << "\n";
483-
return 1;
484-
}
485-
LastType = Type;
486-
}
487-
488502
encodeULEB128(Sec->Type, OS);
489503
std::string OutString;
490504
raw_string_ostream StringStream(OutString);
@@ -509,6 +523,9 @@ int WasmWriter::writeWasm(raw_ostream &OS) {
509523
} else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
510524
if (auto Err = writeSectionContent(StringStream, *S))
511525
return Err;
526+
} else if (auto S = dyn_cast<WasmYAML::EventSection>(Sec.get())) {
527+
if (auto Err = writeSectionContent(StringStream, *S))
528+
return Err;
512529
} else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
513530
if (auto Err = writeSectionContent(StringStream, *S))
514531
return Err;

0 commit comments

Comments
 (0)
Please sign in to comment.