Commit Graph

6164 Commits

Author SHA1 Message Date
Jakub Konka
cbf7cbfa39 Introduce strongly-typed system primitives (#1561)
* Introduce strongly-typed system primitives

This commit does a lot of reshuffling and even some more. It introduces
strongly-typed system primitives which are: `OsFile`, `OsDir`, `Stdio`,
and `OsOther`. Those primitives are separate structs now, each implementing
a subset of `Handle` methods, rather than all being an enumeration of some
supertype such as `OsHandle`. To summarise the structs:

* `OsFile` represents a regular file, and implements fd-ops
  of `Handle` trait
* `OsDir` represents a directory, and primarily implements path-ops, plus
  `readdir` and some common fd-ops such as `fdstat`, etc.
* `Stdio` represents a stdio handle, and implements a subset of fd-ops
  such as `fdstat` _and_ `read_` and `write_vectored` calls
* `OsOther` currently represents anything else and implements a set similar
  to that implemented by `Stdio`

This commit is effectively an experiment and an excercise into better
understanding what's going on for each OS resource/type under-the-hood.
It's meant to give us some intuition in order to move on with the idea
of having strongly-typed handles in WASI both in the syscall impl as well
as at the libc level.

Some more minor changes include making `OsHandle` represent an OS-specific
wrapper for a raw OS handle (Unix fd or Windows handle). Also, since `OsDir`
is tricky across OSes, we also have a supertype of `OsHandle` called
`OsDirHandle` which may store a `DIR*` stream pointer (mainly BSD). Last but not
least, the `Filetype` and `Rights` are now computed when the resource is created,
rather than every time we call `Handle::get_file_type` and `Handle::get_rights`.
Finally, in order to facilitate the latter, I've converted `EntryRights` into
`HandleRights` and pushed them into each `Handle` implementor.

* Do not adjust rights on Stdio

* Clean up testing for TTY and escaping writes

* Implement AsFile for dyn Handle

This cleans up a lot of repeating boilerplate code todo with
dynamic dispatch.

* Delegate definition of OsDir to OS-specific modules

Delegates defining `OsDir` struct to OS-specific modules (BSD, Linux,
Emscripten, Windows). This way, `OsDir` can safely re-use `OsHandle`
for raw OS handle storage, and can store some aux data such as an
initialized stream ptr in case of BSD. As a result, we can safely
get rid of `OsDirHandle` which IMHO was causing unnecessary noise and
overcomplicating the design. On the other hand, delegating definition
of `OsDir` to OS-specific modules isn't super clean in and of itself
either. Perhaps there's a better way of handling this?

* Check if filetype of OS handle matches WASI filetype when creating

It seems prudent to check if the passed in `File` instance is of
type matching that of the requested WASI filetype. In other words,
we'd like to avoid situations where `OsFile` is created from a
pipe.

* Make AsFile fallible

Return `EBADF` in `AsFile` in case a `Handle` cannot be made into
a `std::fs::File`.

* Remove unnecessary as_file conversion

* Remove unnecessary check for TTY for Stdio handle type

* Fix incorrect stdio ctors on Unix

* Split Stdio into three separate types: Stdin, Stdout, Stderr

* Rename PendingEntry::File to PendingEntry::OsHandle to avoid confusion

* Rename OsHandle to RawOsHandle

Also, since `RawOsHandle` on *nix doesn't need interior mutability
wrt the inner raw file descriptor, we can safely swap the `RawFd`
for `File` instance.

* Add docs explaining what OsOther is

* Allow for stdio to be non-character-device (e.g., piped)

* Return error on bad preopen rather than panic
2020-05-07 16:00:14 -07:00
Benjamin Bouvier
528d3c1355 machinst: Steal the used/defs Sets when emitting a call in ABICall; 2020-05-07 12:24:02 +02:00
Benjamin Bouvier
19d8a7f1fb machinst: Reuse memory accross loop iterations in lowering; 2020-05-07 12:24:02 +02:00
Benjamin Bouvier
b24b711c16 machinst: Reduce the number of vec allocations for edge blocks; 2020-05-07 12:24:02 +02:00
Benjamin Bouvier
9215b610ef machinst: Avoid a lot of short-lived allocations in ABICall; 2020-05-07 12:24:02 +02:00
Benjamin Bouvier
4f919c6460 machinst: bump regalloc to 0.0.23 and return a slice on the successor indexes, in block_succs; 2020-05-07 12:24:02 +02:00
Julian Seward
48521393ae Update to regalloc.rs version 0.22. 2020-05-06 20:16:31 +02:00
Alex Crichton
57fb1c69c5 Enable the multi-value proposal by default (#1667)
This was merged into the wasm spec upstream in WebAssembly/spec#1145, so
let's follow the spec and enable it by default here as well!
2020-05-06 12:37:29 -05:00
Chris Fallin
6d73fdb70a Merge pull request #1607 from cfallin/aarch64-stack-frame
Rework aarch64 stack frame implementation to use positive offsets.
2020-05-06 10:29:30 -07:00
Chris Fallin
a66724aafd Rework aarch64 stack frame implementation.
This PR changes the aarch64 ABI implementation to use positive offsets
from SP, rather than negative offsets from FP, to refer to spill slots
and stack-local storage. This allows for better addressing-mode options,
and hence slightly better code: e.g., the unsigned scaled 12-bit offset
mode can be used to reach anywhere in a 32KB frame without extra
address-construction instructions, whereas negative offsets are limited
to a signed 9-bit unscaled mode (-256 bytes).

To enable this, the PR introduces a notion of "nominal SP offsets" as a
virtual addressing mode, lowered during the emission pass. The offsets
are relative to "SP after adjusting downward to allocate stack/spill
slots", but before pushing clobbers. This allows the addressing-mode
expressions to be generated before register allocation (or during it,
for spill/reload sequences).

To convert these offsets into *true* offsets from SP, we need to track
how much further SP is moved downward, and compensate for this. We do so
with "virtual SP offset adjustment" pseudo-instructions: these are seen
by the emission pass, and result in no instruction (0 byte output), but
update state that is now threaded through each instruction emission in
turn. In this way, we can push e.g. stack args for a call and adjust
the virtual SP offset, allowing reloads from nominal-SP-relative
spillslots while we do the argument setup with "real SP offsets" at the
same time.
2020-05-06 09:23:55 -07:00
Benjamin Bouvier
1d90751ba9 machinst: Avoid a full instructions traversal of all the blocks when computing the final block ordering; 2020-05-06 15:13:25 +02:00
whitequark
162fcd3d75 Legalize [su]extend.i64 to iconst/sshr_imm + iconcat.
This was already done for [su]extend.i128, and is necessary for
codegen for 32-bit x86.
2020-05-05 16:08:58 -07:00
whitequark
14bdaf3ce3 Legalize ireduce.iN.i2N to isplit. 2020-05-05 14:13:30 -07:00
Alex Crichton
a7d90af19d Update wasmparser and wast dependencies (#1663)
Brings in updates to SIMD spec ops renumbering.
2020-05-05 16:13:14 -05:00
Graham✈️✈️
176b3a8382 add the _set suffix to static_memory_guard_size and dynamic_memory_guard_size properties in c-api (#1662) 2020-05-05 14:57:19 -05:00
Andrew Brown
cb47611c44 Enable SIMD bit shift spec tests 2020-05-05 12:01:46 -07:00
Andrew Brown
cd49ed9582 Add x86 legalization for sshr.i64x2 2020-05-05 12:01:46 -07:00
Andrew Brown
4155d15e69 Fix masking of vector shift values
Previously, the logic was wrong on two counts:
 - It used the bits of the entire vector (e.g. i32x4 -> 128) instead of just the lane bits (e.g. i32x4 -> 32).
 - It used the type of the first operand before it was bitcast to its correct type. Remember that, by default, vectors are handed around as i8x16 and we must bitcast them to their correct type for Cranelift's verifier; see https://github.com/bytecodealliance/wasmtime/issues/1147 for discussion on this. This fix simply uses the type of the instruction itself, which is equivalent and hopefully less fragile to any changes.
2020-05-05 12:01:46 -07:00
Chris Fallin
59039df001 Merge pull request #1570 from cfallin/fix-long-range-aarch64-call
Fix long-range (non-colocated) aarch64 calls to not use Arm64Call reloc, and fix simplejit to use new long-distance call.
2020-05-05 10:45:55 -07:00
Alex Crichton
8e934e6762 Update Table::grow's return to be the previous size (#1653)
* Update `Table::grow`'s return to be the previous size

This brings it in line with `Memory::grow` and the `table.grow`
instruction which return the size of the table previously, not the size
of the table currently.

* Comment successful return
2020-05-05 12:03:31 -05:00
Chris Fallin
e39b4aba1c Fix long-range (non-colocated) aarch64 calls to not use Arm64Call reloc, and fix simplejit to use it.
Previously, every call was lowered on AArch64 to a `call` instruction, which
takes a signed 26-bit PC-relative offset. Including the 2-bit left shift, this
gives a range of +/- 128 MB. Longer-distance offsets would cause an impossible
relocation record to be emitted (or rather, a record that a more sophisticated
linker would fix up by inserting a shim/veneer).

This commit adds a notion of "relocation distance" in the MachInst backends,
and provides this information for every call target and symbol reference. The
intent is that backends on architectures like AArch64, where there are different
offset sizes / addressing strategies to choose from, can either emit a regular
call or a load-64-bit-constant / call-indirect sequence, as necessary. This
avoids the need to implement complex linking behavior.

The MachInst driver code provides this information based on the "colocated" bit
in the CLIF symbol references, which appears to have been designed for this
purpose, or at least a similar one. Combined with the `use_colocated_libcalls`
setting, this allows client code to ensure that library calls can link to
library code at any location in the address space.

Separately, the `simplejit` example did not handle `Arm64Call`; rather than doing
so, it appears all that is necessary to get its tests to pass is to set the
`use_colocated_libcalls` flag to false, to make use of the above change. This
fixes the `libcall_function` unit-test in this crate.
2020-05-05 09:55:12 -07:00
Benjamin Bouvier
fa54422854 Add a work-in-progress backend for x86_64 using the new instruction selection;
Most of the work is credited to Julian Seward.

Co-authored-by: Julian Seward <jseward@acm.org>
Co-authored-by: Chris Fallin <cfallin@mozilla.com>
2020-05-05 16:35:41 +02:00
Benjamin Bouvier
6bee767129 clif-util: try both global and target-dependent settings when parsing --set flags; 2020-05-05 16:35:41 +02:00
Alex Crichton
6ef106fee9 Fix a missing early-return in Table::get (#1652)
Turns out this was a typo from #1016!
2020-05-04 15:19:37 -05:00
Andrew Brown
d6796d0d23 Improve documentation of the filetest run command (#1645)
* Improve output display of RunCommand

The previous use of Debug for displaying `print` and `run` results was less than clear.

* Avoid checking the types of vectors during trampoline construction

Because DataValue only understands `V128` vectors, we avoid type-checking vector values when constructing the trampoline arguments.

* Improve the documentation of the filetest `run` command

Adds an up-to-date example of how to use the `run` and `print` directives and includes an actual use of the new directives in a SIMD arithmetic filetest.
2020-05-04 14:08:27 -05:00
Alex Crichton
c284ffe6c0 Move trap handler initialization to per-Store (#1644)
Previously we initialized trap handling (signals/etc) once-per-instance
but that's a bit too granular since we only need to do this as
one-time per-program initialization. This moves the initialization to
`Store` instead which means that we'll call this at least once per
thread, which some platforms may need (none currently do, they all only
need per-program initialization, but Fuchsia will need per-thread
initialization).
2020-05-01 19:55:35 -05:00
Nick Fitzgerald
4471a82b0c Merge pull request #1635 from fitzgen/filetests-threads
Allow setting the number of filetest threads via the CRANELIFT_FILETESTS_THREADS env var
2020-05-01 10:06:26 -07:00
Alex Crichton
db92dcd990 Update test ignore annotations for aarch64 (#1643)
Looks like everything is in general passing now so it's probably time to
close #1521 and all other remaining tests that are failing are
classified under new more focused issues.

Closes #1521
2020-05-01 11:24:53 -05:00
Nick Fitzgerald
c0503455be Add documentation about the CRANELIFT_FILETESTS_THREADS environment variable 2020-05-01 09:15:46 -07:00
Nick Fitzgerald
1ec6e6e0eb Merge pull request #1638 from alexcrichton/fuz-debug
Add some debugging assistance to spectest oracle
2020-05-01 09:12:09 -07:00
Chris Fallin
8393412c40 Merge pull request #1632 from cfallin/aarch64-fix-srclocs
MachInst backend: attach SourceLoc span information to all ranges.
2020-04-30 16:13:55 -07:00
Chris Fallin
964c6087bd MachInst backend: attach SourceLoc span information to all ranges.
Previously, the SourceLoc information transferred in `VCode` only
included PC-spans for non-default SourceLocs. I realized that the
invariant we're supposed to keep here is that every PC is covered; if no
source information, just use `SourceLoc::default()`.

This was spurred by @bjorn3's comment in #1575 (thanks!).
2020-04-30 15:40:55 -07:00
Dan Gohman
9d3a84c756 Minor fixes to release scripts (#1639)
- We still saw a timeout with 20 second pauses; bump to 30 seconds.
 - wasmtime-py is now in a separate repository
2020-04-30 14:13:26 -07:00
Alex Crichton
d88a147b4d Add some debugging assistance to spectest oracle
Basically just log what's happening so if you're running the fuzzer you
can see what test is being run.
2020-04-30 12:25:06 -07:00
Andrew Brown
49622bde58 Use complex load-extend instructions in optimize_complex_addresses; fixes #1186 2020-04-30 11:38:01 -07:00
Andrew Brown
a312506262 Add x86 complex encodings for SIMD load-extend instructions 2020-04-30 11:38:01 -07:00
Andrew Brown
38dff29179 Add ability to call CLIF functions with arbitrary arguments in filetests
This resolves the work started in https://github.com/bytecodealliance/cranelift/pull/1231 and https://github.com/bytecodealliance/wasmtime/pull/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 3b7cb6ee64/crates/api/src/func.rs (L510-L526), 3b7cb6ee64/crates/jit/src/compiler.rs (L260)). To avoid re-compiling `Trampoline`s for the same function signatures, `Trampoline`s are cached in the `SingleFunctionCompiler`.
2020-04-30 11:21:00 -07:00
Andrew Brown
2048d3d30c Add x86 encodings for same-size bint conversions up to 64 bits 2020-04-30 11:21:00 -07:00
Nick Fitzgerald
c4292fb2be Allow setting the number of filetest threads via the CRANELIFT_FILETESTS_THREADS env var 2020-04-30 09:20:23 -07:00
Yury Delendik
1873c0ae46 Fix value label ranges resolution (#1572)
There was a bug how value labels were resolved, which caused some DWARF expressions not be transformed, e.g. those are in the registers.

*    Implements FIXME in expression.rs
*    Move TargetIsa from CompiledExpression structure
*    Fix expression format for GDB
*    Add tests for parsing
*    Proper logic in ValueLabelRangesBuilder::process_label
*    Tests for ValueLabelRangesBuilder
*    Refactor build_with_locals to return Iterator instead of Vec<_>
*    Misc comments and magical numbers
2020-04-30 08:07:55 -05:00
Benjamin Bouvier
b7cfd39b53 aarch64: split emit tests into its own file;
This is done to satisfy a check done on the maximal file's size when
vendoring Rust source code into Mozilla central's repository.
2020-04-30 13:50:45 +02:00
Benjamin Bouvier
4c066b1c73 codegen: split lower.rs into multiple files;
This splits off lower.rs into two files: lower.rs keeps all the utility
functions, while lower_inst.rs contains the (gigantic!) function
lowering a single Cranelift instruction into vcode.

This is done to satisfy a check done on the maximal file's size when
vendoring Rust source code into Mozilla central's repository.
2020-04-30 13:50:45 +02:00
Benjamin Bouvier
a2b6c19861 Fix arm32 build: ensure that the expand group is always generated; 2020-04-30 13:50:45 +02:00
Dan Gohman
864cf98c8d Update release notes, wasmtime 0.16, cranelift 0.63. 2020-04-29 17:30:25 -07:00
Alex Crichton
363cd2d20f Expose memory-related options in Config (#1513)
* Expose memory-related options in `Config`

This commit was initially motivated by looking more into #1501, but it
ended up balooning a bit after finding a few issues. The high-level
items in this commit are:

* New configuration options via `wasmtime::Config` are exposed to
  configure the tunable limits of how memories are allocated and such.
* The `MemoryCreator` trait has been updated to accurately reflect the
  required allocation characteristics that JIT code expects.
* A bug has been fixed in the cranelift wasm code generation where if no
  guard page was present bounds checks weren't accurately performed.

The new `Config` methods allow tuning the memory allocation
characteristics of wasmtime. Currently 64-bit platforms will reserve 6GB
chunks of memory for each linear memory, but by tweaking various config
options you can change how this is allocate, perhaps at the cost of
slower JIT code since it needs more bounds checks. The methods are
intended to be pretty thoroughly documented as to the effect they have
on the JIT code and what values you may wish to select. These new
methods have been added to the spectest fuzzer to ensure that various
configuration values for these methods don't affect correctness.

The `MemoryCreator` trait previously only allocated memories with a
`MemoryType`, but this didn't actually reflect the guarantees that JIT
code expected. JIT code is generated with an assumption about the
minimum size of the guard region, as well as whether memory is static or
dynamic (whether the base pointer can be relocated). These properties
must be upheld by custom allocation engines for JIT code to perform
correctly, so extra parameters have been added to
`MemoryCreator::new_memory` to reflect this.

Finally the fuzzing with `Config` turned up an issue where if no guard
pages present the wasm code wouldn't correctly bounds-check memory
accesses. The issue here was that with a guard page we only need to
bounds-check the first byte of access, but without a guard page we need
to bounds-check the last byte of access. This meant that the code
generation needed to account for the size of the memory operation
(load/store) and use this as the offset-to-check in the no-guard-page
scenario. I've attempted to make the various comments in cranelift a bit
more exhaustive too to hopefully make it a bit clearer for future
readers!

Closes #1501

* Review comments

* Update a comment
2020-04-29 17:10:00 -07:00
Joshua Nelson
bc4b4707e3 Re-export object from cranelift-object (#1599)
* Re-export object from cranelift-object

Closes https://github.com/bytecodealliance/wasmtime/issues/1597

* Fix formatting

Co-Authored-By: bjorn3 <bjorn3@users.noreply.github.com>

Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
2020-04-29 17:06:00 -07:00
Jef
957677c6f5 Integrate Lightbeam with latest Wasmtime master (#1232)
* Implement trap info in Lightbeam

* Start using wasm-reader instead of wasmparser for parsing operators

* Update to use wasm-reader, some reductions in allocation, support source location tracking for traps, start to support multi-value

The only thing that still needs to be supported for multi-value is stack returns, but we need to make it compatible with Cranelift.

* Error when running out of registers (although we'd hope it should be impossible) instead of panicking

* WIP: Update Lightbeam to work with latest Wasmtime

* WIP: Update Lightbeam to use current wasmtime

* WIP: Migrate to new system for builtin functions

* WIP: Update Lightbeam to work with latest Wasmtime

* Remove multi_mut

* Format

* Fix some bugs around arguments, add debuginfo offset tracking

* Complete integration with new Wasmtime

* Remove commented code

* Fix formatting

* Fix warnings, remove unused dependencies

* Fix `iter` if there are too many elements, fix compilation for latest wasmtime

* Fix float arguments on stack

* Remove wasm-reader and trap info work

* Allocate stack space _before_ passing arguments, fail if we can't zero a xmm reg

* Fix stack argument offset calculation

* Fix stack arguments in Lightbeam

* Re-add WASI because it somehow got removed during rebase

* Workaround for apparent `type_alias_impl_trait`-related bug in rustdoc

* Fix breakages caused by rebase, remove module offset info as it is unrelated to wasmtime integration PR and was broken by rebase

* Add TODO comment explaining `lightbeam::ModuleContext` trait
2020-04-29 16:26:40 -07:00
teapotd
aa78811fb2 [bugpoint] Remove block params 2020-04-29 14:05:06 -07:00
Chris Fallin
346a3b8a90 Merge pull request #1614 from cfallin/aarch64-regalloc-dense-maps
Use new regalloc.rs version with dense vreg->rreg maps.
2020-04-29 12:29:39 -07:00
Alex Crichton
d719ec7e1c Don't try to handle non-wasmtime segfaults (#1577)
This commit fixes an issue in Wasmtime where Wasmtime would accidentally
"handle" non-wasm segfaults while executing host imports of wasm
modules. If a host import segfaulted then Wasmtime would recognize that
wasm code is on the stack, so it'd longjmp out of the wasm code. This
papers over real bugs though in host code and erroneously classified
segfaults as wasm traps.

The fix here was to add a check to our wasm signal handler for if the
faulting address falls in JIT code itself. Actually threading through
all the right information for that check to happen is a bit tricky,
though, so this involved some refactoring:

* A closure parameter to `catch_traps` was added. This closure is
  responsible for classifying addresses as whether or not they fall in
  JIT code. Anything returning `false` means that the trap won't get
  handled and we'll forward to the next signal handler.

* To avoid passing tons of context all over the place, the start
  function is now no longer automatically invoked by `InstanceHandle`.
  This avoids the need for passing all sorts of trap-handling contextual
  information like the maximum stack size and "is this a jit address"
  closure. Instead creators of `InstanceHandle` (like wasmtime) are now
  responsible for invoking the start function.

* To avoid excessive use of `transmute` with lifetimes since the
  traphandler state now has a lifetime the per-instance custom signal
  handler is now replaced with a per-store custom signal handler. I'm
  not entirely certain the purpose of the custom signal handler, though,
  so I'd look for feedback on this part.

A new test has been added which ensures that if a host function
segfaults we don't accidentally try to handle it, and instead we
correctly report the segfault.
2020-04-29 14:24:54 -05:00