Skip to content

Commit 5b40d5b

Browse files
kateinoigakukunrunner
authored andcommitted
[wasm][SIL/IRGen] HACK: Always forward extra argument to match callee and caller signature
This is a legacy solution for the KeyPath calling convention problem described in https://forums.swift.org/t/wasm-support/16087/21. This patch will be replaced by swiftlang#66273
1 parent 538b024 commit 5b40d5b

File tree

5 files changed

+77
-10
lines changed

5 files changed

+77
-10
lines changed

lib/IRGen/GenKeyPath.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ getAccessorForComputedComponent(IRGenModule &IGM,
224224
componentArgsBuf = params.claimNext();
225225
// Pass the argument pointer down to the underlying function, if it
226226
// wants it.
227-
if (hasSubscriptIndices) {
227+
// Always forward extra argument to match callee and caller signature on WebAssembly
228+
if (hasSubscriptIndices || IGM.TargetInfo.OutputObjectFormat == llvm::Triple::Wasm) {
228229
forwardedArgs.add(componentArgsBuf);
229230
}
230231
break;
@@ -250,6 +251,10 @@ getAccessorForComputedComponent(IRGenModule &IGM,
250251
forwardingSubs,
251252
&ignoreWitnessMetadata,
252253
forwardedArgs);
254+
} else if (IGM.Triple.isOSBinFormatWasm()) {
255+
// wasm: Add null swift.type pointer to match signature even when there is
256+
// no generic environment.
257+
forwardedArgs.add(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy));
253258
}
254259
auto fnPtr =
255260
FunctionPointer::forDirect(IGM, accessorFn, /*secondaryValue*/ nullptr,

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,9 @@ void verifyKeyPathComponent(SILModule &M,
299299
SILFunctionTypeRepresentation::Thin,
300300
"getter should be a thin function");
301301

302-
require(substGetterType->getNumParameters() == 1 + hasIndices,
303-
"getter should have one parameter");
302+
// FIXME(katei): Disabled for now. Will be replaced by keypath cc
303+
// require(substGetterType->getNumParameters() == 1 + hasIndices,
304+
// "getter should have one parameter");
304305
auto baseParam = substGetterType->getParameters()[0];
305306
require(baseParam.getConvention() == normalArgConvention,
306307
"getter base parameter should have normal arg convention");
@@ -351,8 +352,9 @@ void verifyKeyPathComponent(SILModule &M,
351352
SILFunctionTypeRepresentation::Thin,
352353
"setter should be a thin function");
353354

354-
require(substSetterType->getNumParameters() == 2 + hasIndices,
355-
"setter should have two parameters");
355+
// FIXME(katei): Disabled for now. Will be replaced by keypath cc
356+
// require(substSetterType->getNumParameters() == 2 + hasIndices,
357+
// "setter should have two parameters");
356358

357359
auto newValueParam = substSetterType->getParameters()[0];
358360
// TODO: This should probably be unconditionally +1 when we

lib/SILGen/SILGenExpr.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2994,6 +2994,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
29942994
}
29952995
}
29962996

2997+
auto Target = SGM.getASTContext().LangOpts.Target;
29972998
auto genericSig =
29982999
genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature()
29993000
: nullptr;
@@ -3002,6 +3003,14 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
30023003
genericEnv = nullptr;
30033004
}
30043005

3006+
// Add empty generic type parameter to match function signature on WebAssembly
3007+
if (!genericSig && Target.isOSBinFormatWasm()) {
3008+
auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext());
3009+
auto sig = GenericSignature::get(param, { });
3010+
genericSig = CanGenericSignature(sig);
3011+
genericEnv = sig.getGenericEnvironment();
3012+
}
3013+
30053014
// Build the signature of the thunk as expected by the keypath runtime.
30063015
auto signature = [&]() {
30073016
CanType loweredBaseTy, loweredPropTy;
@@ -3017,7 +3026,8 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
30173026
SmallVector<SILParameterInfo, 2> params;
30183027
params.push_back({loweredBaseTy, paramConvention});
30193028
auto &C = SGM.getASTContext();
3020-
if (!indexes.empty())
3029+
// Always take indexes parameter to match callee and caller signature on WebAssembly
3030+
if (!indexes.empty() || C.LangOpts.Target.isOSBinFormatWasm())
30213031
params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(),
30223032
ParameterConvention::Direct_Unowned});
30233033

@@ -3080,7 +3090,8 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
30803090
}
30813091
auto baseArg = entry->createFunctionArgument(baseArgTy);
30823092
SILValue indexPtrArg;
3083-
if (!indexes.empty()) {
3093+
// Always take indexes parameter to match callee and caller signature on WebAssembly
3094+
if (!indexes.empty() || Target.isOSBinFormatWasm()) {
30843095
auto indexArgTy = signature->getParameters()[1].getSILStorageType(
30853096
SGM.M, signature, subSGF.F.getTypeExpansionContext());
30863097
indexPtrArg = entry->createFunctionArgument(indexArgTy);
@@ -3169,6 +3180,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM,
31693180
}
31703181
}
31713182

3183+
auto Target = SGM.getASTContext().LangOpts.Target;
31723184
auto genericSig =
31733185
genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature()
31743186
: nullptr;
@@ -3177,6 +3189,14 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM,
31773189
genericEnv = nullptr;
31783190
}
31793191

3192+
// Add empty generic type parameter to match function signature on WebAssembly
3193+
if (!genericSig && Target.isOSBinFormatWasm()) {
3194+
auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext());
3195+
auto sig = GenericSignature::get(param, { });
3196+
genericSig = CanGenericSignature(sig);
3197+
genericEnv = sig.getGenericEnvironment();
3198+
}
3199+
31803200
// Build the signature of the thunk as expected by the keypath runtime.
31813201
auto signature = [&]() {
31823202
CanType loweredBaseTy, loweredPropTy;
@@ -3202,7 +3222,8 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM,
32023222
? ParameterConvention::Indirect_Inout
32033223
: paramConvention});
32043224
// indexes
3205-
if (!indexes.empty())
3225+
// Always take indexes parameter to match callee and caller signature on WebAssembly
3226+
if (!indexes.empty() || C.LangOpts.Target.isOSBinFormatWasm())
32063227
params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(),
32073228
ParameterConvention::Direct_Unowned});
32083229

@@ -3259,7 +3280,8 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM,
32593280
auto baseArg = entry->createFunctionArgument(baseArgTy);
32603281
SILValue indexPtrArg;
32613282

3262-
if (!indexes.empty()) {
3283+
// Always take indexes parameter to match callee and caller signature on WebAssembly
3284+
if (!indexes.empty() || Target.isOSBinFormatWasm()) {
32633285
auto indexArgTy = signature->getParameters()[2].getSILStorageType(
32643286
SGM.M, signature, subSGF.getTypeExpansionContext());
32653287
indexPtrArg = entry->createFunctionArgument(indexArgTy);
@@ -3350,6 +3372,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM,
33503372
return;
33513373
}
33523374

3375+
auto Target = SGM.getASTContext().LangOpts.Target;
33533376
auto genericSig =
33543377
genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature()
33553378
: nullptr;
@@ -3359,6 +3382,14 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM,
33593382
genericEnv = nullptr;
33603383
}
33613384

3385+
// Add empty generic type parameter to match function signature on WebAssembly
3386+
if (!genericSig && Target.isOSBinFormatWasm()) {
3387+
auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext());
3388+
auto sig = GenericSignature::get(param, { });
3389+
genericSig = CanGenericSignature(sig);
3390+
genericEnv = sig.getGenericEnvironment();
3391+
}
3392+
33623393
auto &C = SGM.getASTContext();
33633394
auto unsafeRawPointerTy = C.getUnsafeRawPointerType()->getCanonicalType();
33643395
auto boolTy = C.getBoolType()->getCanonicalType();

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,13 @@ bool SILCombiner::tryOptimizeKeypathKVCString(ApplyInst *AI,
505505
}
506506

507507
bool SILCombiner::tryOptimizeKeypath(ApplyInst *AI) {
508+
// FIXME(katei): Disable for WebAssembly for now because
509+
// KeyPath cc is unstable and KeyPathProjector hask violates
510+
// some assert assumptions
511+
SILModule &M = AI->getModule();
512+
if (M.getASTContext().LangOpts.Target.isOSBinFormatWasm())
513+
return false;
514+
508515
if (SILFunction *callee = AI->getReferencedFunctionOrNull()) {
509516
return tryOptimizeKeypathApplication(AI, callee);
510517
}
@@ -550,6 +557,13 @@ bool SILCombiner::tryOptimizeKeypath(ApplyInst *AI) {
550557
/// %addr = struct_element_addr/ref_element_addr %root_object
551558
/// // use %inout_addr
552559
bool SILCombiner::tryOptimizeInoutKeypath(BeginApplyInst *AI) {
560+
// FIXME(katei): Disable for WebAssembly for now because
561+
// KeyPath cc is unstable and KeyPathProjector hask violates
562+
// some assert assumptions
563+
SILModule &M = AI->getModule();
564+
if (M.getASTContext().LangOpts.Target.isOSBinFormatWasm())
565+
return false;
566+
553567
// Disable in OSSA because KeyPathProjector is not fully ported
554568
if (AI->getFunction()->hasOwnership())
555569
return false;

lib/SILOptimizer/Utils/KeyPathProjector.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,22 @@ class GettablePropertyProjector : public ComponentProjector {
233233
assert(getter->getConventions().getNumSILArguments());
234234

235235
auto ref = builder.createFunctionRef(loc, getter);
236-
builder.createApply(loc, ref, subs, {addr, parentValue});
236+
237+
std::vector<SILValue> args{addr, parentValue};
238+
// FIXME(wasm): For wasm, KeyPath getter always take indices parameter
239+
// to match callee and caller signature. So need to pass stub pointer.
240+
// See also: getOrCreateKeyPathSetter and getOrCreateKeyPathGetter
241+
if (builder.getASTContext().LangOpts.Target.isOSBinFormatWasm()) {
242+
auto IntTy = SILType::getBuiltinIntegerType(32, builder.getASTContext());
243+
auto UnsafeRawPointerTy = SILType::getRawPointerType(builder.getASTContext());
244+
auto zeroVal = SILValue(builder.createIntegerLiteral(loc, IntTy, 0));
245+
auto stackBuffer = SILValue(builder.createAllocStack(loc, IntTy));
246+
builder.createStore(loc, zeroVal, stackBuffer, StoreOwnershipQualifier::Unqualified);
247+
auto nonePointer = builder.createUncheckedAddrCast(loc, stackBuffer, UnsafeRawPointerTy);
248+
args.push_back(SILValue(nonePointer));
249+
}
250+
251+
builder.createApply(loc, ref, subs, args);
237252

238253
// If we were previously accessing a class member, we're done now.
239254
insertEndAccess(beginAccess, builder);

0 commit comments

Comments
 (0)