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 fizzy-wasi tool #329

Merged
merged 8 commits into from
Oct 1, 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
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ include(CableBuildType)
include(CableCompilerSettings)
include(CMakeDependentOption)

option(FIZZY_WASI "Enable WASI support" OFF)

option(FIZZY_TESTING "Enable Fizzy internal tests" OFF)
cmake_dependent_option(HUNTER_ENABLED "Enable Hunter package manager" ON
"FIZZY_TESTING" OFF)
Expand Down Expand Up @@ -104,6 +106,10 @@ if(FIZZY_TESTING)
add_subdirectory(test)
endif()

if(FIZZY_WASI)
add_subdirectory(tools/wasi)
endif()

set(CMAKE_INSTALL_CMAKEPACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})

write_basic_package_version_file(fizzyConfigVersion.cmake COMPATIBILITY ExactVersion)
Expand Down
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,26 @@ $ cmake --build .
This will build Fizzy as a library and since there is no public API
(the so called *embedder API* in WebAssembly) yet, this is not very useful.

## WASI

Building with the `FIZZY_WASI` option will output a `fizzy-wasi` binary implementing
the [WASI] API (a very limited subset of [wasi_snapshot_preview1], to be precise).
It uses [uvwasi] under the hood. It can be used to execute WASI-compatible binaries on the command line.

```sh
$ mkdir build && cd build
$ cmake -DFIZZY_WASI=ON ..
$ cmake --build .
```

Try it with a Hello World example:
```sh
$ bin/fizzy-wasi ../test/smoketests/wasi/helloworld.wasm
hello world
```

## Testing tools

Building with the `FIZZY_TESTING` option will output a few useful utilities:

```sh
Expand Down Expand Up @@ -152,15 +172,19 @@ For a list of releases and changelog see the [CHANGELOG file](./CHANGELOG.md).

Licensed under the [Apache License, Version 2.0].

[webassembly]: https://webassembly.org/
[webassembly]: https://webassembly.org
[standard readme]: https://github.com/RichardLitt/standard-readme
[circleci]: https://circleci.com/gh/wasmx/fizzy/tree/master
[codecov]: https://codecov.io/gh/wasmx/fizzy/
[codecov]: https://codecov.io/gh/wasmx/fizzy
[Apache License, Version 2.0]: LICENSE
[@axic]: https://github.com/axic
[@chfast]: https://github.com/chfast
[@gumb0]: https://github.com/gumb0

[WASI]: https://github.com/WebAssembly/WASI
[uvwasi]: https://github.com/cjihrig/uvwasi
[wasi_snapshot_preview1]: https://github.com/WebAssembly/WASI/blob/master/phases/snapshot/witx/wasi_snapshot_preview1.witx

[webassembly badge]: https://img.shields.io/badge/WebAssembly-Engine-informational.svg?logo=webassembly
[readme style standard badge]: https://img.shields.io/badge/readme%20style-standard-brightgreen.svg
[circleci badge]: https://img.shields.io/circleci/project/github/wasmx/fizzy/master.svg?logo=circleci
Expand Down
4 changes: 2 additions & 2 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ commands:
working_directory: ~/build
command: |
rm -f CMakeCache.txt
cmake ../project -G Ninja -DCMAKE_INSTALL_PREFIX=~/install -DCMAKE_BUILD_TYPE=<<parameters.build_type>> -DFIZZY_TESTING=ON <<parameters.cmake_options>>
cmake ../project -G Ninja -DCMAKE_INSTALL_PREFIX=~/install -DCMAKE_BUILD_TYPE=<<parameters.build_type>> -DFIZZY_TESTING=ON -DFIZZY_WASI=ON <<parameters.cmake_options>>
- save_cache:
name: "Save Hunter cache"
key: *hunter-cache-key
Expand Down Expand Up @@ -143,7 +143,7 @@ commands:
name: "Collect coverage data"
working_directory: ~/build
command: |
binaries='-object bin/fizzy-unittests -object bin/fizzy-spectests -object bin/fizzy-bench -object bin/fizzy-testfloat'
binaries='-object bin/fizzy-unittests -object bin/fizzy-spectests -object bin/fizzy-bench -object bin/fizzy-testfloat -object bin/fizzy-wasi'

mkdir coverage
find -name '*.profraw'
Expand Down
52 changes: 52 additions & 0 deletions cmake/ProjectUVWASI.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
if(ProjectUVWASIIncluded)
return()
endif()
set(ProjectUVWASIIncluded TRUE)

include(ExternalProject)

set(prefix ${CMAKE_BINARY_DIR}/_deps)
set(source_dir ${prefix}/src/uvwasi)
set(binary_dir ${prefix}/src/uvwasi-build)
set(include_dir ${source_dir}/include)
set(uvwasi_library ${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}uvwasi_a${CMAKE_STATIC_LIBRARY_SUFFIX})
set(uv_library ${binary_dir}/_deps/libuv-build/${CMAKE_STATIC_LIBRARY_PREFIX}uv_a${CMAKE_STATIC_LIBRARY_SUFFIX})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this library built?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You added this line 😉

It is needed because uvwasi builds libuv but doesn't link it into the library (could upstream it). We don't want to build another libuv ourselves due to potential version incompatibility.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are static libraries, so you cannot link uv.a to uvwasi.a.

Answering my question: uvwasi downloads source code of uv using git and git tag, then builds it as a part of uvwasi CMake project.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both are static libraries, so you cannot link uv.a to uvwasi.a.

If you only consider "linking" as creating a shared library, yes. However .a is just an archive so one can certainly "link" aka merge two archives.


if(UNIX AND NOT APPLE)
set(system_libs "pthread;dl;rt")
endif()

ExternalProject_Add(uvwasi
EXCLUDE_FROM_ALL 1
PREFIX ${prefix}
DOWNLOAD_NAME uvwasi-0.0.10.tar.gz
DOWNLOAD_DIR ${prefix}/downloads
SOURCE_DIR ${source_dir}
BINARY_DIR ${binary_dir}
URL https://github.com/cjihrig/uvwasi/archive/v0.0.10.tar.gz
URL_HASH SHA256=39135f4dd4a44013399ceed7166391ffc5c09655e4bfbf851da2be039e6985df
CMAKE_ARGS
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DUVWASI_DEBUG_LOG=OFF
-DCODE_COVERAGE=OFF
-DASAN=OFF
-DUVWASI_BUILD_TESTS=OFF
BUILD_BYPRODUCTS ${uvwasi_library} ${uv_library}
)

add_library(uvwasi::uvwasi STATIC IMPORTED)

file(MAKE_DIRECTORY ${include_dir})

set_target_properties(
uvwasi::uvwasi
PROPERTIES
IMPORTED_CONFIGURATIONS Release
IMPORTED_LOCATION_RELEASE ${uvwasi_library}
INTERFACE_INCLUDE_DIRECTORIES "${include_dir};${binary_dir}"
INTERFACE_LINK_LIBRARIES "${uv_library};${system_libs}"
)

add_dependencies(uvwasi::uvwasi uvwasi)
2 changes: 1 addition & 1 deletion lgtm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ extraction:
configure:
command:
- cd $LGTM_SRC/_lgtm_build_dir
- cmake -DFIZZY_TESTING=ON -DCMAKE_BUILD_TYPE=Release ..
- cmake -DFIZZY_TESTING=ON -DFIZZY_WASI=ON -DCMAKE_BUILD_TYPE=Release ..
3 changes: 3 additions & 0 deletions test/smoketests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@

add_subdirectory(benchmarks)
add_subdirectory(spectests)
if(FIZZY_WASI)
add_subdirectory(wasi)
endif()
97 changes: 97 additions & 0 deletions test/smoketests/wasi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Fizzy: A fast WebAssembly interpreter
# Copyright 2020 The Fizzy Authors.
# SPDX-License-Identifier: Apache-2.0

add_test(
NAME fizzy/smoketests/wasi/cli-missing-arg
COMMAND fizzy-wasi
)
set_tests_properties(
fizzy/smoketests/wasi/cli-missing-arg
PROPERTIES
PASS_REGULAR_EXPRESSION "Missing executable argument"
)

add_test(
NAME fizzy/smoketests/wasi/cli-invalid-file
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}
)
set_tests_properties(
fizzy/smoketests/wasi/cli-invalid-file
PROPERTIES
PASS_REGULAR_EXPRESSION "File does not exists or is irregular:"
)

add_test(
NAME fizzy/smoketests/wasi/cli-missing-file
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/helloworld.nonexistent.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/cli-missing-file
PROPERTIES
PASS_REGULAR_EXPRESSION "File does not exists or is irregular:"
)

add_test(
NAME fizzy/smoketests/wasi/helloworld
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/helloworld.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/helloworld
PROPERTIES
PASS_REGULAR_EXPRESSION "hello world"
)

add_test(
NAME fizzy/smoketests/wasi/missing-start
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/missingstart.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/missing-start
PROPERTIES
PASS_REGULAR_EXPRESSION "File is not WASI compatible \\(_start not found\\)"
)

add_test(
NAME fizzy/smoketests/wasi/invalid-start
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/invalidstart.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/invalid-start
PROPERTIES
PASS_REGULAR_EXPRESSION "File is not WASI compatible \\(_start has invalid signature\\)"
)

add_test(
NAME fizzy/smoketests/wasi/missing-memory
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/missingmemory.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/missing-memory
PROPERTIES
PASS_REGULAR_EXPRESSION "File is not WASI compatible \\(no memory exported\\)"
)

add_test(
NAME fizzy/smoketests/wasi/trap
COMMAND fizzy-wasi ${CMAKE_CURRENT_LIST_DIR}/trap.wasm
)
set_tests_properties(
fizzy/smoketests/wasi/trap
PROPERTIES
PASS_REGULAR_EXPRESSION "Execution aborted with WebAssembly trap"
)

# Dump coverage data to distinct files (otherwise file will be overwritten).
set_tests_properties(
fizzy/smoketests/wasi/cli-missing-arg
fizzy/smoketests/wasi/cli-missing-file
fizzy/smoketests/wasi/cli-invalid-file
fizzy/smoketests/wasi/helloworld
fizzy/smoketests/wasi/missing-start
fizzy/smoketests/wasi/invalid-start
fizzy/smoketests/wasi/missing-memory
fizzy/smoketests/wasi/trap
PROPERTIES
ENVIRONMENT LLVM_PROFILE_FILE=${CMAKE_BINARY_DIR}/wasi-%p.profraw
)
Binary file added test/smoketests/wasi/helloworld.wasm
Binary file not shown.
Binary file added test/smoketests/wasi/invalidstart.wasm
Binary file not shown.
Binary file added test/smoketests/wasi/missingmemory.wasm
Binary file not shown.
Binary file added test/smoketests/wasi/missingstart.wasm
Binary file not shown.
Binary file added test/smoketests/wasi/trap.wasm
Binary file not shown.
20 changes: 20 additions & 0 deletions tools/wasi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Fizzy: A fast WebAssembly interpreter
# Copyright 2019-2020 The Fizzy Authors.
# SPDX-License-Identifier: Apache-2.0

include(ProjectUVWASI)

set(fizzy_include_dir ${PROJECT_SOURCE_DIR}/lib/fizzy)

add_executable(fizzy-wasi wasi.cpp)
target_compile_features(fizzy-wasi PRIVATE cxx_std_17)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed, as fizzy::fizzy has it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a copy of the cmake file from spectests, all of the tools have this line too. Should be removed then.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our CMake scripts are not perfect, but I still vote for removing the line.

target_link_libraries(fizzy-wasi PRIVATE fizzy::fizzy-internal uvwasi::uvwasi)
target_include_directories(fizzy-wasi PRIVATE ${fizzy_include_dir})

if(UNIX AND NOT APPLE)
# For libstdc++ up to version 8 (included) this is needed for proper <filesystem> support.
# Otherwise, the result program will crash on first use (no linker errors).
# For libstdc++ 9, this is not needed, but cause no harm.
# Clang compiler on linux may select libstdc++8 in some configurations.
target_link_libraries(fizzy-wasi PRIVATE stdc++fs)
endif()
Loading