[WebAssembly] Second phase of implemented extended const proposal
This change continues to lay the ground work for supporting extended const expressions in the linker. The included test covers object file reading and writing and the YAML representation. Differential Revision: https://reviews.llvm.org/D121349
This commit is contained in:
parent
8361c5da30
commit
9504ab32b7
@ -44,12 +44,13 @@ protected:
|
||||
|
||||
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<int64_t>(value);
|
||||
ie.Inst.Opcode = llvm::wasm::WASM_OPCODE_I64_CONST;
|
||||
ie.Inst.Value.Int64 = static_cast<int64_t>(value);
|
||||
} else {
|
||||
ie.Opcode = llvm::wasm::WASM_OPCODE_I32_CONST;
|
||||
ie.Value.Int32 = static_cast<int32_t>(value);
|
||||
ie.Inst.Opcode = llvm::wasm::WASM_OPCODE_I32_CONST;
|
||||
ie.Inst.Value.Int32 = static_cast<int32_t>(value);
|
||||
}
|
||||
return ie;
|
||||
}
|
||||
|
@ -412,10 +412,12 @@ void ObjFile::parse(bool ignoreComdats) {
|
||||
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++) {
|
||||
|
@ -159,9 +159,10 @@ void DataSection::finalizeContents() {
|
||||
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));
|
||||
}
|
||||
|
@ -542,15 +542,16 @@ void ElemSection::writeBody() {
|
||||
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);
|
||||
|
||||
|
@ -159,6 +159,11 @@ void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset) {
|
||||
}
|
||||
|
||||
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:
|
||||
|
@ -51,6 +51,9 @@ void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset);
|
||||
|
||||
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);
|
||||
|
@ -91,7 +91,7 @@ struct WasmTable {
|
||||
StringRef SymbolName; // from the "linking" section
|
||||
};
|
||||
|
||||
struct WasmInitExpr {
|
||||
struct WasmInitExprMVP {
|
||||
uint8_t Opcode;
|
||||
union {
|
||||
int32_t Int32;
|
||||
@ -102,6 +102,13 @@ struct WasmInitExpr {
|
||||
} Value;
|
||||
};
|
||||
|
||||
struct WasmInitExpr {
|
||||
uint8_t Extended; // Set to non-zero if extended const is used (i.e. more than
|
||||
// one instruction)
|
||||
WasmInitExprMVP Inst;
|
||||
ArrayRef<uint8_t> Body;
|
||||
};
|
||||
|
||||
struct WasmGlobalType {
|
||||
uint8_t Type;
|
||||
bool Mutable;
|
||||
@ -285,7 +292,11 @@ enum : unsigned {
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -62,11 +62,20 @@ struct Export {
|
||||
uint32_t Index;
|
||||
};
|
||||
|
||||
struct InitExpr {
|
||||
InitExpr() {}
|
||||
bool Extended;
|
||||
union {
|
||||
wasm::WasmInitExprMVP Inst;
|
||||
yaml::BinaryRef Body;
|
||||
};
|
||||
};
|
||||
|
||||
struct ElemSegment {
|
||||
uint32_t Flags;
|
||||
uint32_t TableNumber;
|
||||
ValueType ElemKind;
|
||||
wasm::WasmInitExpr Offset;
|
||||
InitExpr Offset;
|
||||
std::vector<uint32_t> Functions;
|
||||
};
|
||||
|
||||
@ -74,19 +83,20 @@ struct Global {
|
||||
uint32_t Index;
|
||||
ValueType Type;
|
||||
bool Mutable;
|
||||
wasm::WasmInitExpr InitExpr;
|
||||
InitExpr InitExpr;
|
||||
};
|
||||
|
||||
struct Import {
|
||||
Import() {}
|
||||
StringRef Module;
|
||||
StringRef Field;
|
||||
ExportKind Kind;
|
||||
union {
|
||||
uint32_t SigIndex;
|
||||
Global GlobalImport;
|
||||
Table TableImport;
|
||||
Limits Memory;
|
||||
uint32_t TagIndex;
|
||||
Global GlobalImport;
|
||||
};
|
||||
};
|
||||
|
||||
@ -114,7 +124,7 @@ struct DataSegment {
|
||||
uint32_t SectionOffset;
|
||||
uint32_t InitFlags;
|
||||
uint32_t MemoryIndex;
|
||||
wasm::WasmInitExpr Offset;
|
||||
InitExpr Offset;
|
||||
yaml::BinaryRef Content;
|
||||
};
|
||||
|
||||
@ -526,8 +536,8 @@ template <> struct MappingTraits<WasmYAML::LocalDecl> {
|
||||
static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<wasm::WasmInitExpr> {
|
||||
static void mapping(IO &IO, wasm::WasmInitExpr &Expr);
|
||||
template <> struct MappingTraits<WasmYAML::InitExpr> {
|
||||
static void mapping(IO &IO, WasmYAML::InitExpr &Expr);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<WasmYAML::DataSegment> {
|
||||
|
@ -931,7 +931,10 @@ void WasmObjectWriter::writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals) {
|
||||
for (const wasm::WasmGlobal &Global : Globals) {
|
||||
encodeULEB128(Global.Type.Type, W->OS);
|
||||
W->OS << char(Global.Type.Mutable);
|
||||
W->OS << char(Global.InitExpr.Opcode);
|
||||
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);
|
||||
@ -951,6 +954,7 @@ void WasmObjectWriter::writeGlobalSection(ArrayRef<wasm::WasmGlobal> Globals) {
|
||||
default:
|
||||
llvm_unreachable("unexpected type");
|
||||
}
|
||||
}
|
||||
W->OS << char(wasm::WASM_OPCODE_END);
|
||||
}
|
||||
|
||||
@ -1658,21 +1662,22 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
|
||||
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");
|
||||
|
@ -164,23 +164,25 @@ static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
|
||||
|
||||
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<wasm::ValType>(readULEB128(Ctx));
|
||||
@ -191,15 +193,46 @@ static Error readInitExpr(wasm::WasmInitExpr &Expr,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return make_error<GenericBinaryError>("invalid opcode in init_expr",
|
||||
object_error::parse_failed);
|
||||
Expr.Extended = true;
|
||||
}
|
||||
|
||||
if (!Expr.Extended) {
|
||||
uint8_t EndOpcode = readOpcode(Ctx);
|
||||
if (EndOpcode != wasm::WASM_OPCODE_END) {
|
||||
return make_error<GenericBinaryError>("invalid init_expr",
|
||||
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:
|
||||
case wasm::WASM_OPCODE_GLOBAL_GET:
|
||||
case wasm::WASM_OPCODE_REF_NULL:
|
||||
case wasm::WASM_OPCODE_I64_CONST:
|
||||
case wasm::WASM_OPCODE_F32_CONST:
|
||||
case wasm::WASM_OPCODE_F64_CONST:
|
||||
readULEB128(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_END:
|
||||
Expr.Body = ArrayRef<uint8_t>(Start, Ctx.Ptr - Start);
|
||||
return Error::success();
|
||||
default:
|
||||
return make_error<GenericBinaryError>(
|
||||
Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)),
|
||||
object_error::parse_failed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
@ -1441,8 +1474,8 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
|
||||
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 +1534,8 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
|
||||
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 +1633,12 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
|
||||
// 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");
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ private:
|
||||
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::reportError(const Twine &Msg) {
|
||||
}
|
||||
|
||||
void WasmWriter::writeInitExpr(raw_ostream &OS,
|
||||
const wasm::WasmInitExpr &InitExpr) {
|
||||
writeUint8(OS, InitExpr.Opcode);
|
||||
switch (InitExpr.Opcode) {
|
||||
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.Value.Int32, OS);
|
||||
encodeSLEB128(InitExpr.Inst.Value.Int32, OS);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_I64_CONST:
|
||||
encodeSLEB128(InitExpr.Value.Int64, OS);
|
||||
encodeSLEB128(InitExpr.Inst.Value.Int64, OS);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_F32_CONST:
|
||||
writeUint32(OS, InitExpr.Value.Float32);
|
||||
writeUint32(OS, InitExpr.Inst.Value.Float32);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_F64_CONST:
|
||||
writeUint64(OS, InitExpr.Value.Float64);
|
||||
writeUint64(OS, InitExpr.Inst.Value.Float64);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_GLOBAL_GET:
|
||||
encodeULEB128(InitExpr.Value.Global, OS);
|
||||
encodeULEB128(InitExpr.Inst.Value.Global, OS);
|
||||
break;
|
||||
default:
|
||||
reportError("unknown opcode in init_expr: " + Twine(InitExpr.Opcode));
|
||||
reportError("unknown opcode in init_expr: " +
|
||||
Twine(InitExpr.Inst.Opcode));
|
||||
return;
|
||||
}
|
||||
writeUint8(OS, wasm::WASM_OPCODE_END);
|
||||
}
|
||||
}
|
||||
|
||||
void WasmWriter::writeSectionContent(raw_ostream &OS,
|
||||
|
@ -367,8 +367,7 @@ void MappingTraits<WasmYAML::LocalDecl>::mapping(
|
||||
|
||||
void MappingTraits<WasmYAML::Limits>::mapping(IO &IO,
|
||||
WasmYAML::Limits &Limits) {
|
||||
if (!IO.outputting() || Limits.Flags)
|
||||
IO.mapOptional("Flags", Limits.Flags);
|
||||
IO.mapOptional("Flags", Limits.Flags, 0);
|
||||
IO.mapRequired("Minimum", Limits.Minimum);
|
||||
if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
|
||||
IO.mapOptional("Maximum", Limits.Maximum);
|
||||
@ -376,8 +375,7 @@ void MappingTraits<WasmYAML::Limits>::mapping(IO &IO,
|
||||
|
||||
void MappingTraits<WasmYAML::ElemSegment>::mapping(
|
||||
IO &IO, WasmYAML::ElemSegment &Segment) {
|
||||
if (!IO.outputting() || Segment.Flags)
|
||||
IO.mapOptional("Flags", Segment.Flags);
|
||||
IO.mapOptional("Flags", Segment.Flags, 0);
|
||||
if (!IO.outputting() ||
|
||||
Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
|
||||
IO.mapOptional("TableNumber", Segment.TableNumber);
|
||||
@ -423,26 +421,30 @@ void MappingTraits<WasmYAML::Global>::mapping(IO &IO,
|
||||
IO.mapRequired("InitExpr", Global.InitExpr);
|
||||
}
|
||||
|
||||
void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
|
||||
wasm::WasmInitExpr &Expr) {
|
||||
WasmYAML::Opcode Op = Expr.Opcode;
|
||||
void MappingTraits<WasmYAML::InitExpr>::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.Opcode = Op;
|
||||
switch (Expr.Opcode) {
|
||||
Expr.Inst.Opcode = Op;
|
||||
switch (Expr.Inst.Opcode) {
|
||||
case wasm::WASM_OPCODE_I32_CONST:
|
||||
IO.mapRequired("Value", Expr.Value.Int32);
|
||||
IO.mapRequired("Value", Expr.Inst.Value.Int32);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_I64_CONST:
|
||||
IO.mapRequired("Value", Expr.Value.Int64);
|
||||
IO.mapRequired("Value", Expr.Inst.Value.Int64);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_F32_CONST:
|
||||
IO.mapRequired("Value", Expr.Value.Float32);
|
||||
IO.mapRequired("Value", Expr.Inst.Value.Float32);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_F64_CONST:
|
||||
IO.mapRequired("Value", Expr.Value.Float64);
|
||||
IO.mapRequired("Value", Expr.Inst.Value.Float64);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_GLOBAL_GET:
|
||||
IO.mapRequired("Index", Expr.Value.Global);
|
||||
IO.mapRequired("Index", Expr.Inst.Value.Global);
|
||||
break;
|
||||
case wasm::WASM_OPCODE_REF_NULL: {
|
||||
WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF;
|
||||
@ -450,6 +452,7 @@ void MappingTraits<wasm::WasmInitExpr>::mapping(IO &IO,
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MappingTraits<WasmYAML::DataSegment>::mapping(
|
||||
@ -464,8 +467,8 @@ void MappingTraits<WasmYAML::DataSegment>::mapping(
|
||||
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);
|
||||
}
|
||||
|
42
llvm/test/ObjectYAML/wasm/extended_const_expressions.yaml
Normal file
42
llvm/test/ObjectYAML/wasm/extended_const_expressions.yaml
Normal file
@ -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: ...
|
@ -179,13 +179,15 @@ void WasmDumper::printSectionHeaders() {
|
||||
if (!Seg.Name.empty())
|
||||
W.printString("Name", Seg.Name);
|
||||
W.printNumber("Size", static_cast<uint64_t>(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");
|
||||
}
|
||||
|
@ -298,7 +298,12 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
|
||||
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 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
|
||||
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 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user