diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp index 45cf002219a3b..748130e6455ba 100644 --- a/lib/IRGen/GenKeyPath.cpp +++ b/lib/IRGen/GenKeyPath.cpp @@ -250,6 +250,10 @@ getAccessorForComputedComponent(IRGenModule &IGM, forwardingSubs, &ignoreWitnessMetadata, forwardedArgs); + } else if (IGM.Triple.isOSBinFormatWasm()) { + // wasm: Add null swift.type pointer to match signature even when there is + // no generic environment. + forwardedArgs.add(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); } auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn, accessor->getLoweredFunctionType()); diff --git a/lib/SILOptimizer/Utils/KeyPathProjector.cpp b/lib/SILOptimizer/Utils/KeyPathProjector.cpp index 95e4b1c73680d..15d6b559fffd0 100644 --- a/lib/SILOptimizer/Utils/KeyPathProjector.cpp +++ b/lib/SILOptimizer/Utils/KeyPathProjector.cpp @@ -237,7 +237,22 @@ class GettablePropertyProjector : public ComponentProjector { assert(getter->getArguments().size() == 2 + target.isOSBinFormatWasm()); auto ref = builder.createFunctionRef(loc, getter); - builder.createApply(loc, ref, subs, {addr, parentValue}); + + std::vector args{addr, parentValue}; + // FIXME(wasm): For wasm, KeyPath getter always take indices parameter + // to match callee and caller signature. So need to pass stub pointer. + // See also: getOrCreateKeyPathSetter and getOrCreateKeyPathGetter + if (builder.getASTContext().LangOpts.Target.isOSBinFormatWasm()) { + auto IntTy = SILType::getBuiltinIntegerType(32, builder.getASTContext()); + auto UnsafeRawPointerTy = SILType::getRawPointerType(builder.getASTContext()); + auto zeroVal = SILValue(builder.createIntegerLiteral(loc, IntTy, 0)); + auto stackBuffer = SILValue(builder.createAllocStack(loc, IntTy)); + builder.createStore(loc, zeroVal, stackBuffer, StoreOwnershipQualifier::Unqualified); + auto nonePointer = builder.createUncheckedAddrCast(loc, stackBuffer, UnsafeRawPointerTy); + args.push_back(SILValue(nonePointer)); + } + + builder.createApply(loc, ref, subs, args); // If we were previously accessing a class member, we're done now. insertEndAccess(beginAccess, builder);