Skip to content

Commit 4e01560

Browse files
Merge pull request #186 from kateinoigakukun/katei/thin-to-thick
[WASM] Implement thin-to-thick semantic for WebAssembly
2 parents 177f13f + 290e05c commit 4e01560

File tree

13 files changed

+197
-1
lines changed

13 files changed

+197
-1
lines changed

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ CONTEXT_NODE(Structure)
200200
CONTEXT_NODE(Subscript)
201201
NODE(Suffix)
202202
NODE(ThinFunctionType)
203+
NODE(ThinToThickForwarder)
203204
NODE(Tuple)
204205
NODE(TupleElement)
205206
NODE(TupleElementName)

lib/Demangling/Context.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ bool Context::isThunkSymbol(llvm::StringRef MangledName) {
8888
MangledName = stripSuffix(MangledName);
8989
// First do a quick check
9090
if (MangledName.endswith("TA") || // partial application forwarder
91+
MangledName.endswith("Tu")|| // thin-to-thick forwarder
9192
MangledName.endswith("Ta") || // ObjC partial application forwarder
9293
MangledName.endswith("To") || // swift-as-ObjC thunk
9394
MangledName.endswith("TO") || // ObjC-as-swift thunk
@@ -107,6 +108,7 @@ bool Context::isThunkSymbol(llvm::StringRef MangledName) {
107108
case Node::Kind::NonObjCAttribute:
108109
case Node::Kind::PartialApplyObjCForwarder:
109110
case Node::Kind::PartialApplyForwarder:
111+
case Node::Kind::ThinToThickForwarder:
110112
case Node::Kind::ReabstractionThunkHelper:
111113
case Node::Kind::ReabstractionThunk:
112114
case Node::Kind::ProtocolWitness:

lib/Demangling/Demangler.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ bool swift::Demangle::isFunctionAttr(Node::Kind kind) {
113113
case Node::Kind::DirectMethodReferenceAttribute:
114114
case Node::Kind::VTableAttribute:
115115
case Node::Kind::PartialApplyForwarder:
116+
case Node::Kind::ThinToThickForwarder:
116117
case Node::Kind::PartialApplyObjCForwarder:
117118
case Node::Kind::OutlinedVariable:
118119
case Node::Kind::OutlinedBridgedMethod:
@@ -549,7 +550,8 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName,
549550
while (NodePointer FuncAttr = popNode(isFunctionAttr)) {
550551
Parent->addChild(FuncAttr, *this);
551552
if (FuncAttr->getKind() == Node::Kind::PartialApplyForwarder ||
552-
FuncAttr->getKind() == Node::Kind::PartialApplyObjCForwarder)
553+
FuncAttr->getKind() == Node::Kind::PartialApplyObjCForwarder ||
554+
FuncAttr->getKind() == Node::Kind::ThinToThickForwarder)
553555
Parent = FuncAttr;
554556
}
555557
for (Node *Nd : NodeStack) {
@@ -2146,6 +2148,7 @@ NodePointer Demangler::demangleThunkOrSpecialization() {
21462148
case 'd': return createNode(Node::Kind::DirectMethodReferenceAttribute);
21472149
case 'a': return createNode(Node::Kind::PartialApplyObjCForwarder);
21482150
case 'A': return createNode(Node::Kind::PartialApplyForwarder);
2151+
case 'u': return createNode(Node::Kind::ThinToThickForwarder);
21492152
case 'm': return createNode(Node::Kind::MergedFunction);
21502153
case 'X': return createNode(Node::Kind::DynamicallyReplaceableFunctionVar);
21512154
case 'x': return createNode(Node::Kind::DynamicallyReplaceableFunctionKey);

lib/Demangling/NodePrinter.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ class NodePrinter {
466466
case Node::Kind::Subscript:
467467
case Node::Kind::Suffix:
468468
case Node::Kind::ThinFunctionType:
469+
case Node::Kind::ThinToThickForwarder:
469470
case Node::Kind::TupleElement:
470471
case Node::Kind::TypeMangling:
471472
case Node::Kind::TypeMetadata:
@@ -1207,6 +1208,14 @@ NodePointer NodePrinter::print(NodePointer Node, bool asPrefixContext) {
12071208
Printer << "@convention(thin) ";
12081209
printFunctionType(nullptr, Node);
12091210
return nullptr;
1211+
case Node::Kind::ThinToThickForwarder:
1212+
Printer << "thin-to-thick forwarder";
1213+
1214+
if (Node->hasChildren()) {
1215+
Printer << " for ";
1216+
printChildren(Node);
1217+
}
1218+
return nullptr;
12101219
case Node::Kind::FunctionType:
12111220
case Node::Kind::UncurriedFunctionType:
12121221
printFunctionType(nullptr, Node);

lib/Demangling/OldDemangler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,15 @@ class OldDemangler {
364364
DEMANGLE_CHILD_OR_RETURN(forwarder, Global);
365365
return forwarder;
366366
}
367+
368+
// thin-to-thick thunks.
369+
if (Mangled.nextIf("Pu")) {
370+
Node::Kind kind = Node::Kind::ThinToThickForwarder;
371+
auto forwarder = Factory.createNode(kind);
372+
if (Mangled.nextIf("__T"))
373+
DEMANGLE_CHILD_OR_RETURN(forwarder, Global);
374+
return forwarder;
375+
}
367376

368377
// Top-level types, for various consumers.
369378
if (Mangled.nextIf('t')) {

lib/Demangling/OldRemangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@ void Remangler::mangleProtocolSelfConformanceDescriptor(Node *node) {
574574
mangleProtocol(node->begin()[0]);
575575
}
576576

577+
void Remangler::mangleThinToThickForwarder(Node *node) {
578+
Buffer << "Pu__T";
579+
mangleSingleChildNode(node); // global
580+
}
581+
577582
void Remangler::manglePartialApplyForwarder(Node *node) {
578583
Buffer << "PA__T";
579584
mangleSingleChildNode(node); // global

lib/Demangling/Remangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,11 @@ void Remangler::mangleOwningMutableAddressor(Node *node) {
17211721
mangleAbstractStorage(node->getFirstChild(), "aO");
17221722
}
17231723

1724+
void Remangler::mangleThinToThickForwarder(Node *node) {
1725+
mangleChildNodesReversed(node);
1726+
Buffer << "Tu";
1727+
}
1728+
17241729
void Remangler::manglePartialApplyForwarder(Node *node) {
17251730
mangleChildNodesReversed(node);
17261731
Buffer << "TA";

lib/IRGen/GenFunc.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,62 @@ static unsigned findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes(
681681
return firstNonEmpty;
682682
}
683683

684+
685+
llvm::Function *irgen::getThinToThickForwarder(IRGenModule &IGM,
686+
const Optional<FunctionPointer> &staticFnPtr,
687+
const CanSILFunctionType origType) {
688+
auto origSig = IGM.getSignature(origType);
689+
llvm::FunctionType *origFnTy = origSig.getType();
690+
auto origTy = origSig.getType()->getPointerTo();
691+
692+
llvm::SmallVector<llvm::Type *, 4> thunkParams;
693+
694+
for (unsigned i = 0; i < origFnTy->getNumParams(); ++i)
695+
thunkParams.push_back(origFnTy->getParamType(i));
696+
697+
thunkParams.push_back(IGM.RefCountedPtrTy);
698+
699+
auto thunkType = llvm::FunctionType::get(origFnTy->getReturnType(),
700+
thunkParams,
701+
/*vararg*/ false);
702+
703+
StringRef FnName;
704+
if (staticFnPtr)
705+
FnName = staticFnPtr->getPointer()->getName();
706+
707+
IRGenMangler Mangler;
708+
std::string thunkName = Mangler.mangleThinToThickForwarder(FnName);
709+
710+
711+
// FIXME: Maybe cache the thunk by function and closure types?.
712+
llvm::Function *fwd =
713+
llvm::Function::Create(thunkType, llvm::Function::InternalLinkage,
714+
llvm::StringRef(thunkName), &IGM.Module);
715+
716+
fwd->setAttributes(origSig.getAttributes());
717+
fwd->addAttribute(llvm::AttributeList::FirstArgIndex + origFnTy->getNumParams(), llvm::Attribute::SwiftSelf);
718+
IRGenFunction IGF(IGM, fwd);
719+
if (IGM.DebugInfo)
720+
IGM.DebugInfo->emitArtificialFunction(IGF, fwd);
721+
auto args = IGF.collectParameters();
722+
auto rawFnPtr = args.takeLast();
723+
724+
// It comes out of the context as an i8*. Cast to the function type.
725+
rawFnPtr = IGF.Builder.CreateBitCast(rawFnPtr, origTy);
726+
727+
auto fnPtr = FunctionPointer(rawFnPtr, origSig);
728+
729+
auto result = IGF.Builder.CreateCall(fnPtr, args.claimAll());
730+
731+
// Return the result, if we have one.
732+
if (result->getType()->isVoidTy())
733+
IGF.Builder.CreateRetVoid();
734+
else
735+
IGF.Builder.CreateRet(result);
736+
return fwd;
737+
}
738+
739+
684740
/// Emit the forwarding stub function for a partial application.
685741
///
686742
/// If 'layout' is null, there is a single captured value of

lib/IRGen/GenFunc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ namespace irgen {
5454
CanSILFunctionType origType, CanSILFunctionType substType,
5555
CanSILFunctionType outType, Explosion &out, bool isOutlined);
5656

57+
58+
llvm::Function *getThinToThickForwarder(IRGenModule &IGM,
59+
const Optional<FunctionPointer> &staticFnPtr,
60+
const CanSILFunctionType origType);
5761
} // end namespace irgen
5862
} // end namespace swift
5963

lib/IRGen/IRGenMangler.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ std::string IRGenMangler::manglePartialApplyForwarder(StringRef FuncName) {
7878
return finalize();
7979
}
8080

81+
std::string IRGenMangler::mangleThinToThickForwarder(StringRef FuncName) {
82+
if (FuncName.empty()) {
83+
beginMangling();
84+
} else {
85+
if (FuncName.startswith(MANGLING_PREFIX_STR)) {
86+
Buffer << FuncName;
87+
} else {
88+
beginMangling();
89+
appendIdentifier(FuncName);
90+
}
91+
}
92+
appendOperator("Tu");
93+
return finalize();
94+
}
95+
8196
SymbolicMangling
8297
IRGenMangler::withSymbolicReferences(IRGenModule &IGM,
8398
llvm::function_ref<void ()> body) {

0 commit comments

Comments
 (0)