Skip to content
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

Add circle integration #1

Merged
merged 4 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Check https://circleci.com/docs/2.0/language-elixir/ for more details on CircleCI configuration
version: 2
jobs:
build:
parallelism: 1
docker:
- image: circleci/elixir:1.9.1
environment:
MIX_ENV: test

working_directory: ~/repo
steps:
- checkout

- restore_cache:
keys:
- v1-dependency-cache-{{ checksum "mix.lock" }}
- v1-dependency-cache

- run: mix local.hex --force # install Hex locally (without prompt)
- run: mix local.rebar --force # fetch a copy of rebar (without prompt)
- run:
name: "Install Rust"
command: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain stable -y
source $HOME/.cargo/env
rustup component add rustfmt
rustup target add wasm32-unknown-unknown # to compile our example WASM files for testing

- run:
name: "Run Checks (Tests, Formatters, ..)"
command: |
source $HOME/.cargo/env
mix deps.get
mix test
mix format --check-formatted
cargo fmt --manifest-path native/wasmex/Cargo.toml -- --check
mix dialyzer
mix docs

- save_cache:
key: v1-dependency-cache-{{ checksum "mix.lock" }}
paths:
- _build
- deps
- ~/.mix

- store_test_results:
path: _build/test/lib/wasmex
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ erl_crash.dump
wasmex-*.tar

# Cargo things in the Rust part of this package
Cargo.*
priv/native/libwasmex.so
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
</p>

<p align="center">
<a href="https://spectrum.chat/wasmer">
<img src="https://withspectrum.github.io/badge/badge.svg" alt="Join the Wasmer Community">
</a>
<a href="https://github.com/wasmerio/wasmer/blob/master/LICENSE">
<a href="https://github.com/tessi/wasmex/blob/master/LICENSE">
<img src="https://img.shields.io/github/license/wasmerio/wasmer.svg" alt="License">
</a>
[![CircleCI](https://circleci.com/gh/tessi/wasmex.svg?style=svg)](https://circleci.com/gh/tessi/wasmex)
</p>

Wasmex is an Elixir library for executing WebAssembly binaries:
Expand Down Expand Up @@ -42,7 +40,7 @@ The docs can be found at [https://hexdocs.pm/wasmex](https://hexdocs.pm/wasmex).
# Example

There is a toy WASM program in `test/wasm_source/src/lib.rs`, written in Rust (but could potentially be any other language that compiles to Wasm).
It defines many funtions we use for end-to-end testing, but also serves as example code. For example:
It defines many functions we use for end-to-end testing, but also serves as example code. For example:

```rust
#[no_mangle]
Expand Down Expand Up @@ -85,7 +83,7 @@ IO.puts result # 3
All exported functions are accessible via the `call_exported_function` function. Arguments of these functions are automatically casted to WebAssembly values.
Note that WebAssembly only knows number datatypes (floats and integers of various sizes).

You can pass arbritrary data to WebAssembly, though, by writing this data into its memory. The `memory` function returns a `Memory` struct representing the memory of that particular instance, e.g.:
You can pass arbitrary data to WebAssembly, though, by writing this data into its memory. The `memory` function returns a `Memory` struct representing the memory of that particular instance, e.g.:

```elixir
{:ok, memory} = Wasmex.Instance.memory(instance, :uint8, 0)
Expand Down Expand Up @@ -126,7 +124,7 @@ IO.puts Wasmex.Memory.get(memory, index) # 42

The `Memory` struct views the WebAssembly memory of an instance as an array of values of different types.
Possible types are: `uint8`, `int8`, `uint16`, `int16`, `uint32`, and `int32`.
The underlying data is not changed when viewed in different types - its just its represenation that changes.
The underlying data is not changed when viewed in different types - its just its representation that changes.

| View memory buffer as a sequence of… | Bytes per element |
|----------|---|
Expand All @@ -137,7 +135,7 @@ The underlying data is not changed when viewed in different types - its just its
| `int32` | 4 |
| `uint32` | 4 |

This can also be resolved programmatically:
This can also be resolved at runtime:

```elixir
{:ok, memory} = Wasmex.Instance.memory(instance, :uint16, 0)
Expand Down Expand Up @@ -225,9 +223,9 @@ pub extern "C" fn string() -> *const u8 {
```

This function returns a pointer to its memory.
This memory location contains the String "Hellow, World!" (ending with a null-byte since in C-land all strings end with a null-byte to mark the end of the string).
This memory location contains the String "Hello, World!" (ending with a null-byte since in C-land all strings end with a null-byte to mark the end of the string).

Thsi is how we would receive this String in Elixir:
This is how we would receive this String in Elixir:

```elixir
bytes = File.read!(TestHelper.wasm_file_path)
Expand Down
7 changes: 4 additions & 3 deletions lib/wasmex/instance.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule Wasmex.Instance do
All exported functions are accessible via the `call_exported_function` function. Arguments of these functions are automatically casted to WebAssembly values.
Note that WebAssembly only knows number datatypes (floats and integers of various sizes).

You can pass arbritrary data to WebAssembly, though, by writing this data into its memory. The `memory` function returns a `Memory` struct representing the memory of that particular instance, e.g.:
You can pass arbitrary data to WebAssembly, though, by writing this data into its memory. The `memory` function returns a `Memory` struct representing the memory of that particular instance, e.g.:

```elixir
{:ok, memory} = Wasmex.Instance.memory(instance, :uint8, 0)
Expand All @@ -35,7 +35,7 @@ defmodule Wasmex.Instance do
# Normally the compiler will happily do stuff like inlining the
# resource in attributes. This will convert the resource into an
# empty binary with no warning. This will make that harder to
# accidentaly do.
# accidentally do.
# It also serves as a handy way to tell file handles apart.
reference: nil

Expand Down Expand Up @@ -70,7 +70,8 @@ defmodule Wasmex.Instance do
Wasmex.Native.instance_call_exported_function(resource, name, params)
end

@spec memory(__MODULE__.t(), atom(), pos_integer()) :: {:error, binary()} | {:ok, Wasmex.Memory.t()}
@spec memory(__MODULE__.t(), atom(), pos_integer()) ::
{:error, binary()} | {:ok, Wasmex.Memory.t()}
def memory(%__MODULE__{} = instance, size, offset)
when size in [:uint8, :int8, :uint16, :int16, :uint32, :int32] do
Wasmex.Memory.from_instance(instance, size, offset)
Expand Down
10 changes: 6 additions & 4 deletions lib/wasmex/memory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Wasmex.Memory do

The `Memory` struct views the WebAssembly memory of an instance as an array of values of different types.
Possible types are: `uint8`, `int8`, `uint16`, `int16`, `uint32`, and `int32`.
The underlying data is not changed when viewed in different types - its just its represenation that changes.
The underlying data is not changed when viewed in different types - its just its representation that changes.

| View memory buffer as a sequence of… | Bytes per element |
|----------|---|
Expand All @@ -51,7 +51,7 @@ defmodule Wasmex.Memory do
# Normally the compiler will happily do stuff like inlining the
# resource in attributes. This will convert the resource into an
# empty binary with no warning. This will make that harder to
# accidentaly do.
# accidentally do.
# It also serves as a handy way to tell file handles apart.
reference: nil,
size: nil,
Expand All @@ -62,7 +62,8 @@ defmodule Wasmex.Memory do
from_instance(instance, :uint8, 0)
end

@spec from_instance(Wasmex.Instance.t(), atom(), non_neg_integer()) :: {:error, binary()} | {:ok, __MODULE__.t()}
@spec from_instance(Wasmex.Instance.t(), atom(), non_neg_integer()) ::
{:error, binary()} | {:ok, __MODULE__.t()}
def from_instance(%Wasmex.Instance{resource: resource}, size, offset)
when size in [:uint8, :int8, :uint16, :int16, :uint32, :int32] do
case Wasmex.Native.memory_from_instance(resource) do
Expand Down Expand Up @@ -185,7 +186,8 @@ defmodule Wasmex.Memory do
write_binary(memory, memory.size, memory.offset, index, str)
end

@spec write_binary(__MODULE__.t(), atom(), non_neg_integer(), non_neg_integer(), binary()) :: :ok
@spec write_binary(__MODULE__.t(), atom(), non_neg_integer(), non_neg_integer(), binary()) ::
:ok
def write_binary(%Wasmex.Memory{resource: resource}, size, offset, index, str)
when is_binary(str) do
# strings a null-byte terminated in C-land
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ defmodule Wasmex.MixProject do
defp deps do
[
{:rustler, "~> 0.21.0"},
{:ex_doc, "~> 0.21.2", only: :dev},
{:dialyxir, "~> 1.0.0-rc.7", only: [:dev], runtime: false}
{:ex_doc, "~> 0.21.2", only: [:dev, :test]},
{:dialyxir, "~> 1.0.0-rc.7", only: [:dev, :test], runtime: false}
]
end

Expand Down
5 changes: 5 additions & 0 deletions test/wasm_source/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions test/wasm_source/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "wasmex_test"
version = "0.1.0"
authors = ["Philipp Tessenow <philipp@tessenow.org>"]
edition = "2018"

[dependencies]

[lib]
crate-type =["cdylib"]