1
0
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:
Sam Clegg 2017-07-05 20:25:08 +00:00
parent f216b66f0e
commit d6548e35b2
7 changed files with 70 additions and 40 deletions

View File

@ -21,6 +21,8 @@ private:
std::string ModuleName;
SmallVector<wasm::ValType, 1> Returns;
SmallVector<wasm::ValType, 4> Params;
bool ParamsSet = false;
bool ReturnsSet = false;
/// An expression describing how to calculate the size of a symbol. If a
/// symbol has no size this field will be NULL.
@ -45,15 +47,23 @@ public:
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) {
ReturnsSet = true;
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) {
ParamsSet = true;
Params = std::move(Pars);
}
};

View File

@ -153,7 +153,7 @@ struct WasmRelocationEntry {
}
void print(raw_ostream &Out) const {
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend
Out << "Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
<< ", Type=" << Type << ", FixupSection=" << FixupSection;
}

View File

@ -115,8 +115,8 @@ void WebAssemblyTargetAsmStreamer::emitStackPointer(uint32_t Index) {
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
OS << "\t.functype\t" << name;
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
OS << "\t.functype\t" << Symbol->getName();
if (Results.empty())
OS << ", void";
else {
@ -171,7 +171,7 @@ void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
}
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
// 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(
StringRef name, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
// 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.
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) {
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) {

View File

@ -44,7 +44,7 @@ public:
/// .endfunc
virtual void emitEndFunc() = 0;
/// .functype
virtual void emitIndirectFunctionType(StringRef name,
virtual void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) = 0;
/// .indidx
@ -69,7 +69,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name,
void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override;
@ -87,7 +87,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name,
void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override;
@ -105,7 +105,7 @@ public:
void emitGlobal(ArrayRef<wasm::Global> Globals) override;
void emitStackPointer(uint32_t Index) override;
void emitEndFunc() override;
void emitIndirectFunctionType(StringRef name,
void emitIndirectFunctionType(MCSymbol *Symbol,
SmallVectorImpl<MVT> &Params,
SmallVectorImpl<MVT> &Results) override;
void emitIndIdx(const MCExpr *Value) override;

View File

@ -84,7 +84,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
SmallVector<MVT, 4> Results;
SmallVector<MVT, 4> Params;
ComputeSignatureVTs(F, TM, Params, Results);
getTargetStreamer()->emitIndirectFunctionType(F.getName(), Params,
getTargetStreamer()->emitIndirectFunctionType(getSymbol(&F), Params,
Results);
}
}
@ -214,11 +214,8 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
if (GV->getValueType()->isFunctionTy()) {
MCSymbol* Sym = getSymbol(GV);
if (!isa<MCSymbolELF>(Sym))
cast<MCSymbolWasm>(Sym)->setIsFunction(true);
return MCSymbolRefExpr::create(
Sym, MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
}
return AsmPrinter::lowerConstant(CV);
}

View File

@ -112,8 +112,6 @@ MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(MCSymbol *Sym,
MCSymbolRefExpr::VariantKind VK =
IsFunc ? MCSymbolRefExpr::VK_WebAssembly_FUNCTION
: MCSymbolRefExpr::VK_None;
if (!isa<MCSymbolELF>(Sym))
cast<MCSymbolWasm>(Sym)->setIsFunction(IsFunc);
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, VK, Ctx);

View File

@ -2,24 +2,33 @@
; Verify that addresses of external functions generate correctly typed
; imports and relocations or type R_TABLE_INDEX_I32.
declare void @f1() #1
@ptr_to_f1 = hidden global void ()* @f1, align 4
declare void @f1(i32) #1
@ptr_to_f1 = hidden global void (i32)* @f1, align 4
; CHECK: - Type: IMPORT
; CHECK: Imports:
; CHECK: - Module: env
; CHECK: Field: f1
; CHECK: Kind: FUNCTION
; CHECK: SigIndex: 0
; CHECK: - Type: ELEM
; CHECK: Segments:
; CHECK: - Offset:
; CHECK: Opcode: I32_CONST
; CHECK: Value: 0
; CHECK: Functions: [ 0 ]
; CHECK: - Type: DATA
; CHECK: Relocations:
; CHECK: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
; CHECK: Index: 0
; CHECK: Offset: 0x00000006
; CHECK: --- !WASM
; CHECK-NEXT: FileHeader:
; CHECK-NEXT: Version: 0x00000001
; CHECK-NEXT: Sections:
; CHECK-NEXT: - Type: TYPE
; CHECK-NEXT: Signatures:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - I32
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: f1
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
; CHECK: - Type: ELEM
; 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