mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[WebAssembly] Fix types for address taken functions
Differential Revision: https://reviews.llvm.org/D34966 llvm-svn: 307198
This commit is contained in:
parent
f216b66f0e
commit
d6548e35b2
@ -21,6 +21,8 @@ private:
|
|||||||
std::string ModuleName;
|
std::string ModuleName;
|
||||||
SmallVector<wasm::ValType, 1> Returns;
|
SmallVector<wasm::ValType, 1> Returns;
|
||||||
SmallVector<wasm::ValType, 4> Params;
|
SmallVector<wasm::ValType, 4> Params;
|
||||||
|
bool ParamsSet = false;
|
||||||
|
bool ReturnsSet = false;
|
||||||
|
|
||||||
/// An expression describing how to calculate the size of a symbol. If a
|
/// An expression describing how to calculate the size of a symbol. If a
|
||||||
/// symbol has no size this field will be NULL.
|
/// symbol has no size this field will be NULL.
|
||||||
@ -45,15 +47,23 @@ public:
|
|||||||
|
|
||||||
const StringRef getModuleName() const { return ModuleName; }
|
const StringRef getModuleName() const { return ModuleName; }
|
||||||
|
|
||||||
const SmallVector<wasm::ValType, 1> &getReturns() const { return Returns; }
|
const SmallVector<wasm::ValType, 1> &getReturns() const {
|
||||||
|
assert(ReturnsSet);
|
||||||
|
return Returns;
|
||||||
|
}
|
||||||
|
|
||||||
void setReturns(SmallVectorImpl<wasm::ValType> &&Rets) {
|
void setReturns(SmallVectorImpl<wasm::ValType> &&Rets) {
|
||||||
|
ReturnsSet = true;
|
||||||
Returns = std::move(Rets);
|
Returns = std::move(Rets);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SmallVector<wasm::ValType, 4> &getParams() const { return Params; }
|
const SmallVector<wasm::ValType, 4> &getParams() const {
|
||||||
|
assert(ParamsSet);
|
||||||
|
return Params;
|
||||||
|
}
|
||||||
|
|
||||||
void setParams(SmallVectorImpl<wasm::ValType> &&Pars) {
|
void setParams(SmallVectorImpl<wasm::ValType> &&Pars) {
|
||||||
|
ParamsSet = true;
|
||||||
Params = std::move(Pars);
|
Params = std::move(Pars);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ struct WasmRelocationEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void print(raw_ostream &Out) const {
|
void print(raw_ostream &Out) const {
|
||||||
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend
|
Out << "Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
|
||||||
<< ", Type=" << Type << ", FixupSection=" << FixupSection;
|
<< ", Type=" << Type << ", FixupSection=" << FixupSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +115,8 @@ void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) {
|
|||||||
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
|
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
|
||||||
|
|
||||||
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
|
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
|
||||||
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
||||||
OS << "\t.functype\t" << name;
|
OS << "\t.functype\t" << Symbol->getName();
|
||||||
if (Results.empty())
|
if (Results.empty())
|
||||||
OS << ", void";
|
OS << ", void";
|
||||||
else {
|
else {
|
||||||
@ -171,7 +171,7 @@ void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
|
void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
|
||||||
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
||||||
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate
|
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate
|
||||||
// whether it's necessary for .o files to declare indirect function types.
|
// whether it's necessary for .o files to declare indirect function types.
|
||||||
}
|
}
|
||||||
@ -255,9 +255,25 @@ void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
|
void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
|
||||||
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
|
||||||
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate
|
SmallVectorImpl<MVT> &Results) {
|
||||||
// whether it's necessary for .o files to declare indirect function types.
|
MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Symbol);
|
||||||
|
if (WasmSym->isFunction()) {
|
||||||
|
// Symbol already has its arguments and result set.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVector<wasm::ValType, 4> ValParams;
|
||||||
|
for (MVT Ty : Params)
|
||||||
|
ValParams.push_back(WebAssembly::toValType(Ty));
|
||||||
|
|
||||||
|
SmallVector<wasm::ValType, 1> ValResults;
|
||||||
|
for (MVT Ty : Results)
|
||||||
|
ValResults.push_back(WebAssembly::toValType(Ty));
|
||||||
|
|
||||||
|
WasmSym->setParams(std::move(ValParams));
|
||||||
|
WasmSym->setReturns(std::move(ValResults));
|
||||||
|
WasmSym->setIsFunction(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
|
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
/// .endfunc
|
/// .endfunc
|
||||||
virtual void emitEndFunc() = 0;
|
virtual void emitEndFunc() = 0;
|
||||||
/// .functype
|
/// .functype
|
||||||
virtual void emitIndirectFunctionType(StringRef name,
|
virtual void emitIndirectFunctionType(MCSymbol *Symbol,
|
||||||
SmallVectorImpl<MVT> &Params,
|
SmallVectorImpl<MVT> &Params,
|
||||||
SmallVectorImpl<MVT> &Results) = 0;
|
SmallVectorImpl<MVT> &Results) = 0;
|
||||||
/// .indidx
|
/// .indidx
|
||||||
@ -69,7 +69,7 @@ public:
|
|||||||
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
||||||
void emitStackPointer(uint32_t Index) override;
|
void emitStackPointer(uint32_t Index) override;
|
||||||
void emitEndFunc() override;
|
void emitEndFunc() override;
|
||||||
void emitIndirectFunctionType(StringRef name,
|
void emitIndirectFunctionType(MCSymbol *Symbol,
|
||||||
SmallVectorImpl<MVT> &Params,
|
SmallVectorImpl<MVT> &Params,
|
||||||
SmallVectorImpl<MVT> &Results) override;
|
SmallVectorImpl<MVT> &Results) override;
|
||||||
void emitIndIdx(const MCExpr *Value) override;
|
void emitIndIdx(const MCExpr *Value) override;
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
||||||
void emitStackPointer(uint32_t Index) override;
|
void emitStackPointer(uint32_t Index) override;
|
||||||
void emitEndFunc() override;
|
void emitEndFunc() override;
|
||||||
void emitIndirectFunctionType(StringRef name,
|
void emitIndirectFunctionType(MCSymbol *Symbol,
|
||||||
SmallVectorImpl<MVT> &Params,
|
SmallVectorImpl<MVT> &Params,
|
||||||
SmallVectorImpl<MVT> &Results) override;
|
SmallVectorImpl<MVT> &Results) override;
|
||||||
void emitIndIdx(const MCExpr *Value) override;
|
void emitIndIdx(const MCExpr *Value) override;
|
||||||
@ -105,7 +105,7 @@ public:
|
|||||||
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
|
||||||
void emitStackPointer(uint32_t Index) override;
|
void emitStackPointer(uint32_t Index) override;
|
||||||
void emitEndFunc() override;
|
void emitEndFunc() override;
|
||||||
void emitIndirectFunctionType(StringRef name,
|
void emitIndirectFunctionType(MCSymbol *Symbol,
|
||||||
SmallVectorImpl<MVT> &Params,
|
SmallVectorImpl<MVT> &Params,
|
||||||
SmallVectorImpl<MVT> &Results) override;
|
SmallVectorImpl<MVT> &Results) override;
|
||||||
void emitIndIdx(const MCExpr *Value) override;
|
void emitIndIdx(const MCExpr *Value) override;
|
||||||
|
@ -84,7 +84,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
|||||||
SmallVector<MVT, 4> Results;
|
SmallVector<MVT, 4> Results;
|
||||||
SmallVector<MVT, 4> Params;
|
SmallVector<MVT, 4> Params;
|
||||||
ComputeSignatureVTs(F, TM, Params, Results);
|
ComputeSignatureVTs(F, TM, Params, Results);
|
||||||
getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params,
|
getTargetStreamer()->emitIndirectFunctionType(getSymbol(&F), Params,
|
||||||
Results);
|
Results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,11 +214,8 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) {
|
const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) {
|
||||||
if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
|
if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
|
||||||
if (GV->getValueType()->isFunctionTy()) {
|
if (GV->getValueType()->isFunctionTy()) {
|
||||||
MCSymbol* Sym = getSymbol(GV);
|
|
||||||
if (!isa<MCSymbolELF>(Sym))
|
|
||||||
cast<MCSymbolWasm>(Sym)->setIsFunction(true);
|
|
||||||
return MCSymbolRefExpr::create(
|
return MCSymbolRefExpr::create(
|
||||||
Sym, MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
|
getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
|
||||||
}
|
}
|
||||||
return AsmPrinter::lowerConstant(CV);
|
return AsmPrinter::lowerConstant(CV);
|
||||||
}
|
}
|
||||||
|
@ -112,8 +112,6 @@ MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
|
|||||||
MCSymbolRefExpr::VariantKind VK =
|
MCSymbolRefExpr::VariantKind VK =
|
||||||
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
|
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
|
||||||
: MCSymbolRefExpr::VK_None;
|
: MCSymbolRefExpr::VK_None;
|
||||||
if (!isa<MCSymbolELF>(Sym))
|
|
||||||
cast<MCSymbolWasm>(Sym)->setIsFunction(IsFunc);
|
|
||||||
|
|
||||||
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);
|
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);
|
||||||
|
|
||||||
|
@ -2,24 +2,33 @@
|
|||||||
; Verify that addresses of external functions generate correctly typed
|
; Verify that addresses of external functions generate correctly typed
|
||||||
; imports and relocations or type R_TABLE_INDEX_I32.
|
; imports and relocations or type R_TABLE_INDEX_I32.
|
||||||
|
|
||||||
declare void @f1() #1
|
declare void @f1(i32) #1
|
||||||
@ptr_to_f1 = hidden global void ()* @f1, align 4
|
@ptr_to_f1 = hidden global void (i32)* @f1, align 4
|
||||||
|
|
||||||
|
; CHECK: --- !WASM
|
||||||
; CHECK: - Type: IMPORT
|
; CHECK-NEXT: FileHeader:
|
||||||
; CHECK: Imports:
|
; CHECK-NEXT: Version: 0x00000001
|
||||||
; CHECK: - Module: env
|
; CHECK-NEXT: Sections:
|
||||||
; CHECK: Field: f1
|
; CHECK-NEXT: - Type: TYPE
|
||||||
; CHECK: Kind: FUNCTION
|
; CHECK-NEXT: Signatures:
|
||||||
; CHECK: SigIndex: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK: - Type: ELEM
|
; CHECK-NEXT: ReturnType: NORESULT
|
||||||
; CHECK: Segments:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK: - Offset:
|
; CHECK-NEXT: - I32
|
||||||
; CHECK: Opcode: I32_CONST
|
; CHECK: - Type: IMPORT
|
||||||
; CHECK: Value: 0
|
; CHECK-NEXT: Imports:
|
||||||
; CHECK: Functions: [ 0 ]
|
; CHECK-NEXT: - Module: env
|
||||||
; CHECK: - Type: DATA
|
; CHECK-NEXT: Field: f1
|
||||||
; CHECK: Relocations:
|
; CHECK-NEXT: Kind: FUNCTION
|
||||||
; CHECK: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
; CHECK-NEXT: SigIndex: 0
|
||||||
; CHECK: Index: 0
|
; CHECK: - Type: ELEM
|
||||||
; CHECK: Offset: 0x00000006
|
; CHECK-NEXT: Segments:
|
||||||
|
; CHECK-NEXT: - Offset:
|
||||||
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
; CHECK-NEXT: Value: 0
|
||||||
|
; CHECK-NEXT: Functions: [ 0 ]
|
||||||
|
; CHECK: - Type: DATA
|
||||||
|
; CHECK-NEXT: Relocations:
|
||||||
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
||||||
|
; CHECK-NEXT: Index: 0
|
||||||
|
; CHECK-NEXT: Offset: 0x00000006
|
||||||
|
Loading…
x
Reference in New Issue
Block a user