diff --git a/lld/wasm/InputElement.h b/lld/wasm/InputElement.h --- a/lld/wasm/InputElement.h +++ b/lld/wasm/InputElement.h @@ -44,12 +44,13 @@ inline WasmInitExpr intConst(uint64_t value, bool is64) { WasmInitExpr ie; + ie.Extended = false; if (is64) { - ie.Opcode = llvm::wasm::WASM_OPCODE_I64_CONST; - ie.Value.Int64 = static_cast(value); + ie.Inst.Opcode = llvm::wasm::WASM_OPCODE_I64_CONST; + ie.Inst.Value.Int64 = static_cast(value); } else { - ie.Opcode = llvm::wasm::WASM_OPCODE_I32_CONST; - ie.Value.Int32 = static_cast(value); + ie.Inst.Opcode = llvm::wasm::WASM_OPCODE_I32_CONST; + ie.Inst.Value.Int32 = static_cast(value); } return ie; } diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -412,10 +412,12 @@ tableEntries.resize(totalFunctions); for (const WasmElemSegment &seg : wasmObj->elements()) { int64_t offset; - if (seg.Offset.Opcode == WASM_OPCODE_I32_CONST) - offset = seg.Offset.Value.Int32; - else if (seg.Offset.Opcode == WASM_OPCODE_I64_CONST) - offset = seg.Offset.Value.Int64; + if (seg.Offset.Extended) + fatal(toString(this) + ": extended init exprs not supported"); + else if (seg.Offset.Inst.Opcode == WASM_OPCODE_I32_CONST) + offset = seg.Offset.Inst.Value.Int32; + else if (seg.Offset.Inst.Opcode == WASM_OPCODE_I64_CONST) + offset = seg.Offset.Inst.Value.Int64; else fatal(toString(this) + ": invalid table elements"); for (size_t index = 0; index < seg.Functions.size(); index++) { diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -159,9 +159,10 @@ writeUleb128(os, 0, "memory index"); if ((segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { WasmInitExpr initExpr; + initExpr.Extended = false; if (config->isPic) { - initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - initExpr.Value.Global = WasmSym::memoryBase->getGlobalIndex(); + initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Inst.Value.Global = WasmSym::memoryBase->getGlobalIndex(); } else { initExpr = intConst(segment->startVA, config->is64.getValueOr(false)); } diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -542,15 +542,16 @@ writeUleb128(os, tableNumber, "table number"); WasmInitExpr initExpr; + initExpr.Extended = false; if (config->isPic) { - initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; - initExpr.Value.Global = + initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET; + initExpr.Inst.Value.Global = (config->is64.getValueOr(false) ? WasmSym::tableBase32 : WasmSym::tableBase) ->getGlobalIndex(); } else { - initExpr.Opcode = WASM_OPCODE_I32_CONST; - initExpr.Value.Int32 = config->tableBase; + initExpr.Inst.Opcode = WASM_OPCODE_I32_CONST; + initExpr.Inst.Value.Int32 = config->tableBase; } writeInitExpr(os, initExpr); diff --git a/lld/wasm/WriterUtils.h b/lld/wasm/WriterUtils.h --- a/lld/wasm/WriterUtils.h +++ b/lld/wasm/WriterUtils.h @@ -51,6 +51,9 @@ void writeInitExpr(raw_ostream &os, const llvm::wasm::WasmInitExpr &initExpr); +void writeInitExprMVP(raw_ostream &os, + const llvm::wasm::WasmInitExprMVP &initExpr); + void writeLimits(raw_ostream &os, const llvm::wasm::WasmLimits &limits); void writeGlobalType(raw_ostream &os, const llvm::wasm::WasmGlobalType &type); diff --git a/lld/wasm/WriterUtils.cpp b/lld/wasm/WriterUtils.cpp --- a/lld/wasm/WriterUtils.cpp +++ b/lld/wasm/WriterUtils.cpp @@ -159,6 +159,11 @@ } void writeInitExpr(raw_ostream &os, const WasmInitExpr &initExpr) { + assert(!initExpr.Extended); + writeInitExprMVP(os, initExpr.Inst); +} + +void writeInitExprMVP(raw_ostream &os, const WasmInitExprMVP &initExpr) { writeU8(os, initExpr.Opcode, "opcode"); switch (initExpr.Opcode) { case WASM_OPCODE_I32_CONST: diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -91,7 +91,7 @@ StringRef SymbolName; // from the "linking" section }; -struct WasmInitExpr { +struct WasmInitExprMVP { uint8_t Opcode; union { int32_t Int32; @@ -102,6 +102,13 @@ } Value; }; +struct WasmInitExpr { + uint8_t Extended; // Set to non-zero if extended const is used (i.e. more than + // one instruction) + WasmInitExprMVP Inst; + ArrayRef Body; +}; + struct WasmGlobalType { uint8_t Type; bool Mutable; @@ -285,7 +292,11 @@ WASM_OPCODE_F32_CONST = 0x43, WASM_OPCODE_F64_CONST = 0x44, WASM_OPCODE_I32_ADD = 0x6a, + WASM_OPCODE_I32_SUB = 0x6b, + WASM_OPCODE_I32_MUL = 0x6c, WASM_OPCODE_I64_ADD = 0x7c, + WASM_OPCODE_I64_SUB = 0x7d, + WASM_OPCODE_I64_MUL = 0x7e, WASM_OPCODE_REF_NULL = 0xd0, }; diff --git a/llvm/include/llvm/ObjectYAML/WasmYAML.h b/llvm/include/llvm/ObjectYAML/WasmYAML.h --- a/llvm/include/llvm/ObjectYAML/WasmYAML.h +++ b/llvm/include/llvm/ObjectYAML/WasmYAML.h @@ -62,11 +62,17 @@ uint32_t Index; }; +struct InitExpr { + bool Extended; + wasm::WasmInitExprMVP Inst; + yaml::BinaryRef Body; +}; + struct ElemSegment { uint32_t Flags; uint32_t TableNumber; ValueType ElemKind; - wasm::WasmInitExpr Offset; + InitExpr Offset; std::vector Functions; }; @@ -74,7 +80,7 @@ uint32_t Index; ValueType Type; bool Mutable; - wasm::WasmInitExpr InitExpr; + InitExpr InitExpr; }; struct Import { @@ -83,11 +89,13 @@ ExportKind Kind; union { uint32_t SigIndex; - Global GlobalImport; Table TableImport; Limits Memory; uint32_t TagIndex; }; + // Should be in the above union but fails because + // of missing defauilt constructor + Global GlobalImport; }; struct LocalDecl { @@ -114,7 +122,7 @@ uint32_t SectionOffset; uint32_t InitFlags; uint32_t MemoryIndex; - wasm::WasmInitExpr Offset; + InitExpr Offset; yaml::BinaryRef Content; }; @@ -526,8 +534,8 @@ static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); }; -template <> struct MappingTraits { - static void mapping(IO &IO, wasm::WasmInitExpr &Expr); +template <> struct MappingTraits { + static void mapping(IO &IO, WasmYAML::InitExpr &Expr); }; template <> struct MappingTraits { diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -931,25 +931,29 @@ for (const wasm::WasmGlobal &Global : Globals) { encodeULEB128(Global.Type.Type, W->OS); W->OS << char(Global.Type.Mutable); - W->OS << char(Global.InitExpr.Opcode); - switch (Global.Type.Type) { - case wasm::WASM_TYPE_I32: - encodeSLEB128(0, W->OS); - break; - case wasm::WASM_TYPE_I64: - encodeSLEB128(0, W->OS); - break; - case wasm::WASM_TYPE_F32: - writeI32(0); - break; - case wasm::WASM_TYPE_F64: - writeI64(0); - break; - case wasm::WASM_TYPE_EXTERNREF: - writeValueType(wasm::ValType::EXTERNREF); - break; - default: - llvm_unreachable("unexpected type"); + if (Global.InitExpr.Extended) { + llvm_unreachable("extected init expressions not supported"); + } else { + W->OS << char(Global.InitExpr.Inst.Opcode); + switch (Global.Type.Type) { + case wasm::WASM_TYPE_I32: + encodeSLEB128(0, W->OS); + break; + case wasm::WASM_TYPE_I64: + encodeSLEB128(0, W->OS); + break; + case wasm::WASM_TYPE_F32: + writeI32(0); + break; + case wasm::WASM_TYPE_F64: + writeI64(0); + break; + case wasm::WASM_TYPE_EXTERNREF: + writeValueType(wasm::ValType::EXTERNREF); + break; + default: + llvm_unreachable("unexpected type"); + } } W->OS << char(wasm::WASM_OPCODE_END); } @@ -1658,21 +1662,22 @@ wasm::WasmGlobal Global; Global.Type = WS.getGlobalType(); Global.Index = NumGlobalImports + Globals.size(); + Global.InitExpr.Extended = false; switch (Global.Type.Type) { case wasm::WASM_TYPE_I32: - Global.InitExpr.Opcode = wasm::WASM_OPCODE_I32_CONST; + Global.InitExpr.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; break; case wasm::WASM_TYPE_I64: - Global.InitExpr.Opcode = wasm::WASM_OPCODE_I64_CONST; + Global.InitExpr.Inst.Opcode = wasm::WASM_OPCODE_I64_CONST; break; case wasm::WASM_TYPE_F32: - Global.InitExpr.Opcode = wasm::WASM_OPCODE_F32_CONST; + Global.InitExpr.Inst.Opcode = wasm::WASM_OPCODE_F32_CONST; break; case wasm::WASM_TYPE_F64: - Global.InitExpr.Opcode = wasm::WASM_OPCODE_F64_CONST; + Global.InitExpr.Inst.Opcode = wasm::WASM_OPCODE_F64_CONST; break; case wasm::WASM_TYPE_EXTERNREF: - Global.InitExpr.Opcode = wasm::WASM_OPCODE_REF_NULL; + Global.InitExpr.Inst.Opcode = wasm::WASM_OPCODE_REF_NULL; break; default: llvm_unreachable("unexpected type"); diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -164,23 +164,25 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr, WasmObjectFile::ReadContext &Ctx) { - Expr.Opcode = readOpcode(Ctx); + auto Start = Ctx.Ptr; - switch (Expr.Opcode) { + Expr.Extended = false; + Expr.Inst.Opcode = readOpcode(Ctx); + switch (Expr.Inst.Opcode) { case wasm::WASM_OPCODE_I32_CONST: - Expr.Value.Int32 = readVarint32(Ctx); + Expr.Inst.Value.Int32 = readVarint32(Ctx); break; case wasm::WASM_OPCODE_I64_CONST: - Expr.Value.Int64 = readVarint64(Ctx); + Expr.Inst.Value.Int64 = readVarint64(Ctx); break; case wasm::WASM_OPCODE_F32_CONST: - Expr.Value.Float32 = readFloat32(Ctx); + Expr.Inst.Value.Float32 = readFloat32(Ctx); break; case wasm::WASM_OPCODE_F64_CONST: - Expr.Value.Float64 = readFloat64(Ctx); + Expr.Inst.Value.Float64 = readFloat64(Ctx); break; case wasm::WASM_OPCODE_GLOBAL_GET: - Expr.Value.Global = readULEB128(Ctx); + Expr.Inst.Value.Global = readULEB128(Ctx); break; case wasm::WASM_OPCODE_REF_NULL: { wasm::ValType Ty = static_cast(readULEB128(Ctx)); @@ -191,15 +193,54 @@ break; } default: - return make_error("invalid opcode in init_expr", - object_error::parse_failed); + Expr.Extended = true; } - uint8_t EndOpcode = readOpcode(Ctx); - if (EndOpcode != wasm::WASM_OPCODE_END) { - return make_error("invalid init_expr", - object_error::parse_failed); + if (!Expr.Extended) { + uint8_t EndOpcode = readOpcode(Ctx); + if (EndOpcode != wasm::WASM_OPCODE_END) + Expr.Extended = true; + } + + if (Expr.Extended) { + Ctx.Ptr = Start; + while (1) { + uint8_t Opcode = readOpcode(Ctx); + switch (Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + readVarint32(Ctx); + break; + case wasm::WASM_OPCODE_I64_CONST: + readVarint64(Ctx); + break; + case wasm::WASM_OPCODE_F32_CONST: + readFloat32(Ctx); + break; + case wasm::WASM_OPCODE_F64_CONST: + readFloat64(Ctx); + break; + case wasm::WASM_OPCODE_I32_ADD: + case wasm::WASM_OPCODE_I32_SUB: + case wasm::WASM_OPCODE_I32_MUL: + case wasm::WASM_OPCODE_I64_ADD: + case wasm::WASM_OPCODE_I64_SUB: + case wasm::WASM_OPCODE_I64_MUL: + break; + case wasm::WASM_OPCODE_GLOBAL_GET: + case wasm::WASM_OPCODE_REF_NULL: + readULEB128(Ctx); + break; + case wasm::WASM_OPCODE_END: + Expr.Body = ArrayRef(Start, Ctx.Ptr - Start); + return Error::success(); + default: + return make_error( + Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)), + object_error::parse_failed); + } + } } + return Error::success(); } @@ -1441,8 +1482,8 @@ object_error::parse_failed); if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) { - Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; - Segment.Offset.Value.Int32 = 0; + Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Inst.Value.Int32 = 0; } else { if (Error Err = readInitExpr(Segment.Offset, Ctx)) return Err; @@ -1501,8 +1542,8 @@ if (Error Err = readInitExpr(Segment.Data.Offset, Ctx)) return Err; } else { - Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; - Segment.Data.Offset.Value.Int32 = 0; + Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Data.Offset.Inst.Value.Int32 = 0; } uint32_t Size = readVaruint32(Ctx); if (Size > (size_t)(Ctx.End - Ctx.Ptr)) @@ -1600,10 +1641,12 @@ // offset within the segment. uint32_t SegmentIndex = Sym.Info.DataRef.Segment; const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data; - if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) { - return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; - } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) { - return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset; + if (Segment.Offset.Extended) { + llvm_unreachable("extended init exprs not supported"); + } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) { + return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset; + } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) { + return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset; } else { llvm_unreachable("unknown init expr opcode"); } diff --git a/llvm/lib/ObjectYAML/WasmEmitter.cpp b/llvm/lib/ObjectYAML/WasmEmitter.cpp --- a/llvm/lib/ObjectYAML/WasmEmitter.cpp +++ b/llvm/lib/ObjectYAML/WasmEmitter.cpp @@ -33,7 +33,7 @@ void writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec, uint32_t SectionIndex); - void writeInitExpr(raw_ostream &OS, const wasm::WasmInitExpr &InitExpr); + void writeInitExpr(raw_ostream &OS, const WasmYAML::InitExpr &InitExpr); void writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section); void writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section); @@ -129,29 +129,34 @@ } void WasmWriter::writeInitExpr(raw_ostream &OS, - const wasm::WasmInitExpr &InitExpr) { - writeUint8(OS, InitExpr.Opcode); - switch (InitExpr.Opcode) { - case wasm::WASM_OPCODE_I32_CONST: - encodeSLEB128(InitExpr.Value.Int32, OS); - break; - case wasm::WASM_OPCODE_I64_CONST: - encodeSLEB128(InitExpr.Value.Int64, OS); - break; - case wasm::WASM_OPCODE_F32_CONST: - writeUint32(OS, InitExpr.Value.Float32); - break; - case wasm::WASM_OPCODE_F64_CONST: - writeUint64(OS, InitExpr.Value.Float64); - break; - case wasm::WASM_OPCODE_GLOBAL_GET: - encodeULEB128(InitExpr.Value.Global, OS); - break; - default: - reportError("unknown opcode in init_expr: " + Twine(InitExpr.Opcode)); - return; + const WasmYAML::InitExpr &InitExpr) { + if (InitExpr.Extended) { + InitExpr.Body.writeAsBinary(OS); + } else { + writeUint8(OS, InitExpr.Inst.Opcode); + switch (InitExpr.Inst.Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + encodeSLEB128(InitExpr.Inst.Value.Int32, OS); + break; + case wasm::WASM_OPCODE_I64_CONST: + encodeSLEB128(InitExpr.Inst.Value.Int64, OS); + break; + case wasm::WASM_OPCODE_F32_CONST: + writeUint32(OS, InitExpr.Inst.Value.Float32); + break; + case wasm::WASM_OPCODE_F64_CONST: + writeUint64(OS, InitExpr.Inst.Value.Float64); + break; + case wasm::WASM_OPCODE_GLOBAL_GET: + encodeULEB128(InitExpr.Inst.Value.Global, OS); + break; + default: + reportError("unknown opcode in init_expr: " + + Twine(InitExpr.Inst.Opcode)); + return; + } + writeUint8(OS, wasm::WASM_OPCODE_END); } - writeUint8(OS, wasm::WASM_OPCODE_END); } void WasmWriter::writeSectionContent(raw_ostream &OS, diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp --- a/llvm/lib/ObjectYAML/WasmYAML.cpp +++ b/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -423,32 +423,37 @@ IO.mapRequired("InitExpr", Global.InitExpr); } -void MappingTraits::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; - case wasm::WASM_OPCODE_GLOBAL_GET: - IO.mapRequired("Index", Expr.Value.Global); - break; - case wasm::WASM_OPCODE_REF_NULL: { - WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF; - IO.mapRequired("Type", Ty); - break; - } +void MappingTraits::mapping(IO &IO, + WasmYAML::InitExpr &Expr) { + IO.mapOptional("Extended", Expr.Extended, false); + if (Expr.Extended) { + IO.mapRequired("Body", Expr.Body); + } else { + WasmYAML::Opcode Op = Expr.Inst.Opcode; + IO.mapRequired("Opcode", Op); + Expr.Inst.Opcode = Op; + switch (Expr.Inst.Opcode) { + case wasm::WASM_OPCODE_I32_CONST: + IO.mapRequired("Value", Expr.Inst.Value.Int32); + break; + case wasm::WASM_OPCODE_I64_CONST: + IO.mapRequired("Value", Expr.Inst.Value.Int64); + break; + case wasm::WASM_OPCODE_F32_CONST: + IO.mapRequired("Value", Expr.Inst.Value.Float32); + break; + case wasm::WASM_OPCODE_F64_CONST: + IO.mapRequired("Value", Expr.Inst.Value.Float64); + break; + case wasm::WASM_OPCODE_GLOBAL_GET: + IO.mapRequired("Index", Expr.Inst.Value.Global); + break; + case wasm::WASM_OPCODE_REF_NULL: { + WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF; + IO.mapRequired("Type", Ty); + break; + } + } } } @@ -464,8 +469,8 @@ if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { IO.mapRequired("Offset", Segment.Offset); } else { - Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; - Segment.Offset.Value.Int32 = 0; + Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Inst.Value.Int32 = 0; } IO.mapRequired("Content", Segment.Content); } diff --git a/llvm/test/ObjectYAML/wasm/extended_const_expressions.yaml b/llvm/test/ObjectYAML/wasm/extended_const_expressions.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/ObjectYAML/wasm/extended_const_expressions.yaml @@ -0,0 +1,42 @@ +# RUN: yaml2obj %s | obj2yaml | FileCheck %s +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: GLOBAL + Globals: + - Index: 0 + Type: I32 + Mutable: false + InitExpr: + # "extended" encoding of init expression: + # (global.get[0x23] 0x1 end[0x0b]) + Extended: true + Body: 23010b + - Index: 1 + Type: I64 + Mutable: false + InitExpr: + # (global.get[0x23] 0x1 i32.const[0x41] 0x2 i32.add[0x6a] end[0x0b]) + Extended: true + Body: 230141026a0b +... +# CHECK: --- !WASM +# CHECK: FileHeader: +# CHECK: Version: 0x1 +# CHECK: Sections: +# CHECK: - Type: GLOBAL +# CHECK: Globals: +# CHECK: - Index: 0 +# CHECK: Type: I32 +# CHECK: Mutable: false +# CHECK: InitExpr: +# CHECK: Opcode: GLOBAL_GET +# CHECK: Index: 1 +# CHECK: - Index: 1 +# CHECK: Type: I64 +# CHECK: Mutable: false +# CHECK: InitExpr: +# CHECK: Extended: true +# CHECK: Body: 230141026A0B +# CHECK: ... diff --git a/llvm/tools/llvm-readobj/WasmDumper.cpp b/llvm/tools/llvm-readobj/WasmDumper.cpp --- a/llvm/tools/llvm-readobj/WasmDumper.cpp +++ b/llvm/tools/llvm-readobj/WasmDumper.cpp @@ -179,13 +179,15 @@ if (!Seg.Name.empty()) W.printString("Name", Seg.Name); W.printNumber("Size", static_cast(Seg.Content.size())); - if (Seg.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) - W.printNumber("Offset", Seg.Offset.Value.Int32); - else if (Seg.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) - W.printNumber("Offset", Seg.Offset.Value.Int64); - else if (Seg.Offset.Opcode == wasm::WASM_OPCODE_GLOBAL_GET) { + if (Seg.Offset.Extended) + llvm_unreachable("extended const exprs not supported"); + else if (Seg.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) + W.printNumber("Offset", Seg.Offset.Inst.Value.Int32); + else if (Seg.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) + W.printNumber("Offset", Seg.Offset.Inst.Value.Int64); + else if (Seg.Offset.Inst.Opcode == wasm::WASM_OPCODE_GLOBAL_GET) { ListScope Group(W, "Offset"); - W.printNumber("Global", Seg.Offset.Value.Global); + W.printNumber("Global", Seg.Offset.Inst.Value.Global); } else llvm_unreachable("unknown init expr opcode"); } diff --git a/llvm/tools/obj2yaml/wasm2yaml.cpp b/llvm/tools/obj2yaml/wasm2yaml.cpp --- a/llvm/tools/obj2yaml/wasm2yaml.cpp +++ b/llvm/tools/obj2yaml/wasm2yaml.cpp @@ -298,7 +298,12 @@ G.Index = Global.Index; G.Type = Global.Type.Type; G.Mutable = Global.Type.Mutable; - G.InitExpr = Global.InitExpr; + G.InitExpr.Extended = Global.InitExpr.Extended; + if (Global.InitExpr.Extended) { + G.InitExpr.Body = Global.InitExpr.Body; + } else { + G.InitExpr.Inst = Global.InitExpr.Inst; + } GlobalSec->Globals.push_back(G); } S = std::move(GlobalSec); @@ -329,7 +334,12 @@ Seg.Flags = Segment.Flags; Seg.TableNumber = Segment.TableNumber; Seg.ElemKind = Segment.ElemKind; - Seg.Offset = Segment.Offset; + Seg.Offset.Extended = Segment.Offset.Extended; + if (Seg.Offset.Extended) { + Seg.Offset.Body = yaml::BinaryRef(Segment.Offset.Body); + } else { + Seg.Offset.Inst = Segment.Offset.Inst; + } append_range(Seg.Functions, Segment.Functions); ElemSec->Segments.push_back(Seg); } @@ -360,7 +370,12 @@ Seg.SectionOffset = Segment.SectionOffset; Seg.InitFlags = Segment.Data.InitFlags; Seg.MemoryIndex = Segment.Data.MemoryIndex; - Seg.Offset = Segment.Data.Offset; + Seg.Offset.Extended = Segment.Data.Offset.Extended; + if (Seg.Offset.Extended) { + Seg.Offset.Body = yaml::BinaryRef(Segment.Data.Offset.Body); + } else { + Seg.Offset.Inst = Segment.Data.Offset.Inst; + } Seg.Content = yaml::BinaryRef(Segment.Data.Content); DataSec->Segments.push_back(Seg); }