Document and update the API of the externals.rs module (#812)

* Document and update the API of the `externals.rs` module

This commit ensures that all public methods and items are documented in
the `externals.rs` module, notably all external values that can be
imported and exported in WebAssembly. Along the way this also tidies up
the API and fixes a few bugs:

* `Global::new` now returns a `Result` and fails if the provided value
  does not match the type of the global.
* `Global::set` now returns a `Result` and fails if the global is either
  immutable or the provided value doesn't match the type of the global.
* `Table::new` now fails if the provided initializer does not match the
  element type.
* `Table::get` now returns `Option<Val>` instead of implicitly returning
  null.
* `Table::set` now returns `Result<()>`, returning an error on out of
  bounds or if the input type is of the wrong type.
* `Table::grow` now returns `Result<u32>`, returning the previous number
  of table elements if succesful or an error if the maximum is reached
  or the initializer value is of the wrong type. Additionally a bug was
  fixed here where if the wrong initializer was provided the table would
  be grown still, but initialization would fail.
* `Memory::data` was renamed to `Memory::data_unchecked_mut`.
  Additionally `Memory::data_unchecked` was added. Lots of caveats were
  written down about how using the method can go wrong.
* `Memory::grow` now returns `Result<u32>`, returning an error if growth
  fails or the number of pages previous the growth if successful.

* Run rustfmt

* Fix another test

* Update crates/api/src/externals.rs

Co-Authored-By: Sergei Pepyakin <s.pepyakin@gmail.com>

Co-authored-by: Sergei Pepyakin <s.pepyakin@gmail.com>
This commit is contained in:
Alex Crichton
2020-01-17 09:43:35 -06:00
committed by GitHub
parent 7890fa6705
commit 0bee67a852
10 changed files with 384 additions and 99 deletions

View File

@@ -105,9 +105,9 @@ fn main() -> Result<(), Error> {
println!("Checking memory...");
check!(memory.size(), 2u32);
check!(memory.data_size(), 0x20000usize);
check!(unsafe { memory.data()[0] }, 0);
check!(unsafe { memory.data()[0x1000] }, 1);
check!(unsafe { memory.data()[0x1003] }, 4);
check!(unsafe { memory.data_unchecked_mut()[0] }, 0);
check!(unsafe { memory.data_unchecked_mut()[0x1000] }, 1);
check!(unsafe { memory.data_unchecked_mut()[0x1003] }, 4);
check!(call!(size_func,), 2);
check!(call!(load_func, 0), 0);
@@ -119,20 +119,20 @@ fn main() -> Result<(), Error> {
// Mutate memory.
println!("Mutating memory...");
unsafe {
memory.data()[0x1003] = 5;
memory.data_unchecked_mut()[0x1003] = 5;
}
check_ok!(store_func, 0x1002, 6);
check_trap!(store_func, 0x20000, 0);
check!(unsafe { memory.data()[0x1002] }, 6);
check!(unsafe { memory.data()[0x1003] }, 5);
check!(unsafe { memory.data_unchecked()[0x1002] }, 6);
check!(unsafe { memory.data_unchecked()[0x1003] }, 5);
check!(call!(load_func, 0x1002), 6);
check!(call!(load_func, 0x1003), 5);
// Grow memory.
println!("Growing memory...");
check!(memory.grow(1), true);
memory.grow(1)?;
check!(memory.size(), 3u32);
check!(memory.data_size(), 0x30000usize);
@@ -141,8 +141,8 @@ fn main() -> Result<(), Error> {
check_trap!(load_func, 0x30000);
check_trap!(store_func, 0x30000, 0);
check!(memory.grow(1), false);
check!(memory.grow(0), true);
memory.grow(1).unwrap_err();
memory.grow(0).unwrap();
// Create stand-alone memory.
// TODO(wasm+): Once Wasm allows multiple memories, turn this into import.
@@ -150,8 +150,8 @@ fn main() -> Result<(), Error> {
let memorytype = MemoryType::new(Limits::new(5, Some(5)));
let memory2 = Memory::new(&store, memorytype);
check!(memory2.size(), 5u32);
check!(memory2.grow(1), false);
check!(memory2.grow(0), true);
memory2.grow(1).unwrap_err();
memory2.grow(0).unwrap();
// Shut down.
println!("Shutting down...");