-
Notifications
You must be signed in to change notification settings - Fork 10.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Macros] Add support for wasm macros #73031
base: main
Are you sure you want to change the base?
Conversation
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>com.apple.security.cs.allow-jit</key> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Necessary in order for JSC to expose globalThis.WebAssembly
— I don't think there's any security risk here because /System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc
already exposes significantly more surface area. Plus we're able to keep the restrictive sandbox from Sandbox::apply
intact when running this via swiftc.
paging @DougGregor @MaxDesiatov as stakeholders, would love to get your thoughts on this |
also wondering how I should add end-to-end tests for this: I would include some wasm blob fixtures but I don't want to be mistaken for the Second Coming of Jia Tan |
Another question: how much should we generalize this right now? As in, should we have a specialized wasm executor embedded into |
@swift-ci build toolchain |
This method deterministically and synchronously cleans up resources that cannot be dealt with in a deinitializer due to possible errors thrown during the clean up. Usually this includes closure of file handles, sockets, shutting down external processes and IPC resources set up for these processes, etc. This method is required for `swift-plugin-server` to properly clean up file handles there were opened for communication with Wasm macros, as prototyped in swiftlang/swift#73031.
This method deterministically and synchronously cleans up resources that cannot be dealt with in a deinitializer due to possible errors thrown during the clean up. Usually this includes closure of file handles, sockets, shutting down external processes and IPC resources set up for these processes, etc. This method is required for `swift-plugin-server` to properly clean up file handles there were opened for communication with Wasm macros, as prototyped in swiftlang/swift#73031.
@swift-ci test |
@swift-ci build toolchain |
This makes the API more portable, allowing file paths instead of file descriptors to be passed to Wasm engines.
tools/swift-plugin-server/Sources/swift-plugin-server/WasmEngine.swift
Outdated
Show resolved
Hide resolved
@swift-ci build toolchain |
@swift-ci test |
@swift-ci test |
@swift-ci build toolchain |
@swift-ci build toolchain |
@swift-ci test |
@swift-ci test |
@swift-ci build toolchain |
This PR introduces support for WebAssembly-based macros via
-load-plugin-executable Foo.wasm#Foo
.Wasm macros are blazing fast (no SwiftSyntax build required for consumers!) and secure (fully sandboxed on all OSes)
The approach I've taken here is to update
swift-plugin-server
to add special handling for Wasm macros. These macros are executed using WasmKit, but in the future we can add support for other (faster, JIT) runtimes like JavaScriptCore.Note also that these wasm macros currently have an ad-hoc ABI as I wanted to avoid a hard dependency on WASI. It's thus theoretically possible to build macros without a dependency on WASI, though I've had trouble doing so because Swift currently builds for wasm as WASI xor Embedded Mode — we'd need a middle ground with support for String etc. The current ABI is based on the one I built for Wacro. We'll have to iron out the execution model though: my current mental model is that plugins are request-response style (i.e. every HostToPluginMessage must be followed by exactly one PluginToHostMessage) and so the macro effectively exports a
char *macro_parse(char *request_json)
but I don't know if this is a guaranteed contract.There's currently a few things that still need to be done:
Followups:
.binaryMacro
target similar to.binaryTarget
, though this will make the edit-compile-run cycle non-trivial as it splits building the macro into a separate phase. (*)Marking this as a draft until the above items are done but I wanted to make this PR so I could get some input as well as to brainstorm (particularly about the items marked as (*))
Depends on swiftlang/swift-syntax#2623
There's also a corresponding PR in swift-driver, which is blocked by this one: swiftlang/swift-driver#1582