[llvm] r346825 - [WebAssembly] Add support for the event section

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 13 18:46:21 PST 2018


Author: aheejin
Date: Tue Nov 13 18:46:21 2018
New Revision: 346825

URL: http://llvm.org/viewvc/llvm-project?rev=346825&view=rev
Log:
[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

Added:
    llvm/trunk/test/MC/WebAssembly/event-section.ll
    llvm/trunk/test/ObjectYAML/wasm/event_section.yaml
Modified:
    llvm/trunk/include/llvm/BinaryFormat/Wasm.h
    llvm/trunk/include/llvm/BinaryFormat/WasmRelocs.def
    llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h
    llvm/trunk/include/llvm/MC/MCExpr.h
    llvm/trunk/include/llvm/MC/MCSymbolWasm.h
    llvm/trunk/include/llvm/Object/RelocVisitor.h
    llvm/trunk/include/llvm/Object/Wasm.h
    llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
    llvm/trunk/lib/BinaryFormat/Wasm.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.h
    llvm/trunk/lib/MC/MCExpr.cpp
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Object/WasmObjectFile.cpp
    llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
    llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.h
    llvm/trunk/test/CodeGen/WebAssembly/exception.ll
    llvm/trunk/tools/llvm-readobj/WasmDumper.cpp
    llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2wasm.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/Wasm.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/Wasm.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h Tue Nov 13 18:46:21 2018
@@ -75,6 +75,18 @@ struct WasmGlobal {
   StringRef SymbolName; // from the "linking" section
 };
 
+struct WasmEventType {
+  // Kind of event. Currently only WASM_EVENT_ATTRIBUTE_EXCEPTION is possible.
+  uint32_t Attribute;
+  uint32_t SigIndex;
+};
+
+struct WasmEvent {
+  uint32_t Index;
+  WasmEventType Type;
+  StringRef SymbolName; // from the "linking" section
+};
+
 struct WasmImport {
   StringRef Module;
   StringRef Field;
@@ -84,6 +96,7 @@ struct WasmImport {
     WasmGlobalType Global;
     WasmTable Table;
     WasmLimits Memory;
+    WasmEventType Event;
   };
 };
 
@@ -178,7 +191,8 @@ enum : unsigned {
   WASM_SEC_START = 8,    // Start function declaration
   WASM_SEC_ELEM = 9,     // Elements section
   WASM_SEC_CODE = 10,    // Function bodies (code)
-  WASM_SEC_DATA = 11     // Data segments
+  WASM_SEC_DATA = 11,    // Data segments
+  WASM_SEC_EVENT = 12    // Event declarations
 };
 
 // Type immediate encodings used in various contexts.
@@ -200,6 +214,7 @@ enum : unsigned {
   WASM_EXTERNAL_TABLE = 0x1,
   WASM_EXTERNAL_MEMORY = 0x2,
   WASM_EXTERNAL_GLOBAL = 0x3,
+  WASM_EXTERNAL_EVENT = 0x4,
 };
 
 // Opcodes used in initializer expressions.
@@ -243,6 +258,12 @@ enum WasmSymbolType : unsigned {
   WASM_SYMBOL_TYPE_DATA = 0x1,
   WASM_SYMBOL_TYPE_GLOBAL = 0x2,
   WASM_SYMBOL_TYPE_SECTION = 0x3,
+  WASM_SYMBOL_TYPE_EVENT = 0x4,
+};
+
+// Kinds of event attributes.
+enum WasmEventAttribute : unsigned {
+  WASM_EVENT_ATTRIBUTE_EXCEPTION = 0x0,
 };
 
 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;

Modified: llvm/trunk/include/llvm/BinaryFormat/WasmRelocs.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/WasmRelocs.def?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/WasmRelocs.def (original)
+++ llvm/trunk/include/llvm/BinaryFormat/WasmRelocs.def Tue Nov 13 18:46:21 2018
@@ -1,4 +1,3 @@
-
 #ifndef WASM_RELOC
 #error "WASM_RELOC must be defined"
 #endif
@@ -13,3 +12,4 @@ WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB,
 WASM_RELOC(R_WEBASSEMBLY_GLOBAL_INDEX_LEB,     7)
 WASM_RELOC(R_WEBASSEMBLY_FUNCTION_OFFSET_I32,  8)
 WASM_RELOC(R_WEBASSEMBLY_SECTION_OFFSET_I32,   9)
+WASM_RELOC(R_WEBASSEMBLY_EVENT_INDEX_LEB,     10)

Modified: llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h Tue Nov 13 18:46:21 2018
@@ -21,6 +21,8 @@
 
 namespace llvm {
 
+enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };
+
 using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
 
 struct WasmEHFuncInfo {

Modified: llvm/trunk/include/llvm/MC/MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCExpr.h (original)
+++ llvm/trunk/include/llvm/MC/MCExpr.h Tue Nov 13 18:46:21 2018
@@ -288,6 +288,7 @@ public:
     VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
     VK_WebAssembly_GLOBAL,   // Global object index
     VK_WebAssembly_TYPEINDEX,// Type table index
+    VK_WebAssembly_EVENT,    // Event index
 
     VK_AMDGPU_GOTPCREL32_LO, // symbol at gotpcrel32@lo
     VK_AMDGPU_GOTPCREL32_HI, // symbol at gotpcrel32@hi

Modified: llvm/trunk/include/llvm/MC/MCSymbolWasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbolWasm.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbolWasm.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbolWasm.h Tue Nov 13 18:46:21 2018
@@ -21,8 +21,8 @@ class MCSymbolWasm : public MCSymbol {
   bool IsComdat = false;
   std::string ModuleName;
   wasm::WasmSignature *Signature = nullptr;
-  wasm::WasmGlobalType GlobalType;
-  bool GlobalTypeSet = false;
+  Optional<wasm::WasmGlobalType> GlobalType;
+  Optional<wasm::WasmEventType> EventType;
 
   /// An expression describing how to calculate the size of a symbol. If a
   /// symbol has no size this field will be NULL.
@@ -42,6 +42,7 @@ public:
   bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
   bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
   bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
+  bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
   wasm::WasmSymbolType getType() const { return Type; }
   void setType(wasm::WasmSymbolType type) { Type = type; }
 
@@ -61,14 +62,16 @@ public:
   void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
 
   const wasm::WasmGlobalType &getGlobalType() const {
-    assert(GlobalTypeSet);
-    return GlobalType;
+    assert(GlobalType.hasValue());
+    return GlobalType.getValue();
   }
+  void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
 
-  void setGlobalType(wasm::WasmGlobalType GT) {
-    GlobalTypeSet = true;
-    GlobalType = GT;
+  const wasm::WasmEventType &getEventType() const {
+    assert(EventType.hasValue());
+    return EventType.getValue();
   }
+  void setEventType(wasm::WasmEventType ET) { EventType = ET; }
 };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/Object/RelocVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/RelocVisitor.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/RelocVisitor.h (original)
+++ llvm/trunk/include/llvm/Object/RelocVisitor.h Tue Nov 13 18:46:21 2018
@@ -333,6 +333,7 @@ private:
       case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
       case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
       case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
+      case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
         // For wasm section, its offset at 0 -- ignoring Value
         return 0;
       }

Modified: llvm/trunk/include/llvm/Object/Wasm.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Wasm.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Wasm.h (original)
+++ llvm/trunk/include/llvm/Object/Wasm.h Tue Nov 13 18:46:21 2018
@@ -38,12 +38,15 @@ class WasmSymbol {
 public:
   WasmSymbol(const wasm::WasmSymbolInfo &Info,
              const wasm::WasmSignature *FunctionType,
-             const wasm::WasmGlobalType *GlobalType)
-      : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {}
+             const wasm::WasmGlobalType *GlobalType,
+             const wasm::WasmEventType *EventType)
+      : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType),
+        EventType(EventType) {}
 
   const wasm::WasmSymbolInfo &Info;
   const wasm::WasmSignature *FunctionType;
   const wasm::WasmGlobalType *GlobalType;
+  const wasm::WasmEventType *EventType;
 
   bool isTypeFunction() const {
     return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
@@ -59,6 +62,8 @@ public:
     return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
   }
 
+  bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
+
   bool isDefined() const { return !isUndefined(); }
 
   bool isUndefined() const {
@@ -130,6 +135,7 @@ public:
   ArrayRef<wasm::WasmTable> tables() const { return Tables; }
   ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
   ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
+  ArrayRef<wasm::WasmEvent> events() const { return Events; }
   ArrayRef<wasm::WasmExport> exports() const { return Exports; }
   ArrayRef<WasmSymbol> syms() const { return Symbols; }
   const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
@@ -141,6 +147,7 @@ public:
   uint32_t startFunction() const { return StartFunction; }
   uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
   uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
+  uint32_t getNumImportedEvents() const { return NumImportedEvents; }
 
   void moveSymbolNext(DataRefImpl &Symb) const override;
 
@@ -205,12 +212,16 @@ private:
   bool isDefinedFunctionIndex(uint32_t Index) const;
   bool isValidGlobalIndex(uint32_t Index) const;
   bool isDefinedGlobalIndex(uint32_t Index) const;
+  bool isValidEventIndex(uint32_t Index) const;
+  bool isDefinedEventIndex(uint32_t Index) const;
   bool isValidFunctionSymbol(uint32_t Index) const;
   bool isValidGlobalSymbol(uint32_t Index) const;
+  bool isValidEventSymbol(uint32_t Index) const;
   bool isValidDataSymbol(uint32_t Index) const;
   bool isValidSectionSymbol(uint32_t Index) const;
   wasm::WasmFunction &getDefinedFunction(uint32_t Index);
   wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
+  wasm::WasmEvent &getDefinedEvent(uint32_t Index);
 
   const WasmSection &getWasmSection(DataRefImpl Ref) const;
   const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
@@ -226,6 +237,7 @@ private:
   Error parseTableSection(ReadContext &Ctx);
   Error parseMemorySection(ReadContext &Ctx);
   Error parseGlobalSection(ReadContext &Ctx);
+  Error parseEventSection(ReadContext &Ctx);
   Error parseExportSection(ReadContext &Ctx);
   Error parseStartSection(ReadContext &Ctx);
   Error parseElemSection(ReadContext &Ctx);
@@ -246,6 +258,7 @@ private:
   std::vector<wasm::WasmTable> Tables;
   std::vector<wasm::WasmLimits> Memories;
   std::vector<wasm::WasmGlobal> Globals;
+  std::vector<wasm::WasmEvent> Events;
   std::vector<wasm::WasmImport> Imports;
   std::vector<wasm::WasmExport> Exports;
   std::vector<wasm::WasmElemSegment> ElemSegments;
@@ -258,9 +271,11 @@ private:
   wasm::WasmLinkingData LinkingData;
   uint32_t NumImportedGlobals = 0;
   uint32_t NumImportedFunctions = 0;
+  uint32_t NumImportedEvents = 0;
   uint32_t CodeSection = 0;
   uint32_t DataSection = 0;
   uint32_t GlobalSection = 0;
+  uint32_t EventSection = 0;
 };
 
 } // end namespace object

Modified: llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h Tue Nov 13 18:46:21 2018
@@ -74,6 +74,12 @@ struct Global {
   wasm::WasmInitExpr InitExpr;
 };
 
+struct Event {
+  uint32_t Index;
+  uint32_t Attribute;
+  uint32_t SigIndex;
+};
+
 struct Import {
   StringRef Module;
   StringRef Field;
@@ -83,6 +89,7 @@ struct Import {
     Global GlobalImport;
     Table TableImport;
     Limits Memory;
+    Event EventImport;
   };
 };
 
@@ -262,6 +269,16 @@ struct GlobalSection : Section {
   std::vector<Global> Globals;
 };
 
+struct EventSection : Section {
+  EventSection() : Section(wasm::WASM_SEC_EVENT) {}
+
+  static bool classof(const Section *S) {
+    return S->Type == wasm::WASM_SEC_EVENT;
+  }
+
+  std::vector<Event> Events;
+};
+
 struct ExportSection : Section {
   ExportSection() : Section(wasm::WASM_SEC_EXPORT) {}
 
@@ -339,6 +356,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmY
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ComdatEntry)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Comdat)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Event)
 
 namespace llvm {
 namespace yaml {
@@ -471,6 +489,10 @@ template <> struct ScalarEnumerationTrai
   static void enumeration(IO &IO, WasmYAML::RelocType &Kind);
 };
 
+template <> struct MappingTraits<WasmYAML::Event> {
+  static void mapping(IO &IO, WasmYAML::Event &Event);
+};
+
 } // end namespace yaml
 } // end namespace llvm
 

Modified: llvm/trunk/lib/BinaryFormat/Wasm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/BinaryFormat/Wasm.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/BinaryFormat/Wasm.cpp (original)
+++ llvm/trunk/lib/BinaryFormat/Wasm.cpp Tue Nov 13 18:46:21 2018
@@ -19,6 +19,8 @@ std::string llvm::wasm::toString(wasm::W
     return "WASM_SYMBOL_TYPE_DATA";
   case wasm::WASM_SYMBOL_TYPE_SECTION:
     return "WASM_SYMBOL_TYPE_SECTION";
+  case wasm::WASM_SYMBOL_TYPE_EVENT:
+    return "WASM_SYMBOL_TYPE_EVENT";
   }
   llvm_unreachable("unknown symbol type");
 }

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.cpp Tue Nov 13 18:46:21 2018
@@ -13,9 +13,25 @@
 //===----------------------------------------------------------------------===//
 
 #include "WasmException.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCStreamer.h"
 using namespace llvm;
 
+void WasmException::endModule() {
+  // This is the symbol used in 'throw' and 'if_except' instruction to denote
+  // this is a C++ exception. This symbol has to be emitted somewhere once in
+  // the module.  Check if the symbol has already been created, i.e., we have at
+  // least one 'throw' or 'if_except' instruction in the module, and emit the
+  // symbol only if so.
+  SmallString<60> NameStr;
+  Mangler::getNameWithPrefix(NameStr, "__cpp_exception", Asm->getDataLayout());
+  if (Asm->OutContext.lookupSymbol(NameStr)) {
+    MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol("__cpp_exception");
+    Asm->OutStreamer->EmitLabel(ExceptionSym);
+  }
+}
+
 void WasmException::markFunctionEnd() {
   // Get rid of any dead landing pads.
   if (!Asm->MF->getLandingPads().empty()) {

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WasmException.h Tue Nov 13 18:46:21 2018
@@ -24,7 +24,7 @@ class LLVM_LIBRARY_VISIBILITY WasmExcept
 public:
   WasmException(AsmPrinter *A) : EHStreamer(A) {}
 
-  void endModule() override {}
+  void endModule() override;
   void beginFunction(const MachineFunction *MF) override {}
   virtual void markFunctionEnd() override;
   void endFunction(const MachineFunction *MF) override;

Modified: llvm/trunk/lib/MC/MCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCExpr.cpp (original)
+++ llvm/trunk/lib/MC/MCExpr.cpp Tue Nov 13 18:46:21 2018
@@ -306,6 +306,7 @@ StringRef MCSymbolRefExpr::getVariantKin
   case VK_WebAssembly_FUNCTION: return "FUNCTION";
   case VK_WebAssembly_GLOBAL: return "GLOBAL";
   case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
+  case VK_WebAssembly_EVENT: return "EVENT";
   case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32 at lo";
   case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32 at hi";
   case VK_AMDGPU_REL32_LO: return "rel32 at lo";
@@ -421,6 +422,7 @@ MCSymbolRefExpr::getVariantKindForName(S
     .Case("function", VK_WebAssembly_FUNCTION)
     .Case("global", VK_WebAssembly_GLOBAL)
     .Case("typeindex", VK_WebAssembly_TYPEINDEX)
+    .Case("event", VK_WebAssembly_EVENT)
     .Case("gotpcrel32 at lo", VK_AMDGPU_GOTPCREL32_LO)
     .Case("gotpcrel32 at hi", VK_AMDGPU_GOTPCREL32_HI)
     .Case("rel32 at lo", VK_AMDGPU_REL32_LO)

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Tue Nov 13 18:46:21 2018
@@ -56,10 +56,10 @@ struct SectionBookkeeping {
   uint32_t Index;
 };
 
-// The signature of a wasm function, in a struct capable of being used as a
-// DenseMap key.
-// TODO: Consider using WasmSignature directly instead.
-struct WasmFunctionType {
+// The signature of a wasm function or event, in a struct capable of being used
+// as a DenseMap key.
+// TODO: Consider using wasm::WasmSignature directly instead.
+struct WasmSignature {
   // Support empty and tombstone instances, needed by DenseMap.
   enum { Plain, Empty, Tombstone } State;
 
@@ -69,36 +69,35 @@ struct WasmFunctionType {
   // The parameter types of the function.
   SmallVector<wasm::ValType, 4> Params;
 
-  WasmFunctionType() : State(Plain) {}
+  WasmSignature() : State(Plain) {}
 
-  bool operator==(const WasmFunctionType &Other) const {
+  bool operator==(const WasmSignature &Other) const {
     return State == Other.State && Returns == Other.Returns &&
            Params == Other.Params;
   }
 };
 
-// Traits for using WasmFunctionType in a DenseMap.
-struct WasmFunctionTypeDenseMapInfo {
-  static WasmFunctionType getEmptyKey() {
-    WasmFunctionType FuncTy;
-    FuncTy.State = WasmFunctionType::Empty;
-    return FuncTy;
-  }
-  static WasmFunctionType getTombstoneKey() {
-    WasmFunctionType FuncTy;
-    FuncTy.State = WasmFunctionType::Tombstone;
-    return FuncTy;
-  }
-  static unsigned getHashValue(const WasmFunctionType &FuncTy) {
-    uintptr_t Value = FuncTy.State;
-    for (wasm::ValType Ret : FuncTy.Returns)
+// Traits for using WasmSignature in a DenseMap.
+struct WasmSignatureDenseMapInfo {
+  static WasmSignature getEmptyKey() {
+    WasmSignature Sig;
+    Sig.State = WasmSignature::Empty;
+    return Sig;
+  }
+  static WasmSignature getTombstoneKey() {
+    WasmSignature Sig;
+    Sig.State = WasmSignature::Tombstone;
+    return Sig;
+  }
+  static unsigned getHashValue(const WasmSignature &Sig) {
+    uintptr_t Value = Sig.State;
+    for (wasm::ValType Ret : Sig.Returns)
       Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Ret));
-    for (wasm::ValType Param : FuncTy.Params)
+    for (wasm::ValType Param : Sig.Params)
       Value += DenseMapInfo<uint32_t>::getHashValue(uint32_t(Param));
     return Value;
   }
-  static bool isEqual(const WasmFunctionType &LHS,
-                      const WasmFunctionType &RHS) {
+  static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) {
     return LHS == RHS;
   }
 };
@@ -118,7 +117,7 @@ struct WasmDataSegment {
 
 // A wasm function to be written into the function section.
 struct WasmFunction {
-  uint32_t Type;
+  uint32_t SigIndex;
   const MCSymbolWasm *Sym;
 };
 
@@ -216,7 +215,8 @@ class WasmObjectWriter : public MCObject
   // Maps function symbols to the table element index space. Used
   // for TABLE_INDEX relocation types (i.e. address taken functions).
   DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
-  // Maps function/global symbols to the function/global/section index space.
+  // Maps function/global symbols to the function/global/event/section index
+  // space.
   DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
   // Maps data symbols to the Wasm segment and offset/size with the segment.
   DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
@@ -231,13 +231,13 @@ class WasmObjectWriter : public MCObject
   // Map from section to defining function symbol.
   DenseMap<const MCSection *, const MCSymbol *> SectionFunctions;
 
-  DenseMap<WasmFunctionType, uint32_t, WasmFunctionTypeDenseMapInfo>
-      FunctionTypeIndices;
-  SmallVector<WasmFunctionType, 4> FunctionTypes;
+  DenseMap<WasmSignature, uint32_t, WasmSignatureDenseMapInfo> SignatureIndices;
+  SmallVector<WasmSignature, 4> Signatures;
   SmallVector<WasmGlobal, 4> Globals;
   SmallVector<WasmDataSegment, 4> DataSegments;
   unsigned NumFunctionImports = 0;
   unsigned NumGlobalImports = 0;
+  unsigned NumEventImports = 0;
   uint32_t SectionCount = 0;
 
   // TargetObjectWriter wrappers.
@@ -266,8 +266,8 @@ private:
     TableIndices.clear();
     DataLocations.clear();
     CustomSectionsRelocations.clear();
-    FunctionTypeIndices.clear();
-    FunctionTypes.clear();
+    SignatureIndices.clear();
+    Signatures.clear();
     Globals.clear();
     DataSegments.clear();
     SectionFunctions.clear();
@@ -294,7 +294,7 @@ private:
 
   void writeValueType(wasm::ValType Ty) { W.OS << static_cast<char>(Ty); }
 
-  void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
+  void writeTypeSection(ArrayRef<WasmSignature> Signatures);
   void writeImportSection(ArrayRef<wasm::WasmImport> Imports, uint32_t DataSize,
                           uint32_t NumElements);
   void writeFunctionSection(ArrayRef<WasmFunction> Functions);
@@ -304,6 +304,7 @@ private:
   void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
                         ArrayRef<WasmFunction> Functions);
   void writeDataSection();
+  void writeEventSection(ArrayRef<wasm::WasmEventType> Events);
   void writeRelocSection(uint32_t SectionIndex, StringRef Name,
                          std::vector<WasmRelocationEntry> &Relocations);
   void writeLinkingMetaDataSection(
@@ -322,7 +323,9 @@ private:
 
   uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
   uint32_t getFunctionType(const MCSymbolWasm &Symbol);
+  uint32_t getEventType(const MCSymbolWasm &Symbol);
   uint32_t registerFunctionType(const MCSymbolWasm &Symbol);
+  uint32_t registerEventType(const MCSymbolWasm &Symbol);
 };
 
 } // end anonymous namespace
@@ -581,7 +584,8 @@ WasmObjectWriter::getProvisionalValue(co
     return getRelocationIndexValue(RelEntry);
   case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
   case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
-    // Provisional value is function/global Wasm index
+  case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
+    // Provisional value is function/global/event Wasm index
     if (!WasmIndices.count(RelEntry.Symbol))
       report_fatal_error("symbol not found in wasm index space: " +
                          RelEntry.Symbol->getName());
@@ -678,6 +682,7 @@ void WasmObjectWriter::applyRelocations(
     case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
     case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
+    case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
       WritePatchableLEB(Stream, Value, Offset);
       break;
     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
@@ -696,23 +701,22 @@ void WasmObjectWriter::applyRelocations(
   }
 }
 
-void WasmObjectWriter::writeTypeSection(
-    ArrayRef<WasmFunctionType> FunctionTypes) {
-  if (FunctionTypes.empty())
+void WasmObjectWriter::writeTypeSection(ArrayRef<WasmSignature> Signatures) {
+  if (Signatures.empty())
     return;
 
   SectionBookkeeping Section;
   startSection(Section, wasm::WASM_SEC_TYPE);
 
-  encodeULEB128(FunctionTypes.size(), W.OS);
+  encodeULEB128(Signatures.size(), W.OS);
 
-  for (const WasmFunctionType &FuncTy : FunctionTypes) {
+  for (const WasmSignature &Sig : Signatures) {
     W.OS << char(wasm::WASM_TYPE_FUNC);
-    encodeULEB128(FuncTy.Params.size(), W.OS);
-    for (wasm::ValType Ty : FuncTy.Params)
+    encodeULEB128(Sig.Params.size(), W.OS);
+    for (wasm::ValType Ty : Sig.Params)
       writeValueType(Ty);
-    encodeULEB128(FuncTy.Returns.size(), W.OS);
-    for (wasm::ValType Ty : FuncTy.Returns)
+    encodeULEB128(Sig.Returns.size(), W.OS);
+    for (wasm::ValType Ty : Sig.Returns)
       writeValueType(Ty);
   }
 
@@ -753,6 +757,10 @@ void WasmObjectWriter::writeImportSectio
       encodeULEB128(0, W.OS);           // flags
       encodeULEB128(NumElements, W.OS); // initial
       break;
+    case wasm::WASM_EXTERNAL_EVENT:
+      encodeULEB128(Import.Event.Attribute, W.OS);
+      encodeULEB128(Import.Event.SigIndex, W.OS);
+      break;
     default:
       llvm_unreachable("unsupported import kind");
     }
@@ -770,7 +778,7 @@ void WasmObjectWriter::writeFunctionSect
 
   encodeULEB128(Functions.size(), W.OS);
   for (const WasmFunction &Func : Functions)
-    encodeULEB128(Func.Type, W.OS);
+    encodeULEB128(Func.SigIndex, W.OS);
 
   endSection(Section);
 }
@@ -795,6 +803,22 @@ void WasmObjectWriter::writeGlobalSectio
   endSection(Section);
 }
 
+void WasmObjectWriter::writeEventSection(ArrayRef<wasm::WasmEventType> Events) {
+  if (Events.empty())
+    return;
+
+  SectionBookkeeping Section;
+  startSection(Section, wasm::WASM_SEC_EVENT);
+
+  encodeULEB128(Events.size(), W.OS);
+  for (const wasm::WasmEventType &Event : Events) {
+    encodeULEB128(Event.Attribute, W.OS);
+    encodeULEB128(Event.SigIndex, W.OS);
+  }
+
+  endSection(Section);
+}
+
 void WasmObjectWriter::writeExportSection(ArrayRef<wasm::WasmExport> Exports) {
   if (Exports.empty())
     return;
@@ -956,6 +980,7 @@ void WasmObjectWriter::writeLinkingMetaD
       switch (Sym.Kind) {
       case wasm::WASM_SYMBOL_TYPE_FUNCTION:
       case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+      case wasm::WASM_SYMBOL_TYPE_EVENT:
         encodeULEB128(Sym.ElementIndex, W.OS);
         if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
           writeString(Sym.Name);
@@ -1047,20 +1072,25 @@ uint32_t WasmObjectWriter::getFunctionTy
   return TypeIndices[&Symbol];
 }
 
+uint32_t WasmObjectWriter::getEventType(const MCSymbolWasm &Symbol) {
+  assert(Symbol.isEvent());
+  assert(TypeIndices.count(&Symbol));
+  return TypeIndices[&Symbol];
+}
+
 uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm &Symbol) {
   assert(Symbol.isFunction());
 
-  WasmFunctionType F;
+  WasmSignature S;
   const MCSymbolWasm *ResolvedSym = ResolveSymbol(Symbol);
   if (auto *Sig = ResolvedSym->getSignature()) {
-    F.Returns = Sig->Returns;
-    F.Params = Sig->Params;
+    S.Returns = Sig->Returns;
+    S.Params = Sig->Params;
   }
 
-  auto Pair =
-      FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
+  auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
   if (Pair.second)
-    FunctionTypes.push_back(F);
+    Signatures.push_back(S);
   TypeIndices[&Symbol] = Pair.first->second;
 
   LLVM_DEBUG(dbgs() << "registerFunctionType: " << Symbol
@@ -1069,6 +1099,28 @@ uint32_t WasmObjectWriter::registerFunct
   return Pair.first->second;
 }
 
+uint32_t WasmObjectWriter::registerEventType(const MCSymbolWasm &Symbol) {
+  assert(Symbol.isEvent());
+
+  // TODO Currently we don't generate imported exceptions, but if we do, we
+  // should have a way of infering types of imported exceptions.
+  WasmSignature S;
+  if (auto *Sig = Symbol.getSignature()) {
+    S.Returns = Sig->Returns;
+    S.Params = Sig->Params;
+  }
+
+  auto Pair = SignatureIndices.insert(std::make_pair(S, Signatures.size()));
+  if (Pair.second)
+    Signatures.push_back(S);
+  TypeIndices[&Symbol] = Pair.first->second;
+
+  LLVM_DEBUG(dbgs() << "registerEventType: " << Symbol << " new:" << Pair.second
+                    << "\n");
+  LLVM_DEBUG(dbgs() << "  -> type index: " << Pair.first->second << "\n");
+  return Pair.first->second;
+}
+
 static bool isInSymtab(const MCSymbolWasm &Sym) {
   if (Sym.isUsedInReloc())
     return true;
@@ -1100,6 +1152,7 @@ uint64_t WasmObjectWriter::writeObject(M
   SmallVector<uint32_t, 4> TableElems;
   SmallVector<wasm::WasmImport, 4> Imports;
   SmallVector<wasm::WasmExport, 4> Exports;
+  SmallVector<wasm::WasmEventType, 1> Events;
   SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
   SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
   std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
@@ -1128,7 +1181,7 @@ uint64_t WasmObjectWriter::writeObject(M
   TableImport.Table.ElemType = wasm::WASM_TYPE_ANYFUNC;
   Imports.push_back(TableImport);
 
-  // Populate FunctionTypeIndices, and Imports and WasmIndices for undefined
+  // Populate SignatureIndices, and Imports and WasmIndices for undefined
   // symbols.  This must be done before populating WasmIndices for defined
   // symbols.
   for (const MCSymbol &S : Asm.symbols()) {
@@ -1139,6 +1192,9 @@ uint64_t WasmObjectWriter::writeObject(M
     if (WS.isFunction())
       registerFunctionType(WS);
 
+    if (WS.isEvent())
+      registerEventType(WS);
+
     if (WS.isTemporary())
       continue;
 
@@ -1163,6 +1219,18 @@ uint64_t WasmObjectWriter::writeObject(M
         Import.Global = WS.getGlobalType();
         Imports.push_back(Import);
         WasmIndices[&WS] = NumGlobalImports++;
+      } else if (WS.isEvent()) {
+        if (WS.isWeak())
+          report_fatal_error("undefined event symbol cannot be weak");
+
+        wasm::WasmImport Import;
+        Import.Module = WS.getModuleName();
+        Import.Field = WS.getName();
+        Import.Kind = wasm::WASM_EXTERNAL_EVENT;
+        Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
+        Import.Event.SigIndex = getEventType(WS);
+        Imports.push_back(Import);
+        WasmIndices[&WS] = NumEventImports++;
       }
     }
   }
@@ -1254,7 +1322,7 @@ uint64_t WasmObjectWriter::writeObject(M
         // A definition. Write out the function body.
         Index = NumFunctionImports + Functions.size();
         WasmFunction Func;
-        Func.Type = getFunctionType(WS);
+        Func.SigIndex = getFunctionType(WS);
         Func.Sym = &WS;
         WasmIndices[&WS] = Index;
         Functions.push_back(Func);
@@ -1270,6 +1338,7 @@ uint64_t WasmObjectWriter::writeObject(M
       }
 
       LLVM_DEBUG(dbgs() << "  -> function index: " << Index << "\n");
+
     } else if (WS.isData()) {
       if (WS.isTemporary() && !WS.getSize())
         continue;
@@ -1299,6 +1368,7 @@ uint64_t WasmObjectWriter::writeObject(M
           static_cast<uint32_t>(Size)};
       DataLocations[&WS] = Ref;
       LLVM_DEBUG(dbgs() << "  -> segment index: " << Ref.Segment << "\n");
+
     } else if (WS.isGlobal()) {
       // A "true" Wasm global (currently just __stack_pointer)
       if (WS.isDefined())
@@ -1307,6 +1377,24 @@ uint64_t WasmObjectWriter::writeObject(M
       // An import; the index was assigned above
       LLVM_DEBUG(dbgs() << "  -> global index: "
                         << WasmIndices.find(&WS)->second << "\n");
+
+    } else if (WS.isEvent()) {
+      // C++ exception symbol (__cpp_exception)
+      unsigned Index;
+      if (WS.isDefined()) {
+        Index = NumEventImports + Events.size();
+        wasm::WasmEventType Event;
+        Event.SigIndex = getEventType(WS);
+        Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
+        WasmIndices[&WS] = Index;
+        Events.push_back(Event);
+      } else {
+        // An import; the index was assigned above.
+        Index = WasmIndices.find(&WS)->second;
+      }
+      LLVM_DEBUG(dbgs() << "  -> event index: " << WasmIndices.find(&WS)->second
+                        << "\n");
+
     } else {
       assert(WS.isSection());
     }
@@ -1340,7 +1428,7 @@ uint64_t WasmObjectWriter::writeObject(M
       DataLocations[&WS] = Ref;
       LLVM_DEBUG(dbgs() << "  -> index:" << Ref.Segment << "\n");
     } else {
-      report_fatal_error("don't yet support global aliases");
+      report_fatal_error("don't yet support global/event aliases");
     }
   }
 
@@ -1473,12 +1561,13 @@ uint64_t WasmObjectWriter::writeObject(M
   // Write out the Wasm header.
   writeHeader(Asm);
 
-  writeTypeSection(FunctionTypes);
+  writeTypeSection(Signatures);
   writeImportSection(Imports, DataSize, TableElems.size());
   writeFunctionSection(Functions);
   // Skip the "table" section; we import the table instead.
   // Skip the "memory" section; we import the memory instead.
   writeGlobalSection();
+  writeEventSection(Events);
   writeExportSection(Exports);
   writeElemSection(TableElems);
   writeCodeSection(Asm, Layout, Functions);

Modified: llvm/trunk/lib/Object/WasmObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/WasmObjectFile.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Object/WasmObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/WasmObjectFile.cpp Tue Nov 13 18:46:21 2018
@@ -295,6 +295,8 @@ Error WasmObjectFile::parseSection(WasmS
     return parseMemorySection(Ctx);
   case wasm::WASM_SEC_GLOBAL:
     return parseGlobalSection(Ctx);
+  case wasm::WASM_SEC_EVENT:
+    return parseEventSection(Ctx);
   case wasm::WASM_SEC_EXPORT:
     return parseExportSection(Ctx);
   case wasm::WASM_SEC_START:
@@ -439,19 +441,24 @@ Error WasmObjectFile::parseLinkingSectio
 
   std::vector<wasm::WasmImport *> ImportedGlobals;
   std::vector<wasm::WasmImport *> ImportedFunctions;
+  std::vector<wasm::WasmImport *> ImportedEvents;
   ImportedGlobals.reserve(Imports.size());
   ImportedFunctions.reserve(Imports.size());
+  ImportedEvents.reserve(Imports.size());
   for (auto &I : Imports) {
     if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
       ImportedFunctions.emplace_back(&I);
     else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
       ImportedGlobals.emplace_back(&I);
+    else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
+      ImportedEvents.emplace_back(&I);
   }
 
   while (Count--) {
     wasm::WasmSymbolInfo Info;
     const wasm::WasmSignature *FunctionType = nullptr;
     const wasm::WasmGlobalType *GlobalType = nullptr;
+    const wasm::WasmEventType *EventType = nullptr;
 
     Info.Kind = readUint8(Ctx);
     Info.Flags = readVaruint32(Ctx);
@@ -532,6 +539,32 @@ Error WasmObjectFile::parseLinkingSectio
       break;
     }
 
+    case wasm::WASM_SYMBOL_TYPE_EVENT: {
+      Info.ElementIndex = readVaruint32(Ctx);
+      if (!isValidEventIndex(Info.ElementIndex) ||
+          IsDefined != isDefinedEventIndex(Info.ElementIndex))
+        return make_error<GenericBinaryError>("invalid event symbol index",
+                                              object_error::parse_failed);
+      if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
+                            wasm::WASM_SYMBOL_BINDING_WEAK)
+        return make_error<GenericBinaryError>("undefined weak global symbol",
+                                              object_error::parse_failed);
+      if (IsDefined) {
+        Info.Name = readString(Ctx);
+        unsigned EventIndex = Info.ElementIndex - NumImportedEvents;
+        wasm::WasmEvent &Event = Events[EventIndex];
+        EventType = &Event.Type;
+        if (Event.SymbolName.empty())
+          Event.SymbolName = Info.Name;
+
+      } else {
+        wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
+        EventType = &Import.Event;
+        Info.Name = Import.Field;
+      }
+      break;
+    }
+
     default:
       return make_error<GenericBinaryError>("Invalid symbol type",
                                             object_error::parse_failed);
@@ -545,7 +578,7 @@ Error WasmObjectFile::parseLinkingSectio
                                             object_error::parse_failed);
     LinkingData.SymbolTable.emplace_back(Info);
     Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
-                         GlobalType);
+                         GlobalType, EventType);
     LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
   }
 
@@ -635,6 +668,11 @@ Error WasmObjectFile::parseRelocSection(
         return make_error<GenericBinaryError>("Bad relocation global index",
                                               object_error::parse_failed);
       break;
+    case wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB:
+      if (!isValidEventSymbol(Reloc.Index))
+        return make_error<GenericBinaryError>("Bad relocation event index",
+                                              object_error::parse_failed);
+      break;
     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
@@ -755,6 +793,11 @@ Error WasmObjectFile::parseImportSection
         return make_error<GenericBinaryError>("Invalid table element type",
                                               object_error::parse_failed);
       break;
+    case wasm::WASM_EXTERNAL_EVENT:
+      NumImportedEvents++;
+      Im.Event.Attribute = readVarint32(Ctx);
+      Im.Event.SigIndex = readVarint32(Ctx);
+      break;
     default:
       return make_error<GenericBinaryError>("Unexpected import kind",
                                             object_error::parse_failed);
@@ -831,6 +874,24 @@ Error WasmObjectFile::parseGlobalSection
   return Error::success();
 }
 
+Error WasmObjectFile::parseEventSection(ReadContext &Ctx) {
+  EventSection = Sections.size();
+  uint32_t Count = readVarint32(Ctx);
+  Events.reserve(Count);
+  while (Count--) {
+    wasm::WasmEvent Event;
+    Event.Index = NumImportedEvents + Events.size();
+    Event.Type.Attribute = readVaruint32(Ctx);
+    Event.Type.SigIndex = readVarint32(Ctx);
+    Events.push_back(Event);
+  }
+
+  if (Ctx.Ptr != Ctx.End)
+    return make_error<GenericBinaryError>("Event section ended prematurely",
+                                          object_error::parse_failed);
+  return Error::success();
+}
+
 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
   uint32_t Count = readVaruint32(Ctx);
   Exports.reserve(Count);
@@ -850,6 +911,11 @@ Error WasmObjectFile::parseExportSection
         return make_error<GenericBinaryError>("Invalid global export",
                                               object_error::parse_failed);
       break;
+    case wasm::WASM_EXTERNAL_EVENT:
+      if (!isValidEventIndex(Ex.Index))
+        return make_error<GenericBinaryError>("Invalid event export",
+                                              object_error::parse_failed);
+      break;
     case wasm::WASM_EXTERNAL_MEMORY:
     case wasm::WASM_EXTERNAL_TABLE:
       break;
@@ -881,6 +947,14 @@ bool WasmObjectFile::isDefinedGlobalInde
   return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
 }
 
+bool WasmObjectFile::isValidEventIndex(uint32_t Index) const {
+  return Index < NumImportedEvents + Events.size();
+}
+
+bool WasmObjectFile::isDefinedEventIndex(uint32_t Index) const {
+  return Index >= NumImportedEvents && isValidEventIndex(Index);
+}
+
 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
   return Index < Symbols.size() && Symbols[Index].isTypeFunction();
 }
@@ -889,6 +963,10 @@ bool WasmObjectFile::isValidGlobalSymbol
   return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
 }
 
+bool WasmObjectFile::isValidEventSymbol(uint32_t Index) const {
+  return Index < Symbols.size() && Symbols[Index].isTypeEvent();
+}
+
 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
   return Index < Symbols.size() && Symbols[Index].isTypeData();
 }
@@ -907,6 +985,11 @@ wasm::WasmGlobal &WasmObjectFile::getDef
   return Globals[Index - NumImportedGlobals];
 }
 
+wasm::WasmEvent &WasmObjectFile::getDefinedEvent(uint32_t Index) {
+  assert(isDefinedEventIndex(Index));
+  return Events[Index - NumImportedEvents];
+}
+
 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
   StartFunction = readVaruint32(Ctx);
   if (!isValidFunctionIndex(StartFunction))
@@ -1070,6 +1153,7 @@ uint64_t WasmObjectFile::getWasmSymbolVa
   switch (Sym.Info.Kind) {
   case wasm::WASM_SYMBOL_TYPE_FUNCTION:
   case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+  case wasm::WASM_SYMBOL_TYPE_EVENT:
     return Sym.Info.ElementIndex;
   case wasm::WASM_SYMBOL_TYPE_DATA: {
     // The value of a data symbol is the segment offset, plus the symbol
@@ -1112,6 +1196,8 @@ WasmObjectFile::getSymbolType(DataRefImp
     return SymbolRef::ST_Data;
   case wasm::WASM_SYMBOL_TYPE_SECTION:
     return SymbolRef::ST_Debug;
+  case wasm::WASM_SYMBOL_TYPE_EVENT:
+    return SymbolRef::ST_Other;
   }
 
   llvm_unreachable("Unknown WasmSymbol::SymbolType");
@@ -1135,10 +1221,12 @@ WasmObjectFile::getSymbolSection(DataRef
   case wasm::WASM_SYMBOL_TYPE_DATA:
     Ref.d.a = DataSection;
     break;
-  case wasm::WASM_SYMBOL_TYPE_SECTION: {
+  case wasm::WASM_SYMBOL_TYPE_SECTION:
     Ref.d.a = Sym.Info.ElementIndex;
     break;
-  }
+  case wasm::WASM_SYMBOL_TYPE_EVENT:
+    Ref.d.a = EventSection;
+    break;
   default:
     llvm_unreachable("Unknown WasmSymbol::SymbolType");
   }
@@ -1161,6 +1249,7 @@ std::error_code WasmObjectFile::getSecti
     ECase(TABLE);
     ECase(MEMORY);
     ECase(GLOBAL);
+    ECase(EVENT);
     ECase(EXPORT);
     ECase(START);
     ECase(ELEM);

Modified: llvm/trunk/lib/ObjectYAML/WasmYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/WasmYAML.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/WasmYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/WasmYAML.cpp Tue Nov 13 18:46:21 2018
@@ -100,6 +100,11 @@ static void sectionMapping(IO &IO, WasmY
   IO.mapOptional("Globals", Section.Globals);
 }
 
+static void sectionMapping(IO &IO, WasmYAML::EventSection &Section) {
+  commonSectionMapping(IO, Section);
+  IO.mapOptional("Events", Section.Events);
+}
+
 static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) {
   commonSectionMapping(IO, Section);
   IO.mapOptional("Exports", Section.Exports);
@@ -187,6 +192,11 @@ void MappingTraits<std::unique_ptr<WasmY
       Section.reset(new WasmYAML::GlobalSection());
     sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
     break;
+  case wasm::WASM_SEC_EVENT:
+    if (!IO.outputting())
+      Section.reset(new WasmYAML::EventSection());
+    sectionMapping(IO, *cast<WasmYAML::EventSection>(Section.get()));
+    break;
   case wasm::WASM_SEC_EXPORT:
     if (!IO.outputting())
       Section.reset(new WasmYAML::ExportSection());
@@ -227,6 +237,7 @@ void ScalarEnumerationTraits<WasmYAML::S
   ECase(TABLE);
   ECase(MEMORY);
   ECase(GLOBAL);
+  ECase(EVENT);
   ECase(EXPORT);
   ECase(START);
   ECase(ELEM);
@@ -307,6 +318,9 @@ void MappingTraits<WasmYAML::Import>::ma
   } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
     IO.mapRequired("GlobalType", Import.GlobalImport.Type);
     IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
+  } else if (Import.Kind == wasm::WASM_EXTERNAL_EVENT) {
+    IO.mapRequired("EventAttribute", Import.EventImport.Attribute);
+    IO.mapRequired("EventSigIndex", Import.EventImport.SigIndex);
   } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
     IO.mapRequired("Table", Import.TableImport);
   } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) {
@@ -399,6 +413,8 @@ void MappingTraits<WasmYAML::SymbolInfo>
     IO.mapRequired("Function", Info.ElementIndex);
   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
     IO.mapRequired("Global", Info.ElementIndex);
+  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
+    IO.mapRequired("Event", Info.ElementIndex);
   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
     if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
       IO.mapRequired("Segment", Info.DataRef.Segment);
@@ -412,6 +428,12 @@ void MappingTraits<WasmYAML::SymbolInfo>
   }
 }
 
+void MappingTraits<WasmYAML::Event>::mapping(IO &IO, WasmYAML::Event &Event) {
+  IO.mapRequired("Index", Event.Index);
+  IO.mapRequired("Attribute", Event.Attribute);
+  IO.mapRequired("SigIndex", Event.SigIndex);
+}
+
 void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
     IO &IO, WasmYAML::LimitFlags &Value) {
 #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
@@ -443,6 +465,7 @@ void ScalarEnumerationTraits<WasmYAML::S
   ECase(DATA);
   ECase(GLOBAL);
   ECase(SECTION);
+  ECase(EVENT);
 #undef ECase
 }
 
@@ -467,6 +490,7 @@ void ScalarEnumerationTraits<WasmYAML::E
   ECase(TABLE);
   ECase(MEMORY);
   ECase(GLOBAL);
+  ECase(EVENT);
 #undef ECase
 }
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp Tue Nov 13 18:46:21 2018
@@ -86,6 +86,7 @@ void WebAssemblyMCCodeEmitter::encodeIns
     const MCOperand &MO = MI.getOperand(i);
     if (MO.isReg()) {
       /* nothing to encode */
+
     } else if (MO.isImm()) {
       if (i < Desc.getNumOperands()) {
         assert(Desc.TSFlags == 0 &&
@@ -128,6 +129,7 @@ void WebAssemblyMCCodeEmitter::encodeIns
                                 WebAssemblyII::VariableOpImmediateIsLabel));
         encodeULEB128(uint64_t(MO.getImm()), OS);
       }
+
     } else if (MO.isFPImm()) {
       assert(i < Desc.getNumOperands() &&
              "Unexpected floating-point immediate as a non-fixed operand");
@@ -144,22 +146,27 @@ void WebAssemblyMCCodeEmitter::encodeIns
         double d = MO.getFPImm();
         support::endian::write<double>(OS, d, support::little);
       }
+
     } else if (MO.isExpr()) {
       const MCOperandInfo &Info = Desc.OpInfo[i];
       llvm::MCFixupKind FixupKind;
       size_t PaddedSize = 5;
-      if (Info.OperandType == WebAssembly::OPERAND_I32IMM) {
+      switch (Info.OperandType) {
+      case WebAssembly::OPERAND_I32IMM:
         FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i32);
-      } else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) {
+        break;
+      case WebAssembly::OPERAND_I64IMM:
         FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i64);
         PaddedSize = 10;
-      } else if (Info.OperandType == WebAssembly::OPERAND_FUNCTION32 ||
-                 Info.OperandType == WebAssembly::OPERAND_OFFSET32 ||
-                 Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) {
+        break;
+      case WebAssembly::OPERAND_FUNCTION32:
+      case WebAssembly::OPERAND_OFFSET32:
+      case WebAssembly::OPERAND_TYPEINDEX:
+      case WebAssembly::OPERAND_GLOBAL:
+      case WebAssembly::OPERAND_EVENT:
         FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32);
-      } else if (Info.OperandType == WebAssembly::OPERAND_GLOBAL) {
-        FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32);
-      } else {
+        break;
+      default:
         llvm_unreachable("unexpected symbolic operand kind");
       }
       Fixups.push_back(MCFixup::create(OS.tell() - Start, MO.getExpr(),

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h Tue Nov 13 18:46:21 2018
@@ -77,6 +77,8 @@ enum OperandType {
   OPERAND_SIGNATURE,
   /// type signature immediate for call_indirect.
   OPERAND_TYPEINDEX,
+  /// Event index.
+  OPERAND_EVENT,
 };
 } // end namespace WebAssembly
 
@@ -97,7 +99,8 @@ enum TOF {
   // Flags to indicate the type of the symbol being referenced
   MO_SYMBOL_FUNCTION = 0x1,
   MO_SYMBOL_GLOBAL = 0x2,
-  MO_SYMBOL_MASK = 0x3,
+  MO_SYMBOL_EVENT = 0x4,
+  MO_SYMBOL_MASK = 0x7,
 };
 } // end namespace WebAssemblyII
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp Tue Nov 13 18:46:21 2018
@@ -100,12 +100,28 @@ void WebAssemblyTargetAsmStreamer::emitI
 }
 
 void WebAssemblyTargetAsmStreamer::emitGlobalType(MCSymbolWasm *Sym) {
+  assert(Sym->isGlobal());
   OS << "\t.globaltype\t" << Sym->getName() << ", " <<
         WebAssembly::TypeToString(
           static_cast<wasm::ValType>(Sym->getGlobalType().Type)) <<
         '\n';
 }
 
+void WebAssemblyTargetAsmStreamer::emitEventType(MCSymbolWasm *Sym) {
+  assert(Sym->isEvent());
+  OS << "\t.eventtype\t" << Sym->getName();
+  if (Sym->getSignature()->Returns.empty())
+    OS << ", void";
+  else {
+    assert(Sym->getSignature()->Returns.size() == 1);
+    OS << ", "
+       << WebAssembly::TypeToString(Sym->getSignature()->Returns.front());
+  }
+  for (auto Ty : Sym->getSignature()->Params)
+    OS << ", " << WebAssembly::TypeToString(Ty);
+  OS << '\n';
+}
+
 void WebAssemblyTargetAsmStreamer::emitImportModule(MCSymbolWasm *Sym,
                                                     StringRef ModuleName) {
   OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n';
@@ -159,6 +175,9 @@ void WebAssemblyTargetWasmStreamer::emit
   // Not needed.
 }
 
+void WebAssemblyTargetWasmStreamer::emitEventType(MCSymbolWasm *Sym) {
+  // Not needed.
+}
 void WebAssemblyTargetWasmStreamer::emitImportModule(MCSymbolWasm *Sym,
                                                      StringRef ModuleName) {
   Sym->setModuleName(ModuleName);

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.h Tue Nov 13 18:46:21 2018
@@ -45,6 +45,8 @@ public:
   virtual void emitIndIdx(const MCExpr *Value) = 0;
   /// .globaltype
   virtual void emitGlobalType(MCSymbolWasm *Sym) = 0;
+  /// .eventtype
+  virtual void emitEventType(MCSymbolWasm *Sym) = 0;
   /// .import_module
   virtual void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) = 0;
 
@@ -66,6 +68,7 @@ public:
   void emitIndirectFunctionType(MCSymbolWasm *Symbol) override;
   void emitIndIdx(const MCExpr *Value) override;
   void emitGlobalType(MCSymbolWasm *Sym) override;
+  void emitEventType(MCSymbolWasm *Sym) override;
   void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
 };
 
@@ -81,6 +84,7 @@ public:
   void emitIndirectFunctionType(MCSymbolWasm *Symbol) override;
   void emitIndIdx(const MCExpr *Value) override;
   void emitGlobalType(MCSymbolWasm *Sym) override;
+  void emitEventType(MCSymbolWasm *Sym) override;
   void emitImportModule(MCSymbolWasm *Sym, StringRef ModuleName) override;
 };
 

Modified: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp Tue Nov 13 18:46:21 2018
@@ -86,6 +86,11 @@ static bool IsGlobalType(const MCValue &
   return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_GLOBAL;
 }
 
+static bool IsEventType(const MCValue &Target) {
+  const MCSymbolRefExpr *RefA = Target.getSymA();
+  return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_EVENT;
+}
+
 unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
                                                    const MCFixup &Fixup) const {
   // WebAssembly functions are not allocated in the data address space. To
@@ -106,6 +111,8 @@ unsigned WebAssemblyWasmObjectWriter::ge
       return wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB;
     if (IsFunction)
       return wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB;
+    if (IsEventType(Target))
+      return wasm::R_WEBASSEMBLY_EVENT_INDEX_LEB;
     return wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB;
   case FK_Data_4:
     if (IsFunction)

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Tue Nov 13 18:46:21 2018
@@ -79,11 +79,12 @@ WebAssemblyTargetStreamer *WebAssemblyAs
 
 void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
   for (auto &It : OutContext.getSymbols()) {
-    // Emit a .globaltype declaration.
+    // Emit a .globaltype and .eventtype declaration.
     auto Sym = cast<MCSymbolWasm>(It.getValue());
-    if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+    if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL)
       getTargetStreamer()->emitGlobalType(Sym);
-    }
+    else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
+      getTargetStreamer()->emitEventType(Sym);
   }
 
   for (const auto &F : M) {

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISD.def Tue Nov 13 18:46:21 2018
@@ -25,5 +25,6 @@ HANDLE_NODETYPE(SHUFFLE)
 HANDLE_NODETYPE(VEC_SHL)
 HANDLE_NODETYPE(VEC_SHR_S)
 HANDLE_NODETYPE(VEC_SHR_U)
+HANDLE_NODETYPE(THROW)
 
 // add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here...

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Tue Nov 13 18:46:21 2018
@@ -24,6 +24,7 @@
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/WasmEHFuncInfo.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/Function.h"
@@ -234,6 +235,7 @@ WebAssemblyTargetLowering::WebAssemblyTa
 
   // Exception handling intrinsics
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
+  setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
 
   setMaxAtomicSizeInBitsSupported(64);
 }
@@ -882,6 +884,8 @@ SDValue WebAssemblyTargetLowering::Lower
   case ISD::EXTRACT_VECTOR_ELT:
   case ISD::INSERT_VECTOR_ELT:
     return LowerAccessVectorElement(Op, DAG);
+  case ISD::INTRINSIC_VOID:
+    return LowerINTRINSIC_VOID(Op, DAG);
   case ISD::VECTOR_SHUFFLE:
     return LowerVECTOR_SHUFFLE(Op, DAG);
   case ISD::SHL:
@@ -1044,6 +1048,44 @@ WebAssemblyTargetLowering::LowerINTRINSI
   }
   }
 }
+
+SDValue
+WebAssemblyTargetLowering::LowerINTRINSIC_VOID(SDValue Op,
+                                               SelectionDAG &DAG) const {
+  MachineFunction &MF = DAG.getMachineFunction();
+  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
+  SDLoc DL(Op);
+
+  switch (IntNo) {
+  default:
+    return {}; // Don't custom lower most intrinsics.
+
+  case Intrinsic::wasm_throw: {
+    int Tag = cast<ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue();
+    switch (Tag) {
+    case CPP_EXCEPTION: {
+      const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+      MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+      const char *SymName = MF.createExternalSymbolName("__cpp_exception");
+      SDValue SymNode =
+          DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
+                      DAG.getTargetExternalSymbol(
+                          SymName, PtrVT, WebAssemblyII::MO_SYMBOL_EVENT));
+      return DAG.getNode(WebAssemblyISD::THROW, DL,
+                         MVT::Other, // outchain type
+                         {
+                             Op.getOperand(0), // inchain
+                             SymNode,          // exception symbol
+                             Op.getOperand(3)  // thrown value
+                         });
+    }
+    default:
+      llvm_unreachable("Invalid tag!");
+    }
+    break;
+  }
+  }
+}
 
 SDValue
 WebAssemblyTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Tue Nov 13 18:46:21 2018
@@ -98,6 +98,7 @@ private:
   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerCopyToReg(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerAccessVectorElement(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerShift(SDValue Op, SelectionDAG &DAG) const;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrControl.td Tue Nov 13 18:46:21 2018
@@ -146,14 +146,16 @@ let Predicates = [HasExceptionHandling]
 
 // Throwing an exception: throw / rethrow
 let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
-defm THROW_I32 : I<(outs), (ins i32imm:$tag, I32:$val),
-                   (outs), (ins i32imm:$tag),
-                   [(int_wasm_throw imm:$tag, I32:$val)],
+defm THROW_I32 : I<(outs), (ins event_op:$tag, I32:$val),
+                   (outs), (ins event_op:$tag),
+                   [(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag),
+                                      I32:$val)],
                    "throw   \t$tag, $val", "throw   \t$tag",
                    0x08>;
-defm THROW_I64 : I<(outs), (ins i32imm:$tag, I64:$val),
-                   (outs), (ins i32imm:$tag),
-                   [(int_wasm_throw imm:$tag, I64:$val)],
+defm THROW_I64 : I<(outs), (ins event_op:$tag, I64:$val),
+                   (outs), (ins event_op:$tag),
+                   [(WebAssemblythrow (WebAssemblywrapper texternalsym:$tag),
+                                      I64:$val)],
                    "throw   \t$tag, $val", "throw   \t$tag",
                    0x08>;
 defm RETHROW : NRI<(outs), (ins bb_op:$dst), [], "rethrow \t$dst", 0x09>;

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Tue Nov 13 18:46:21 2018
@@ -64,6 +64,7 @@ def SDT_WebAssemblyArgument : SDTypeProf
 def SDT_WebAssemblyReturn   : SDTypeProfile<0, -1, []>;
 def SDT_WebAssemblyWrapper  : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>,
                                                    SDTCisPtrTy<0>]>;
+def SDT_WebAssemblyThrow    : SDTypeProfile<0, 2, [SDTCisPtrTy<0>]>;
 
 //===----------------------------------------------------------------------===//
 // WebAssembly-specific DAG Nodes.
@@ -90,6 +91,8 @@ def WebAssemblyreturn   : SDNode<"WebAss
                                  SDT_WebAssemblyReturn, [SDNPHasChain]>;
 def WebAssemblywrapper  : SDNode<"WebAssemblyISD::Wrapper",
                                  SDT_WebAssemblyWrapper>;
+def WebAssemblythrow : SDNode<"WebAssemblyISD::THROW", SDT_WebAssemblyThrow,
+                              [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
 // WebAssembly-specific Operands.
@@ -140,6 +143,10 @@ let OperandType = "OPERAND_P2ALIGN" in {
 def P2Align : Operand<i32> {
   let PrintMethod = "printWebAssemblyP2AlignOperand";
 }
+
+let OperandType = "OPERAND_EVENT" in
+def event_op : Operand<i32>;
+
 } // OperandType = "OPERAND_P2ALIGN"
 
 let OperandType = "OPERAND_SIGNATURE" in {

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp Tue Nov 13 18:46:21 2018
@@ -75,10 +75,10 @@ MCSymbol *WebAssemblyMCInstLower::GetExt
       cast<MCSymbolWasm>(Printer.GetExternalSymbolSymbol(Name));
   const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
 
-  // __stack_pointer is a global variable; all other external symbols used by
-  // CodeGen are functions.  It's OK to hardcode knowledge of specific symbols
-  // here; this method is precisely there for fetching the signatures of known
-  // Clang-provided symbols.
+  // Except for the two exceptions (__stack_pointer and __cpp_exception), all
+  // other external symbols used by CodeGen are functions. It's OK to hardcode
+  // knowledge of specific symbols here; this method is precisely there for
+  // fetching the signatures of known Clang-provided symbols.
   if (strcmp(Name, "__stack_pointer") == 0) {
     WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
     WasmSym->setGlobalType(wasm::WasmGlobalType{
@@ -90,24 +90,45 @@ MCSymbol *WebAssemblyMCInstLower::GetExt
 
   SmallVector<wasm::ValType, 4> Returns;
   SmallVector<wasm::ValType, 4> Params;
-  GetLibcallSignature(Subtarget, Name, Returns, Params);
+  if (strcmp(Name, "__cpp_exception") == 0) {
+    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_EVENT);
+    // We can't confirm its signature index for now because there can be
+    // imported exceptions. Set it to be 0 for now.
+    WasmSym->setEventType(
+        {wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION, /* SigIndex */ 0});
+    // We may have multiple C++ compilation units to be linked together, each of
+    // which defines the exception symbol. To resolve them, we declare them as
+    // weak.
+    WasmSym->setWeak(true);
+    WasmSym->setExternal(true);
+
+    // All C++ exceptions are assumed to have a single i32 (for wasm32) or i64
+    // (for wasm64) param type and void return type. The reaon is, all C++
+    // exception values are pointers, and to share the type section with
+    // functions, exceptions are assumed to have void return type.
+    Params.push_back(Subtarget.hasAddr64() ? wasm::ValType::I64
+                                           : wasm::ValType::I32);
+  } else { // Function symbols
+    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
+    GetLibcallSignature(Subtarget, Name, Returns, Params);
+  }
   auto Signature =
       make_unique<wasm::WasmSignature>(std::move(Returns), std::move(Params));
   WasmSym->setSignature(Signature.get());
   Printer.addSignature(std::move(Signature));
-  WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
 
   return WasmSym;
 }
 
 MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
                                                      int64_t Offset,
-                                                     bool IsFunc,
-                                                     bool IsGlob) const {
+                                                     bool IsFunc, bool IsGlob,
+                                                     bool IsEvent) const {
   MCSymbolRefExpr::VariantKind VK =
       IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
              : IsGlob ? MCSymbolRefExpr::VK_WebAssembly_GLOBAL
-                      : MCSymbolRefExpr::VK_None;
+                      : IsEvent ? MCSymbolRefExpr::VK_WebAssembly_EVENT
+                                : MCSymbolRefExpr::VK_None;
 
   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);
 
@@ -116,6 +137,8 @@ MCOperand WebAssemblyMCInstLower::LowerS
       report_fatal_error("Function addresses with offsets not supported");
     if (IsGlob)
       report_fatal_error("Global indexes with offsets not supported");
+    if (IsEvent)
+      report_fatal_error("Event indexes with offsets not supported");
     Expr =
         MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, Ctx), Ctx);
   }
@@ -218,7 +241,7 @@ void WebAssemblyMCInstLower::Lower(const
              "WebAssembly does not use target flags on GlobalAddresses");
       MCOp = LowerSymbolOperand(GetGlobalAddressSymbol(MO), MO.getOffset(),
                                 MO.getGlobal()->getValueType()->isFunctionTy(),
-                                false);
+                                false, false);
       break;
     case MachineOperand::MO_ExternalSymbol:
       // The target flag indicates whether this is a symbol for a
@@ -228,14 +251,16 @@ void WebAssemblyMCInstLower::Lower(const
       MCOp = LowerSymbolOperand(
           GetExternalSymbolSymbol(MO), /*Offset=*/0,
           (MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_FUNCTION) != 0,
-          (MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0);
+          (MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_GLOBAL) != 0,
+          (MO.getTargetFlags() & WebAssemblyII::MO_SYMBOL_EVENT) != 0);
       break;
     case MachineOperand::MO_MCSymbol:
       // This is currently used only for LSDA symbols (GCC_except_table),
       // because global addresses or other external symbols are handled above.
       assert(MO.getTargetFlags() == 0 &&
              "WebAssembly does not use target flags on MCSymbol");
-      MCOp = LowerSymbolOperand(MO.getMCSymbol(), /*Offset=*/0, false, false);
+      MCOp = LowerSymbolOperand(MO.getMCSymbol(), /*Offset=*/0, false, false,
+                                false);
       break;
     }
 

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.h?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.h Tue Nov 13 18:46:21 2018
@@ -34,7 +34,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssembl
   MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
   MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
   MCOperand LowerSymbolOperand(MCSymbol *Sym, int64_t Offset, bool IsFunc,
-                               bool IsGlob) const;
+                               bool IsGlob, bool IsEvent) const;
 
 public:
   WebAssemblyMCInstLower(MCContext &ctx, WebAssemblyAsmPrinter &printer)

Modified: llvm/trunk/test/CodeGen/WebAssembly/exception.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/exception.ll?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/exception.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/exception.ll Tue Nov 13 18:46:21 2018
@@ -13,7 +13,7 @@ declare void @llvm.wasm.throw(i32, i8*)
 
 ; CHECK-LABEL: test_throw:
 ; CHECK-NEXT: i32.const $push0=, 0
-; CHECK-NEXT: throw 0, $pop0
+; CHECK-NEXT: throw __cpp_exception at EVENT, $pop0
 define void @test_throw() {
   call void @llvm.wasm.throw(i32 0, i8* null)
   ret void
@@ -259,3 +259,6 @@ declare void @__cxa_rethrow()
 declare void @__clang_call_terminate(i8*)
 declare void @_ZSt9terminatev()
 declare %struct.Cleanup* @_ZN7CleanupD1Ev(%struct.Cleanup* returned)
+
+; CHECK: __cpp_exception:
+; CHECK: .eventtype  __cpp_exception, void, i32

Added: llvm/trunk/test/MC/WebAssembly/event-section.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/event-section.ll?rev=346825&view=auto
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/event-section.ll (added)
+++ llvm/trunk/test/MC/WebAssembly/event-section.ll Tue Nov 13 18:46:21 2018
@@ -0,0 +1,58 @@
+; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %s -o - | obj2yaml | FileCheck %s
+; RUN: llc -filetype=obj -exception-model=wasm -mattr=+exception-handling %s -o - | llvm-readobj -s | FileCheck -check-prefix=SEC %s
+
+target triple = "wasm32-unknown-unknown"
+
+declare void @llvm.wasm.throw(i32, i8*)
+
+define i32 @test_throw0(i8* %p) {
+  call void @llvm.wasm.throw(i32 0, i8* %p)
+  ret i32 0
+}
+
+define i32 @test_throw1(i8* %p) {
+  call void @llvm.wasm.throw(i32 0, i8* %p)
+  ret i32 1
+}
+
+; CHECK:      Sections:
+; CHECK-NEXT:   - Type:            TYPE
+; CHECK-NEXT:     Signatures:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         ReturnType:      I32
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:           - I32
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         ReturnType:      NORESULT
+; CHECK-NEXT:         ParamTypes:
+; CHECK-NEXT:           - I32
+
+; CHECK:        - Type:            EVENT
+; CHECK-NEXT:     Events:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Attribute:       0
+; CHECK-NEXT:         SigIndex:        1
+
+; CHECK-NEXT:   - Type:            CODE
+; CHECK-NEXT:     Relocations:
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_EVENT_INDEX_LEB
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Offset:          0x00000006
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_EVENT_INDEX_LEB
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Offset:          0x00000013
+
+; CHECK:        - Type:            CUSTOM
+; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         1
+; CHECK-NEXT:     SymbolTable:
+
+; CHECK:            - Index:           1
+; CHECK-NEXT:         Kind:            EVENT
+; CHECK-NEXT:         Name:            __cpp_exception
+; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
+; CHECK-NEXT:         Event:           0
+
+; SEC:          Type: EVENT (0xC)
+; SEC-NEXT:     Size: 3
+; SEC-NEXT:     Offset: 97

Added: llvm/trunk/test/ObjectYAML/wasm/event_section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/wasm/event_section.yaml?rev=346825&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/wasm/event_section.yaml (added)
+++ llvm/trunk/test/ObjectYAML/wasm/event_section.yaml Tue Nov 13 18:46:21 2018
@@ -0,0 +1,92 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !WASM
+FileHeader:
+  Version:         0x00000001
+Sections:
+  - Type:            TYPE
+    Signatures:
+      - Index:           0
+        ReturnType:      I32
+        ParamTypes:
+          - I32
+      - Index:           1
+        ReturnType:      NORESULT
+        ParamTypes:
+          - I32
+  - Type:            FUNCTION
+    FunctionTypes:   [ 0 ]
+  - Type:            EVENT
+    Events:
+      - Index:           0
+        Attribute:       0
+        SigIndex:        1
+  - Type:            CODE
+    Relocations:
+      - Type:            R_WEBASSEMBLY_EVENT_INDEX_LEB
+        Index:           1
+        Offset:          0x00000006
+    Functions:
+      - Index:           0
+        Locals:
+        Body:            200008808080800041000B
+  - Type:            CUSTOM
+    Name:            linking
+    Version:         1
+    SymbolTable:
+      - Index:           0
+        Kind:            FUNCTION
+        Name:            test_throw0
+        Flags:           [  ]
+        Function:        0
+      - Index:           1
+        Kind:            EVENT
+        Name:            __cpp_exception
+        Flags:           [ BINDING_WEAK ]
+        Event:           0
+...
+
+# CHECK:      --- !WASM
+# CHECK-NEXT: FileHeader:
+# CHECK-NEXT:   Version:         0x00000001
+# CHECK-NEXT: Sections:
+# CHECK-NEXT:   - Type:            TYPE
+# CHECK-NEXT:     Signatures:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         ReturnType:      I32
+# CHECK-NEXT:         ParamTypes:
+# CHECK-NEXT:           - I32
+# CHECK-NEXT:       - Index:           1
+# CHECK-NEXT:         ReturnType:      NORESULT
+# CHECK-NEXT:         ParamTypes:
+# CHECK-NEXT:           - I32
+# CHECK-NEXT:   - Type:            FUNCTION
+# CHECK-NEXT:     FunctionTypes:   [ 0 ]
+# CHECK-NEXT:   - Type:            EVENT
+# CHECK-NEXT:     Events:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         Attribute:       0
+# CHECK-NEXT:         SigIndex:        1
+# CHECK-NEXT:   - Type:            CODE
+# CHECK-NEXT:     Relocations:
+# CHECK-NEXT:       - Type:            R_WEBASSEMBLY_EVENT_INDEX_LEB
+# CHECK-NEXT:         Index:           1
+# CHECK-NEXT:         Offset:          0x00000006
+# CHECK-NEXT:     Functions:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         Locals:
+# CHECK-NEXT:         Body:            200008808080800041000B
+# CHECK-NEXT:   - Type:            CUSTOM
+# CHECK-NEXT:     Name:            linking
+# CHECK-NEXT:     Version:         1
+# CHECK-NEXT:     SymbolTable:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         Kind:            FUNCTION
+# CHECK-NEXT:         Name:            test_throw0
+# CHECK-NEXT:         Flags:           [  ]
+# CHECK-NEXT:         Function:        0
+# CHECK-NEXT:       - Index:           1
+# CHECK-NEXT:         Kind:            EVENT
+# CHECK-NEXT:         Name:            __cpp_exception
+# CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
+# CHECK-NEXT:         Event:           0

Modified: llvm/trunk/tools/llvm-readobj/WasmDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/WasmDumper.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/WasmDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/WasmDumper.cpp Tue Nov 13 18:46:21 2018
@@ -25,20 +25,19 @@ namespace {
 static const EnumEntry<unsigned> WasmSymbolTypes[] = {
 #define ENUM_ENTRY(X)                                                          \
   { #X, wasm::WASM_SYMBOL_TYPE_##X }
-    ENUM_ENTRY(FUNCTION),
-    ENUM_ENTRY(DATA),
-    ENUM_ENTRY(GLOBAL),
-    ENUM_ENTRY(SECTION),
+    ENUM_ENTRY(FUNCTION), ENUM_ENTRY(DATA),  ENUM_ENTRY(GLOBAL),
+    ENUM_ENTRY(SECTION),  ENUM_ENTRY(EVENT),
 #undef ENUM_ENTRY
 };
 
 static const EnumEntry<uint32_t> WasmSectionTypes[] = {
 #define ENUM_ENTRY(X)                                                          \
   { #X, wasm::WASM_SEC_##X }
-    ENUM_ENTRY(CUSTOM),   ENUM_ENTRY(TYPE),   ENUM_ENTRY(IMPORT),
-    ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE),  ENUM_ENTRY(MEMORY),
-    ENUM_ENTRY(GLOBAL),   ENUM_ENTRY(EXPORT), ENUM_ENTRY(START),
-    ENUM_ENTRY(ELEM),     ENUM_ENTRY(CODE),   ENUM_ENTRY(DATA),
+    ENUM_ENTRY(CUSTOM),   ENUM_ENTRY(TYPE),  ENUM_ENTRY(IMPORT),
+    ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
+    ENUM_ENTRY(GLOBAL),   ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
+    ENUM_ENTRY(START),    ENUM_ENTRY(ELEM),  ENUM_ENTRY(CODE),
+    ENUM_ENTRY(DATA),
 #undef ENUM_ENTRY
 };
 

Modified: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/wasm2yaml.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp Tue Nov 13 18:46:21 2018
@@ -107,6 +107,7 @@ WasmDumper::dumpCustomSection(const Wasm
         break;
       case wasm::WASM_SYMBOL_TYPE_FUNCTION:
       case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+      case wasm::WASM_SYMBOL_TYPE_EVENT:
         Info.ElementIndex = Symbol.ElementIndex;
         break;
       case wasm::WASM_SYMBOL_TYPE_SECTION:
@@ -182,6 +183,10 @@ ErrorOr<WasmYAML::Object *> WasmDumper::
           Im.GlobalImport.Type = Import.Global.Type;
           Im.GlobalImport.Mutable = Import.Global.Mutable;
           break;
+        case wasm::WASM_EXTERNAL_EVENT:
+          Im.EventImport.Attribute = Import.Event.Attribute;
+          Im.EventImport.SigIndex = Import.Event.SigIndex;
+          break;
         case wasm::WASM_EXTERNAL_TABLE:
           Im.TableImport = make_table(Import.Table);
           break;
@@ -231,6 +236,18 @@ ErrorOr<WasmYAML::Object *> WasmDumper::
       S = std::move(GlobalSec);
       break;
     }
+    case wasm::WASM_SEC_EVENT: {
+      auto EventSec = make_unique<WasmYAML::EventSection>();
+      for (auto &Event : Obj.events()) {
+        WasmYAML::Event E;
+        E.Index = Event.Index;
+        E.Attribute = Event.Type.Attribute;
+        E.SigIndex = Event.Type.SigIndex;
+        EventSec->Events.push_back(E);
+      }
+      S = std::move(EventSec);
+      break;
+    }
     case wasm::WASM_SEC_START: {
       auto StartSec = make_unique<WasmYAML::StartSection>();
       StartSec->StartFunction = Obj.startFunction();

Modified: llvm/trunk/tools/yaml2obj/yaml2wasm.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2wasm.cpp?rev=346825&r1=346824&r2=346825&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2wasm.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2wasm.cpp Tue Nov 13 18:46:21 2018
@@ -37,6 +37,7 @@ private:
   int writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section);
+  int writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section);
   int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
@@ -49,6 +50,7 @@ private:
   WasmYAML::Object &Obj;
   uint32_t NumImportedFunctions = 0;
   uint32_t NumImportedGlobals = 0;
+  uint32_t NumImportedEvents = 0;
 };
 
 static int writeUint64(raw_ostream &OS, uint64_t Value) {
@@ -152,6 +154,7 @@ int WasmWriter::writeSectionContent(raw_
       switch (Info.Kind) {
       case wasm::WASM_SYMBOL_TYPE_FUNCTION:
       case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+      case wasm::WASM_SYMBOL_TYPE_EVENT:
         encodeULEB128(Info.ElementIndex, SubSection.GetStream());
         if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
           writeStringRef(Info.Name, SubSection.GetStream());
@@ -292,6 +295,11 @@ int WasmWriter::writeSectionContent(raw_
       writeUint8(OS, Import.GlobalImport.Mutable);
       NumImportedGlobals++;
       break;
+    case wasm::WASM_EXTERNAL_EVENT:
+      writeUint32(OS, Import.EventImport.Attribute);
+      writeUint32(OS, Import.EventImport.SigIndex);
+      NumImportedGlobals++;
+      break;
     case wasm::WASM_EXTERNAL_MEMORY:
       writeLimits(Import.Memory, OS);
       break;
@@ -370,6 +378,22 @@ int WasmWriter::writeSectionContent(raw_
 }
 
 int WasmWriter::writeSectionContent(raw_ostream &OS,
+                                    WasmYAML::EventSection &Section) {
+  encodeULEB128(Section.Events.size(), OS);
+  uint32_t ExpectedIndex = NumImportedEvents;
+  for (auto &Event : Section.Events) {
+    if (Event.Index != ExpectedIndex) {
+      errs() << "Unexpected event index: " << Event.Index << "\n";
+      return 1;
+    }
+    ++ExpectedIndex;
+    encodeULEB128(Event.Attribute, OS);
+    encodeULEB128(Event.SigIndex, OS);
+  }
+  return 0;
+}
+
+int WasmWriter::writeSectionContent(raw_ostream &OS,
                                     WasmYAML::ElemSection &Section) {
   encodeULEB128(Section.Segments.size(), OS);
   for (auto &Segment : Section.Segments) {
@@ -474,17 +498,7 @@ int WasmWriter::writeWasm(raw_ostream &O
   writeUint32(OS, Obj.Header.Version);
 
   // Write each section
-  uint32_t LastType = 0;
   for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
-    uint32_t Type = Sec->Type;
-    if (Type != wasm::WASM_SEC_CUSTOM) {
-      if (Type < LastType) {
-        errs() << "Out of order section type: " << Type << "\n";
-        return 1;
-      }
-      LastType = Type;
-    }
-
     encodeULEB128(Sec->Type, OS);
     std::string OutString;
     raw_string_ostream StringStream(OutString);
@@ -509,6 +523,9 @@ int WasmWriter::writeWasm(raw_ostream &O
     } else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get())) {
       if (auto Err = writeSectionContent(StringStream, *S))
         return Err;
+    } else if (auto S = dyn_cast<WasmYAML::EventSection>(Sec.get())) {
+      if (auto Err = writeSectionContent(StringStream, *S))
+        return Err;
     } else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get())) {
       if (auto Err = writeSectionContent(StringStream, *S))
         return Err;




More information about the llvm-commits mailing list