1 //===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines classes for handling the YAML representation of wasm. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ObjectYAML/WasmYAML.h" 15 #include "llvm/Object/Wasm.h" 16 #include "llvm/Support/Casting.h" 17 #include "llvm/Support/MipsABIFlags.h" 18 19 namespace llvm { 20 21 namespace WasmYAML { 22 23 // Declared here rather than in the header to comply with: 24 // http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers 25 Section::~Section() {} 26 27 } // end namespace WasmYAML 28 29 namespace yaml { 30 31 void MappingTraits<WasmYAML::FileHeader>::mapping( 32 IO &IO, WasmYAML::FileHeader &FileHdr) { 33 IO.mapRequired("Version", FileHdr.Version); 34 } 35 36 void MappingTraits<WasmYAML::Object>::mapping(IO &IO, 37 WasmYAML::Object &Object) { 38 IO.setContext(&Object); 39 IO.mapTag("!WASM", true); 40 IO.mapRequired("FileHeader", Object.Header); 41 IO.mapOptional("Sections", Object.Sections); 42 IO.setContext(nullptr); 43 } 44 45 static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) { 46 IO.mapRequired("Type", Section.Type); 47 IO.mapOptional("Relocations", Section.Relocations); 48 } 49 50 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { 51 commonSectionMapping(IO, Section); 52 IO.mapRequired("Name", Section.Name); 53 IO.mapRequired("Payload", Section.Payload); 54 } 55 56 static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { 57 commonSectionMapping(IO, Section); 58 IO.mapOptional("Signatures", Section.Signatures); 59 } 60 61 static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { 62 commonSectionMapping(IO, Section); 63 IO.mapOptional("Imports", Section.Imports); 64 } 65 66 static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { 67 commonSectionMapping(IO, Section); 68 IO.mapOptional("FunctionTypes", Section.FunctionTypes); 69 } 70 71 static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { 72 commonSectionMapping(IO, Section); 73 IO.mapOptional("Tables", Section.Tables); 74 } 75 76 static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { 77 commonSectionMapping(IO, Section); 78 IO.mapOptional("Memories", Section.Memories); 79 } 80 81 static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { 82 commonSectionMapping(IO, Section); 83 IO.mapOptional("Globals", Section.Globals); 84 } 85 86 static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { 87 commonSectionMapping(IO, Section); 88 IO.mapOptional("Exports", Section.Exports); 89 } 90 91 static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { 92 commonSectionMapping(IO, Section); 93 IO.mapOptional("StartFunction", Section.StartFunction); 94 } 95 96 static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { 97 commonSectionMapping(IO, Section); 98 IO.mapOptional("Segments", Section.Segments); 99 } 100 101 static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { 102 commonSectionMapping(IO, Section); 103 IO.mapRequired("Functions", Section.Functions); 104 } 105 106 static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { 107 commonSectionMapping(IO, Section); 108 IO.mapRequired("Segments", Section.Segments); 109 } 110 111 void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( 112 IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { 113 WasmYAML::SectionType SectionType; 114 if (IO.outputting()) 115 SectionType = Section->Type; 116 else 117 IO.mapRequired("Type", SectionType); 118 119 switch (SectionType) { 120 case wasm::WASM_SEC_CUSTOM: 121 if (!IO.outputting()) 122 Section.reset(new WasmYAML::CustomSection()); 123 sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get())); 124 break; 125 case wasm::WASM_SEC_TYPE: 126 if (!IO.outputting()) 127 Section.reset(new WasmYAML::TypeSection()); 128 sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get())); 129 break; 130 case wasm::WASM_SEC_IMPORT: 131 if (!IO.outputting()) 132 Section.reset(new WasmYAML::ImportSection()); 133 sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get())); 134 break; 135 case wasm::WASM_SEC_FUNCTION: 136 if (!IO.outputting()) 137 Section.reset(new WasmYAML::FunctionSection()); 138 sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get())); 139 break; 140 case wasm::WASM_SEC_TABLE: 141 if (!IO.outputting()) 142 Section.reset(new WasmYAML::TableSection()); 143 sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get())); 144 break; 145 case wasm::WASM_SEC_MEMORY: 146 if (!IO.outputting()) 147 Section.reset(new WasmYAML::MemorySection()); 148 sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get())); 149 break; 150 case wasm::WASM_SEC_GLOBAL: 151 if (!IO.outputting()) 152 Section.reset(new WasmYAML::GlobalSection()); 153 sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get())); 154 break; 155 case wasm::WASM_SEC_EXPORT: 156 if (!IO.outputting()) 157 Section.reset(new WasmYAML::ExportSection()); 158 sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get())); 159 break; 160 case wasm::WASM_SEC_START: 161 if (!IO.outputting()) 162 Section.reset(new WasmYAML::StartSection()); 163 sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get())); 164 break; 165 case wasm::WASM_SEC_ELEM: 166 if (!IO.outputting()) 167 Section.reset(new WasmYAML::ElemSection()); 168 sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get())); 169 break; 170 case wasm::WASM_SEC_CODE: 171 if (!IO.outputting()) 172 Section.reset(new WasmYAML::CodeSection()); 173 sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get())); 174 break; 175 case wasm::WASM_SEC_DATA: 176 if (!IO.outputting()) 177 Section.reset(new WasmYAML::DataSection()); 178 sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get())); 179 break; 180 default: 181 llvm_unreachable("Unknown section type"); 182 } 183 } 184 185 void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( 186 IO &IO, WasmYAML::SectionType &Type) { 187 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); 188 ECase(CUSTOM); 189 ECase(TYPE); 190 ECase(IMPORT); 191 ECase(FUNCTION); 192 ECase(TABLE); 193 ECase(MEMORY); 194 ECase(GLOBAL); 195 ECase(EXPORT); 196 ECase(START); 197 ECase(ELEM); 198 ECase(CODE); 199 ECase(DATA); 200 #undef ECase 201 } 202 203 void MappingTraits<WasmYAML::Signature>::mapping( 204 IO &IO, WasmYAML::Signature &Signature) { 205 IO.mapOptional("Index", Signature.Index); 206 IO.mapRequired("ReturnType", Signature.ReturnType); 207 IO.mapRequired("ParamTypes", Signature.ParamTypes); 208 } 209 210 void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { 211 IO.mapRequired("ElemType", Table.ElemType); 212 IO.mapRequired("Limits", Table.TableLimits); 213 } 214 215 void MappingTraits<WasmYAML::Function>::mapping(IO &IO, 216 WasmYAML::Function &Function) { 217 IO.mapRequired("Locals", Function.Locals); 218 IO.mapRequired("Body", Function.Body); 219 } 220 221 void MappingTraits<WasmYAML::Relocation>::mapping( 222 IO &IO, WasmYAML::Relocation &Relocation) { 223 IO.mapRequired("Type", Relocation.Type); 224 IO.mapRequired("Index", Relocation.Index); 225 IO.mapRequired("Offset", Relocation.Offset); 226 IO.mapRequired("Addend", Relocation.Addend); 227 } 228 229 void MappingTraits<WasmYAML::LocalDecl>::mapping( 230 IO &IO, WasmYAML::LocalDecl &LocalDecl) { 231 IO.mapRequired("Type", LocalDecl.Type); 232 IO.mapRequired("Count", LocalDecl.Count); 233 } 234 235 void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, 236 WasmYAML::Limits &Limits) { 237 if (!IO.outputting() || Limits.Flags) 238 IO.mapOptional("Flags", Limits.Flags); 239 IO.mapRequired("Initial", Limits.Initial); 240 if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) 241 IO.mapOptional("Maximum", Limits.Maximum); 242 } 243 244 void MappingTraits<WasmYAML::ElemSegment>::mapping( 245 IO &IO, WasmYAML::ElemSegment &Segment) { 246 IO.mapRequired("Offset", Segment.Offset); 247 IO.mapRequired("Functions", Segment.Functions); 248 } 249 250 void MappingTraits<WasmYAML::Import>::mapping(IO &IO, 251 WasmYAML::Import &Import) { 252 IO.mapRequired("Module", Import.Module); 253 IO.mapRequired("Field", Import.Field); 254 IO.mapRequired("Kind", Import.Kind); 255 if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) { 256 IO.mapRequired("SigIndex", Import.SigIndex); 257 } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { 258 IO.mapRequired("GlobalType", Import.GlobalType); 259 IO.mapRequired("GlobalMutable", Import.GlobalMutable); 260 } else { 261 llvm_unreachable("unhandled import type"); 262 } 263 } 264 265 void MappingTraits<WasmYAML::Export>::mapping(IO &IO, 266 WasmYAML::Export &Export) { 267 IO.mapRequired("Name", Export.Name); 268 IO.mapRequired("Kind", Export.Kind); 269 IO.mapRequired("Index", Export.Index); 270 } 271 272 void MappingTraits<WasmYAML::Global>::mapping(IO &IO, 273 WasmYAML::Global &Global) { 274 IO.mapRequired("Type", Global.Type); 275 IO.mapRequired("Mutable", Global.Mutable); 276 IO.mapRequired("InitExpr", Global.InitExpr); 277 } 278 279 void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO, 280 wasm::WasmInitExpr &Expr) { 281 WasmYAML::Opcode Op = Expr.Opcode; 282 IO.mapRequired("Opcode", Op); 283 Expr.Opcode = Op; 284 switch (Expr.Opcode) { 285 case wasm::WASM_OPCODE_I32_CONST: 286 IO.mapRequired("Value", Expr.Value.Int32); 287 break; 288 case wasm::WASM_OPCODE_I64_CONST: 289 IO.mapRequired("Value", Expr.Value.Int64); 290 break; 291 case wasm::WASM_OPCODE_F32_CONST: 292 IO.mapRequired("Value", Expr.Value.Float32); 293 break; 294 case wasm::WASM_OPCODE_F64_CONST: 295 IO.mapRequired("Value", Expr.Value.Float64); 296 break; 297 } 298 } 299 300 void MappingTraits<WasmYAML::DataSegment>::mapping( 301 IO &IO, WasmYAML::DataSegment &Segment) { 302 IO.mapRequired("Index", Segment.Index); 303 IO.mapRequired("Offset", Segment.Offset); 304 IO.mapRequired("Content", Segment.Content); 305 } 306 307 void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( 308 IO &IO, WasmYAML::ValueType &Type) { 309 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 310 ECase(I32); 311 ECase(I64); 312 ECase(F32); 313 ECase(F64); 314 ECase(ANYFUNC); 315 ECase(FUNC); 316 ECase(NORESULT); 317 #undef ECase 318 } 319 320 void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( 321 IO &IO, WasmYAML::ExportKind &Kind) { 322 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); 323 ECase(FUNCTION); 324 ECase(TABLE); 325 ECase(MEMORY); 326 ECase(GLOBAL); 327 #undef ECase 328 } 329 330 void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( 331 IO &IO, WasmYAML::Opcode &Code) { 332 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); 333 ECase(END); 334 ECase(I32_CONST); 335 ECase(I64_CONST); 336 ECase(F64_CONST); 337 ECase(F32_CONST); 338 ECase(GET_GLOBAL); 339 #undef ECase 340 } 341 342 void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( 343 IO &IO, WasmYAML::TableType &Type) { 344 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 345 ECase(ANYFUNC); 346 #undef ECase 347 } 348 349 void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( 350 IO &IO, WasmYAML::RelocType &Type) { 351 #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); 352 #include "llvm/Support/WasmRelocs/WebAssembly.def" 353 #undef WASM_RELOC 354 } 355 356 } // end namespace yaml 357 } // end namespace llvm 358