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 if (Section.Name == "name") { 54 IO.mapOptional("FunctionNames", Section.FunctionNames); 55 } else { 56 IO.mapRequired("Payload", Section.Payload); 57 } 58 } 59 60 static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { 61 commonSectionMapping(IO, Section); 62 IO.mapOptional("Signatures", Section.Signatures); 63 } 64 65 static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { 66 commonSectionMapping(IO, Section); 67 IO.mapOptional("Imports", Section.Imports); 68 } 69 70 static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { 71 commonSectionMapping(IO, Section); 72 IO.mapOptional("FunctionTypes", Section.FunctionTypes); 73 } 74 75 static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { 76 commonSectionMapping(IO, Section); 77 IO.mapOptional("Tables", Section.Tables); 78 } 79 80 static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { 81 commonSectionMapping(IO, Section); 82 IO.mapOptional("Memories", Section.Memories); 83 } 84 85 static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { 86 commonSectionMapping(IO, Section); 87 IO.mapOptional("Globals", Section.Globals); 88 } 89 90 static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { 91 commonSectionMapping(IO, Section); 92 IO.mapOptional("Exports", Section.Exports); 93 } 94 95 static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { 96 commonSectionMapping(IO, Section); 97 IO.mapOptional("StartFunction", Section.StartFunction); 98 } 99 100 static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { 101 commonSectionMapping(IO, Section); 102 IO.mapOptional("Segments", Section.Segments); 103 } 104 105 static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { 106 commonSectionMapping(IO, Section); 107 IO.mapRequired("Functions", Section.Functions); 108 } 109 110 static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { 111 commonSectionMapping(IO, Section); 112 IO.mapRequired("Segments", Section.Segments); 113 } 114 115 void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( 116 IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { 117 WasmYAML::SectionType SectionType; 118 if (IO.outputting()) 119 SectionType = Section->Type; 120 else 121 IO.mapRequired("Type", SectionType); 122 123 switch (SectionType) { 124 case wasm::WASM_SEC_CUSTOM: 125 if (!IO.outputting()) 126 Section.reset(new WasmYAML::CustomSection()); 127 sectionMapping(IO, *cast<WasmYAML::CustomSection>(Section.get())); 128 break; 129 case wasm::WASM_SEC_TYPE: 130 if (!IO.outputting()) 131 Section.reset(new WasmYAML::TypeSection()); 132 sectionMapping(IO, *cast<WasmYAML::TypeSection>(Section.get())); 133 break; 134 case wasm::WASM_SEC_IMPORT: 135 if (!IO.outputting()) 136 Section.reset(new WasmYAML::ImportSection()); 137 sectionMapping(IO, *cast<WasmYAML::ImportSection>(Section.get())); 138 break; 139 case wasm::WASM_SEC_FUNCTION: 140 if (!IO.outputting()) 141 Section.reset(new WasmYAML::FunctionSection()); 142 sectionMapping(IO, *cast<WasmYAML::FunctionSection>(Section.get())); 143 break; 144 case wasm::WASM_SEC_TABLE: 145 if (!IO.outputting()) 146 Section.reset(new WasmYAML::TableSection()); 147 sectionMapping(IO, *cast<WasmYAML::TableSection>(Section.get())); 148 break; 149 case wasm::WASM_SEC_MEMORY: 150 if (!IO.outputting()) 151 Section.reset(new WasmYAML::MemorySection()); 152 sectionMapping(IO, *cast<WasmYAML::MemorySection>(Section.get())); 153 break; 154 case wasm::WASM_SEC_GLOBAL: 155 if (!IO.outputting()) 156 Section.reset(new WasmYAML::GlobalSection()); 157 sectionMapping(IO, *cast<WasmYAML::GlobalSection>(Section.get())); 158 break; 159 case wasm::WASM_SEC_EXPORT: 160 if (!IO.outputting()) 161 Section.reset(new WasmYAML::ExportSection()); 162 sectionMapping(IO, *cast<WasmYAML::ExportSection>(Section.get())); 163 break; 164 case wasm::WASM_SEC_START: 165 if (!IO.outputting()) 166 Section.reset(new WasmYAML::StartSection()); 167 sectionMapping(IO, *cast<WasmYAML::StartSection>(Section.get())); 168 break; 169 case wasm::WASM_SEC_ELEM: 170 if (!IO.outputting()) 171 Section.reset(new WasmYAML::ElemSection()); 172 sectionMapping(IO, *cast<WasmYAML::ElemSection>(Section.get())); 173 break; 174 case wasm::WASM_SEC_CODE: 175 if (!IO.outputting()) 176 Section.reset(new WasmYAML::CodeSection()); 177 sectionMapping(IO, *cast<WasmYAML::CodeSection>(Section.get())); 178 break; 179 case wasm::WASM_SEC_DATA: 180 if (!IO.outputting()) 181 Section.reset(new WasmYAML::DataSection()); 182 sectionMapping(IO, *cast<WasmYAML::DataSection>(Section.get())); 183 break; 184 default: 185 llvm_unreachable("Unknown section type"); 186 } 187 } 188 189 void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( 190 IO &IO, WasmYAML::SectionType &Type) { 191 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); 192 ECase(CUSTOM); 193 ECase(TYPE); 194 ECase(IMPORT); 195 ECase(FUNCTION); 196 ECase(TABLE); 197 ECase(MEMORY); 198 ECase(GLOBAL); 199 ECase(EXPORT); 200 ECase(START); 201 ECase(ELEM); 202 ECase(CODE); 203 ECase(DATA); 204 #undef ECase 205 } 206 207 void MappingTraits<WasmYAML::Signature>::mapping( 208 IO &IO, WasmYAML::Signature &Signature) { 209 IO.mapOptional("Index", Signature.Index); 210 IO.mapRequired("ReturnType", Signature.ReturnType); 211 IO.mapRequired("ParamTypes", Signature.ParamTypes); 212 } 213 214 void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { 215 IO.mapRequired("ElemType", Table.ElemType); 216 IO.mapRequired("Limits", Table.TableLimits); 217 } 218 219 void MappingTraits<WasmYAML::Function>::mapping(IO &IO, 220 WasmYAML::Function &Function) { 221 IO.mapRequired("Locals", Function.Locals); 222 IO.mapRequired("Body", Function.Body); 223 } 224 225 void MappingTraits<WasmYAML::Relocation>::mapping( 226 IO &IO, WasmYAML::Relocation &Relocation) { 227 IO.mapRequired("Type", Relocation.Type); 228 IO.mapRequired("Index", Relocation.Index); 229 IO.mapRequired("Offset", Relocation.Offset); 230 IO.mapOptional("Addend", Relocation.Addend, 0); 231 } 232 233 void MappingTraits<WasmYAML::NameEntry>::mapping( 234 IO &IO, WasmYAML::NameEntry &NameEntry) { 235 IO.mapRequired("Index", NameEntry.Index); 236 IO.mapRequired("Name", NameEntry.Name); 237 } 238 239 void MappingTraits<WasmYAML::LocalDecl>::mapping( 240 IO &IO, WasmYAML::LocalDecl &LocalDecl) { 241 IO.mapRequired("Type", LocalDecl.Type); 242 IO.mapRequired("Count", LocalDecl.Count); 243 } 244 245 void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, 246 WasmYAML::Limits &Limits) { 247 if (!IO.outputting() || Limits.Flags) 248 IO.mapOptional("Flags", Limits.Flags); 249 IO.mapRequired("Initial", Limits.Initial); 250 if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) 251 IO.mapOptional("Maximum", Limits.Maximum); 252 } 253 254 void MappingTraits<WasmYAML::ElemSegment>::mapping( 255 IO &IO, WasmYAML::ElemSegment &Segment) { 256 IO.mapRequired("Offset", Segment.Offset); 257 IO.mapRequired("Functions", Segment.Functions); 258 } 259 260 void MappingTraits<WasmYAML::Import>::mapping(IO &IO, 261 WasmYAML::Import &Import) { 262 IO.mapRequired("Module", Import.Module); 263 IO.mapRequired("Field", Import.Field); 264 IO.mapRequired("Kind", Import.Kind); 265 if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) { 266 IO.mapRequired("SigIndex", Import.SigIndex); 267 } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { 268 IO.mapRequired("GlobalType", Import.GlobalImport.Type); 269 IO.mapRequired("GlobalMutable", Import.GlobalImport.Mutable); 270 } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) { 271 IO.mapRequired("Table", Import.TableImport); 272 } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) { 273 IO.mapRequired("Memory", Import.Memory); 274 } else { 275 llvm_unreachable("unhandled import type"); 276 } 277 } 278 279 void MappingTraits<WasmYAML::Export>::mapping(IO &IO, 280 WasmYAML::Export &Export) { 281 IO.mapRequired("Name", Export.Name); 282 IO.mapRequired("Kind", Export.Kind); 283 IO.mapRequired("Index", Export.Index); 284 } 285 286 void MappingTraits<WasmYAML::Global>::mapping(IO &IO, 287 WasmYAML::Global &Global) { 288 IO.mapRequired("Type", Global.Type); 289 IO.mapRequired("Mutable", Global.Mutable); 290 IO.mapRequired("InitExpr", Global.InitExpr); 291 } 292 293 void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO, 294 wasm::WasmInitExpr &Expr) { 295 WasmYAML::Opcode Op = Expr.Opcode; 296 IO.mapRequired("Opcode", Op); 297 Expr.Opcode = Op; 298 switch (Expr.Opcode) { 299 case wasm::WASM_OPCODE_I32_CONST: 300 IO.mapRequired("Value", Expr.Value.Int32); 301 break; 302 case wasm::WASM_OPCODE_I64_CONST: 303 IO.mapRequired("Value", Expr.Value.Int64); 304 break; 305 case wasm::WASM_OPCODE_F32_CONST: 306 IO.mapRequired("Value", Expr.Value.Float32); 307 break; 308 case wasm::WASM_OPCODE_F64_CONST: 309 IO.mapRequired("Value", Expr.Value.Float64); 310 break; 311 case wasm::WASM_OPCODE_GET_GLOBAL: 312 IO.mapRequired("Index", Expr.Value.Global); 313 break; 314 } 315 } 316 317 void MappingTraits<WasmYAML::DataSegment>::mapping( 318 IO &IO, WasmYAML::DataSegment &Segment) { 319 IO.mapRequired("Index", Segment.Index); 320 IO.mapRequired("Offset", Segment.Offset); 321 IO.mapRequired("Content", Segment.Content); 322 } 323 324 void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( 325 IO &IO, WasmYAML::ValueType &Type) { 326 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 327 ECase(I32); 328 ECase(I64); 329 ECase(F32); 330 ECase(F64); 331 ECase(ANYFUNC); 332 ECase(FUNC); 333 ECase(NORESULT); 334 #undef ECase 335 } 336 337 void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( 338 IO &IO, WasmYAML::ExportKind &Kind) { 339 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); 340 ECase(FUNCTION); 341 ECase(TABLE); 342 ECase(MEMORY); 343 ECase(GLOBAL); 344 #undef ECase 345 } 346 347 void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( 348 IO &IO, WasmYAML::Opcode &Code) { 349 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); 350 ECase(END); 351 ECase(I32_CONST); 352 ECase(I64_CONST); 353 ECase(F64_CONST); 354 ECase(F32_CONST); 355 ECase(GET_GLOBAL); 356 #undef ECase 357 } 358 359 void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( 360 IO &IO, WasmYAML::TableType &Type) { 361 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); 362 ECase(ANYFUNC); 363 #undef ECase 364 } 365 366 void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( 367 IO &IO, WasmYAML::RelocType &Type) { 368 #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); 369 #include "llvm/BinaryFormat/WasmRelocs/WebAssembly.def" 370 #undef WASM_RELOC 371 } 372 373 } // end namespace yaml 374 } // end namespace llvm 375