================
@@ -1034,13 +1136,52 @@ class WebAssemblyAsmParser final : public
MCTargetAsmParser {
// Now set this symbol with the correct type.
auto *WasmSym =
static_cast<MCSymbolWasm *>(Ctx.getOrCreateSymbol(SymName));
+ if (WasmSym->hasGlobalInitExpr()) {
+ std::optional<wasm::WasmInitExpr> Expected =
+ WebAssembly::makeGlobalInitExpr(*Type, 0);
+ if (!Expected ||
+ Expected->Inst.Opcode != WasmSym->getGlobalInitExpr().Inst.Opcode)
+ return error(
+ "Type does not match the .globalinit already given for: ",
+ SymNameTok);
+ }
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
WasmSym->setGlobalType(wasm::WasmGlobalType{uint8_t(*Type), Mutable});
// And emit the directive again.
TOut.emitGlobalType(WasmSym);
return expect(AsmToken::EndOfStatement, "EOL");
}
+ if (DirectiveID.getString() == ".globalinit") {
----------------
kateinoigakukun wrote:
It looks like `.globalinit` is not extensible to extended-const as written. It
takes exactly one `<type>.const` and requires the const's type to equal the
global's type, which isn't true for a multi-instruction expression.
Note that `;` is the statement separator in the WebAssembly assembler (the
default `SeparatorString`), so `.globalinit g, i32.const 1; i32.const 2;
i32.add` can't be a single directive either.
How about a block form that mirrors function bodies, where the init expr is the
instruction lines between `.globalinit` and a terminator, parsed through the
regular `parseInstruction` -> `MatchInstructionImpl` path and type-checked
against the global's type?
```
.globaltype g, i32
.globalinit g
i32.const 1
i32.const 2
i32.add
end_globalinit
```
`end_globalinit` would mirror `end_function`. Having the block form as the only
spelling avoids maintaining two parsers and printers.
https://github.com/llvm/llvm-project/pull/212007
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits