-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Parse run commands #1436
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
Parse run commands #1436
Conversation
Subscribe to Label ActionThis issue or pull request has been labeled: "cranelift" Users Subscribed to "cranelift"To subscribe or unsubscribe from this label, edit the |
13f527c to
19a8f58
Compare
I think this is relatively nontrivial unfortunately. If you statically know the function signature it's significantly more easy since you know what to transmute to and how to pass arguments, but a completely dynamic function signature will require a jit stub one way or another. For example in wasmtime if you use If you want to support a small set of signatures you could probably create something like a hash set of shims and make it pretty easily with some macros/traits, but if you want to support "given this list of string arguments from the CLI, parse them and call this jit function" it'll be more involved b/c you'll need to jit a stub at that point. |
19a8f58 to
adc180c
Compare
|
Thanks @alexcrichton for the comment and discussion on Zulip. Yeah, I think I understand what it would take to JIT-compile trampoline-like functions to implement the "given this list of string arguments from the CLI, parse them and call this jit function" idea. I think this PR still makes sense then as a precursor to that. @alexcrichton, how do you feel about reviewing this Cranelift stuff? |
|
Ah sorry I don't know much about the cranelift parser so it may be best for someone else to take a look at that |
bnjbvr
left a comment
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.
lgtm, thanks
| } | ||
|
|
||
| /// Helper function for displaying `Vec<DataValue>`. | ||
| fn write_data_value_list(f: &mut Formatter<'_>, list: &[DataValue]) -> Result { |
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.
Isn't this possibly inferred by the compiler for Vec when T implements Display? Or can we use {:?} for the Vec type and it'll do the right thing here?
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.
It complained that I hadn't implemented Debug for T, IIRC. I think this boils down to: how do I use the Display of T as a Debug so that I can use the Debug of Vec<T>? Preferably without adding Debug to the whole type hierarchy of T... I don't yet see a good Rust-y way of doing this.
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.
@alexcrichton suggested I use impl Display instead of DataValue, which is a good solution to avoid this function; but I remembered that I made this because sometimes I need the data values enclosed in parentheses and sometimes in brackets. E.g. %fn() = [1, 2, 3] vs %fn(1, 2, 3) == 42. I'm going to leave this function in for that reason.
Also, make some stylistic tweaks to `match_imm16` and `match_imm32` based on the review comments.
This is necessary to avoid build errors from dead code (and I didn't want to litter all of the structs with `#[allow(dead_code)]` just to remove in a subsequent PR).
adc180c to
bf3aba5
Compare
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and bytecodealliance#1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This resolves the work started in bytecodealliance/cranelift#1231 and #1436. Cranelift filetests currently have the ability to run CLIF functions with a signature like `() -> b*` and check that the result is true under the `test run` directive. This PR adds the ability to call functions with arbitrary arguments and non-boolean returns and either print the result or check against a list of expected results: - `run` commands look like `; run: %add(2, 2) == 4` or `; run: %add(2, 2) != 5` and verify that the executed CLIF function returns the expected value - `print` commands look like `; print: %add(2, 2)` and print the result of the function to stdout To make this work, this PR compiles a single Cranelift `Function` into a `CompiledFunction` using a `SingleFunctionCompiler`. Because we will not know the signature of the function until runtime, we use a `Trampoline` to place the values in the appropriate location for the calling convention; this should look a lot like what @alexcrichton is doing with `VMTrampoline` in wasmtime (see https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/api/src/func.rs#L510-L526, https://github.com/bytecodealliance/wasmtime/blob/3b7cb6ee64469470fcdd68e185abca8eb2a1b20a/crates/jit/src/compiler.rs#L260). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
This PR adds the ability to parse CLIF run commands like
run: %fn0(42, 4.2) == true. It seems like a good first step towards closing out bytecodealliance/cranelift#1231; it also factors out some of the functionality that was implemented separately in #1223 and incorporates it into cranelift-reader.My plan is to use this parsing in
FunctionRunnerto:true(the current hard-coded behavior); this would be useful in testingFunctionRunnerwith, e.g.,print: %fn(42)(this was the original point of Print return values of run tests if type is not boolean. cranelift#1231)FunctionRunnercan only run functions of() -> b*. To do this, I think I need to do something along the lines ofWasmTyorValin wasmtime-api. @alexcrichton, what do you think?ValueDatais a bit likeValand I will need to cast the function compiled byFunctionRunnerto types known at runtime.