Skip to content

Commit

Permalink
[WebAssembly] Add support for the event section
Browse files Browse the repository at this point in the history
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
  • Loading branch information
aheejin committed Nov 14, 2018
1 parent 6a3c279 commit da419bd
Show file tree
Hide file tree
Showing 34 changed files with 708 additions and 116 deletions.
23 changes: 22 additions & 1 deletion llvm/include/llvm/BinaryFormat/Wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -84,6 +96,7 @@ struct WasmImport {
WasmGlobalType Global;
WasmTable Table;
WasmLimits Memory;
WasmEventType Event;
};
};

Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/BinaryFormat/WasmRelocs.def
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#ifndef WASM_RELOC
#error "WASM_RELOC must be defined"
#endif
Expand All @@ -13,3 +12,4 @@ WASM_RELOC(R_WEBASSEMBLY_TYPE_INDEX_LEB, 6)
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)
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/WasmEHFuncInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

namespace llvm {

enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };

using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;

struct WasmEHFuncInfo {
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/MC/MCExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class MCSymbolRefExpr : public MCExpr {
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@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
Expand Down
17 changes: 10 additions & 7 deletions llvm/include/llvm/MC/MCSymbolWasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -42,6 +42,7 @@ class MCSymbolWasm : public MCSymbol {
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; }

Expand All @@ -61,14 +62,16 @@ class MCSymbolWasm : public MCSymbol {
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
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Object/RelocVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ class RelocVisitor {
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;
}
Expand Down
19 changes: 17 additions & 2 deletions llvm/include/llvm/Object/Wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -59,6 +62,8 @@ class WasmSymbol {
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 {
Expand Down Expand Up @@ -130,6 +135,7 @@ class WasmObjectFile : public ObjectFile {
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; }
Expand All @@ -141,6 +147,7 @@ class WasmObjectFile : public ObjectFile {
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;

Expand Down Expand Up @@ -205,12 +212,16 @@ class WasmObjectFile : public ObjectFile {
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;
Expand All @@ -226,6 +237,7 @@ class WasmObjectFile : public ObjectFile {
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);
Expand All @@ -246,6 +258,7 @@ class WasmObjectFile : public ObjectFile {
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;
Expand All @@ -258,9 +271,11 @@ class WasmObjectFile : public ObjectFile {
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
Expand Down
22 changes: 22 additions & 0 deletions llvm/include/llvm/ObjectYAML/WasmYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -83,6 +89,7 @@ struct Import {
Global GlobalImport;
Table TableImport;
Limits Memory;
Event EventImport;
};
};

Expand Down Expand Up @@ -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) {}

Expand Down Expand Up @@ -339,6 +356,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
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 {
Expand Down Expand Up @@ -471,6 +489,10 @@ template <> struct ScalarEnumerationTraits<WasmYAML::RelocType> {
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

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/BinaryFormat/Wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ std::string llvm::wasm::toString(wasm::WasmSymbolType type) {
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");
}
Expand Down
16 changes: 16 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/AsmPrinter/WasmException.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {
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;
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/MC/MCExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
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@lo";
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
case VK_AMDGPU_REL32_LO: return "rel32@lo";
Expand Down Expand Up @@ -421,6 +422,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("function", VK_WebAssembly_FUNCTION)
.Case("global", VK_WebAssembly_GLOBAL)
.Case("typeindex", VK_WebAssembly_TYPEINDEX)
.Case("event", VK_WebAssembly_EVENT)
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
.Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
.Case("rel32@lo", VK_AMDGPU_REL32_LO)
Expand Down
Loading

0 comments on commit da419bd

Please sign in to comment.