-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Implement support for async functions in Wasmtime
#2434
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
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
c471a1c
Implement support for `async` functions in Wasmtime
alexcrichton e46bccb
Add wasmtime-fiber to publish script
alexcrichton 20833b5
Save vector/float registers on ARM too.
alexcrichton 549461c
Fix a typo
alexcrichton 30993d6
Update lock file
alexcrichton d94648c
Implement periodically yielding with fuel consumption
alexcrichton 06974ac
Fix compile without async
alexcrichton 0e243da
Save/restore the frame pointer in fiber switching
alexcrichton f6a211b
Simplify x86_64 fiber asm
alexcrichton 5996126
Add x86 support to wasmtime-fiber
alexcrichton 44c73e8
Add ARM32 support to fiber crate
alexcrichton d837e47
Make fiber build file probing more flexible
alexcrichton 625e9c9
Use CreateFiberEx on Windows
alexcrichton 4951df8
Remove a stray no-longer-used trait declaration
alexcrichton 5026144
Don't reach into `Caller` internals
alexcrichton ca4c492
Tweak async fuel to eventually run out.
alexcrichton 0aa739a
Fix some typos
alexcrichton 77a2f7e
Cleanup asm a bit
alexcrichton a8d73f0
Update lock file
alexcrichton 663a3f7
Fix compile error
alexcrichton 807a226
Review comments
alexcrichton File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| [package] | ||
| name = "wasmtime-fiber" | ||
| version = "0.23.0" | ||
| authors = ["The Wasmtime Project Developers"] | ||
| description = "Fiber support for Wasmtime" | ||
| license = "Apache-2.0 WITH LLVM-exception" | ||
| repository = "https://github.com/bytecodealliance/wasmtime" | ||
| edition = "2018" | ||
|
|
||
| # We link to some native code with symbols that don't change often, so let Cargo | ||
| # know that we can't show up multiple times in a crate graph. If this is an | ||
| # issue in the future we should tweak the build script to set `#define` | ||
| # directives or similar to embed a version number of this crate in symbols. | ||
| links = "wasmtime-fiber-shims" | ||
|
|
||
| [target.'cfg(unix)'.dependencies] | ||
| libc = "0.2.80" | ||
|
|
||
| [target.'cfg(windows)'.dependencies.winapi] | ||
| version = "0.3.9" | ||
| features = [ | ||
| "fibersapi", | ||
| "winbase", | ||
| ] | ||
|
|
||
| [build-dependencies] | ||
| cc = "1.0" | ||
|
|
||
| [dev-dependencies] | ||
| backtrace = "0.3" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| use std::env; | ||
| use std::fs; | ||
|
|
||
| fn main() { | ||
| let mut build = cc::Build::new(); | ||
| let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); | ||
| let family = env::var("CARGO_CFG_TARGET_FAMILY").unwrap(); | ||
| let os = env::var("CARGO_CFG_TARGET_OS").unwrap(); | ||
|
|
||
| let family_file = format!("src/arch/{}.c", family); | ||
| let arch_file = format!("src/arch/{}.S", arch); | ||
| if fs::metadata(&family_file).is_ok() { | ||
| build.file(&family_file); | ||
| } else if fs::metadata(&arch_file).is_ok() { | ||
| build.file(&arch_file); | ||
| } else { | ||
| panic!( | ||
| "wasmtime doesn't support fibers on platform: {}", | ||
| env::var("TARGET").unwrap() | ||
| ); | ||
| } | ||
| build.define(&format!("CFG_TARGET_OS_{}", os), None); | ||
| build.define(&format!("CFG_TARGET_ARCH_{}", arch), None); | ||
| build.compile("wasmtime-fiber"); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| // A WORD OF CAUTION | ||
| // | ||
| // This entire file basically needs to be kept in sync with itself. It's not | ||
| // really possible to modify just one bit of this file without understanding | ||
| // all the other bits. Documentation tries to reference various bits here and | ||
| // there but try to make sure to read over everything before tweaking things! | ||
| // | ||
| // Also at this time this file is heavily based off the x86_64 file, so you'll | ||
| // probably want to read that one as well. | ||
|
|
||
| #include "header.h" | ||
|
|
||
| // fn(top_of_stack(%x0): *mut u8) | ||
| HIDDEN(wasmtime_fiber_switch) | ||
| GLOBL(wasmtime_fiber_switch) | ||
| .p2align 2 | ||
| TYPE(wasmtime_fiber_switch) | ||
| FUNCTION(wasmtime_fiber_switch): | ||
| // Save all callee-saved registers on the stack since we're assuming | ||
| // they're clobbered as a result of the stack switch. | ||
| stp lr, fp, [sp, -16]! | ||
| stp x20, x19, [sp, -16]! | ||
| stp x22, x21, [sp, -16]! | ||
| stp x24, x23, [sp, -16]! | ||
| stp x26, x25, [sp, -16]! | ||
| stp x28, x27, [sp, -16]! | ||
| stp d9, d8, [sp, -16]! | ||
| stp d11, d10, [sp, -16]! | ||
| stp d13, d12, [sp, -16]! | ||
| stp d15, d14, [sp, -16]! | ||
|
|
||
| // Load our previously saved stack pointer to resume to, and save off our | ||
| // current stack pointer on where to come back to eventually. | ||
| ldr x8, [x0, -0x10] | ||
| mov x9, sp | ||
| str x9, [x0, -0x10] | ||
|
|
||
| // Switch to the new stack and restore all our callee-saved registers after | ||
| // the switch and return to our new stack. | ||
| mov sp, x8 | ||
| ldp d15, d14, [sp], 16 | ||
| ldp d13, d12, [sp], 16 | ||
| ldp d11, d10, [sp], 16 | ||
| ldp d9, d8, [sp], 16 | ||
| ldp x28, x27, [sp], 16 | ||
| ldp x26, x25, [sp], 16 | ||
| ldp x24, x23, [sp], 16 | ||
| ldp x22, x21, [sp], 16 | ||
| ldp x20, x19, [sp], 16 | ||
| ldp lr, fp, [sp], 16 | ||
| ret | ||
| SIZE(wasmtime_fiber_switch) | ||
|
|
||
| // fn( | ||
| // top_of_stack(%x0): *mut u8, | ||
| // entry_point(%x1): extern fn(*mut u8, *mut u8), | ||
| // entry_arg0(%x2): *mut u8, | ||
| // ) | ||
| HIDDEN(wasmtime_fiber_init) | ||
| GLOBL(wasmtime_fiber_init) | ||
| .p2align 2 | ||
| TYPE(wasmtime_fiber_init) | ||
| FUNCTION(wasmtime_fiber_init): | ||
| adr x8, FUNCTION(wasmtime_fiber_start) | ||
| stp x0, x8, [x0, -0x28] // x0 => x19, x8 => lr | ||
| stp x2, x1, [x0, -0x38] // x1 => x20, x2 => x21 | ||
|
|
||
| // `wasmtime_fiber_switch` has an 0xa0 byte stack, and we add 0x10 more for | ||
| // the original reserved 16 bytes. | ||
| add x8, x0, -0xb0 | ||
| str x8, [x0, -0x10] | ||
| ret | ||
| SIZE(wasmtime_fiber_init) | ||
|
|
||
| .p2align 2 | ||
| TYPE(wasmtime_fiber_start) | ||
| FUNCTION(wasmtime_fiber_start): | ||
| .cfi_startproc simple | ||
|
|
||
| // See the x86_64 file for more commentary on what these CFI directives are | ||
| // doing. Like over there note that the relative offsets to registers here | ||
| // match the frame layout in `wasmtime_fiber_switch`. | ||
| .cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \ | ||
| 5, /* the byte length of this expression */ \ | ||
| 0x6f, /* DW_OP_reg31(%sp) */ \ | ||
| 0x06, /* DW_OP_deref */ \ | ||
| 0x23, 0xa0, 0x1 /* DW_OP_plus_uconst 0xa0 */ | ||
|
|
||
| .cfi_rel_offset lr, -0x10 | ||
| .cfi_rel_offset x19, -0x18 | ||
| .cfi_rel_offset x20, -0x20 | ||
| .cfi_rel_offset x21, -0x28 | ||
| .cfi_rel_offset x22, -0x30 | ||
| .cfi_rel_offset x23, -0x38 | ||
| .cfi_rel_offset x24, -0x40 | ||
| .cfi_rel_offset x25, -0x48 | ||
| .cfi_rel_offset x26, -0x50 | ||
| .cfi_rel_offset x27, -0x58 | ||
| .cfi_rel_offset x29, -0x60 | ||
|
|
||
| // Load our two arguments from the stack, where x1 is our start procedure | ||
| // and x0 is its first argument. This also blows away the stack space used | ||
| // by those two arguments. | ||
| mov x0, x21 | ||
| mov x1, x19 | ||
|
|
||
| // ... and then we call the function! Note that this is a function call so | ||
| // our frame stays on the stack to backtrace through. | ||
| blr x20 | ||
| // .. technically we shouldn't get here, and I would like to write in an | ||
| // instruction which just aborts, but I don't know such an instruction in | ||
| // aarch64 land. | ||
| .cfi_endproc | ||
| SIZE(wasmtime_fiber_start) | ||
|
|
||
| // This omits the `.subsections_via_symbols` directive on macOS which means we | ||
| // can't GC specific intrinsics from this file, but it enables usage of the | ||
| // `adr` instruction above in lieu of figuring out a slightly more complicated | ||
| // way of implementing that. | ||
| #ifndef CFG_TARGET_OS_macos | ||
| FOOTER | ||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| // A WORD OF CAUTION | ||
| // | ||
| // This entire file basically needs to be kept in sync with itself. It's not | ||
| // really possible to modify just one bit of this file without understanding | ||
| // all the other bits. Documentation tries to reference various bits here and | ||
| // there but try to make sure to read over everything before tweaking things! | ||
| // | ||
| // Also at this time this file is heavily based off the x86_64 file, so you'll | ||
| // probably want to read that one as well. | ||
|
|
||
| #include "header.h" | ||
|
|
||
| // fn(top_of_stack(%r0): *mut u8) | ||
| HIDDEN(wasmtime_fiber_switch) | ||
| GLOBL(wasmtime_fiber_switch) | ||
| TYPE(wasmtime_fiber_switch) | ||
| FUNCTION(wasmtime_fiber_switch): | ||
| // Save callee-saved registers | ||
| push {r4-r11,lr} | ||
|
|
||
| // Swap stacks, recording our current stack pointer | ||
| ldr r4, [r0, #-0x08] | ||
| str sp, [r0, #-0x08] | ||
| mov sp, r4 | ||
|
|
||
| // Restore and return | ||
| pop {r4-r11,lr} | ||
| bx lr | ||
| SIZE(wasmtime_fiber_switch) | ||
|
|
||
| // fn( | ||
| // top_of_stack(%r0): *mut u8, | ||
| // entry_point(%r1): extern fn(*mut u8, *mut u8), | ||
| // entry_arg0(%r2): *mut u8, | ||
| // ) | ||
| HIDDEN(wasmtime_fiber_init) | ||
| GLOBL(wasmtime_fiber_init) | ||
| TYPE(wasmtime_fiber_init) | ||
| FUNCTION(wasmtime_fiber_init): | ||
| adr r3, FUNCTION(wasmtime_fiber_start) | ||
| str r3, [r0, #-0x0c] // => lr | ||
| str r0, [r0, #-0x10] // => r11 | ||
| str r1, [r0, #-0x14] // => r10 | ||
| str r2, [r0, #-0x18] // => r9 | ||
|
|
||
| add r3, r0, #-0x2c | ||
| str r3, [r0, #-0x08] | ||
| bx lr | ||
| SIZE(wasmtime_fiber_init) | ||
|
|
||
| FUNCTION(wasmtime_fiber_start): | ||
| .cfi_startproc simple | ||
| // See the x86_64 file for more commentary on what these CFI directives are | ||
| // doing. Like over there note that the relative offsets to registers here | ||
| // match the frame layout in `wasmtime_fiber_switch`. | ||
| // | ||
| // TODO: this is only lightly tested. This gets backtraces in gdb but not | ||
| // at runtime. Perhaps the libgcc at runtime was too old? Doesn't support | ||
| // something here? Unclear. Will need investigation if someone ends up | ||
| // needing this and it still doesn't work. | ||
| .cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \ | ||
| 5, /* the byte length of this expression */ \ | ||
| 0x7d, 0x00, /* DW_OP_breg14(%sp) + 0 */ \ | ||
| 0x06, /* DW_OP_deref */ \ | ||
| 0x23, 0x24 /* DW_OP_plus_uconst 0x24 */ | ||
|
|
||
| .cfi_rel_offset lr, -0x04 | ||
| .cfi_rel_offset r11, -0x08 | ||
| .cfi_rel_offset r10, -0x0c | ||
| .cfi_rel_offset r9, -0x10 | ||
| .cfi_rel_offset r8, -0x14 | ||
| .cfi_rel_offset r7, -0x18 | ||
| .cfi_rel_offset r6, -0x1c | ||
| .cfi_rel_offset r5, -0x20 | ||
| .cfi_rel_offset r4, -0x24 | ||
|
|
||
| mov r1, r11 | ||
| mov r0, r9 | ||
| blx r10 | ||
| .cfi_endproc | ||
| SIZE(wasmtime_fiber_start) | ||
|
|
||
| FOOTER |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| #ifndef __wasmtime_common_h | ||
| #define __wasmtime_common_h | ||
|
|
||
| #if CFG_TARGET_OS_macos | ||
|
|
||
| .section __TEXT,__text,regular,pure_instructions | ||
|
|
||
| #define GLOBL(fnname) .globl _##fnname | ||
| #define HIDDEN(fnname) .private_extern _##fnname | ||
| #define TYPE(fnname) | ||
| #define FUNCTION(fnname) _##fnname | ||
| #define SIZE(fnname) | ||
|
|
||
| // Tells the linker it's safe to gc symbols away if not used. | ||
| #define FOOTER .subsections_via_symbols | ||
|
|
||
| #else | ||
|
|
||
| .text | ||
|
|
||
| #define GLOBL(fnname) .globl fnname | ||
| #define HIDDEN(fnname) .hidden fnname | ||
| #ifdef CFG_TARGET_ARCH_arm | ||
| #define TYPE(fnname) .type fnname,%function | ||
| #else | ||
| #define TYPE(fnname) .type fnname,@function | ||
| #endif | ||
| #define FUNCTION(fnname) fnname | ||
| #define SIZE(fnname) .size fnname,.-fnname | ||
|
|
||
| // Mark that we don't need executable stack. | ||
| #define FOOTER .section .note.GNU-stack,"",%progbits | ||
|
|
||
| #endif | ||
|
|
||
| #endif // __wasmtime_common_h |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| #include <windows.h> | ||
|
|
||
| LPVOID wasmtime_fiber_get_current() { | ||
| return GetCurrentFiber(); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.