diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 5c72c14adfd8b..8e6c4faa15ff5 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -118,6 +118,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly : public ToolChain { const JobContext &context) const override; InvocationInfo constructInvocation(const StaticLinkJobAction &job, const JobContext &context) const override; + void validateArguments(DiagnosticEngine &diags, + const llvm::opt::ArgList &args, + StringRef defaultTarget) const override; public: WebAssembly(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {} diff --git a/lib/Driver/WebAssemblyToolChains.cpp b/lib/Driver/WebAssemblyToolChains.cpp index 55f1c329a5f39..0d7958078cd12 100644 --- a/lib/Driver/WebAssemblyToolChains.cpp +++ b/lib/Driver/WebAssemblyToolChains.cpp @@ -12,6 +12,8 @@ #include "ToolChains.h" +#include "swift/ABI/System.h" +#include "swift/AST/DiagnosticsDriver.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/Platform.h" @@ -192,6 +194,15 @@ toolchains::WebAssembly::constructInvocation(const DynamicLinkJobAction &job, Arguments.push_back("-v"); } + // WebAssembly doesn't reserve low addresses But without "extra inhabitants" + // of the pointer representation, runtime performance and memory footprint are + // worse. So assume that compiler driver uses wasm-ld and --global-base=1024 + // to reserve low 1KB. + Arguments.push_back("-Xlinker"); + Arguments.push_back(context.Args.MakeArgString( + Twine("--global-base=") + + std::to_string(SWIFT_ABI_WASM32_LEAST_VALID_POINTER))); + // These custom arguments should be right before the object file at the end. context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); context.Args.AddAllArgs(Arguments, options::OPT_Xlinker); @@ -208,6 +219,23 @@ toolchains::WebAssembly::constructInvocation(const DynamicLinkJobAction &job, return II; } +void validateLinkerArguments(DiagnosticEngine &diags, + ArgStringList linkerArgs) { + for (auto arg : linkerArgs) { + if (StringRef(arg).startswith("--global-base=")) { + diags.diagnose(SourceLoc(), diag::error_option_not_supported, arg, + "wasm32"); + } + } +} +void toolchains::WebAssembly::validateArguments(DiagnosticEngine &diags, + const llvm::opt::ArgList &args, + StringRef defaultTarget) const { + ArgStringList linkerArgs; + args.AddAllArgValues(linkerArgs, options::OPT_Xlinker); + validateLinkerArguments(diags, linkerArgs); +} + ToolChain::InvocationInfo toolchains::WebAssembly::constructInvocation(const StaticLinkJobAction &job, const JobContext &context) const { diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp index a7b6f84bf06c0..643144a98d6de 100644 --- a/lib/IRGen/SwiftTargetInfo.cpp +++ b/lib/IRGen/SwiftTargetInfo.cpp @@ -140,6 +140,13 @@ static void configureSystemZ(IRGenModule &IGM, const llvm::Triple &triple, target.SwiftRetainIgnoresNegativeValues = true; } +/// Configures target-specific information for wasm32 platforms. +static void configureWasm32(IRGenModule &IGM, const llvm::Triple &triple, + SwiftTargetInfo &target) { + target.LeastValidPointerValue = + SWIFT_ABI_WASM32_LEAST_VALID_POINTER; +} + /// Configure a default target. SwiftTargetInfo::SwiftTargetInfo( llvm::Triple::ObjectFormatType outputObjectFormat, @@ -196,7 +203,9 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) { case llvm::Triple::systemz: configureSystemZ(IGM, triple, target); break; - + case llvm::Triple::wasm32: + configureWasm32(IGM, triple, target); + break; default: // FIXME: Complain here? Default target info is unlikely to be correct. break; diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h index e69d1072ce6e5..74319993d5280 100644 --- a/stdlib/public/SwiftShims/HeapObject.h +++ b/stdlib/public/SwiftShims/HeapObject.h @@ -190,6 +190,22 @@ static_assert(alignof(HeapObject) == alignof(void*), #define _swift_BridgeObject_TaggedPointerBits \ (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64 +#elif defined(__wasm32__) +extern unsigned char __global_base; +#define _swift_abi_LeastValidPointerValue \ + (__swift_uintptr_t) SWIFT_ABI_WASM32_LEAST_VALID_POINTER + +#define _swift_abi_SwiftSpareBitsMask \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK + +#define _swift_abi_ObjCReservedBitsMask \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK +#define _swift_abi_ObjCReservedLowBits \ + (unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS + +#define _swift_BridgeObject_TaggedPointerBits \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_32 + #else #define _swift_abi_LeastValidPointerValue \ diff --git a/stdlib/public/SwiftShims/System.h b/stdlib/public/SwiftShims/System.h index 715ce8031f372..e6733aa21e61b 100644 --- a/stdlib/public/SwiftShims/System.h +++ b/stdlib/public/SwiftShims/System.h @@ -192,4 +192,12 @@ #define SWIFT_ABI_S390X_OBJC_WEAK_REFERENCE_MARKER_VALUE \ (1<