2017-03-30 21:44:09 +02:00
|
|
|
//===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2017-03-30 21:44:09 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines classes for handling the YAML representation of wasm.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/ObjectYAML/WasmYAML.h"
|
2017-07-01 03:35:55 +02:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2017-03-30 21:44:09 +02:00
|
|
|
#include "llvm/Support/Casting.h"
|
2017-07-01 03:35:55 +02:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include "llvm/Support/YAMLTraits.h"
|
2017-03-30 21:44:09 +02:00
|
|
|
|
|
|
|
namespace llvm {
|
2017-04-01 00:14:14 +02:00
|
|
|
|
|
|
|
namespace WasmYAML {
|
|
|
|
|
|
|
|
// Declared here rather than in the header to comply with:
|
|
|
|
// http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
|
2017-07-01 03:35:55 +02:00
|
|
|
Section::~Section() = default;
|
2017-04-01 00:14:14 +02:00
|
|
|
|
|
|
|
} // end namespace WasmYAML
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
namespace yaml {
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::FileHeader>::mapping(
|
|
|
|
IO &IO, WasmYAML::FileHeader &FileHdr) {
|
|
|
|
IO.mapRequired("Version", FileHdr.Version);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Object>::mapping(IO &IO,
|
|
|
|
WasmYAML::Object &Object) {
|
|
|
|
IO.setContext(&Object);
|
|
|
|
IO.mapTag("!WASM", true);
|
|
|
|
IO.mapRequired("FileHeader", Object.Header);
|
|
|
|
IO.mapOptional("Sections", Object.Sections);
|
|
|
|
IO.setContext(nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) {
|
|
|
|
IO.mapRequired("Type", Section.Type);
|
|
|
|
IO.mapOptional("Relocations", Section.Relocations);
|
|
|
|
}
|
|
|
|
|
2018-11-14 19:36:24 +01:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::DylinkSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
|
|
|
IO.mapRequired("MemorySize", Section.MemorySize);
|
|
|
|
IO.mapRequired("MemoryAlignment", Section.MemoryAlignment);
|
|
|
|
IO.mapRequired("TableSize", Section.TableSize);
|
|
|
|
IO.mapRequired("TableAlignment", Section.TableAlignment);
|
2018-12-13 00:40:58 +01:00
|
|
|
IO.mapRequired("Needed", Section.Needed);
|
2018-11-14 19:36:24 +01:00
|
|
|
}
|
|
|
|
|
2017-06-20 06:04:59 +02:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
|
|
|
IO.mapOptional("FunctionNames", Section.FunctionNames);
|
2020-11-19 06:38:23 +01:00
|
|
|
IO.mapOptional("GlobalNames", Section.GlobalNames);
|
2020-12-09 06:47:19 +01:00
|
|
|
IO.mapOptional("DataSegmentNames", Section.DataSegmentNames);
|
2017-06-20 06:04:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
2018-04-26 20:15:32 +02:00
|
|
|
IO.mapRequired("Version", Section.Version);
|
2018-02-23 06:08:34 +01:00
|
|
|
IO.mapOptional("SymbolTable", Section.SymbolTable);
|
2017-09-29 18:50:08 +02:00
|
|
|
IO.mapOptional("SegmentInfo", Section.SegmentInfos);
|
2017-12-14 22:10:03 +01:00
|
|
|
IO.mapOptional("InitFunctions", Section.InitFunctions);
|
2018-01-10 00:43:14 +01:00
|
|
|
IO.mapOptional("Comdats", Section.Comdats);
|
2017-06-20 06:04:59 +02:00
|
|
|
}
|
|
|
|
|
2019-01-17 03:29:55 +01:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::ProducersSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
|
|
|
IO.mapOptional("Languages", Section.Languages);
|
|
|
|
IO.mapOptional("Tools", Section.Tools);
|
|
|
|
IO.mapOptional("SDKs", Section.SDKs);
|
|
|
|
}
|
|
|
|
|
[WebAssembly] Target features section
Summary:
Implements a new target features section in assembly and object files
that records what features are used, required, and disallowed in
WebAssembly objects. The linker uses this information to ensure that
all objects participating in a link are feature-compatible and records
the set of used features in the output binary for use by optimizers
and other tools later in the toolchain.
The "atomics" feature is always required or disallowed to prevent
linking code with stripped atomics into multithreaded binaries. Other
features are marked used if they are enabled globally or on any
function in a module.
Future CLs will add linker flags for ignoring feature compatibility
checks and for specifying the set of allowed features, implement using
the presence of the "atomics" feature to control the type of memory
and segments in the linked binary, and add front-end flags for
relaxing the linkage policy for atomics.
Reviewers: aheejin, sbc100, dschuff
Subscribers: jgravelle-google, hiraditya, sunfish, mgrang, jfb, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59173
llvm-svn: 356610
2019-03-20 21:26:45 +01:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
|
|
|
IO.mapRequired("Features", Section.Features);
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Name", Section.Name);
|
2017-06-20 06:04:59 +02:00
|
|
|
IO.mapRequired("Payload", Section.Payload);
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Signatures", Section.Signatures);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Imports", Section.Imports);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("FunctionTypes", Section.FunctionTypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Tables", Section.Tables);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Memories", Section.Memories);
|
|
|
|
}
|
|
|
|
|
2020-03-25 03:36:13 +01:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::EventSection &Section) {
|
2017-03-30 21:44:09 +02:00
|
|
|
commonSectionMapping(IO, Section);
|
2020-03-25 03:36:13 +01:00
|
|
|
IO.mapOptional("Events", Section.Events);
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
|
2020-03-25 03:36:13 +01:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) {
|
2018-11-14 03:46:21 +01:00
|
|
|
commonSectionMapping(IO, Section);
|
2020-03-25 03:36:13 +01:00
|
|
|
IO.mapOptional("Globals", Section.Globals);
|
2018-11-14 03:46:21 +01:00
|
|
|
}
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Exports", Section.Exports);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("StartFunction", Section.StartFunction);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapOptional("Segments", Section.Segments);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Functions", Section.Functions);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Segments", Section.Segments);
|
|
|
|
}
|
|
|
|
|
2019-04-13 00:27:48 +02:00
|
|
|
static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
|
|
|
|
commonSectionMapping(IO, Section);
|
|
|
|
IO.mapRequired("Count", Section.Count);
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping(
|
|
|
|
IO &IO, std::unique_ptr<WasmYAML::Section> &Section) {
|
|
|
|
WasmYAML::SectionType SectionType;
|
|
|
|
if (IO.outputting())
|
|
|
|
SectionType = Section->Type;
|
|
|
|
else
|
|
|
|
IO.mapRequired("Type", SectionType);
|
|
|
|
|
|
|
|
switch (SectionType) {
|
2017-06-20 06:04:59 +02:00
|
|
|
case wasm::WASM_SEC_CUSTOM: {
|
|
|
|
StringRef SectionName;
|
|
|
|
if (IO.outputting()) {
|
|
|
|
auto CustomSection = cast<WasmYAML::CustomSection>(Section.get());
|
|
|
|
SectionName = CustomSection->Name;
|
|
|
|
} else {
|
|
|
|
IO.mapRequired("Name", SectionName);
|
|
|
|
}
|
2018-11-14 19:36:24 +01:00
|
|
|
if (SectionName == "dylink") {
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::DylinkSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::DylinkSection>(Section.get()));
|
|
|
|
} else if (SectionName == "linking") {
|
2017-06-20 06:04:59 +02:00
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::LinkingSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::LinkingSection>(Section.get()));
|
|
|
|
} else if (SectionName == "name") {
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::NameSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::NameSection>(Section.get()));
|
2019-01-17 03:29:55 +01:00
|
|
|
} else if (SectionName == "producers") {
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::ProducersSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::ProducersSection>(Section.get()));
|
[WebAssembly] Target features section
Summary:
Implements a new target features section in assembly and object files
that records what features are used, required, and disallowed in
WebAssembly objects. The linker uses this information to ensure that
all objects participating in a link are feature-compatible and records
the set of used features in the output binary for use by optimizers
and other tools later in the toolchain.
The "atomics" feature is always required or disallowed to prevent
linking code with stripped atomics into multithreaded binaries. Other
features are marked used if they are enabled globally or on any
function in a module.
Future CLs will add linker flags for ignoring feature compatibility
checks and for specifying the set of allowed features, implement using
the presence of the "atomics" feature to control the type of memory
and segments in the linked binary, and add front-end flags for
relaxing the linkage policy for atomics.
Reviewers: aheejin, sbc100, dschuff
Subscribers: jgravelle-google, hiraditya, sunfish, mgrang, jfb, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59173
llvm-svn: 356610
2019-03-20 21:26:45 +01:00
|
|
|
} else if (SectionName == "target_features") {
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::TargetFeaturesSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::TargetFeaturesSection>(Section.get()));
|
2017-06-20 06:04:59 +02:00
|
|
|
} else {
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::CustomSection(SectionName));
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get()));
|
|
|
|
}
|
2017-03-30 21:44:09 +02:00
|
|
|
break;
|
2017-06-20 06:04:59 +02:00
|
|
|
}
|
2017-03-30 21:44:09 +02:00
|
|
|
case wasm::WASM_SEC_TYPE:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::TypeSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_IMPORT:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::ImportSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_FUNCTION:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::FunctionSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_TABLE:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::TableSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_MEMORY:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::MemorySection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get()));
|
|
|
|
break;
|
2018-11-14 03:46:21 +01:00
|
|
|
case wasm::WASM_SEC_EVENT:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::EventSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::EventSection>(Section.get()));
|
|
|
|
break;
|
2020-03-25 03:36:13 +01:00
|
|
|
case wasm::WASM_SEC_GLOBAL:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::GlobalSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get()));
|
|
|
|
break;
|
2017-03-30 21:44:09 +02:00
|
|
|
case wasm::WASM_SEC_EXPORT:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::ExportSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_START:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::StartSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_ELEM:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::ElemSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_CODE:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::CodeSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get()));
|
|
|
|
break;
|
|
|
|
case wasm::WASM_SEC_DATA:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::DataSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get()));
|
|
|
|
break;
|
2019-04-13 00:27:48 +02:00
|
|
|
case wasm::WASM_SEC_DATACOUNT:
|
|
|
|
if (!IO.outputting())
|
|
|
|
Section.reset(new WasmYAML::DataCountSection());
|
|
|
|
sectionMapping(IO, *cast<WasmYAML::DataCountSection>(Section.get()));
|
|
|
|
break;
|
2017-03-30 21:44:09 +02:00
|
|
|
default:
|
|
|
|
llvm_unreachable("Unknown section type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
|
|
|
|
IO &IO, WasmYAML::SectionType &Type) {
|
|
|
|
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X);
|
|
|
|
ECase(CUSTOM);
|
|
|
|
ECase(TYPE);
|
|
|
|
ECase(IMPORT);
|
|
|
|
ECase(FUNCTION);
|
|
|
|
ECase(TABLE);
|
|
|
|
ECase(MEMORY);
|
|
|
|
ECase(GLOBAL);
|
2018-11-14 03:46:21 +01:00
|
|
|
ECase(EVENT);
|
2017-03-30 21:44:09 +02:00
|
|
|
ECase(EXPORT);
|
|
|
|
ECase(START);
|
|
|
|
ECase(ELEM);
|
|
|
|
ECase(CODE);
|
|
|
|
ECase(DATA);
|
2019-04-13 00:27:48 +02:00
|
|
|
ECase(DATACOUNT);
|
2017-03-30 21:44:09 +02:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Signature>::mapping(
|
|
|
|
IO &IO, WasmYAML::Signature &Signature) {
|
2018-01-09 22:38:53 +01:00
|
|
|
IO.mapRequired("Index", Signature.Index);
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("ParamTypes", Signature.ParamTypes);
|
2019-10-18 22:27:30 +02:00
|
|
|
IO.mapRequired("ReturnTypes", Signature.ReturnTypes);
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) {
|
2020-10-13 16:13:10 +02:00
|
|
|
IO.mapRequired("Index", Table.Index);
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("ElemType", Table.ElemType);
|
|
|
|
IO.mapRequired("Limits", Table.TableLimits);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Function>::mapping(IO &IO,
|
|
|
|
WasmYAML::Function &Function) {
|
2018-01-09 22:38:53 +01:00
|
|
|
IO.mapRequired("Index", Function.Index);
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("Locals", Function.Locals);
|
|
|
|
IO.mapRequired("Body", Function.Body);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Relocation>::mapping(
|
|
|
|
IO &IO, WasmYAML::Relocation &Relocation) {
|
|
|
|
IO.mapRequired("Type", Relocation.Type);
|
|
|
|
IO.mapRequired("Index", Relocation.Index);
|
|
|
|
IO.mapRequired("Offset", Relocation.Offset);
|
2017-04-26 02:02:31 +02:00
|
|
|
IO.mapOptional("Addend", Relocation.Addend, 0);
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
|
2017-05-05 20:12:34 +02:00
|
|
|
void MappingTraits<WasmYAML::NameEntry>::mapping(
|
|
|
|
IO &IO, WasmYAML::NameEntry &NameEntry) {
|
|
|
|
IO.mapRequired("Index", NameEntry.Index);
|
|
|
|
IO.mapRequired("Name", NameEntry.Name);
|
|
|
|
}
|
|
|
|
|
2019-01-17 03:29:55 +01:00
|
|
|
void MappingTraits<WasmYAML::ProducerEntry>::mapping(
|
|
|
|
IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
|
|
|
|
IO.mapRequired("Name", ProducerEntry.Name);
|
|
|
|
IO.mapRequired("Version", ProducerEntry.Version);
|
|
|
|
}
|
|
|
|
|
[WebAssembly] Target features section
Summary:
Implements a new target features section in assembly and object files
that records what features are used, required, and disallowed in
WebAssembly objects. The linker uses this information to ensure that
all objects participating in a link are feature-compatible and records
the set of used features in the output binary for use by optimizers
and other tools later in the toolchain.
The "atomics" feature is always required or disallowed to prevent
linking code with stripped atomics into multithreaded binaries. Other
features are marked used if they are enabled globally or on any
function in a module.
Future CLs will add linker flags for ignoring feature compatibility
checks and for specifying the set of allowed features, implement using
the presence of the "atomics" feature to control the type of memory
and segments in the linked binary, and add front-end flags for
relaxing the linkage policy for atomics.
Reviewers: aheejin, sbc100, dschuff
Subscribers: jgravelle-google, hiraditya, sunfish, mgrang, jfb, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D59173
llvm-svn: 356610
2019-03-20 21:26:45 +01:00
|
|
|
void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration(
|
|
|
|
IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
|
|
|
|
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
|
|
|
|
ECase(USED);
|
|
|
|
ECase(REQUIRED);
|
|
|
|
ECase(DISALLOWED);
|
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::FeatureEntry>::mapping(
|
|
|
|
IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
|
|
|
|
IO.mapRequired("Prefix", FeatureEntry.Prefix);
|
|
|
|
IO.mapRequired("Name", FeatureEntry.Name);
|
|
|
|
}
|
|
|
|
|
2017-09-29 18:50:08 +02:00
|
|
|
void MappingTraits<WasmYAML::SegmentInfo>::mapping(
|
|
|
|
IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
|
|
|
|
IO.mapRequired("Index", SegmentInfo.Index);
|
|
|
|
IO.mapRequired("Name", SegmentInfo.Name);
|
|
|
|
IO.mapRequired("Alignment", SegmentInfo.Alignment);
|
|
|
|
IO.mapRequired("Flags", SegmentInfo.Flags);
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
void MappingTraits<WasmYAML::LocalDecl>::mapping(
|
|
|
|
IO &IO, WasmYAML::LocalDecl &LocalDecl) {
|
|
|
|
IO.mapRequired("Type", LocalDecl.Type);
|
|
|
|
IO.mapRequired("Count", LocalDecl.Count);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Limits>::mapping(IO &IO,
|
|
|
|
WasmYAML::Limits &Limits) {
|
|
|
|
if (!IO.outputting() || Limits.Flags)
|
|
|
|
IO.mapOptional("Flags", Limits.Flags);
|
|
|
|
IO.mapRequired("Initial", Limits.Initial);
|
|
|
|
if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
|
|
|
|
IO.mapOptional("Maximum", Limits.Maximum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::ElemSegment>::mapping(
|
|
|
|
IO &IO, WasmYAML::ElemSegment &Segment) {
|
2021-03-04 10:30:00 +01:00
|
|
|
if (!IO.outputting() || Segment.Flags)
|
|
|
|
IO.mapOptional("Flags", Segment.Flags);
|
|
|
|
if (!IO.outputting() ||
|
|
|
|
Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
|
|
|
|
IO.mapOptional("TableNumber", Segment.TableNumber);
|
|
|
|
if (!IO.outputting() ||
|
|
|
|
Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND)
|
|
|
|
IO.mapOptional("ElemKind", Segment.ElemKind);
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("Offset", Segment.Offset);
|
|
|
|
IO.mapRequired("Functions", Segment.Functions);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Import>::mapping(IO &IO,
|
|
|
|
WasmYAML::Import &Import) {
|
|
|
|
IO.mapRequired("Module", Import.Module);
|
|
|
|
IO.mapRequired("Field", Import.Field);
|
|
|
|
IO.mapRequired("Kind", Import.Kind);
|
|
|
|
if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
|
|
|
|
IO.mapRequired("SigIndex", Import.SigIndex);
|
|
|
|
} else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
|
2017-05-10 02:14:04 +02:00
|
|
|
IO.mapRequired("GlobalType", Import.GlobalImport.Type);
|
|
|
|
IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable);
|
2018-11-14 03:46:21 +01:00
|
|
|
} else if (Import.Kind == wasm::WASM_EXTERNAL_EVENT) {
|
|
|
|
IO.mapRequired("EventAttribute", Import.EventImport.Attribute);
|
|
|
|
IO.mapRequired("EventSigIndex", Import.EventImport.SigIndex);
|
2017-05-10 01:48:41 +02:00
|
|
|
} else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
|
2017-05-10 02:14:04 +02:00
|
|
|
IO.mapRequired("Table", Import.TableImport);
|
2018-09-05 03:27:38 +02:00
|
|
|
} else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) {
|
2017-05-10 01:48:41 +02:00
|
|
|
IO.mapRequired("Memory", Import.Memory);
|
2017-03-30 21:44:09 +02:00
|
|
|
} else {
|
|
|
|
llvm_unreachable("unhandled import type");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Export>::mapping(IO &IO,
|
|
|
|
WasmYAML::Export &Export) {
|
|
|
|
IO.mapRequired("Name", Export.Name);
|
|
|
|
IO.mapRequired("Kind", Export.Kind);
|
|
|
|
IO.mapRequired("Index", Export.Index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::Global>::mapping(IO &IO,
|
|
|
|
WasmYAML::Global &Global) {
|
2018-01-09 22:38:53 +01:00
|
|
|
IO.mapRequired("Index", Global.Index);
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("Type", Global.Type);
|
|
|
|
IO.mapRequired("Mutable", Global.Mutable);
|
|
|
|
IO.mapRequired("InitExpr", Global.InitExpr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
|
|
|
|
wasm::WasmInitExpr &Expr) {
|
|
|
|
WasmYAML::Opcode Op = Expr.Opcode;
|
|
|
|
IO.mapRequired("Opcode", Op);
|
|
|
|
Expr.Opcode = Op;
|
|
|
|
switch (Expr.Opcode) {
|
|
|
|
case wasm::WASM_OPCODE_I32_CONST:
|
|
|
|
IO.mapRequired("Value", Expr.Value.Int32);
|
|
|
|
break;
|
|
|
|
case wasm::WASM_OPCODE_I64_CONST:
|
|
|
|
IO.mapRequired("Value", Expr.Value.Int64);
|
|
|
|
break;
|
|
|
|
case wasm::WASM_OPCODE_F32_CONST:
|
|
|
|
IO.mapRequired("Value", Expr.Value.Float32);
|
|
|
|
break;
|
|
|
|
case wasm::WASM_OPCODE_F64_CONST:
|
|
|
|
IO.mapRequired("Value", Expr.Value.Float64);
|
|
|
|
break;
|
2019-01-08 07:25:55 +01:00
|
|
|
case wasm::WASM_OPCODE_GLOBAL_GET:
|
2017-04-25 19:11:56 +02:00
|
|
|
IO.mapRequired("Index", Expr.Value.Global);
|
|
|
|
break;
|
2020-06-17 00:41:20 +02:00
|
|
|
case wasm::WASM_OPCODE_REF_NULL: {
|
|
|
|
WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF;
|
|
|
|
IO.mapRequired("Type", Ty);
|
|
|
|
break;
|
|
|
|
}
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::DataSegment>::mapping(
|
|
|
|
IO &IO, WasmYAML::DataSegment &Segment) {
|
2017-07-12 02:24:54 +02:00
|
|
|
IO.mapOptional("SectionOffset", Segment.SectionOffset);
|
2019-02-19 23:56:19 +01:00
|
|
|
IO.mapRequired("InitFlags", Segment.InitFlags);
|
2020-11-30 14:55:29 +01:00
|
|
|
if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) {
|
2019-02-19 23:56:19 +01:00
|
|
|
IO.mapRequired("MemoryIndex", Segment.MemoryIndex);
|
|
|
|
} else {
|
|
|
|
Segment.MemoryIndex = 0;
|
|
|
|
}
|
2020-11-30 14:55:29 +01:00
|
|
|
if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
|
2019-02-19 23:56:19 +01:00
|
|
|
IO.mapRequired("Offset", Segment.Offset);
|
|
|
|
} else {
|
|
|
|
Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
|
|
|
|
Segment.Offset.Value.Int32 = 0;
|
|
|
|
}
|
2017-03-30 21:44:09 +02:00
|
|
|
IO.mapRequired("Content", Segment.Content);
|
|
|
|
}
|
|
|
|
|
2017-12-14 22:10:03 +01:00
|
|
|
void MappingTraits<WasmYAML::InitFunction>::mapping(
|
|
|
|
IO &IO, WasmYAML::InitFunction &Init) {
|
|
|
|
IO.mapRequired("Priority", Init.Priority);
|
2018-02-23 06:08:34 +01:00
|
|
|
IO.mapRequired("Symbol", Init.Symbol);
|
2017-12-14 22:10:03 +01:00
|
|
|
}
|
|
|
|
|
2018-01-10 00:43:14 +01:00
|
|
|
void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
|
|
|
|
IO &IO, WasmYAML::ComdatKind &Kind) {
|
|
|
|
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
|
|
|
|
ECase(FUNCTION);
|
|
|
|
ECase(DATA);
|
2020-12-04 22:45:42 +01:00
|
|
|
ECase(SECTION);
|
2018-01-10 00:43:14 +01:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void MappingTraits<WasmYAML::ComdatEntry>::mapping(
|
|
|
|
IO &IO, WasmYAML::ComdatEntry &ComdatEntry) {
|
|
|
|
IO.mapRequired("Kind", ComdatEntry.Kind);
|
|
|
|
IO.mapRequired("Index", ComdatEntry.Index);
|
|
|
|
}
|
|
|
|
|
2018-09-05 03:27:38 +02:00
|
|
|
void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO,
|
|
|
|
WasmYAML::Comdat &Comdat) {
|
2018-01-10 00:43:14 +01:00
|
|
|
IO.mapRequired("Name", Comdat.Name);
|
|
|
|
IO.mapRequired("Entries", Comdat.Entries);
|
|
|
|
}
|
|
|
|
|
2017-06-20 06:04:59 +02:00
|
|
|
void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
|
|
|
|
WasmYAML::SymbolInfo &Info) {
|
2018-02-23 06:08:34 +01:00
|
|
|
IO.mapRequired("Index", Info.Index);
|
|
|
|
IO.mapRequired("Kind", Info.Kind);
|
2019-05-07 05:53:16 +02:00
|
|
|
if (Info.Kind != wasm::WASM_SYMBOL_TYPE_SECTION)
|
|
|
|
IO.mapRequired("Name", Info.Name);
|
2017-06-20 06:04:59 +02:00
|
|
|
IO.mapRequired("Flags", Info.Flags);
|
2018-02-23 06:08:34 +01:00
|
|
|
if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
|
|
|
|
IO.mapRequired("Function", Info.ElementIndex);
|
|
|
|
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
|
|
|
|
IO.mapRequired("Global", Info.ElementIndex);
|
2020-10-13 16:13:10 +02:00
|
|
|
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) {
|
|
|
|
IO.mapRequired("Table", Info.ElementIndex);
|
2018-11-14 03:46:21 +01:00
|
|
|
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
|
|
|
|
IO.mapRequired("Event", Info.ElementIndex);
|
2018-02-23 06:08:34 +01:00
|
|
|
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
|
|
|
|
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
|
|
|
|
IO.mapRequired("Segment", Info.DataRef.Segment);
|
|
|
|
IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
|
|
|
|
IO.mapRequired("Size", Info.DataRef.Size);
|
|
|
|
}
|
2018-04-26 21:27:28 +02:00
|
|
|
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) {
|
|
|
|
IO.mapRequired("Section", Info.ElementIndex);
|
2018-02-23 06:08:34 +01:00
|
|
|
} else {
|
|
|
|
llvm_unreachable("unsupported symbol kind");
|
|
|
|
}
|
2017-06-20 06:04:59 +02:00
|
|
|
}
|
|
|
|
|
2018-11-14 03:46:21 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2017-12-13 23:02:25 +01:00
|
|
|
void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
|
|
|
|
IO &IO, WasmYAML::LimitFlags &Value) {
|
|
|
|
#define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
|
|
|
|
BCase(HAS_MAX);
|
2018-11-06 18:27:25 +01:00
|
|
|
BCase(IS_SHARED);
|
2020-06-30 02:53:09 +02:00
|
|
|
BCase(IS_64);
|
2017-12-13 23:02:25 +01:00
|
|
|
#undef BCase
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset(
|
2018-09-05 03:27:38 +02:00
|
|
|
IO &IO, WasmYAML::SegmentFlags &Value) {}
|
2017-12-13 23:02:25 +01:00
|
|
|
|
|
|
|
void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
|
|
|
|
IO &IO, WasmYAML::SymbolFlags &Value) {
|
2018-09-05 03:27:38 +02:00
|
|
|
#define BCaseMask(M, X) \
|
|
|
|
IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
|
|
|
|
// BCaseMask(BINDING_MASK, BINDING_GLOBAL);
|
2017-12-13 23:02:25 +01:00
|
|
|
BCaseMask(BINDING_MASK, BINDING_WEAK);
|
|
|
|
BCaseMask(BINDING_MASK, BINDING_LOCAL);
|
2018-09-05 03:27:38 +02:00
|
|
|
// BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
|
2017-12-13 23:02:25 +01:00
|
|
|
BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
|
2018-02-23 06:08:34 +01:00
|
|
|
BCaseMask(UNDEFINED, UNDEFINED);
|
2019-02-07 02:24:44 +01:00
|
|
|
BCaseMask(EXPORTED, EXPORTED);
|
2019-04-30 21:30:24 +02:00
|
|
|
BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME);
|
2019-08-30 00:40:00 +02:00
|
|
|
BCaseMask(NO_STRIP, NO_STRIP);
|
2017-12-13 23:02:25 +01:00
|
|
|
#undef BCaseMask
|
|
|
|
}
|
|
|
|
|
2018-02-23 06:08:34 +01:00
|
|
|
void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
|
|
|
|
IO &IO, WasmYAML::SymbolKind &Kind) {
|
|
|
|
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
|
|
|
|
ECase(FUNCTION);
|
|
|
|
ECase(DATA);
|
|
|
|
ECase(GLOBAL);
|
2020-10-13 16:13:10 +02:00
|
|
|
ECase(TABLE);
|
2018-04-26 21:27:28 +02:00
|
|
|
ECase(SECTION);
|
2018-11-14 03:46:21 +01:00
|
|
|
ECase(EVENT);
|
2018-02-23 06:08:34 +01:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
|
|
|
|
IO &IO, WasmYAML::ValueType &Type) {
|
|
|
|
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
|
|
|
|
ECase(I32);
|
|
|
|
ECase(I64);
|
|
|
|
ECase(F32);
|
|
|
|
ECase(F64);
|
2018-09-21 00:04:44 +02:00
|
|
|
ECase(V128);
|
2019-01-08 07:25:55 +01:00
|
|
|
ECase(FUNCREF);
|
2020-06-17 00:41:20 +02:00
|
|
|
ECase(EXTERNREF);
|
2017-03-30 21:44:09 +02:00
|
|
|
ECase(FUNC);
|
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration(
|
|
|
|
IO &IO, WasmYAML::ExportKind &Kind) {
|
|
|
|
#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X);
|
|
|
|
ECase(FUNCTION);
|
|
|
|
ECase(TABLE);
|
|
|
|
ECase(MEMORY);
|
|
|
|
ECase(GLOBAL);
|
2018-11-14 03:46:21 +01:00
|
|
|
ECase(EVENT);
|
2017-03-30 21:44:09 +02:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration(
|
|
|
|
IO &IO, WasmYAML::Opcode &Code) {
|
|
|
|
#define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X);
|
|
|
|
ECase(END);
|
|
|
|
ECase(I32_CONST);
|
|
|
|
ECase(I64_CONST);
|
|
|
|
ECase(F64_CONST);
|
|
|
|
ECase(F32_CONST);
|
2019-01-08 07:25:55 +01:00
|
|
|
ECase(GLOBAL_GET);
|
2020-06-17 00:41:20 +02:00
|
|
|
ECase(REF_NULL);
|
2017-03-30 21:44:09 +02:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration(
|
|
|
|
IO &IO, WasmYAML::TableType &Type) {
|
|
|
|
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
|
2019-01-08 07:25:55 +01:00
|
|
|
ECase(FUNCREF);
|
2020-10-13 16:13:10 +02:00
|
|
|
ECase(EXTERNREF);
|
2017-03-30 21:44:09 +02:00
|
|
|
#undef ECase
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration(
|
|
|
|
IO &IO, WasmYAML::RelocType &Type) {
|
|
|
|
#define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name);
|
2017-12-21 04:16:34 +01:00
|
|
|
#include "llvm/BinaryFormat/WasmRelocs.def"
|
2017-03-30 21:44:09 +02:00
|
|
|
#undef WASM_RELOC
|
2021-02-03 03:28:37 +01:00
|
|
|
IO.enumFallback<Hex32>(Type);
|
2017-03-30 21:44:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace yaml
|
2017-07-01 03:35:55 +02:00
|
|
|
|
2017-03-30 21:44:09 +02:00
|
|
|
} // end namespace llvm
|