Commit Graph

3148 Commits

Author SHA1 Message Date
Ivan Enderlin
700c290e55 feat(interface-types) Move the values and serde modules to the root of the crate. 2020-04-09 11:23:26 +02:00
Ivan Enderlin
e4b05d0b00 feat(interface-types) Remove the re-export of InterfaceType in values. 2020-04-09 10:54:09 +02:00
Ivan Enderlin
f955617d17 feat(interface-types) Extract InterfaceType and RecordType into its own types module. 2020-04-09 10:48:50 +02:00
bors[bot]
ad6f939e85
Merge #1362
1362: feat(interface-types) Remove allocator index from `string.lower_memory` r=Hywan a=Hywan

This PR updates `string.lower_memory` to remove the allocator index. Indeed, the string pointer is assumed to be present on the stack.
Also, this PR updates `string.size` to pop, and not to peek, the string to compute the length from.

That way, it matches the WIT proposal.

Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2020-04-09 08:05:50 +00:00
Mark McCaskey
23bc0fd720 Fix kernel-net check, fix misc warnings
Split out nightly check step
2020-04-08 17:05:25 -07:00
Mark McCaskey
b72000a2d6 Update emscripten in C API to use new API crate 2020-04-08 16:40:41 -07:00
Mark McCaskey
4d58ae2d14 Fix issue with kernel-net; add it to CI 2020-04-08 15:18:04 -07:00
Mark McCaskey
9e8d08a771
Merge branch 'master' into feature/dev-utils-in-tests 2020-04-08 12:15:22 -07:00
Mark McCaskey
3d4ed92466 Move dev-utils crate into tests 2020-04-08 11:59:47 -07:00
bors[bot]
45c412e8dd
Merge #1363
1363: fix(interface-types) Don't duplicate code in the binary encoder. r=MarkMcCaskey a=Hywan

Use the `ToBytes` implementation of `RecordType` to encode the inner
record type of a type, so that it avoids code duplication.

Co-authored-by: Ivan Enderlin <ivan@mnt.io>
2020-04-08 18:48:49 +00:00
Mark McCaskey
db76aea198 Remove more uses of wasmer_runtime_core from the C API 2020-04-07 17:28:23 -07:00
Ivan Enderlin
4eae19ccc7 fix(interface-types) Don't duplicate code in the binary encoder.
Use the `ToBytes` implementation of `RecordType` to encode the inner
record type of a type, so that it avoids code duplication.
2020-04-07 14:29:57 +02:00
Ivan Enderlin
1687744ec9 feat(interface-types) string.size pops the string.
Previously, `string.size` was just peeking the string.
2020-04-07 12:40:14 +02:00
Ivan Enderlin
bfa5821d98 test(interface-types) Update the test_executable_instruction macro.
It provides a better failure message.
2020-04-07 12:34:30 +02:00
Ivan Enderlin
2fffee32a5 fix(interface-types) Remove allocator index from string.lower_memory. 2020-04-07 12:34:07 +02:00
Ivan Enderlin
c0623b0f8c doc(interface-types) Add record instructions. 2020-04-07 11:58:13 +02:00
Mark McCaskey
83f0a043e7 Update C API to use new API 2020-04-06 17:09:50 -07:00
Mark McCaskey
4c29cd4af3 Merge branch 'master' into feature/reorganized-tests 2020-04-06 12:04:36 -07:00
Mark McCaskey
52cbb60743 Fix up tests for CI 2020-04-06 11:42:44 -07:00
bors[bot]
99f8c949d1
Merge #1354
1354: test(middleware-common) Remove an unused import r=MarkMcCaskey a=Hywan

This PR removes an unused import.

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
2020-04-06 17:40:35 +00:00
Ivan Enderlin
ac3288db1c test(middleware-common) Remove an unused import. 2020-04-06 08:34:55 +02:00
bors[bot]
4d33020b35
Merge #1331
1331: feat(interface-types) Implement the `record` instructions r=Hywan a=Hywan

### Description

This PR implements the `record` WIT type, along with the `record.lift` and `record.lower` instructions.

With my current understanding of the draft/specification, here is how it works. Let's say we want to represent a Rust struct like the following:

```rust
struct S {
    x: String,
    y: i32
}
```

First declare a WIT type, such as:

```wat
(@interface type (record (field string) (field i32)))
```

The `record` type is supported by the binary encoder, the WAT encoder, the binary decoder, and the WAT decoder. A new `TypeKind` node has been introduced in the AST to differentiate a function type (`(@interface type (func (param …) (result …)))`) of a record type (see above).

Second, the `record.lower` transforms a host value (here Rust value, `S`) into a WIT value. In our implementation, a record value is defined as:

```rust
InterfaceValue::Record(Vec<InterfaceValue>)
```

Multiple mechanisms are used to type check a record value based on a record type. The code of the `record.lower` is pretty straightforward.

Because transforming a host value into a WIT value isn't obvious, a `Serializer` has been implemented, based on [`serde`](https://serde.rs/). This feature is behind the `serde` flag, which is turned on by default.

Serde is only used to cross the host/Wasm boundary, but it's not used to represent the value in memory or anything. It's only a shortcut to transform a host value into a WIT value, and vice versa.

Use the following code to transform `S` into a WIT value:

```rust
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct S {
    x: String,
    y: i32,
}

let host_value = S { x: "hello".to_string(), y: 42 };
let wit_value = to_interface_value(&host_value).unwrap();

assert_eq!(
    wit_value,
    InterfaceValue::Record(vec![
        InterfaceValue::String("hello".to_string()),
        InterfaceValue::I32(42),
    ])
);
```

Third, the `record.lift`  instruction does the opposite of `record.lower`: It transforms WIT values into a host value. To also facilitate the user experience, this PR contains a `Deserializer` implementation, still based on `serde`, with the `from_interface_values` function. It looks like this:

```rust
let wit_values = vec![
    InterfaceValue::Record(vec![
        InterfaceValue::String("hello".to_string()),
        InterfaceValue::I32(42),
    ])
];
let host_value = from_interface_values::<S>(&wit_values).unwrap();

assert_eq!(
    host_value,
    S { x: "hello".to_string(), y: 42 },
);
```

With the `Serializer` and `Deserializer`, it's super easy for the user to send or receive values from WIT.

The `record.lift` and `record.lower` instructions are kind of basic. The `record.lift` instruction has a little trick to reduce vector allocations, but there is a documentation for that.

#### Opened questions

Records of dimension 1 do not raise any issue. With `record.lift`, all values on the stack (the WIT interpreter stack) are popped, and are used as record field values. Something like:

```
[stack]
i32(1)
i64(2),
string("hello")
record.lift <record_type>
```

generates

```
[stack]
record { i32(1), i64(2), string("hello") }
```

But it's not clear what happens with record of dimension > 1, for instance for a type like `record (field i32) (record (field i32) (field i32)) (field string)`, it is assumed (in this PR) that the stack must be like this:

```
[stack]
i32(1)
i32(2)
i32(3)
string("hello")
record.lift <record_type>
```

to generate:

```
[stack]
record { i32(1), record { i32(2), i32(3) }, string("hello") }
```

If we want the stack to contain an intermediate record, we should have something like this:

```
[stack]
i32(1)
i32(2)
i32(3)
record.lift <record_type_2>
string("hello")
record.lift <record_type_1>
```

But it would imply that `record_type_1` is defined as `record (field i32) (record (type record_type_2)) (field i32)`.

A sub-record defined by another record type isn't support, as it is not specified in the draft. I believe my assumption is fine enough for a first implementation of records in WIT.

### To do

- [x] Encode and decode record type (`(@interface type (record string i32))`):
  - [x] Binary encoder/decoder
  - [x] WAT encoder/decoder
- [x] Implement the `record.lift` instruction
- [x] Implement the `record.lower` instruction
- [x] Test
- [x] Documentation
- [x] Surprise!
  - [x] Serialize a Rust value to WIT values (useful for `record`s)
  - [x] Deserialize WIT values to a Rust value (useful for `record`s)

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
2020-04-06 06:17:45 +00:00
Ivan Enderlin
9f10b7ae50 doc(interface-types) Update from_interface_values's doc.
Using `InterfaceValue::Record` explicitely doesn't change anything
since values are flatten, but it's better for a usual reading to avoid
confusion.
2020-04-06 08:13:10 +02:00
Ivan Enderlin
27053d5ca6 doc(interface-types) Rewrite record_lift_ documentation. 2020-04-06 08:09:10 +02:00
Ivan Enderlin
c2b1b87f9a feat(interface-types) Use VecDeque to remove unsafe code. 2020-04-06 07:55:56 +02:00
Ivan Enderlin
4faf827dc9 feat(interface-types) Avoid clones by using owned items in an iterator.
`into_iter` owned the item, so no need to clone when moving them in
the stack.
2020-04-06 07:54:51 +02:00
Ivan Enderlin
4ad3d7f123 doc(interface-types) Explain a part of an algorithm. 2020-04-04 08:10:38 +02:00
Mark McCaskey
dfa6247075 Move spectests, wrap up test restructure 2020-04-03 14:24:40 -07:00
Ivan Enderlin
5119b6a58f feat(interface-types) Simplify FlattenInterfaceValueIterator with last_mut. 2020-04-03 16:22:26 +02:00
Ivan Enderlin
e4921bd496 feat(interface-types) Use Vec::last_mut to simplify code. 2020-04-03 16:20:22 +02:00
Ivan Enderlin
398d791c9f fix(interface-types) Also apply another lazy evaluation in the deserializer. 2020-04-03 16:19:07 +02:00
Ivan Enderlin
e160feb99a fix(interface-types) Use lazy evaluation in the deserializer. 2020-04-03 16:18:24 +02:00
Ivan Enderlin
d186142507 doc(interface-types) Fix a typo. 2020-04-03 16:16:53 +02:00
Ivan Enderlin
3159da5bfe feat(interface-types) Add the Vec1 type to represent a non-empty vector.
`Vec1` is used by `RecordType` to ensure that a record have at least 1
field. Then an `InterfaceValue::Record` is ensured to get at least one
value with the type-checking pass.
2020-04-03 16:13:44 +02:00
Ivan Enderlin
6cef1c244a doc(interface-types) Fix typos. 2020-04-03 14:46:59 +02:00
Mark McCaskey
513e6acbc1 Move emscripten-tests to tests dir + misc fixes 2020-04-02 16:51:58 -07:00
bors[bot]
1833af7eba
Merge #1350
1350: update blake3 to 0.3.1 r=syrusakbary a=oconnor663

Version 0.3.0 caused problems because it required a C compiler with
AVX-512 support, which broke Android x86 cross-compilation. Version
0.3.1 automatically falls back to a pure Rust build when the C compiler
either doesn't exist or doesn't support the flags we need.

Co-authored-by: Jack O'Connor <oconnor663@gmail.com>
2020-04-02 15:11:41 +00:00
Jack O'Connor
aca0bd11c0 update blake3 to 0.3.1
Version 0.3.0 caused problems because it required a C compiler with
AVX-512 support, which broke Android x86 cross-compilation. Version
0.3.1 automatically falls back to a pure Rust build when the C compiler
either doesn't exist or doesn't support the flags we need.
2020-04-02 11:02:49 -04:00
Ivan Enderlin
2011fda31d chore(interface-types) Split the serde module…
… into `serde/ser.rs` and `serde/de.rs`. I like smaller files.
2020-04-02 16:46:23 +02:00
Ivan Enderlin
be66ac8aa4 doc(interface-types) Improve serde module documentation. 2020-04-02 16:41:03 +02:00
Ivan Enderlin
e385bf66c7 feat(interface-types) Make unwraps safe by introducing more errors. 2020-04-02 16:38:40 +02:00
Ivan Enderlin
b0af014339 doc(interface-types) Update an example. 2020-04-02 16:29:52 +02:00
Ivan Enderlin
ee0596d2c3 feat(interface-types) Restrict supported type in the Deserializer.
`seq`, `map` and `tuple` for instance are not supported officially. It
was fun to play with it at the beginning, but it is time to remove it
to match the `Serializer` implementation.
2020-04-02 16:26:24 +02:00
Ivan Enderlin
d6f7e3ff02 doc(interface-types) Describe to_interface_value. 2020-04-02 15:59:07 +02:00
Ivan Enderlin
f9832fecaf feat(interface-types) Implement a serializer for WIT values. 2020-04-02 15:54:39 +02:00
Ivan Enderlin
8868d640fa feat(interface-types) Rename from_values to from_interface_values. 2020-04-02 13:56:20 +02:00
Ivan Enderlin
7b182416df feat(interface-types) Make serde optional behind a feature flag. 2020-04-02 13:53:10 +02:00
Ivan Enderlin
f8507533fb fix(interface-types) Fix a git-merge issue. 2020-04-02 12:16:30 +02:00
Ivan Enderlin
bac56a6e0b Merge branch 'master' into feat-interface-types-record-instructions 2020-04-02 12:10:01 +02:00
Ivan Enderlin
8f8c5f1bc8 chore(interface-types) Improve code readabilit of the record.lift instruction. 2020-04-02 12:06:54 +02:00
Ivan Enderlin
0023eea275 feat(interface-types) Implement the record.lower instruction. 2020-04-02 12:06:27 +02:00
Ivan Enderlin
11687c57ca feat(interface-types) Encodes/decodes the record.lower instruction. 2020-04-02 12:05:22 +02:00
Ivan Enderlin
b8ef82d1d0 test(interface-types) Rename test cases. 2020-04-02 11:59:35 +02:00
Ivan Enderlin
a1551b52af test(interface-types) Rename a test case. 2020-04-02 11:58:05 +02:00
Ivan Enderlin
aab82c122d feat(interface-types) Implement From<&Vec<InterfaceValue>> for RecordType. 2020-04-02 11:55:54 +02:00
Ivan Enderlin
3411ac7a1c feat(interface-types) Move serde::InterfaceTypeIterator into values::FlattenInterfaceValueIterator. 2020-04-02 11:55:20 +02:00
Ivan Enderlin
5ba6fda1c9 chore(interface-types) Improve code readibility of string instructions. 2020-04-02 11:51:34 +02:00
Mark McCaskey
976bf9b6a3 Move integration tests to tests dir in workspace root 2020-04-01 17:09:51 -07:00
Mark McCaskey
0527b50af3 Improve consistency of names, reuse more code, and reorganize a bit 2020-03-31 16:00:52 -07:00
Mark McCaskey
bde319d9fb Fix bug and un-deprecate Instance::call 2020-03-31 14:06:30 -07:00
Mark McCaskey
836711f7cd Implement Instance::call in terms of the exports API 2020-03-31 12:40:55 -07:00
Mark McCaskey
50fcd57e45 Improve consistency and add misc clean ups 2020-03-31 12:37:50 -07:00
Ivan Enderlin
1a17cbb17e test(interface-types) Deserialize WIT record to Rust struct. 2020-03-31 14:44:04 +02:00
Ivan Enderlin
02b7e21345 feat(interface-types) Implement the record.lift instruction. 2020-03-31 12:34:32 +02:00
Ivan Enderlin
0af1076eee feat(interface-types) Encodes/decodes the record.lift instruction. 2020-03-31 08:17:52 +02:00
Ivan Enderlin
3655ef8bb7 chore(interface-types) Reorganize the serde module. 2020-03-31 08:02:46 +02:00
Ivan Enderlin
ee57b47770 feat(interface-types) Improve the Deserializer API. 2020-03-31 07:47:54 +02:00
Ivan Enderlin
c87c2ef33b feat(interface-values) Improve the TypeMismatch error. 2020-03-31 07:47:15 +02:00
Mark McCaskey
403d4b4c8b
Merge branch 'master' into feature/update-api 2020-03-30 17:40:18 -07:00
Mark McCaskey
7ca721bd83 Update from feedback
Deprecate more methods on `Instance`, add `into_iter` method on
`Exports`, add FuncSig to ImportType and other updates.
2020-03-30 17:38:51 -07:00
Ivan Enderlin
154dcba42c feat(interface-types) Implement Serde deserializing for WIT records to Rust values.
WIT values are native Rust values. But records are represented as a
vector of WIT values. In order to provide a super neat API to the
user, Serde is used to deserialize this vector of WIT values to a
large variety of Rust values.
2020-03-30 15:42:35 +02:00
Ivan Enderlin
a99ae6bdb2 feat(interface-types) Add the Record WIT value. 2020-03-30 08:32:31 +02:00
nlewycky
c4c4adb7bf
Merge branch 'master' into feature/llvm-target-triple 2020-03-28 11:55:37 -07:00
Syrus Akbary
baa74d7385
Merge pull request #1335 from Hywan/fix-runtime-c-api-1314
fix(runtime-c-api) Change mutability of `memory` to`const` in `wasmer_memory_data_length`
2020-03-28 10:41:33 -07:00
Syrus Akbary
b7ad8b2c7a
Merge pull request #1337 from Hywan/fix-interface-types-remove-as
feat(interface-types) Better handling of i32 to usize casts
2020-03-28 10:41:06 -07:00
Nick Lewycky
5b7a06c07b Use the inkwell package on crates.io!! 2020-03-27 15:47:50 -07:00
Mark McCaskey
7cd9e82015 Simplify ImportType 2020-03-27 14:00:02 -07:00
Nick Lewycky
5bd6b161d5 Create a valid target triple in the LLVM Module. 2020-03-27 13:54:18 -07:00
Mark McCaskey
a0dca15fbc Add misc. fixes and updates from feedback 2020-03-27 13:25:51 -07:00
Ivan Enderlin
2276d16f36
Merge branch 'master' into fix-runtime-c-api-1314 2020-03-27 07:48:23 +01:00
Mark McCaskey
3eff8c1973 Convert usages of Instance::{func,dyn_func} to exports.get 2020-03-26 18:13:45 -07:00
Mark McCaskey
2fb8f8197b Deprecate Instance::func and Instance::dyn_func 2020-03-26 17:11:37 -07:00
Mark McCaskey
a18371eb91 Implement instance.exports field syntax 2020-03-26 16:24:23 -07:00
Ivan Enderlin
bd9226eb68 feat(interface-types) Introduce RecordType for InterfaceType and Type.
The `Type::Record` variant now is defined by `RecordType`. In
addition, `InterfaceType` has a new variant: `Record`, that is also
defined by `RecordType`. Encoders and decoders are updated to consider
`RecordType`, which removes code duplication and simplify code.
2020-03-26 13:35:24 +01:00
Ivan Enderlin
3c02c501ed chore(interface-types) Move the instruction.rs module in instructions/mod.rs. 2020-03-26 11:24:10 +01:00
Ivan Enderlin
734795c1f4 test(interface-types) Test Type::Record. 2020-03-26 11:18:24 +01:00
Ivan Enderlin
bbb4f1fc0f feat(interface-types) Introduce the record type.
This patch updates the `Type` type to be an enum with 2 variants:
`Function` and `Record`, resp. to represent:

1. `(@interface type (func (param i32 i32) (result string)))`
2. `(@interface type (record string i32))`

This patch updates the binary encoder and decoder, along with the WAT
encoder and decoder.
2020-03-26 10:54:58 +01:00
Ivan Enderlin
6e5d9624f1 feat(interface-types) Simplify code by implementing From<TryFromIntError>. 2020-03-26 10:49:49 +01:00
Ivan Enderlin
25cd6cd24a feat(interface-types) Add the NegativeValue instruction error. 2020-03-26 08:31:06 +01:00
Ivan Enderlin
f3be7981d2 test(interface-types) Test negative pointer or length in string.lift_memory. 2020-03-26 08:30:32 +01:00
Ivan Enderlin
86b545fd49 fix(interface-types) Avoid integer overflows in string instructions. 2020-03-26 08:27:51 +01:00
Ivan Enderlin
0e70e538cc fix(interface-types) Instruction::CallCore.function_index is a u32. 2020-03-26 07:53:44 +01:00
Ivan Enderlin
b0879d1d12 fix(interface-types) Cast index to usize to compare index to length.
The index is bound to `u32::max_value()`. The invocation inputs'
length is bound to `usize::max_value()`, which can be
`u64::max_value`. Consequently, casting the invocation inputs' length
to `u32` can lead to an integer overflow. It is better to cast `index`
to `usize` when comparing with the invocation inputs' length.
2020-03-26 07:46:59 +01:00
Ivan Enderlin
6eaf87d651 chore(runtime-c-api) Update C/C++ headers. 2020-03-26 07:32:57 +01:00
Ivan Enderlin
9826ff3813 fix(runtime-c-api) Change mutability of memory for const in wasmer_memory_data_length. 2020-03-26 07:30:34 +01:00
Ivan Enderlin
4a86cd16f9
Merge branch 'master' into feat-interface-types-new-types-and-instructions 2020-03-26 07:26:37 +01:00
Mark McCaskey
c14c88fb72 Improve high level API test 2020-03-25 16:14:04 -07:00
Mark McCaskey
cc13e45215 Add skeleton of external API and tests 2020-03-24 18:59:09 -07:00
Mark McCaskey
697da669a1 Minor code update, move conditional block inwards 2020-03-24 16:00:32 -07:00
Mark McCaskey
ce1b1f67cf Update opt name in CompilerConfig, enable IR verification in spectests 2020-03-24 15:46:58 -07:00