WIP: WASI Support (#267)

* feat: Preliminary WASI with fib workload

* refactor: Clarify initialize globals

* chore: Update empty to WASI

* chore: cleanup fib test

* chore: cleanup build tooling

* chore: cleanup test Makefiles and some nits

* chore: Update LLVM and install WASI-SDK

* chore: Update build tools and specs

* docs: Update example module spec in README

* refactor: Clean up HTTP handling

* feat: Implement exit WASI call

* style: apply clang-format

* ci: rewrite compile sledge step

* build: Remove LLVM install shims

* build: Try manually adding libunwind

* build: Try adding libunwind-dev

* ci: break out aWsm compile step

* fix: Correct test build error

* fix: Correct error in WASI fd_write

* chore: Increase gocr http buffer size

* test: Correct image resize test

* chore: Remove zombie wasmception functions

* chore: Reduce dummy args to single arg

* chore: Add debugging makefile fivebyeight

* chore: Remove erronious PHONYs in tests Makefile

* ci: Disable gocr tests

* chore: Add wat Make rule to fibonacci test

* chore: fix apt package name

* chore: Enable clean of failed ck install

* chore: use LLVM 12

* test: Disable gocr tests

* chore: Enhance test makefile

* chore: Add CFILES as sledgert dep

* chore: Add NULL check for function table pointer

* chore: Add missing header

* chore: uncomment cleanup in imageresize test

* refactor: Remove unused linear memory functions

* build: Add bimodal debug makefile

* chore: Add linear memory debug logs

* refactor: Cleanup region initialization

* build: Correct PHONY in runtime Makefile

* chore: deb install script for outside of container

* refactor: Remove zombie extern.

* feat: WebAssembly traps

* refactor: Use C18 features

* chore: Remove git diff annotations

* fix: tweaks to run all sample apps with WASI

* test: convert shell script to Makefile

* build: clean generated ck Makefile

* chore: Use awsm branch with fixes

* chore: Revert name changes

* fix: Correct type issues

* refactor: Reverse additional name change

* refactor: Remove awsm compat shims

* chore: Remove libc association

* build: Better detect header file changes

* refactor: current_wasm_module_instance_trap

* test: reenable tests

* chore: Delete copied script

* build: Fix test workloads

* fix: Implement HTTP 500

* fix: Protect against overflow on comparison

* build: Replace test.sh with makefile

* refactor: blow away tmp directory conflicts

* refactor: centralize wasm in single submodule

* feat: libsledge and sledge ABI

* chore: move tests

* refactor: tests

* chore: update wasm_apps with new sample data

* doc: Initial ABI README

* feat: globals table

* docs: Merge aWsm ABI docs

* docs: libsledge ABI

* build: rename apps to keep consistent

* build: Disable wasm proposals

* build: Update wasm apps and fix typo

* test: test makefiles

* test: Additional test makefiles

* build: top-level build and install rules wo Docker

* docs: Add wasm lld comment

* build: top level makefile

* chore: merge debug flags

* fix: Correct out of bounds error

* feat: indirection to awsm ABI

* fix: Correct link hack with proper flag

* fix: gps typo

* chore: format nit

* ci: update makefile rules

* ci: check WASI_SDK_PATH

* fix: Adjust paths

* ci: fix make rule name

* refactor: Attempt to use generic vec

* refactor: Remove type-specific vec

* fix: Resolve assorted TODOs

* chore: fix clang format issue

* ci: Invalidate app cache on libsledge changes

* fix: Correct wasm trap check

* fix: free wasm globals

* docs: example of running top level tests via make

* chore: option to log unsupported wasi

* test: add preempt client generator for fib bimodal

* refactor: Allocate wasm memory with 4096 align

* fix: Handle build without runtime globals

* refactor: bypass runtime call for first global

* fix: Correct sandbox logging

* test: fix incorrect paths in test.mk

* refactor: remove wasm traps

* refactor: Revert additional traps and changes

* refactor: Remove additional traps

* refactor: Disable exit support

* fix: block preemption in memory allocation

* feat: wasm g0 write back

* build: cleanup applications Makefile

* chore: Reorder bash variables

* docs: Add comment explaining LOG_SANDBOX_STDERR

* fix: Remove tracking of nonpreemptive siglarms

* chore: Validate Linux, C, and POSIX requirements

* build: Dry up libsledge makefile

* refactor: Remove unused macros

* fix: Writeback global 0 on cooperative sched

* refactor: Fork WASI from aWsm uvwasi example

* build: remove awsm-wasi rules

* chore: clang-format 15

* ci: apt update

* chore: clang 13

* ci: use llvm script

* ci: Use LLVM 13

* refactor: Remove WASI indirection
master
Sean McBride 3 years ago committed by GitHub
parent 5d19891e63
commit 7cacac64c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -67,4 +67,4 @@ UseTab: ForIndentation
PenaltyBreakAssignment: 100
PenaltyBreakBeforeFirstCallParameter: 1000
PenaltyReturnTypeOnItsOwnLine: 0
PenaltyReturnTypeOnItsOwnLine: 0

@ -1,6 +1,12 @@
# top-most EditorConfig file
root = true
[.clang-format]
ignore = true
[*.yaml]
ignore = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf

@ -3,8 +3,9 @@ name: sledge
on: [push, pull_request]
env:
LLVM_VERSION: 8
WASMCEPTION_URL: https://github.com/gwsystems/wasmception/releases/download/v0.2.0/wasmception-linux-x86_64-0.2.0.tar.gz
LLVM_VERSION: 13
WASI_SDK_URL: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk-12.0-linux.tar.gz
WASI_SDK_PATH: /opt/wasi-sdk
LANG: C.UTF-8
LANGUAGE: C.UTF-8
LC_ALL: C.UTF-8
@ -14,13 +15,12 @@ jobs:
format:
runs-on: ubuntu-latest
steps:
- name: Apt Update
run: sudo apt-get update
- uses: actions/checkout@v2
- name: Install clang-format-11
run: |
sudo apt-get remove -y --no-install-recommends clang-format-10 && sudo apt-get install -y --no-install-recommends clang-format-11
- name: Update alternatives
- name: Install LLVM
run: |
sudo update-alternatives --remove-all clang-format && sudo update-alternatives --install /usr/bin/clang-format clang-format "/usr/bin/clang-format-11" 100
sudo ./install_llvm.sh $LLVM_VERSION
- name: Clang Format
run: ./format.sh -d
test:
@ -60,6 +60,11 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- --default-toolchain stable --component rustfmt --target wasm32-wasi -y
echo "/root/.cargo/bin:$PATH" >> $GITHUB_PATH
- name: Get wasi-sdk
run: |
wget $WASI_SDK_URL -O wasi-sdk.tar.gz
mkdir -p $WASI_SDK_PATH
tar xvfz wasi-sdk.tar.gz --strip-components=1 -C $WASI_SDK_PATH
- name: Install Test Script Utilities
run: |
sudo apt-get install -y --no-install-recommends \
@ -79,30 +84,26 @@ jobs:
~/.cargo/git
./awsm/target
key: ${{ runner.os }}-cargo-${{ hashFiles('./awsm/Cargo.lock') }}
- name: Compile sledge
run: |
make build
make rtinit
mkdir bin
mkdir lib
SYS_PREFIX="$(pwd)" ./install.sh
PATH="$(pwd)/bin:$PATH"
echo "$PATH" >> $GITHUB_PATH
LD_LIBRARY_PATH="$(pwd)/lib:$LD_LIBRARY_PATH"
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> $GITHUB_ENV
make build-validate
- name: Compile aWsm
run: |
make awsm
- name: Compile libsledge
run: |
make libsledge
- name: Compile SLEdge
run: |
make runtime
# TODO:Cache assets before being copied to ./runtime/bin
- name: Cache gocr
uses: actions/cache@v2
with:
path: ./runtime/bin/gocr.wasm.so
key: ${{ runner.os }}-gocr2-${{ hashFiles('./applications/Makefile', './applications/wasmception_apps/gocr/**', './runtime/compiletime/**') }}
key: ${{ runner.os }}-gocr2-${{ hashFiles('./applications/Makefile', './applications/wasm_apps/gocr/**', './libsledge/Makefile' , './libsledge/src/**', './libsledge/include/**') }}
if: success() || failure()
- name: Hyde
run: |
echo $WASI_SDK_PATH
ls $WASI_SDK_PATH
make -f test.mk gocr__hyde
if: success() || failure()
- name: Upload Hyde Logs on Failure
@ -136,7 +137,7 @@ jobs:
uses: actions/cache@v2
with:
path: ./runtime/bin/gps_ekf.wasm.so
key: ${{ runner.os }}-gocr2-${{ hashFiles('./applications/Makefile', './applications/wasmception_apps/TinyEKF/**', './runtime/compiletime/**') }}
key: ${{ runner.os }}-gocr2-${{ hashFiles('./applications/Makefile', './applications/wasm_apps/TinyEKF/**', './libsledge/Makefile' , './libsledge/src/**', './libsledge/include/**') }}
if: success() || failure()
- name: EKF one iteration
run: |

25
.gitmodules vendored

@ -2,6 +2,7 @@
path = awsm
url = https://github.com/gwsystems/aWsm
ignore = dirty
branch = sledge-compat
[submodule "http-parser"]
path = runtime/thirdparty/http-parser
url = https://github.com/gwsystems/http-parser.git
@ -11,23 +12,7 @@ url = https://github.com/gwsystems/ck.git
[submodule "jsmn"]
path = runtime/thirdparty/jsmn
url = https://github.com/gwsystems/jsmn.git
[submodule "runtime/tests/gocr"]
path = applications/wasmception_apps/gocr
url = https://github.com/gwsystems/gocr.git
branch = sledge
[submodule "runtime/tests/TinyEKF"]
path = applications/wasmception_apps/TinyEKF
url = https://github.com/gwsystems/TinyEKF.git
branch = sledge
[submodule "runtime/tests/CMSIS_5_NN"]
path = applications/wasmception_apps/CMSIS_5_NN
url = https://github.com/gwsystems/CMSIS_5_NN.git
branch = sledge
[submodule "runtime/tests/sod"]
path = applications/wasmception_apps/sod
url = https://github.com/gwsystems/sod.git
branch = sledge
[submodule "runtime/tests/speechtotext"]
path = applications/wasmception_apps/speechtotext
url = https://github.com/gwsystems/speechtotext.git
branch = sledge
[submodule "wasm_apps"]
path = applications/wasm_apps
url = https://github.com/gwsystems/wasm_apps.git
branch = master

@ -9,6 +9,7 @@
"${workspaceFolder}/runtime/thirdparty/ck/include/",
"${workspaceFolder}/runtime/thirdparty/http-parser/",
"${workspaceFolder}/runtime/thirdparty/jsmn/",
"${workspaceFolder}/awsm/runtime/libc/wasi/include/",
"${workspaceFolder}/libsledge/include"
],
"defines": [

@ -81,7 +81,6 @@
"sandbox_set_as_complete.h": "c",
"deque.h": "c",
"sandbox_send_response.h": "c",
"sandbox_setup_arguments.h": "c",
"worker_thread.h": "c",
"sandbox_set_as_error.h": "c",
"likely.h": "c",
@ -90,6 +89,9 @@
"sandbox_set_as_running.h": "c",
"sandbox_summarize_page_allocations.h": "c",
"wasm_types.h": "c",
"wasi_impl.h": "c",
"wasi_backing.h": "c",
"wasi_serdes.h": "c",
"atomic": "c",
"sandbox_set_as_running_kernel.h": "c",
"stdbool.h": "c",
@ -104,7 +106,10 @@
"wasm_module_instance.h": "c",
"wasm_stack.h": "c",
"wasm_table.h": "c",
"sledge_abi.h": "c"
"wasi_spec.h": "c",
"current_wasm_module_instance.h": "c",
"wasm_memory.h": "c",
"sledge_abi.h": "c",
},
"files.exclude": {
"**/.git": true,
@ -127,10 +132,12 @@
],
"shellformat.path": "/usr/local/bin/shfmt",
"shellformat.flag": "-ln=bash -i 0 -bn -ci -sr -kp",
"terminal.integrated.shell.linux": "bash",
"[jsonc]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[yaml]": {
"editor.formatOnSave": false,
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
@ -156,5 +163,12 @@
"*.o": true,
"*.bc": true,
"*.wasm": true,
}
},
"C_Cpp.formatting": "clangFormat",
"cSpell.words": [
"gregs",
"mctx",
"TKILL",
"WASI"
]
}

@ -50,4 +50,6 @@ RUN rustup target add wasm32-wasi
RUN cargo install --debug cargo-audit cargo-watch rsign2
ENV PATH=/opt/sledge/bin:$PATH
ENV PATH=/sledge/runtime/bin:$PATH
ENV PATH=/sledge/awsm/target/release:$PATH
ENV LD_LIBRARY_PATH=/sledge/runtime/bin:$LD_LIBRARY_PATH

@ -3,7 +3,7 @@ FROM ubuntu:focal
ARG DEBIAN_FRONTEND=noninteractive
ARG HEY_URL=https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
ARG WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-8/wasi-sdk_8.0_amd64.deb
ARG WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk_12.0_amd64.deb
ARG SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.2.4/shfmt_v3.2.4_linux_amd64
ARG SHELLCHECK_URL=https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz
@ -74,14 +74,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
vim \
wabt
ENV LLVM_VERSION=8
ENV LLVM_VERSION=12
ADD install_llvm.sh /sledge/install_llvm.sh
RUN ./sledge/install_llvm.sh $LLVM_VERSION
# WASI-SDK
# TODO: Refactor to output as an arch-neutral filename
# RUN curl -sS -L -O $WASI_SDK_URL && dpkg -i wasi-sdk_8.0_amd64.deb && rm -f wasi-sdk_8.0_amd64.deb
# ENV WASI_SDK=/opt/wasi-sdk
RUN curl -sS -L -O $WASI_SDK_URL && dpkg -i wasi-sdk_12.0_amd64.deb && rm -f wasi-sdk_12.0_amd64.deb
ENV WASI_SDK=/opt/wasi-sdk
# Create non-root user and add to sudoers
ARG USERNAME=dev
@ -100,8 +99,6 @@ USER $USER_UID
RUN sudo chown $USER_GID:$USER_GID /sledge
ADD fix_root.sh /sledge/fix_root.sh
RUN cd sledge && ./fix_root.sh
RUN sudo mkdir /opt/sledge
RUN sudo chown $USER_GID:$USER_GID /opt/sledge
################################
# Final Setup as non-root user #
@ -119,8 +116,6 @@ ENV LANGUAGE C.UTF-8
ENV LC_ALL C.UTF-8
# Update PATH and LD_LIBRARY_PATH
ENV PATH=/opt/sledge/bin:$PATH
# TODO: Does the build process for the sample applications actually copy here?
# TODO: Should we create a special SLEDGE_MODULE_PATH that is searched for these modules?
ENV LD_LIBRARY_PATH=/opt/sledge/bin:$LD_LIBRARY_PATH
ENV PATH=/sledge/runtime/bin:$PATH
ENV PATH=/sledge/awsm/target/release:$PATH
ENV LD_LIBRARY_PATH=/sledge/runtime/bin:$LD_LIBRARY_PATH

@ -1,57 +1,56 @@
SHELL:=/bin/bash
ARCH:=$(shell arch)
COMPILER=awsm
ROOT=${ROOT:-$(cd "$(dirname ${BASH_SOURCE:-$0})" && pwd)}
WASMCEPTION_URL=https://github.com/gwsystems/wasmception/releases/download/v0.2.0/wasmception-linux-x86_64-0.2.0.tar.gz
# TODO: Add ARM release build
.PHONY: build
build:
ifeq ($(ARCH),x86_64)
cd ./awsm/wasmception && wget ${WASMCEPTION_URL} -O wasmception.tar.gz && tar xvfz wasmception.tar.gz && rm wasmception.tar.gz
endif
test -f ./${COMPILER}/wasmception/dist/bin/clang || make -C ${COMPILER}/wasmception
@cd ${COMPILER} && RUSTUP_TOOLCHAIN=stable cargo build --release && cd ${ROOT}
# Sanity check that the aWsm compiler built and is in our PATH
.PHONY: build-validate
build-validate:
which awsm
awsm --version
.PHONY: build-dev
build-dev:
test -f ./${COMPILER}/wasmception/dist/bin/clang || make -C ${COMPILER}/wasmception
@echo "Building aWsm compiler (default==debug)"
@cd ${COMPILER} && cargo build && cd ${ROOT}
.PHONY: all
all: awsm libsledge runtime
.PHONY: clean
clean:
@echo "Cleaning aWsm compiler"
@cd ${COMPILER} && cargo clean && cd ${ROOT}
# wasmception is too slow to recompile,
# so lets not make that part of the "aWsm" cleanup
.PHONY: wclean
wclean:
@echo "Cleaning wasmception toolchain"
@cd ${COMPILER} && make -C wasmception clean && cd ${ROOT}
.PHONY: rtinit
rtinit:
@echo "Building runtime for the first time!"
make -C runtime init
clean: awsm.clean libsledge.clean runtime.clean
.PHONY: runtime
runtime:
@echo "Building runtime!"
make -C runtime
.PHONY: submodules
submodules:
git submodule update --init --recursive
.PHONY: install
install: build rtinit
@./install.sh wasmception
install: submodules all
# aWsm: the WebAssembly to LLVM bitcode compiler
.PHONY: awsm
awsm:
cd awsm && cargo build --release
.PHONY: awsm.clean
awsm.clean:
cd awsm && cargo clean
# libsledge: the support library linked with LLVM bitcode emitted by aWsm when building *.so modules
.PHONY: libsledge
libsledge:
make -C libsledge clean all
make -C libsledge dist/libsledge.a
.PHONY: libsledge.clean
libsledge.clean:
make -C libsledge clean
# sledgert: the runtime that executes *.so modules
.PHONY: runtime
runtime:
make -C runtime
.PHONY: runtime.clean
runtime.clean:
make -C runtime clean
# SLEdge Applications
.PHONY: applications
applications:
make -C applications all
.PHONY: applications.clean
applications.clean:
make -C applications clean
# Tests
.PHONY: test
test:
make -f test.mk all

@ -8,6 +8,17 @@
## Setting up the environment
You may either build the application natively on your host or in a Docker environment.
### Native on Debian Host
1. Run `install_deb.sh` to install host dependencies
2. Run `make install` to clone submodules and build all components
3. Run `make applications` to build all sample WebAssembly apps for execution on SLEdge
4. Run `make test` to execute end-to-end tests running WebAssembly apps on SLEdge.
### Docker
**Note: These steps require Docker. Make sure you've got it installed!**
We provide a Docker build environment configured with the dependencies and toolchain needed to build the SLEdge runtime and serverless functions.
@ -18,7 +29,7 @@ To setup this environment, run:
./devenv.sh setup
```
## Using the Docker container to compile your serverless functions
### Using the Docker container to compile your serverless functions
To enter the docker environment, run:
@ -54,6 +65,16 @@ To stop the Docker container:
./devenv.sh stop
```
### Deleting Docker Build Containers
If you are finished working with the SLEdge runtime and wish to remove it, run the following command to delete our Docker build and runtime images.
```bash
./devenv.sh rma
```
And then simply delete this repository.
## Running your first serverless function
An SLEdge serverless function consists of a shared library (\*.so) and a JSON configuration file that determines how the runtime should execute the serverless function. As an example, here is the configuration file for our sample fibonacci function:
@ -115,18 +136,10 @@ When done, terminal the SLEdge runtime with `Ctrl+c`
## Running Test Workloads
Various synthetic and real-world tests can be found in `runtime/experiments`. Generally, each experiment can be run be executing the `run.sh` script.
## Removing the SLEdge Runtime
If you are finished working with the SLEdge runtime and wish to remove it, run the following command to delete our Docker build and runtime images.
```bash
./devenv.sh rma
```
Various synthetic and real-world tests can be found in `runtime/tests`. Generally, each experiment can be run by Make rules in the top level `test.mk`.
And then simply delete this repository.
`make -f test.mk all`
## Problems or Feedback?
If you encountered bugs or have feedback, please let us know in our [issue tracker.](https://github.com/phanikishoreg/awsm-Serverless-Framework/issues)
If you encountered bugs or have feedback, please let us know in our [issue tracker.](https://github.com/gwsystems/sledge-serverless-framework/issues)

@ -1,3 +1 @@
*.wasm
*.bc
*.so
dist/*

@ -1,5 +1,5 @@
AWSMCC=../awsm/target/release/awsm
CC=clang-8
CC=clang
# Used by aWsm when compiling the *.wasm to *.bc
AWSMFLAGS= --inline-constant-globals --runtime-globals
@ -8,34 +8,30 @@ AWSMFLAGS= --inline-constant-globals --runtime-globals
# --whole-archive causes the symbols in the listed static archive to be exported from the resulting *.so
# https://stackoverflow.com/questions/805555/ld-linker-question-the-whole-archive-option
CFLAGS=-O3 -flto
LDFLAGS=-shared -fPIC -Wl,--export-dynamic,--whole-archive -L../libsledge/dist/ -lsledge -Wl,--no-whole-archive -lm
LDFLAGS=-shared -fPIC -Wl,--export-dynamic,--whole-archive -L../libsledge/dist/ -lsledge -Wl,--no-whole-archive
# LDFLAGS=-flto -fvisibility=hidden
dist:
mkdir dist
.PHONY: all
all: \
cifar10.install \
empty.install \
gps_ekf.install \
fibonacci.install \
gocr.install \
gps_ekf.install \
license_plate_detection.install \
resize_image.install
.PHONY: clean
clean:
@make clean -C ./wasmception_apps/fibonacci
@make clean -C ./wasmception_apps/empty
@make clean -C ./wasmception_apps/TinyEKF/extras/c/ -f wasm.mk
@make clean -C ./wasmception_apps/CMSIS_5_NN/ -f Makefile
@make clean -C ./wasmception_apps/gocr/src/ -f wasm.mk
@make clean -C ./wasmception_apps/sod/
@rm -f *.wasm
@make -C wasm_apps clean
@rm -rf dist
@rm -f ../runtime/bin/*.so
@rm -rf ../runtime/bin/*.so
dist:
mkdir -p dist
wasm_apps/dist/%.wasm:
make -C wasm_apps $(addprefix dist/,$(notdir $@))
../libsledge/dist/:
mkdir ../libsledge/dist
@ -43,82 +39,40 @@ dist:
../libsledge/dist/libsledge.a: ../libsledge/dist/
make -C .. libsledge
%.bc: %.wasm dist
dist/%.bc: ./wasm_apps/dist/%.wasm dist
${AWSMCC} ${AWSMFLAGS} $< -o $@
%.wasm.so: %.bc
mkdir -p dist
dist/%.ll: dist/%.bc
llvm-dis-12 $< -o $@
dist/%.wasm.so: dist/%.bc
${CC} ${CFLAGS} ${LDFLAGS} $^ -o $@
../runtime/bin/%.wasm.so: dist/%.wasm.so
cp $^ $@
# Fibonacci
./wasmception_apps/fibonacci/fibonacci.wasm:
@make fibonacci.wasm -C ./wasmception_apps/fibonacci
dist/fibonacci.wasm: ./wasmception_apps/fibonacci/fibonacci.wasm dist
@cp ./wasmception_apps/fibonacci/fibonacci.wasm dist/fibonacci.wasm
.PHONY: fibonacci.install
fibonacci.install: ../runtime/bin/fibonacci.wasm.so
# Empty
./wasmception_apps/empty/empty.wasm:
@make empty.wasm -C ./wasmception_apps/empty
.PHONY: cifar10.install
cifar10.install: ../runtime/bin/cifar10.wasm.so
dist/empty.wasm: ./wasmception_apps/empty/empty.wasm dist
@cp ./wasmception_apps/empty/empty.wasm dist/empty.wasm
# Echo?
.PHONY: empty.install
empty.install: ../runtime/bin/empty.wasm.so
# EKF
./wasmception_apps/TinyEKF/extras/c/gps_ekf_fn.wasm:
@make gps_ekf_fn.wasm -C ./wasmception_apps/TinyEKF/extras/c/ -f wasm.mk
dist/gps_ekf.wasm: ./wasmception_apps/TinyEKF/extras/c/gps_ekf_fn.wasm dist
@cp ./wasmception_apps/TinyEKF/extras/c/gps_ekf_fn.wasm dist/gps_ekf.wasm
.PHONY: gps_ekf.install
gps_ekf.install: ../runtime/bin/gps_ekf.wasm.so
# CIFAR10
./wasmception_apps/CMSIS_5_NN/cifar10.wasm:
@make cifar10.wasm -C ./wasmception_apps/CMSIS_5_NN/ -f Makefile
.PHONY: exit.install
exit.install: ../runtime/bin/exit.wasm.so
dist/cifar10.wasm: ./wasmception_apps/CMSIS_5_NN/cifar10.wasm dist
@cp ./wasmception_apps/CMSIS_5_NN/cifar10.wasm dist/cifar10.wasm
.PHONY: cifar10.install
cifar10.install: ../runtime/bin/cifar10.wasm.so
# GOCR
./wasmception_apps/gocr/src/gocr.wasm:
@make gocr.wasm -C ./wasmception_apps/gocr/src/ -f wasm.mk
dist/gocr.wasm: ./wasmception_apps/gocr/src/gocr.wasm dist
@cp ./wasmception_apps/gocr/src/gocr.wasm dist/gocr.wasm
.PHONY: fibonacci.install
fibonacci.install: ../runtime/bin/fibonacci.wasm.so
.PHONY: gocr.install
gocr.install: ../runtime/bin/gocr.wasm.so
# LPD
./wasmception_apps/sod/bin/license_plate_detection.wasm:
@make dir license_plate_detection.wasm -C ./wasmception_apps/sod/
.PHONY: resize_image.install
resize_image.install: ../runtime/bin/resize_image.wasm.so
dist/license_plate_detection.wasm: ./wasmception_apps/sod/bin/license_plate_detection.wasm dist
@cp ./wasmception_apps/sod/bin/license_plate_detection.wasm dist/license_plate_detection.wasm
.PHONY: gps_ekf.install
gps_ekf.install: ../runtime/bin/gps_ekf.wasm.so
.PHONY: license_plate_detection.install
license_plate_detection.install: ../runtime/bin/license_plate_detection.wasm.so
# Resize
./wasmception_apps/sod/bin/resize_image.wasm:
@make dir resize_image.wasm -C ./wasmception_apps/sod/
dist/resize_image.wasm: ./wasmception_apps/sod/bin/resize_image.wasm dist
@cp ./wasmception_apps/sod/bin/resize_image.wasm dist/resize_image.wasm
.PHONY: resize_image.install
resize_image.install: ../runtime/bin/resize_image.wasm.so

@ -0,0 +1 @@
Subproject commit 1125852cf199a53bf194f53da880aca97b64c124

@ -1 +0,0 @@
Subproject commit 9e01b5a5914d3456c3018b3265d74a01656d10bd

@ -1 +0,0 @@
Subproject commit 8c2654d622e39b0eee84a3fd00174c2cfb5996ee

@ -1,12 +0,0 @@
WASMCC=wasm32-unknown-unknown-wasm-clang
OPTFLAGS=-O3 -flto
WASMLINKFLAGS=-Wl,-z,stack-size=524288,--allow-undefined,--no-threads,--stack-first,--no-entry,--export-all,--export=main,--export=dummy
WASMCFLAGS=${WASMLINKFLAGS} -nostartfiles
all: empty.wasm
clean:
rm -rf empty.wasm
empty.wasm: *.c
${WASMCC} ${WASMCFLAGS} ${OPTFLAGS} $^ -o $@

@ -1,11 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int
main(int argc, char **argv)
{
printf("S\n");
return 0;
}

@ -1,15 +0,0 @@
// !!! HACK ALERT !!!
// We need the __init_libc symbol in the output executable (so the runtime can initialize libc)
// We can't directly export it since it's in a linked library
// Thus we export a dummy function that uses it, forcing it to be included
#define IMPORT __attribute__((visibility("default")))
#define EXPORT __attribute__((visibility("default")))
IMPORT void __init_libc(char **, char *);
EXPORT void
dummy()
{
__init_libc(0, 0);
}

@ -1,12 +0,0 @@
WASMCC=wasm32-unknown-unknown-wasm-clang
OPTFLAGS=-O3 -flto
WASMLINKFLAGS=-Wl,-z,stack-size=524288,--allow-undefined,--no-threads,--stack-first,--no-entry,--export=main,--export=dummy,--export=__init_libc
WASMCFLAGS=${WASMLINKFLAGS} -nostartfiles
all: fibonacci.wasm
clean:
rm -rf fibonacci.wasm
fibonacci.wasm: *.c
${WASMCC} ${WASMCFLAGS} ${OPTFLAGS} $^ -o $@

@ -1,20 +0,0 @@
#include <stdio.h>
#include <stdint.h>
uint32_t
fib(uint32_t n)
{
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int
main(int argc, char **argv)
{
uint32_t n = 0;
scanf("%u", &n);
uint32_t result = fib(n);
printf("%u\n", result);
return 0;
}

@ -1,15 +0,0 @@
// !!! HACK ALERT !!!
// We need the __init_libc symbol in the output executable (so the runtime can initialize libc)
// We can't directly export it since it's in a linked library
// Thus we export a dummy function that uses it, forcing it to be included
#define IMPORT __attribute__((visibility("default")))
#define EXPORT __attribute__((visibility("default")))
IMPORT void __init_libc(char **, char *);
EXPORT void
dummy()
{
__init_libc(0, 0);
}

@ -1 +0,0 @@
Subproject commit 0976fd036462264f581a588fa6cfa46718c67716

@ -1 +0,0 @@
Subproject commit 3bdd8c58c7f9159dd88ec56e5beefccdd503ad9e

@ -1 +0,0 @@
Subproject commit 0ef276b96503c40bedae5e85453d28e738743f93

@ -1,7 +1,7 @@
#!/bin/bash
validate() {
utility="clang-format"
utility="clang-format-13"
utility_version="$("$utility" --version 2> /dev/null)" || {
echo "$utility not found in path!"
exit 1
@ -11,7 +11,7 @@ validate() {
declare -i major=0
declare -i minor=0
declare -i patch=0
declare -i required_major=11
declare -i required_major=13
declare -i required_minor=0
declare -i required_patch=0
@ -51,8 +51,8 @@ dry_run() {
format() {
find runtime \
\( -path "runtime/thirdparty" -o -path "applications/gocr" -o -path "applications/TinyEKF" -o -path "applications/CMSIS_5_NN" -o -path "applications/sod" -o -path "applications/**/thirdparty" \) -prune -false -o \
-type f \( -iname \*.h -o -iname \*.c -o -iname \*.s \) -print \
| xargs clang-format -i
-type f \( -iname \*.h -o -iname \*.c -o -iname \*.s \) -print0 \
| xargs --null clang-format -i
}
case $1 in

@ -1,147 +0,0 @@
#!/bin/bash
# This script is responsible for copying, linking, and aliasing all of our build tools such that they are
# in known paths that we can add to PATH and LD_LIBRARY_PATH. The binaries go into "${SYS_PREFIX}/bin" and
# the libraries go into "${SYS_PREFIX}/lib". By default, SYS_PREFIX is `/opt/sledge/`, which means that this
# script is assumed to be executed as root, as in our Docker build container. However, by by setting
# SYS_PREFIX to a directory that the user has access to, this can be avoided.
#
# For example, in the GitHub Actions workflow, SYS_PREFIX is set to the topmost project directory and the
# environment is updated as follows.
#
# SYS_PREFIX="$(pwd)" ./install.sh
# PATH="$(pwd)/bin:$PATH"
# LD_LIBRARY_PATH="$(pwd)/lib:$LD_LIBRARY_PATH"
#
# This is currently executed
# - Indirectly via `make install` in the root Makefile, typically when the sledge-dev build container is built
# - Directly by the GitHub workflow
#
# The script takes either wasmception or wasi as the first argument to install either wasmception or WASI-SDK
# If no argument is provided, wasmception is assumed
# If either wasmception or wasi is provided, an additional `-d` or `--dry-run` flag can be provided to view the commands
# and paths that would be generated. This is helpful for sanity checking when setting SYS_PREFIX and using in a new context
echo "Setting up toolchain environment"
for last_arg in "$@"; do :; done
if [[ $last_arg == "-d" ]] || [[ $last_arg == "--dry-run" ]]; then
DRY_RUN=true
else
DRY_RUN=false
fi
if $DRY_RUN; then
DRY_RUN_PREFIX=echo
else
DRY_RUN_PREFIX=
fi
# Get the absolute path of the topmost project directly
# The use of dirname is particular. It seems unneccesary how this script is run
SYS_SRC_PREFIX=${SYS_SRC_PREFIX:-"$(
cd "$(dirname "$(dirname "${0}")")" || exit 1
pwd -P
)"}
$DRY_RUN && echo SYS_SRC_PREFIX: "$SYS_SRC_PREFIX"
# And check for the presence of this script to make sure we got it right
if [ ! -x "${SYS_SRC_PREFIX}/install.sh" ]; then
echo "Unable to find the install script" >&2
exit 1
fi
SYS_NAME='sledge'
COMPILER='awsm'
COMPILER_EXECUTABLE=$COMPILER
# /opt/sledge
SYS_PREFIX=${SYS_PREFIX:-"/opt/${SYS_NAME}"}
$DRY_RUN && echo SYS_PREFIX: "$SYS_PREFIX"
# /sledge, where the sledge repo is mounted from the host
SYS_SRC_PREFIX=${SYS_SRC_PREFIX:-"/${SYS_NAME}"}
$DRY_RUN && echo SYS_SRC_PREFIX: "$SYS_SRC_PREFIX"
# The release directory containing the binary of the aWsm compiler
SYS_COMPILER_REL_DIR=${SYS_COMPILER_REL_DIR:-"${SYS_SRC_PREFIX}/${COMPILER}/target/release"}
$DRY_RUN && echo SYS_COMPILER_REL_DIR: "$SYS_COMPILER_REL_DIR"
# /opt/sledge/bin
SYS_BIN_DIR=${SYS_BIN_DIR:-"${SYS_PREFIX}/bin"}
$DRY_RUN && echo SYS_BIN_DIR: "$SYS_BIN_DIR"
# /opt/sledge/lib
SYS_LIB_DIR=${SYS_LIB_DIR:-"${SYS_PREFIX}/lib"}
$DRY_RUN && echo SYS_LIB_DIR: "$SYS_LIB_DIR"
# The first argument can be either wasi or wasmception. This determines the system interface used
# The default is wasmception
# Currently, WASI is not actually supported by the runtime.
if [ $# -eq 0 ] || [ "$1" = "wasmception" ]; then
echo "Setting up for wasmception"
WASM_PREFIX=${WASM_PREFIX:-"${SYS_SRC_PREFIX}/${COMPILER}/wasmception"}
WASM_BIN=${WASM_BIN:-"${WASM_PREFIX}/dist/bin"}
WASM_SYSROOT=${WASM_SYSROOT:-"${WASM_PREFIX}/sysroot"}
WASM_TARGET=${WASM_TARGET:-"wasm32-unknown-unknown-wasm"}
WASM_BIN_PREFIX=${WASM_BIN_PREFIX:-"$WASM_TARGET"}
WASM_TOOLS=(ar)
elif [ "$1" = "wasi" ]; then
echo "Setting up for wasi-sdk"
WASM_PREFIX=${WASM_PREFIX:-${WASM_SDK:-"/opt/wasi-sdk"}}
WASM_BIN=${WASM_BIN:-"${WASM_PREFIX}/bin"}
WASM_SYSROOT=${WASM_SYSROOT:-"${WASM_PREFIX}/share/sysroot"}
WASM_TARGET=${WASM_TARGET:-"wasm32-wasi"}
WASM_BIN_PREFIX=${WASM_BIN_PREFIX:-"$WASM_TARGET"}
WASM_TOOLS=(ar dwarfdump nm ranlib size)
fi
$DRY_RUN && echo WASM_PREFIX: "$WASM_PREFIX"
$DRY_RUN && echo WASM_BIN: "$WASM_BIN"
$DRY_RUN && echo WASM_SYSROOT: "$WASM_SYSROOT"
$DRY_RUN && echo WASM_TARGET: "$WASM_TARGET"
$DRY_RUN && echo WASM_BIN_PREFIX: "$WASM_BIN_PREFIX"
$DRY_RUN && echo WASM_TOOLS: "${WASM_TOOLS[@]}"
# Delete all existing installations of the binaries
$DRY_RUN_PREFIX rm -f "${SYS_BIN_DIR}"/*
# And reinstall
$DRY_RUN_PREFIX install -d -v "$SYS_BIN_DIR" || exit 1
# Symbolically link the Awsm compiler
# /sledge/awsm/target/release/silverfish /opt/sledge/bin/awsm
$DRY_RUN_PREFIX ln -sfv "${SYS_COMPILER_REL_DIR}/${COMPILER_EXECUTABLE}" "${SYS_BIN_DIR}/${COMPILER_EXECUTABLE}"
# Generate shell script stubs that act as aliases that automatically set the approproiate target and sysroot
# for either Wasmception or WASI-SDK
# For example, when wasmception is set, calling `wasm32-unknown-unknown-wasm-clang` results in
# `exec "/sledge/awsm/wasmception/dist/bin/clang" --target="wasm32-unknown-unknown-wasm" --sysroot="/sledge/awsm/wasmception/sysroot" "$@"`
for file in clang clang++; do
wrapper_file="$(mktemp)"
cat > "$wrapper_file" << EOT
#! /bin/sh
exec "${WASM_BIN}/${file}" --target="$WASM_TARGET" --sysroot="$WASM_SYSROOT" "\$@"
EOT
cat "$wrapper_file"
$DRY_RUN_PREFIX install -p -v "$wrapper_file" "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-${file}"
$DRY_RUN && echo rm -f "$wrapper_file"
rm -f "$wrapper_file"
done
# Link the LLVM Tools with the proper prefix
for file in "${WASM_TOOLS[@]}"; do
$DRY_RUN_PREFIX ln -sfv "${WASM_BIN}/llvm-${file}" "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-${file}"
done
# Link any other tools with the proper prefix
OTHER_TOOLS=(ld)
for file in "${OTHER_TOOLS[@]}"; do
$DRY_RUN_PREFIX ln -sfv "${WASM_BIN}/wasm-${file}" "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-${file}"
done
# Link clang as gcc if needed
$DRY_RUN_PREFIX ln -svf "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-clang" "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-gcc"
$DRY_RUN_PREFIX ln -svf "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-clang++" "${SYS_BIN_DIR}/${WASM_BIN_PREFIX}-g++"
echo "Done!"

@ -0,0 +1,33 @@
#!/bin/bash
HEY_URL=https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
LLVM_VERSION=12
SHELLCHECK_URL=https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz
SHFMT_URL=https://github.com/mvdan/sh/releases/download/v3.2.4/shfmt_v3.2.4_linux_amd64
WASI_SDK_URL=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-12/wasi-sdk_12.0_amd64.deb
apt-get update && apt-get install -y --no-install-recommends \
bc \
fonts-dejavu \
fonts-cascadia-code \
fonts-roboto \
gnuplot \
imagemagick \
jq \
libz3-4 \
netpbm \
pango1.0-tools \
wamerican
wget $HEY_URL -O hey && chmod +x hey && sudo mv hey /usr/bin/hey
wget $SHFMT_URL -O shfmt && chmod +x shfmt && sudo mv shfmt /usr/local/bin/shfmt
wget $SHELLCHECK_URL -O shellcheck && chmod +x shellcheck && sudo mv shellcheck /usr/local/bin/shellcheck
./install_llvm.sh $LLVM_VERSION
curl -sS -L -O $WASI_SDK_URL && dpkg -i wasi-sdk_12.0_amd64.deb && rm -f wasi-sdk_12.0_amd64.deb
echo "Add WASI_SDK_PATH to your bashrc and resource!"
echo "Example: export WASI_SDK_PATH=/opt/wasi-sdk"

@ -1,39 +1,34 @@
#!/bin/bash
# Installs LLVM tooling, delegating the to the LLVM script as much as possible
# We need to shim support for LLVM 8 because the LLVM script only supports 9-12
LLVM_VERSION=$1
echo "Installing LLVM $LLVM_VERSION"
# Script Installs clang, lldb, lld, and clangd
if [[ "$LLVM_VERSION" -gt 8 ]]; then
curl --proto '=https' --tlsv1.2 -sSf https://apt.llvm.org/llvm.sh | bash -s -- "$LLVM_VERSION"
else
apt-get install -y --no-install-recommends \
"clang-$LLVM_VERSION" \
"lldb-$LLVM_VERSION" \
"lld-$LLVM_VERSION" \
"clangd-$LLVM_VERSION"
fi
curl --proto '=https' --tlsv1.2 -sSf https://apt.llvm.org/llvm.sh | bash -s -- "$LLVM_VERSION"
apt-get install -y --no-install-recommends \
"libc++-$LLVM_VERSION-dev" \
"libc++abi-$LLVM_VERSION-dev" \
"libc++1-$LLVM_VERSION"
"libc++1-$LLVM_VERSION" \
"libunwind-$LLVM_VERSION" \
"libunwind-$LLVM_VERSION-dev" \
"clang-tools-$LLVM_VERSION" \
"clang-tidy-$LLVM_VERSION" \
"clang-format-$LLVM_VERSION"
sudo update-alternatives --remove-all clang-format
sudo update-alternatives --remove-all clang
sudo update-alternatives --remove-all clang++
sudo update-alternatives --remove-all llvm-config
sudo update-alternatives --remove-all llvm-objdump
sudo update-alternatives --remove-all llvm-objdump
sudo update-alternatives --remove-all clang-tidy
update-alternatives --install /usr/bin/clang-format clang-format "/usr/bin/clang-format-$LLVM_VERSION" 100
update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-$LLVM_VERSION" 100
update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-$LLVM_VERSION" 100
update-alternatives --install /usr/bin/llvm-config llvm-config "/usr/bin/llvm-config-$LLVM_VERSION" 100
update-alternatives --install /usr/bin/llvm-objdump llvm-objdump "/usr/bin/llvm-objdump-$LLVM_VERSION" 100
# Explicitly use at least clang-format-11 to format source because of changes between 10 and 11
if [[ "$LLVM_VERSION" -ge 11 ]]; then
apt-get install -y --no-install-recommends \
"clang-format-$LLVM_VERSION"
update-alternatives --install /usr/bin/clang-format clang-format "/usr/bin/clang-format-$LLVM_VERSION" 100
else
apt-get install -y --no-install-recommends \
"clang-format-11"
update-alternatives --install /usr/bin/clang-format clang-format "/usr/bin/clang-format-11" 100
fi
update-alternatives --install /usr/bin/clang-tidy clang-tidy "/usr/bin/clang-tidy-$LLVM_VERSION" 100

@ -23,22 +23,10 @@ all: dist/libsledge.a
dist:
mkdir dist
dist/memory_instructions.o: src/memory_instructions.c dist
dist/%.o: src/%.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/numeric_instructions.o: src/numeric_instructions.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/table_instructions.o: src/table_instructions.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/variable_instructions.o: src/variable_instructions.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/instantiation.o: src/instantiation.c dist
clang ${CFLAGS} -c ${INCLUDES} -o $@ $<
dist/libsledge.a: dist/memory_instructions.o dist/numeric_instructions.o dist/table_instructions.o dist/variable_instructions.o dist/instantiation.o
dist/libsledge.a: dist/memory_instructions.o dist/numeric_instructions.o dist/table_instructions.o dist/variable_instructions.o dist/instantiation.o dist/wasi_snapshot_preview1.o
ar rcs dist/libsledge.a $^
clean:

@ -146,7 +146,6 @@ The path to the JSON file is passed to `module_alloc_from_json`, which uses the
`module init` then calls `module.abi.initialize_table`, which populates the indirect function table with the actual functions. This is performed once during module initialization because this table does not actually vary between instances of a module.
# SLEdge \*.so Module Instantiation
When `sledgert` receives a request at the registered port specified in the JSON, it performs assorted allocation and initialization steps. The scheduler sets the expected ABI symbols and yields to `current_sandbox_start`, which immediately calls `current_sandbox_init`. This function initializes the associated runtime state and
@ -161,4 +160,3 @@ When `sledgert` receives a request at the registered port specified in the JSON,
# Questions:
- Should `sledge_abi__current_wasm_module_instance` be turned into a macro defined int the ABI header?
- What happens if the runtime is executing and calls `sledge_abi__current_wasm_module_instance_trap`?

@ -15,7 +15,7 @@
struct sledge_abi__wasm_table_entry {
uint32_t type_id;
void * func_pointer;
void *func_pointer;
};
struct sledge_abi__wasm_table {
@ -58,7 +58,7 @@ extern int32_t sledge_abi__wasm_globals_set_i64(uint32_t idx, int64_t value, boo
extern void sledge_abi__init_globals(void);
extern void sledge_abi__init_mem(void);
extern void sledge_abi__init_tbl(void);
extern int32_t sledge_abi__entrypoint(int32_t, int32_t);
extern int32_t sledge_abi__entrypoint(void);
extern uint32_t sledge_abi__wasm_memory_starting_pages(void);
extern uint32_t sledge_abi__wasm_memory_max_pages(void);
@ -71,10 +71,7 @@ typedef void (*sledge_abi__init_mem_fn_t)(void);
typedef void (*sledge_abi__init_tbl_fn_t)(void);
#define SLEDGE_ABI__INITIALIZE_TABLE "sledge_abi__init_tbl"
typedef void (*sledge_abi__init_libc_fn_t)(int32_t, int32_t);
#define SLEDGE_ABI__INITIALIZE_LIBC "sledge_abi__init_libc"
typedef int32_t (*sledge_abi__entrypoint_fn_t)(int32_t a, int32_t b);
typedef int32_t (*sledge_abi__entrypoint_fn_t)(void);
#define SLEDGE_ABI__ENTRYPOINT "sledge_abi__entrypoint"
typedef uint32_t (*sledge_abi__wasm_memory_starting_pages_fn_t)(void);
@ -82,3 +79,158 @@ typedef uint32_t (*sledge_abi__wasm_memory_starting_pages_fn_t)(void);
typedef uint32_t (*sledge_abi__wasm_memory_max_pages_fn_t)(void);
#define SLEDGE_ABI__MAX_PAGES "sledge_abi__wasm_memory_max_pages"
typedef uint32_t __wasi_clockid_t;
typedef uint64_t __wasi_dircookie_t;
typedef uint32_t __wasi_exitcode_t;
typedef int32_t __wasi_fd_t;
typedef int64_t __wasi_filedelta_t;
typedef uint64_t __wasi_filesize_t;
typedef uint32_t __wasi_lookupflags_t;
typedef uint64_t __wasi_rights_t;
typedef uint32_t __wasi_size_t;
typedef uint64_t __wasi_timestamp_t;
#ifndef unlikely
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#endif
uint32_t sledge_abi__wasi_snapshot_preview1_args_get(__wasi_size_t argv_retoffset, __wasi_size_t argv_buf_retoffset);
uint32_t
sledge_abi__wasi_snapshot_preview1_args_sizes_get(__wasi_size_t argc_retoffset, __wasi_size_t argv_buf_len_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_clock_res_get(__wasi_clockid_t id, __wasi_size_t resolution_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
__wasi_size_t time_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_environ_get(__wasi_size_t env_retoffset, __wasi_size_t env_buf_retoffset);
uint32_t
sledge_abi__wasi_snapshot_preview1_environ_sizes_get(__wasi_size_t envc_retoffset, __wasi_size_t env_buf_len_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_advise(__wasi_fd_t fd, __wasi_filesize_t file_offset,
__wasi_filesize_t len, uint32_t advice_extended);
uint32_t
sledge_abi__wasi_snapshot_preview1_fd_allocate(__wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_close(__wasi_fd_t fd);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_datasync(__wasi_fd_t fd);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_fdstat_get(__wasi_fd_t fd, __wasi_size_t fdstat_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_flags(__wasi_fd_t fd, uint32_t fdflags_extended);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_rights(__wasi_fd_t fd, __wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_filestat_get(__wasi_fd_t fd, __wasi_size_t filestat_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_filestat_set_size(__wasi_fd_t fd, __wasi_filesize_t size);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_filestat_set_times(__wasi_fd_t fd, __wasi_timestamp_t atim,
__wasi_timestamp_t mtim, uint32_t fstflags_extended);
uint32_t
sledge_abi__wasi_snapshot_preview1_fd_pread(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_filesize_t offset, __wasi_size_t nread_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_prestat_get(__wasi_fd_t fd, __wasi_size_t prestat_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_prestat_dir_name(__wasi_fd_t fd, __wasi_size_t dirname_retoffset,
__wasi_size_t dirname_len);
uint32_t
sledge_abi__wasi_snapshot_preview1_fd_pwrite(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_filesize_t file_offset, __wasi_size_t nwritten_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_read(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset,
__wasi_size_t iovs_len, __wasi_size_t nread_retoffset);
uint32_t
sledge_abi__wasi_snapshot_preview1_fd_readdir(__wasi_fd_t fd, __wasi_size_t buf_baseoffset, __wasi_size_t buf_len,
__wasi_dircookie_t cookie, __wasi_size_t nread_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_renumber(__wasi_fd_t fd, __wasi_fd_t to);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_seek(__wasi_fd_t fd, __wasi_filedelta_t file_offset,
uint32_t whence_extended, __wasi_size_t newoffset_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_sync(__wasi_fd_t fd);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_tell(__wasi_fd_t fd, __wasi_size_t fileoffset_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_fd_write(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset,
__wasi_size_t iovs_len, __wasi_size_t nwritten_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_path_create_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
__wasi_size_t path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_path_filestat_get(__wasi_fd_t fd, __wasi_lookupflags_t flags,
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
__wasi_size_t filestat_retoffset);
uint32_t
sledge_abi__wasi_snapshot_preview1_path_filestat_set_times(__wasi_fd_t fd, __wasi_lookupflags_t flags,
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
__wasi_timestamp_t atim, __wasi_timestamp_t mtim,
uint32_t fstflags_extended);
uint32_t sledge_abi__wasi_snapshot_preview1_path_link(__wasi_fd_t old_fd, __wasi_lookupflags_t old_flags,
__wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len,
__wasi_fd_t new_fd, __wasi_size_t new_path_baseoffset,
__wasi_size_t new_path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_path_open(__wasi_fd_t dirfd, __wasi_lookupflags_t lookupflags,
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
uint32_t oflags_extended, __wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting, uint32_t fdflags_extended,
__wasi_size_t fd_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_path_readlink(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
__wasi_size_t path_len, __wasi_size_t buf_baseretoffset,
__wasi_size_t buf_len, __wasi_size_t nread_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_path_remove_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
__wasi_size_t path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_path_rename(__wasi_fd_t fd, __wasi_size_t old_path_baseoffset,
__wasi_size_t old_path_len, __wasi_fd_t new_fd,
__wasi_size_t new_path_baseoffset, __wasi_size_t new_path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_path_symlink(__wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len,
__wasi_fd_t fd, __wasi_size_t new_path_baseoffset,
__wasi_size_t new_path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_path_unlink_file(__wasi_fd_t fd, __wasi_size_t path_baseoffset,
__wasi_size_t path_len);
uint32_t sledge_abi__wasi_snapshot_preview1_poll_oneoff(__wasi_size_t in_baseoffset, __wasi_size_t out_baseoffset,
__wasi_size_t nsubscriptions, __wasi_size_t nevents_retoffset);
void sledge_abi__wasi_snapshot_preview1_proc_exit(__wasi_exitcode_t exitcode);
uint32_t sledge_abi__wasi_snapshot_preview1_proc_raise(uint32_t sig_extended);
uint32_t sledge_abi__wasi_snapshot_preview1_random_get(__wasi_size_t buf_baseretoffset, __wasi_size_t buf_len);
uint32_t sledge_abi__wasi_snapshot_preview1_sched_yield(void);
uint32_t sledge_abi__wasi_snapshot_preview1_sock_recv(__wasi_fd_t fd, __wasi_size_t ri_data_baseretoffset,
__wasi_size_t ri_data_len, uint32_t ri_flags_extended,
__wasi_size_t ri_data_nbytes_retoffset,
__wasi_size_t message_nbytes_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_sock_send(__wasi_fd_t fd, __wasi_size_t si_data_baseoffset,
__wasi_size_t si_data_len, uint32_t si_flags_extended,
__wasi_size_t nbytes_retoffset);
uint32_t sledge_abi__wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how);

@ -1,5 +0,0 @@
A WebAssembly module instance is statically linked with the backing functions implementing the wasm32 ABI, yielding a *.so file that SLEdge can execute. This ensures that the instance is able to aggressively inline and optimize this code.
They are broken into instruction types as on https://webassembly.github.io/spec/core/exec/instructions.html. They depend on common headers for the WebAssembly types located in the WebAssembly instance struct. These are located in runtime/include/common.
The stubs correspond to awsm/src/codegen/runtime_stubs.rs

@ -17,8 +17,7 @@ extern void populate_globals(void);
extern void populate_memory(void);
extern void populate_table(void);
extern void populate_table(void);
extern void wasmf___init_libc(int32_t, int32_t);
extern int32_t wasmf_main(int32_t, int32_t);
extern int32_t wasmf__start(void);
extern uint32_t starting_pages;
extern uint32_t max_pages;
@ -42,17 +41,10 @@ sledge_abi__init_tbl(void)
populate_table();
}
// Wasmception Initialization. Unsure what a and b is here
EXPORT void
sledge_abi__init_libc(int32_t envp, int32_t pn)
{
wasmf___init_libc(envp, pn);
}
EXPORT int32_t
sledge_abi__entrypoint(int32_t argc, int32_t argv)
sledge_abi__entrypoint(void)
{
return wasmf_main(argc, argv);
return wasmf__start();
}
EXPORT uint32_t

@ -2,8 +2,6 @@
#define INLINE __attribute__((always_inline))
#define WASM_PAGE_SIZE (1024 * 64) /* 64KB */
#define likely(X) __builtin_expect(!!(X), 1)
#define unlikely(X) __builtin_expect(!!(X), 0)
/* This is private and NOT in the sledge_abi.h header because the runtime uses an overlay struct that extends this
* symbol with private members */
@ -12,7 +10,7 @@ extern thread_local struct sledge_abi__wasm_module_instance sledge_abi__current_
INLINE uint32_t
instruction_memory_size()
{
return (uint32_t)(sledge_abi__current_wasm_module_instance.memory.size / WASM_PAGE_SIZE);
return (uint32_t)(sledge_abi__current_wasm_module_instance.memory.size / (uint64_t)WASM_PAGE_SIZE);
}
// These functions are equivalent to those in wasm_memory.h, but they minimize pointer dereferencing
@ -20,7 +18,7 @@ INLINE float
get_f32(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(float) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(float) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(float *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -28,7 +26,7 @@ INLINE double
get_f64(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(double) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(double) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(double *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -36,7 +34,7 @@ INLINE int8_t
get_i8(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int8_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int8_t) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(int8_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -44,7 +42,7 @@ INLINE int16_t
get_i16(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int16_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int16_t) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(int16_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -52,7 +50,7 @@ INLINE int32_t
get_i32(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int32_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int32_t) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(int32_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -60,7 +58,7 @@ INLINE int64_t
get_i64(uint32_t offset)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int64_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int64_t) <= sledge_abi__current_wasm_module_instance.memory.size);
return *(int64_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset];
}
@ -69,7 +67,7 @@ INLINE void
set_f32(uint32_t offset, float value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(float) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(float) <= sledge_abi__current_wasm_module_instance.memory.size);
*(float *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}
@ -77,8 +75,7 @@ INLINE void
set_f64(uint32_t offset, double value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(double) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(double) <= sledge_abi__current_wasm_module_instance.memory.size);
*(double *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}
@ -86,7 +83,7 @@ INLINE void
set_i8(uint32_t offset, int8_t value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int8_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int8_t) <= sledge_abi__current_wasm_module_instance.memory.size);
*(int8_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}
@ -94,8 +91,7 @@ INLINE void
set_i16(uint32_t offset, int16_t value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int16_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int16_t) <= sledge_abi__current_wasm_module_instance.memory.size);
*(int16_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}
@ -103,7 +99,7 @@ INLINE void
set_i32(uint32_t offset, int32_t value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int32_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int32_t) <= sledge_abi__current_wasm_module_instance.memory.size);
*(int32_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}
@ -111,7 +107,7 @@ INLINE void
set_i64(uint32_t offset, int64_t value)
{
assert(sledge_abi__current_wasm_module_instance.memory.buffer != NULL);
assert(offset + sizeof(int64_t) <= sledge_abi__current_wasm_module_instance.memory.size);
assert((uint64_t)offset + sizeof(int64_t) <= sledge_abi__current_wasm_module_instance.memory.size);
*(int64_t *)&sledge_abi__current_wasm_module_instance.memory.buffer[offset] = value;
}

@ -3,9 +3,7 @@
#include "sledge_abi.h"
#define INLINE __attribute__((always_inline))
#define likely(X) __builtin_expect(!!(X), 1)
#define unlikely(X) __builtin_expect(!!(X), 0)
#define INLINE __attribute__((always_inline))
// ROTL and ROTR helper functions
INLINE uint32_t

@ -2,8 +2,6 @@
#define INDIRECT_TABLE_SIZE (1 << 10)
#define INLINE __attribute__((always_inline))
#define likely(X) __builtin_expect(!!(X), 1)
#define unlikely(X) __builtin_expect(!!(X), 0)
/* This is private and NOT in the sledge_abi.h header because the runtime uses an overlay struct that extends this
* symbol with private members */
@ -17,9 +15,7 @@ wasm_table_get(struct sledge_abi__wasm_table *wasm_table, uint32_t idx, uint32_t
struct sledge_abi__wasm_table_entry f = wasm_table->buffer[idx];
/* Wasmception-based modules trigger function type mismatches for an unknown reason.
* This should be reenabled when WASI is added */
// assert(f.type_id != type_id);
assert(f.type_id == type_id);
assert(f.func_pointer != NULL);
return f.func_pointer;
@ -46,5 +42,14 @@ add_function_to_table(uint32_t idx, uint32_t type_id, char *pointer)
INLINE char *
get_function_from_table(uint32_t idx, uint32_t type_id)
{
return wasm_table_get(sledge_abi__current_wasm_module_instance.table, idx, type_id);
assert(sledge_abi__current_wasm_module_instance.table != NULL);
assert(idx < sledge_abi__current_wasm_module_instance.table->capacity);
struct sledge_abi__wasm_table_entry f = sledge_abi__current_wasm_module_instance.table->buffer[idx];
assert(f.type_id == type_id);
assert(f.func_pointer != NULL);
return f.func_pointer;
}

@ -30,21 +30,25 @@ get_global_i64(uint32_t idx)
void
set_global_i32(uint32_t idx, int32_t value)
{
if (idx == 0) sledge_abi__current_wasm_module_instance.wasmg_0 = (uint64_t)value;
/* aWsm does not currently pass the is_mutable flag, so all runtime globals are assumed to be mutable.
This is true if aWsm uses the flags to inline constant globals */
int rc = sledge_abi__wasm_globals_set_i32(idx, value, true);
assert(rc == 0);
if (idx == 0) {
sledge_abi__current_wasm_module_instance.wasmg_0 = (uint64_t)value;
} else {
/* aWsm does not currently pass the is_mutable flag, so all runtime globals are assumed to be mutable.
This is true if aWsm uses the flags to inline constant globals */
int rc = sledge_abi__wasm_globals_set_i32(idx, value, true);
assert(rc == 0);
}
}
void
set_global_i64(uint32_t idx, int64_t value)
{
if (idx == 0) sledge_abi__current_wasm_module_instance.wasmg_0 = (uint64_t)value;
/* aWsm does not currently pass the is_mutable flag, so all runtime globals are assumed to be mutable.
This is true if aWsm uses the flags to inline constant globals */
int rc = sledge_abi__wasm_globals_set_i64(idx, value, true);
assert(rc == 0);
if (idx == 0) {
sledge_abi__current_wasm_module_instance.wasmg_0 = (uint64_t)value;
} else {
/* aWsm does not currently pass the is_mutable flag, so all runtime globals are assumed to be mutable.
This is true if aWsm uses the flags to inline constant globals */
int rc = sledge_abi__wasm_globals_set_i64(idx, value, true);
assert(rc == 0);
}
}

@ -0,0 +1,313 @@
#include <stdint.h>
#include "sledge_abi.h"
// TODO: Validate uint32_t as return value;
uint32_t
wasi_snapshot_preview1_args_get(__wasi_size_t argv_retoffset, __wasi_size_t argv_buf_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_args_get(argv_buf_retoffset, argv_buf_retoffset);
}
uint32_t
wasi_snapshot_preview1_args_sizes_get(__wasi_size_t argc_retoffset, __wasi_size_t argv_buf_len_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_args_sizes_get(argc_retoffset, argv_buf_len_retoffset);
};
uint32_t
wasi_snapshot_preview1_clock_res_get(__wasi_clockid_t id, __wasi_size_t resolution_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_clock_res_get(id, resolution_retoffset);
}
uint32_t
wasi_snapshot_preview1_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision,
__wasi_size_t time_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_clock_time_get(clock_id, precision, time_retoffset);
}
uint32_t
wasi_snapshot_preview1_environ_get(__wasi_size_t env_retoffset, __wasi_size_t env_buf_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_environ_get(env_retoffset, env_buf_retoffset);
}
uint32_t
wasi_snapshot_preview1_environ_sizes_get(__wasi_size_t envc_retoffset, __wasi_size_t env_buf_len_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_environ_sizes_get(envc_retoffset, env_buf_len_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_advise(__wasi_fd_t fd, __wasi_filesize_t file_offset, __wasi_filesize_t len,
uint32_t advice_extended)
{
return sledge_abi__wasi_snapshot_preview1_fd_advise(fd, file_offset, len, advice_extended);
}
uint32_t
wasi_snapshot_preview1_fd_allocate(__wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len)
{
return sledge_abi__wasi_snapshot_preview1_fd_allocate(fd, offset, len);
}
uint32_t
wasi_snapshot_preview1_fd_close(__wasi_fd_t fd)
{
return sledge_abi__wasi_snapshot_preview1_fd_close(fd);
}
uint32_t
wasi_snapshot_preview1_fd_datasync(__wasi_fd_t fd)
{
return sledge_abi__wasi_snapshot_preview1_fd_datasync(fd);
}
uint32_t
wasi_snapshot_preview1_fd_fdstat_get(__wasi_fd_t fd, __wasi_size_t fdstat_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_fdstat_get(fd, fdstat_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_fdstat_set_flags(__wasi_fd_t fd, uint32_t fdflags_extended)
{
return sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_flags(fd, fdflags_extended);
}
uint32_t
wasi_snapshot_preview1_fd_fdstat_set_rights(__wasi_fd_t fd, __wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting)
{
return sledge_abi__wasi_snapshot_preview1_fd_fdstat_set_rights(fd, fs_rights_base, fs_rights_inheriting);
}
uint32_t
wasi_snapshot_preview1_fd_filestat_get(__wasi_fd_t fd, __wasi_size_t filestat_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_filestat_get(fd, filestat_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_filestat_set_size(__wasi_fd_t fd, __wasi_filesize_t size)
{
return sledge_abi__wasi_snapshot_preview1_fd_filestat_set_size(fd, size);
}
uint32_t
wasi_snapshot_preview1_fd_filestat_set_times(__wasi_fd_t fd, __wasi_timestamp_t atim, __wasi_timestamp_t mtim,
uint32_t fstflags_extended)
{
return sledge_abi__wasi_snapshot_preview1_fd_filestat_set_times(fd, atim, mtim, fstflags_extended);
}
uint32_t
wasi_snapshot_preview1_fd_pread(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_filesize_t offset, __wasi_size_t nread_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_pread(fd, iovs_baseoffset, iovs_len, offset, nread_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_prestat_get(__wasi_fd_t fd, __wasi_size_t prestat_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_prestat_get(fd, prestat_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_prestat_dir_name(__wasi_fd_t fd, __wasi_size_t dirname_retoffset, __wasi_size_t dirname_len)
{
return sledge_abi__wasi_snapshot_preview1_fd_prestat_dir_name(fd, dirname_retoffset, dirname_len);
}
uint32_t
wasi_snapshot_preview1_fd_pwrite(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_filesize_t file_offset, __wasi_size_t nwritten_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_pwrite(fd, iovs_baseoffset, iovs_len, file_offset,
nwritten_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_read(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_size_t nread_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_read(fd, iovs_baseoffset, iovs_len, nread_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_readdir(__wasi_fd_t fd, __wasi_size_t buf_baseoffset, __wasi_size_t buf_len,
__wasi_dircookie_t cookie, __wasi_size_t nread_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_readdir(fd, buf_baseoffset, buf_len, cookie, nread_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_renumber(__wasi_fd_t fd, __wasi_fd_t to)
{
return sledge_abi__wasi_snapshot_preview1_fd_renumber(fd, to);
}
uint32_t
wasi_snapshot_preview1_fd_seek(__wasi_fd_t fd, __wasi_filedelta_t file_offset, uint32_t whence_extended,
__wasi_size_t newoffset_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_seek(fd, file_offset, whence_extended, newoffset_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_sync(__wasi_fd_t fd)
{
return sledge_abi__wasi_snapshot_preview1_fd_sync(fd);
}
uint32_t
wasi_snapshot_preview1_fd_tell(__wasi_fd_t fd, __wasi_size_t fileoffset_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_tell(fd, fileoffset_retoffset);
}
uint32_t
wasi_snapshot_preview1_fd_write(__wasi_fd_t fd, __wasi_size_t iovs_baseoffset, __wasi_size_t iovs_len,
__wasi_size_t nwritten_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_fd_write(fd, iovs_baseoffset, iovs_len, nwritten_retoffset);
}
uint32_t
wasi_snapshot_preview1_path_create_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset, __wasi_size_t path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_create_directory(fd, path_baseoffset, path_len);
}
uint32_t
wasi_snapshot_preview1_path_filestat_get(__wasi_fd_t fd, __wasi_lookupflags_t flags, __wasi_size_t path_baseoffset,
__wasi_size_t path_len, __wasi_size_t filestat_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_path_filestat_get(fd, flags, path_baseoffset, path_len,
filestat_retoffset);
}
uint32_t
wasi_snapshot_preview1_path_filestat_set_times(__wasi_fd_t fd, __wasi_lookupflags_t flags,
__wasi_size_t path_baseoffset, __wasi_size_t path_len,
__wasi_timestamp_t atim, __wasi_timestamp_t mtim,
uint32_t fstflags_extended)
{
return sledge_abi__wasi_snapshot_preview1_path_filestat_set_times(fd, flags, path_baseoffset, path_len, atim,
mtim, fstflags_extended);
}
uint32_t
wasi_snapshot_preview1_path_link(__wasi_fd_t old_fd, __wasi_lookupflags_t old_flags, __wasi_size_t old_path_baseoffset,
__wasi_size_t old_path_len, __wasi_fd_t new_fd, __wasi_size_t new_path_baseoffset,
__wasi_size_t new_path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_link(old_fd, old_flags, old_path_baseoffset, old_path_len,
new_fd, new_path_baseoffset, new_path_len);
}
uint32_t
wasi_snapshot_preview1_path_open(__wasi_fd_t dirfd, __wasi_lookupflags_t lookupflags, __wasi_size_t path_baseoffset,
__wasi_size_t path_len, uint32_t oflags_extended, __wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting, uint32_t fdflags_extended,
__wasi_size_t fd_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_path_open(dirfd, lookupflags, path_baseoffset, path_len,
oflags_extended, fs_rights_base, fs_rights_inheriting,
fdflags_extended, fd_retoffset);
}
uint32_t
wasi_snapshot_preview1_path_readlink(__wasi_fd_t fd, __wasi_size_t path_baseoffset, __wasi_size_t path_len,
__wasi_size_t buf_baseretoffset, __wasi_size_t buf_len,
__wasi_size_t nread_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_path_readlink(fd, path_baseoffset, path_len, buf_baseretoffset,
buf_len, nread_retoffset);
}
uint32_t
wasi_snapshot_preview1_path_remove_directory(__wasi_fd_t fd, __wasi_size_t path_baseoffset, __wasi_size_t path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_remove_directory(fd, path_baseoffset, path_len);
}
uint32_t
wasi_snapshot_preview1_path_rename(__wasi_fd_t fd, __wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len,
__wasi_fd_t new_fd, __wasi_size_t new_path_baseoffset, __wasi_size_t new_path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_rename(fd, old_path_baseoffset, old_path_len, new_fd,
new_path_baseoffset, new_path_len);
}
uint32_t
wasi_snapshot_preview1_path_symlink(__wasi_size_t old_path_baseoffset, __wasi_size_t old_path_len, __wasi_fd_t fd,
__wasi_size_t new_path_baseoffset, __wasi_size_t new_path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_symlink(old_path_baseoffset, old_path_len, fd,
new_path_baseoffset, new_path_len);
}
uint32_t
wasi_snapshot_preview1_path_unlink_file(__wasi_fd_t fd, __wasi_size_t path_baseoffset, __wasi_size_t path_len)
{
return sledge_abi__wasi_snapshot_preview1_path_unlink_file(fd, path_baseoffset, path_len);
}
uint32_t
wasi_snapshot_preview1_poll_oneoff(__wasi_size_t in_baseoffset, __wasi_size_t out_baseoffset,
__wasi_size_t nsubscriptions, __wasi_size_t nevents_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_poll_oneoff(in_baseoffset, out_baseoffset, nsubscriptions,
nevents_retoffset);
}
void
wasi_snapshot_preview1_proc_exit(__wasi_exitcode_t exitcode)
{
sledge_abi__wasi_snapshot_preview1_proc_raise(exitcode);
}
uint32_t
wasi_snapshot_preview1_proc_raise(uint32_t sig_extended)
{
return sledge_abi__wasi_snapshot_preview1_proc_raise(sig_extended);
}
uint32_t
wasi_snapshot_preview1_random_get(__wasi_size_t buf_baseretoffset, __wasi_size_t buf_len)
{
return sledge_abi__wasi_snapshot_preview1_random_get(buf_baseretoffset, buf_len);
}
uint32_t
wasi_snapshot_preview1_sched_yield(void)
{
return sledge_abi__wasi_snapshot_preview1_sched_yield();
}
uint32_t
wasi_snapshot_preview1_sock_recv(__wasi_fd_t fd, __wasi_size_t ri_data_baseretoffset, __wasi_size_t ri_data_len,
uint32_t ri_flags_extended, __wasi_size_t ri_data_nbytes_retoffset,
__wasi_size_t message_nbytes_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_sock_recv(fd, ri_data_baseretoffset, ri_data_len, ri_flags_extended,
ri_data_nbytes_retoffset, message_nbytes_retoffset);
}
uint32_t
wasi_snapshot_preview1_sock_send(__wasi_fd_t fd, __wasi_size_t si_data_baseoffset, __wasi_size_t si_data_len,
uint32_t si_flags_extended, __wasi_size_t nbytes_retoffset)
{
return sledge_abi__wasi_snapshot_preview1_sock_send(fd, si_data_baseoffset, si_data_len, si_flags_extended,
nbytes_retoffset);
}
uint32_t
wasi_snapshot_preview1_sock_shutdown(__wasi_fd_t fd, uint32_t how)
{
return sledge_abi__wasi_snapshot_preview1_sock_shutdown(fd, how);
}

@ -11,7 +11,7 @@ CFLAGS=-std=c18 -pthread
# We use several non-standard glibc / Linux features:
# sched_getcpu, MAP_ANONYMOUS, acceess to 'gregs' in 'mcontext_t', REG_RIP, REG_RSP
CFLAGS+=-D_GNU_SOURCE
CFLAGS+=-D_GNU_SOURCE
# Release Flags
CFLAGS+=-O3 -flto
@ -42,6 +42,13 @@ BINARY_NAME=sledgert
# Debugging Flags
# Enables logs of WASI syscalls
# CFLAGS += -DLOG_WASI
# Sandbox writes to stdout and stderr are both written to the client socket
# However, when set, stderr is also written to the host stderr to assist with debugging
# CFLAGS += -DLOG_SANDBOX_STDERR
# Strips out calls to assert() and disables debuglog
# CFLAGS += -DNDEBUG
@ -56,6 +63,7 @@ BINARY_NAME=sledgert
# CFLAGS += -DLOG_MODULE_LOADING
# CFLAGS += -DLOG_PREEMPTION
# CFLAGS += -DLOG_SANDBOX_ALLOCATION
# CFLAGS += -DLOG_UNSUPPORTED_WASI
# Stores and logs extended signal information for each worker
# CFLAGS += -DLOG_SOFTWARE_INTERRUPT_COUNTS
@ -144,10 +152,3 @@ thirdparty:
.PHONY: thirdparty.clean
thirdparty.clean:
@make --no-print-directory -C thirdparty clean
.PHONY: submodules
submodules:
@git submodule update --init --recursive
.PHONY: init
init: submodules clean thirdparty runtime

@ -43,10 +43,13 @@ current_sandbox_set(struct sandbox *sandbox)
.table = NULL,
.wasmg_0 = 0,
},
/* Private */
.wasi_context = NULL,
};
worker_thread_current_sandbox = NULL;
runtime_worker_threads_deadline[worker_thread_idx] = UINT64_MAX;
} else {
sledge_abi__current_wasm_module_instance.wasi_context = sandbox->wasi_context;
memcpy(&sledge_abi__current_wasm_module_instance.abi.memory, &sandbox->memory->abi,
sizeof(struct sledge_abi__wasm_memory));
sledge_abi__current_wasm_module_instance.abi.table = sandbox->module->indirect_table;

@ -32,7 +32,7 @@ current_sandbox_send_response()
/* Determine values to template into our HTTP response */
size_t response_body_size = response->length;
char * module_content_type = sandbox->module->response_content_type;
char *module_content_type = sandbox->module->response_content_type;
const char *content_type = strlen(module_content_type) > 0 ? module_content_type : "text/plain";
/* Capture Timekeeping data for end-to-end latency */

@ -15,7 +15,7 @@ struct http_header {
struct http_request {
struct http_header headers[HTTP_MAX_HEADER_COUNT];
int header_count;
char * body;
char *body;
int body_length;
int body_read_length; /* How far we've read */

@ -13,6 +13,7 @@
#include "pool.h"
#include "sledge_abi_symbols.h"
#include "types.h"
#include "sledge_abi_symbols.h"
#include "wasm_stack.h"
#include "wasm_memory.h"
#include "wasm_table.h"
@ -131,7 +132,6 @@ module_initialize_table(struct module *module)
static inline int
module_alloc_table(struct module *module)
{
/* WebAssembly Indirect Table */
/* TODO: Should this be part of the module or per-sandbox? */
/* TODO: How should this table be sized? */
module->indirect_table = wasm_table_alloc(INDIRECT_TABLE_SIZE);
@ -150,18 +150,6 @@ module_initialize_pools(struct module *module)
}
}
/**
* Invoke a module's initialize_libc
* @param module - module whose libc we are initializing
* @param env - address?
* @param arguments - address?
*/
static inline void
module_initialize_libc(struct module *module, int32_t env, int32_t arguments)
{
module->abi.initialize_libc(env, arguments);
}
/**
* Invoke a module's initialize_memory
* @param module - the module whose memory we are initializing
@ -180,9 +168,9 @@ module_initialize_memory(struct module *module)
* @return return code of module's main function
*/
static inline int32_t
module_entrypoint(struct module *module, int32_t argc, int32_t argv)
module_entrypoint(struct module *module)
{
return module->abi.entrypoint(argc, argv);
return module->abi.entrypoint();
}
/**

@ -91,7 +91,7 @@ perf_window_add(struct perf_window *perf_window, uint64_t value)
for (int i = 0; i < PERF_WINDOW_BUFFER_SIZE; i++) {
perf_window->by_termination[i] = i;
perf_window->by_duration[i] = (struct execution_node){ .execution_time = value,
.by_termination_idx = i };
.by_termination_idx = i };
}
perf_window->count = PERF_WINDOW_BUFFER_SIZE;
goto done;

@ -27,7 +27,7 @@ struct priority_queue {
uint64_t highest_priority;
size_t size;
size_t capacity;
void * items[];
void *items[];
};
/**

@ -40,10 +40,10 @@ extern bool runtime_preemption_enabled;
extern uint32_t runtime_processor_speed_MHz;
extern uint32_t runtime_quantum_us;
extern enum RUNTIME_SIGALRM_HANDLER runtime_sigalrm_handler;
extern pthread_t * runtime_worker_threads;
extern pthread_t *runtime_worker_threads;
extern uint32_t runtime_worker_threads_count;
extern int * runtime_worker_threads_argument;
extern uint64_t * runtime_worker_threads_deadline;
extern int *runtime_worker_threads_argument;
extern uint64_t *runtime_worker_threads_deadline;
extern void runtime_initialize(void);
extern void runtime_set_pthread_prio(pthread_t thread, unsigned int nice);

@ -38,7 +38,7 @@ sandbox_free_linear_memory(struct sandbox *sandbox)
{
assert(sandbox != NULL);
assert(sandbox->memory != NULL);
module_free_linear_memory(sandbox->module, sandbox->memory);
module_free_linear_memory(sandbox->module, (struct wasm_memory *)sandbox->memory);
sandbox->memory = NULL;
}

@ -35,7 +35,7 @@ sandbox_receive_request(struct sandbox *sandbox)
/* Read from the Socket */
/* Structured to closely follow usage example at https://github.com/nodejs/http-parser */
http_parser * parser = &sandbox->http_parser;
http_parser *parser = &sandbox->http_parser;
const http_parser_settings *settings = http_parser_settings_get();
size_t request_length = request->length;

@ -23,6 +23,7 @@ sandbox_set_as_allocated(struct sandbox *sandbox)
uint64_t now = __getcycles();
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_init(&sandbox->state_history);
sandbox_state_history_append(&sandbox->state_history, SANDBOX_ALLOCATED);

@ -36,6 +36,7 @@ sandbox_set_as_asleep(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_ASLEEP);

@ -39,6 +39,7 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_COMPLETE);

@ -48,6 +48,7 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->duration_of_state[last_state] += duration_of_last_state;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_ERROR);

@ -34,6 +34,7 @@ sandbox_set_as_initialized(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_INITIALIZED);

@ -22,6 +22,7 @@ sandbox_set_as_interrupted(struct sandbox *sandbox, sandbox_state_t last_state)
uint64_t now = __getcycles();
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
/* We do not append SANDBOX_INTERRUPTED to the sandbox_state_history because it would quickly fill the buffer */

@ -36,6 +36,7 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_PREEMPTED);

@ -43,6 +43,7 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_RETURNED);

@ -43,6 +43,7 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNABLE);

@ -38,6 +38,7 @@ sandbox_set_as_running_sys(struct sandbox *sandbox, sandbox_state_t last_state)
}
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNING_SYS);

@ -34,6 +34,7 @@ sandbox_set_as_running_user(struct sandbox *sandbox, sandbox_state_t last_state)
/* State Change Bookkeeping */
assert(now > sandbox->timestamp_of.last_state_change);
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(&sandbox->state_history, SANDBOX_RUNNING_USER);

@ -1,35 +0,0 @@
#pragma once
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "sandbox_types.h"
extern void stub_init(int32_t offset);
/**
* Takes the arguments from the sandbox struct and writes them into the WebAssembly linear memory
*/
static inline void
sandbox_setup_arguments(struct sandbox *sandbox)
{
assert(sandbox != NULL);
int32_t argument_count = 0;
/* Copy arguments into linear memory. It seems like malloc would clobber this, but I think this goes away in
* WASI, so not worth fixing*/
sandbox->arguments_offset = wasm_memory_get_size(sandbox->memory);
/* Assumption: we can fit the arguments in a single wasm page */
int rc = wasm_memory_expand(sandbox->memory, WASM_PAGE_SIZE);
assert(rc == 0);
/* We have to update our cache here */
memcpy(&sledge_abi__current_wasm_module_instance.abi.memory, &sandbox->memory->abi,
sizeof(struct sledge_abi__wasm_memory));
stub_init(sandbox->arguments_offset);
}

@ -18,10 +18,7 @@
#include "wasm_types.h"
#include "wasm_stack.h"
#include "wasm_globals.h"
#ifdef LOG_SANDBOX_MEMORY_PROFILE
#define SANDBOX_PAGE_ALLOCATION_TIMESTAMP_COUNT 1024
#endif
#include "wasi.h"
#define u8 uint8_t
VEC(u8)
@ -62,8 +59,8 @@ struct sandbox {
/* WebAssembly Instance State */
struct arch_context ctxt;
struct wasm_stack * stack;
struct wasm_memory * memory;
struct wasm_stack *stack;
struct wasm_memory *memory;
struct vec_wasm_global_t globals;
/* Scheduling and Temporal State */
@ -76,7 +73,7 @@ struct sandbox {
uint64_t total_time; /* Total time from Request to Response */
/* System Interface State */
int32_t arguments_offset; /* actual placement of arguments in the sandbox. */
int32_t return_value;
int32_t return_value;
wasi_context_t *wasi_context;
} PAGE_ALIGNED;

@ -254,6 +254,11 @@ scheduler_preemptive_sched(ucontext_t *interrupted_context)
/* Preempt executing sandbox */
scheduler_log_sandbox_switch(interrupted_sandbox, next);
sandbox_preempt(interrupted_sandbox);
// Write back global at idx 0
wasm_globals_set_i64(&interrupted_sandbox->globals, 0, sledge_abi__current_wasm_module_instance.abi.wasmg_0,
true);
arch_context_save_slow(&interrupted_sandbox->ctxt, &interrupted_context->uc_mcontext);
scheduler_preemptive_switch_to(interrupted_context, next);
}
@ -370,6 +375,9 @@ scheduler_cooperative_sched(bool add_to_completion_queue)
scheduler_log_sandbox_switch(exiting_sandbox, next_sandbox);
// Write back global at idx 0
wasm_globals_set_i64(&exiting_sandbox->globals, 0, sledge_abi__current_wasm_module_instance.abi.wasmg_0, true);
if (add_to_completion_queue) local_completion_queue_add(exiting_sandbox);
/* Do not touch sandbox struct after this point! */

@ -23,7 +23,7 @@ scheduler_execute_epoll_loop(void)
while (true) {
struct epoll_event epoll_events[RUNTIME_MAX_EPOLL_EVENTS];
int descriptor_count = epoll_wait(worker_thread_epoll_file_descriptor, epoll_events,
RUNTIME_MAX_EPOLL_EVENTS, 0);
RUNTIME_MAX_EPOLL_EVENTS, 0);
if (descriptor_count < 0) {
if (errno == EINTR) continue;

@ -9,11 +9,10 @@
#include "sledge_abi.h"
struct sledge_abi_symbols {
void * handle;
void *handle;
sledge_abi__init_globals_fn_t initialize_globals;
sledge_abi__init_mem_fn_t initialize_memory;
sledge_abi__init_tbl_fn_t initialize_tables;
sledge_abi__init_libc_fn_t initialize_libc;
sledge_abi__entrypoint_fn_t entrypoint;
uint32_t starting_pages;
uint32_t max_pages;
@ -62,13 +61,6 @@ sledge_abi_symbols_init(struct sledge_abi_symbols *abi, char *path)
goto dl_error;
};
abi->initialize_libc = (sledge_abi__init_libc_fn_t)dlsym(abi->handle, SLEDGE_ABI__INITIALIZE_LIBC);
if (abi->initialize_libc == NULL) {
fprintf(stderr, "Failed to resolve symbol %s in %s with error: %s\n", SLEDGE_ABI__INITIALIZE_LIBC, path,
dlerror());
goto dl_error;
};
sledge_abi__wasm_memory_starting_pages_fn_t get_starting_pages = dlsym(abi->handle, SLEDGE_ABI__STARTING_PAGES);
if (get_starting_pages == NULL) {
fprintf(stderr, "Failed to resolve symbol %s in %s with error: %s\n", SLEDGE_ABI__STARTING_PAGES, path,
@ -102,7 +94,6 @@ sledge_abi_symbols_deinit(struct sledge_abi_symbols *abi)
abi->initialize_globals = NULL;
abi->initialize_memory = NULL;
abi->initialize_tables = NULL;
abi->initialize_libc = NULL;
int rc = dlclose(abi->handle);
if (rc != 0) {

@ -8,7 +8,7 @@
struct vec_##TYPE { \
size_t length; \
size_t capacity; \
TYPE * buffer; /* Backing heap allocation. Different lifetime because realloc might move this */ \
TYPE *buffer; /* Backing heap allocation. Different lifetime because realloc might move this */ \
}; \
\
static inline int vec_##TYPE##_init(struct vec_##TYPE *vec, size_t capacity); \

File diff suppressed because it is too large Load Diff

@ -0,0 +1,427 @@
#ifndef __WASI_SERDES_H__
#define __WASI_SERDES_H__
/*
The serialization/deserialization logic in this file is derived from uvwasi source code
located at the following URL:
https://github.com/nodejs/uvwasi/blob/7523499546c351a1642442e6ec7bd32bcac76e2c/src/wasi_serdes.c
It retains the the Node.js license as follows:
MIT License
-----------
Copyright (c) 2019 Colin Ihrig and Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "wasi.h"
/* Basic uint{8,16,32,64}_t read/write functions. */
#define BASIC_TYPE(name, type) \
static inline void wasi_serdes_write_##name(void *ptr, size_t offset, type value); \
static inline type wasi_serdes_read_##name(const void *ptr, size_t offset);
#define BASIC_TYPE_WASI(type) BASIC_TYPE(type, __wasi_##type)
#define WASI_SERDES_SIZE_uint8_t sizeof(uint8_t)
BASIC_TYPE(uint8_t, uint8_t)
#define WASI_SERDES_SIZE_uint16_t sizeof(uint16_t)
BASIC_TYPE(uint16_t, uint16_t)
#define WASI_SERDES_SIZE_uint32_t sizeof(uint32_t)
BASIC_TYPE(uint32_t, uint32_t)
#define WASI_SERDES_SIZE_uint64_t sizeof(uint64_t)
BASIC_TYPE(uint64_t, uint64_t)
#define WASI_SERDES_SIZE_advice_t sizeof(__wasi_advice_t)
BASIC_TYPE_WASI(advice_t)
#define WASI_SERDES_SIZE_clockid_t sizeof(__wasi_clockid_t)
BASIC_TYPE_WASI(clockid_t)
#define WASI_SERDES_SIZE_device_t sizeof(__wasi_device_t)
BASIC_TYPE_WASI(device_t)
#define WASI_SERDES_SIZE_dircookie_t sizeof(__wasi_dircookie_t)
BASIC_TYPE_WASI(dircookie_t)
#define WASI_SERDES_SIZE_eventrwflags_t sizeof(__wasi_eventrwflags_t)
BASIC_TYPE_WASI(eventrwflags_t)
#define WASI_SERDES_SIZE_eventtype_t sizeof(__wasi_eventtype_t)
BASIC_TYPE_WASI(eventtype_t)
#define WASI_SERDES_SIZE_exitcode_t sizeof(__wasi_exitcode_t)
BASIC_TYPE_WASI(exitcode_t)
#define WASI_SERDES_SIZE_fd_t sizeof(__wasi_fd_t)
BASIC_TYPE_WASI(fd_t)
#define WASI_SERDES_SIZE_fdflags_t sizeof(__wasi_fdflags_t)
BASIC_TYPE_WASI(fdflags_t)
#define WASI_SERDES_SIZE_filesize_t sizeof(__wasi_filesize_t)
BASIC_TYPE_WASI(filesize_t)
#define WASI_SERDES_SIZE_fstflags_t sizeof(__wasi_fstflags_t)
BASIC_TYPE_WASI(fstflags_t)
#define WASI_SERDES_SIZE_inode_t sizeof(__wasi_inode_t)
BASIC_TYPE_WASI(inode_t)
#define WASI_SERDES_SIZE_linkcount_t sizeof(__wasi_linkcount_t)
BASIC_TYPE_WASI(linkcount_t)
#define WASI_SERDES_SIZE_lookupflags_t sizeof(__wasi_lookupflags_t)
BASIC_TYPE_WASI(lookupflags_t)
#define WASI_SERDES_SIZE_oflags_t sizeof(__wasi_oflags_t)
BASIC_TYPE_WASI(oflags_t)
#define WASI_SERDES_SIZE_preopentype_t sizeof(__wasi_preopentype_t)
BASIC_TYPE_WASI(preopentype_t)
#define WASI_SERDES_SIZE_riflags_t sizeof(__wasi_riflags_t)
BASIC_TYPE_WASI(riflags_t)
#define WASI_SERDES_SIZE_rights_t sizeof(__wasi_rights_t)
BASIC_TYPE_WASI(rights_t)
#define WASI_SERDES_SIZE_roflags_t sizeof(__wasi_roflags_t)
BASIC_TYPE_WASI(roflags_t)
#define WASI_SERDES_SIZE_sdflags_t sizeof(__wasi_sdflags_t)
BASIC_TYPE_WASI(sdflags_t)
#define WASI_SERDES_SIZE_siflags_t sizeof(__wasi_siflags_t)
BASIC_TYPE_WASI(siflags_t)
#define WASI_SERDES_SIZE_size_t sizeof(__wasi_size_t)
BASIC_TYPE_WASI(size_t)
#define WASI_SERDES_SIZE_inode_t sizeof(__wasi_inode_t)
BASIC_TYPE_WASI(inode_t)
#define WASI_SERDES_SIZE_signal_t sizeof(__wasi_signal_t)
BASIC_TYPE_WASI(signal_t)
#define WASI_SERDES_SIZE_subclockflags_t sizeof(__wasi_subclockflags_t)
BASIC_TYPE_WASI(subclockflags_t)
#define WASI_SERDES_SIZE_timestamp_t sizeof(__wasi_timestamp_t)
BASIC_TYPE_WASI(timestamp_t)
#define WASI_SERDES_SIZE_userdata_t sizeof(__wasi_userdata_t)
BASIC_TYPE_WASI(userdata_t)
#define WASI_SERDES_SIZE_whence_t sizeof(__wasi_whence_t)
BASIC_TYPE_WASI(whence_t)
#undef BASIC_TYPE_WASI
#undef BASIC_TYPE
/* WASI structure read/write functions. */
#define STRUCT(name) \
void wasi_serdes_write_##name(void *ptr, size_t offset, const __wasi_##name *value); \
void wasi_serdes_read_##name(const void *ptr, size_t offset, __wasi_##name *value);
/* iovs currently only need to be read from WASM memory. */
#define IOVS_STRUCT(name) \
static inline __wasi_errno_t wasi_serdes_read_##name(const void *ptr, size_t end, size_t offset, \
__wasi_##name *value);
#define WASI_SERDES_SIZE_ciovec_t 8
IOVS_STRUCT(ciovec_t)
#define WASI_SERDES_SIZE_iovec_t 8
IOVS_STRUCT(iovec_t)
#define WASI_SERDES_SIZE_dirent_t 24
STRUCT(dirent_t)
#define WASI_SERDES_SIZE_fdstat_t 24
STRUCT(fdstat_t)
#define WASI_SERDES_SIZE_filestat_t 64
STRUCT(filestat_t)
#define WASI_SERDES_SIZE_prestat_t 8
STRUCT(prestat_t)
#define WASI_SERDES_SIZE_event_t 32
STRUCT(event_t)
#define WASI_SERDES_SIZE_subscription_t 48
STRUCT(subscription_t)
#undef STRUCT
#undef IOVS_STRUCT
static inline __wasi_errno_t
wasi_serdes_readv_ciovec_t(const void *ptr, size_t end, size_t offset, __wasi_ciovec_t *iovs, __wasi_size_t iovs_len);
static inline __wasi_errno_t
wasi_serdes_readv_iovec_t(const void *ptr, size_t end, size_t offset, __wasi_iovec_t *iovs, __wasi_size_t iovs_len);
/* Helper functions for memory bounds checking. */
static inline int wasi_serdes_check_bounds(size_t offset, size_t end, size_t size);
static inline int wasi_serdes_check_array_bounds(size_t offset, size_t end, size_t size, size_t count);
static inline int
wasi_serdes_check_bounds(size_t offset, size_t end, size_t size)
{
return end > offset && size <= (end - offset);
}
static inline void
wasi_serdes_write_uint64_t(void *ptr, size_t offset, uint64_t value)
{
wasi_serdes_write_uint32_t(ptr, offset, (uint32_t)value);
wasi_serdes_write_uint32_t(ptr, offset + 4, value >> 32);
}
static inline void
wasi_serdes_write_uint32_t(void *ptr, size_t offset, uint32_t value)
{
wasi_serdes_write_uint16_t(ptr, offset, (uint16_t)value);
wasi_serdes_write_uint16_t(ptr, offset + 2, value >> 16);
}
static inline void
wasi_serdes_write_uint16_t(void *ptr, size_t offset, uint16_t value)
{
wasi_serdes_write_uint8_t(ptr, offset, (uint8_t)value);
wasi_serdes_write_uint8_t(ptr, offset + 1, value >> 8);
}
static inline void
wasi_serdes_write_uint8_t(void *ptr, size_t offset, uint8_t value)
{
((uint8_t *)ptr)[offset] = value;
}
static inline uint64_t
wasi_serdes_read_uint64_t(const void *ptr, size_t offset)
{
uint64_t low = wasi_serdes_read_uint32_t(ptr, offset);
uint64_t high = wasi_serdes_read_uint32_t(ptr, offset + 4);
return low | (high << 32);
}
static inline uint32_t
wasi_serdes_read_uint32_t(const void *ptr, size_t offset)
{
uint32_t low = wasi_serdes_read_uint16_t(ptr, offset);
uint32_t high = wasi_serdes_read_uint16_t(ptr, offset + 2);
return low | (high << 16);
}
static inline uint16_t
wasi_serdes_read_uint16_t(const void *ptr, size_t offset)
{
uint16_t low = wasi_serdes_read_uint8_t(ptr, offset);
uint16_t high = wasi_serdes_read_uint8_t(ptr, offset + 1);
return low | (high << 8);
}
static inline uint8_t
wasi_serdes_read_uint8_t(const void *ptr, size_t offset)
{
return ((const uint8_t *)ptr)[offset];
}
#define TYPE_SWITCH switch (value->type)
#define TAG_SWITCH switch (value->u.tag)
#define ALL_TYPES(STRUCT, FIELD, ALIAS) \
\
ALIAS(advice_t, uint8_t) \
ALIAS(clockid_t, uint32_t) \
ALIAS(device_t, uint64_t) \
ALIAS(dircookie_t, uint64_t) \
ALIAS(errno_t, uint16_t) \
ALIAS(eventrwflags_t, uint16_t) \
ALIAS(eventtype_t, uint8_t) \
ALIAS(exitcode_t, uint32_t) \
ALIAS(fd_t, uint32_t) \
ALIAS(fdflags_t, uint16_t) \
ALIAS(filesize_t, uint64_t) \
ALIAS(filetype_t, uint8_t) \
ALIAS(fstflags_t, uint16_t) \
ALIAS(inode_t, uint64_t) \
ALIAS(linkcount_t, uint64_t) \
ALIAS(lookupflags_t, uint32_t) \
ALIAS(oflags_t, uint16_t) \
ALIAS(preopentype_t, uint8_t) \
ALIAS(riflags_t, uint16_t) \
ALIAS(rights_t, uint64_t) \
ALIAS(roflags_t, uint16_t) \
ALIAS(sdflags_t, uint8_t) \
ALIAS(siflags_t, uint16_t) \
ALIAS(signal_t, uint8_t) \
ALIAS(size_t, uint32_t) \
ALIAS(subclockflags_t, uint16_t) \
ALIAS(timestamp_t, uint64_t) \
ALIAS(userdata_t, uint64_t) \
ALIAS(whence_t, uint8_t) \
\
STRUCT(dirent_t) \
{ \
FIELD(0, dircookie_t, d_next); \
FIELD(8, inode_t, d_ino); \
FIELD(16, uint32_t, d_namlen); \
FIELD(20, filetype_t, d_type); \
} \
\
STRUCT(fdstat_t) \
{ \
FIELD(0, filetype_t, fs_filetype); \
FIELD(2, fdflags_t, fs_flags); \
FIELD(8, rights_t, fs_rights_base); \
FIELD(16, rights_t, fs_rights_inheriting); \
} \
\
STRUCT(filestat_t) \
{ \
FIELD(0, device_t, dev); \
FIELD(8, inode_t, ino); \
FIELD(16, filetype_t, filetype); \
FIELD(24, linkcount_t, nlink); \
FIELD(32, filesize_t, size); \
FIELD(40, timestamp_t, atim); \
FIELD(48, timestamp_t, mtim); \
FIELD(56, timestamp_t, ctim); \
} \
\
STRUCT(prestat_t) \
{ \
FIELD(0, preopentype_t, tag); \
FIELD(4, uint32_t, u.dir.pr_name_len); \
} \
\
STRUCT(event_t) \
{ \
FIELD(0, userdata_t, userdata); \
FIELD(8, errno_t, error); \
FIELD(10, eventtype_t, type); \
TYPE_SWITCH \
{ \
case __WASI_EVENTTYPE_FD_READ: \
case __WASI_EVENTTYPE_FD_WRITE: \
FIELD(16, filesize_t, fd_readwrite.nbytes); \
FIELD(24, eventrwflags_t, fd_readwrite.flags); \
} \
} \
\
STRUCT(subscription_t) \
{ \
FIELD(0, userdata_t, userdata); \
FIELD(8, eventtype_t, u.tag); \
TAG_SWITCH \
{ \
case __WASI_EVENTTYPE_CLOCK: \
FIELD(16, clockid_t, u.u.clock.id); \
FIELD(24, timestamp_t, u.u.clock.timeout); \
FIELD(32, timestamp_t, u.u.clock.precision); \
FIELD(40, subclockflags_t, u.u.clock.flags); \
break; \
case __WASI_EVENTTYPE_FD_READ: \
FIELD(16, fd_t, u.u.fd_read.file_descriptor); \
break; \
case __WASI_EVENTTYPE_FD_WRITE: \
FIELD(16, fd_t, u.u.fd_write.file_descriptor); \
break; \
} \
}
#define WRITE_STRUCT(name) void wasi_serdes_write_##name(void *ptr, size_t offset, const __wasi_##name *value)
#define READ_STRUCT(name) void wasi_serdes_read_##name(const void *ptr, size_t offset, __wasi_##name *value)
#define WRITE_FIELD(field_offset, type, field) \
do { \
wasi_serdes_write_##type(ptr, offset + field_offset, value->field); \
} while (0)
#define READ_FIELD(field_offset, type, field) \
do { \
value->field = wasi_serdes_read_##type(ptr, offset + field_offset); \
} while (0)
#define WRITE_ALIAS(new_name, old_name) \
void wasi_serdes_write_##new_name(void *ptr, size_t offset, __wasi_##new_name value) \
{ \
wasi_serdes_write_##old_name(ptr, offset, value); \
}
#define READ_ALIAS(new_name, old_name) \
__wasi_##new_name wasi_serdes_read_##new_name(const void *ptr, size_t offset) \
{ \
return wasi_serdes_read_##old_name(ptr, offset); \
}
ALL_TYPES(WRITE_STRUCT, WRITE_FIELD, WRITE_ALIAS)
ALL_TYPES(READ_STRUCT, READ_FIELD, READ_ALIAS)
static inline __wasi_errno_t
wasi_serdes_read_ciovec_t(const void *ptr, size_t end, size_t offset, __wasi_ciovec_t *value)
{
uint32_t buf_ptr;
buf_ptr = wasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = wasi_serdes_read_size_t(ptr, offset + 4);
if (!wasi_serdes_check_bounds(buf_ptr, end, value->buf_len)) return __WASI_ERRNO_OVERFLOW;
value->buf = ((uint8_t *)ptr + buf_ptr);
return __WASI_ERRNO_SUCCESS;
}
static inline __wasi_errno_t
wasi_serdes_read_iovec_t(const void *ptr, size_t end, size_t offset, __wasi_iovec_t *value)
{
uint32_t buf_ptr;
buf_ptr = wasi_serdes_read_uint32_t(ptr, offset);
value->buf_len = wasi_serdes_read_size_t(ptr, offset + 4);
if (!wasi_serdes_check_bounds(buf_ptr, end, value->buf_len)) return __WASI_ERRNO_OVERFLOW;
value->buf = ((uint8_t *)ptr + buf_ptr);
return __WASI_ERRNO_SUCCESS;
}
static inline __wasi_errno_t
wasi_serdes_readv_ciovec_t(const void *ptr, size_t end, size_t offset, __wasi_ciovec_t *iovs, __wasi_size_t iovs_len)
{
__wasi_errno_t err;
__wasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = wasi_serdes_read_ciovec_t(ptr, end, offset, &iovs[i]);
if (err != __WASI_ERRNO_SUCCESS) return err;
offset += WASI_SERDES_SIZE_ciovec_t;
}
return __WASI_ERRNO_SUCCESS;
}
static inline __wasi_errno_t
wasi_serdes_readv_iovec_t(const void *ptr, size_t end, size_t offset, __wasi_iovec_t *iovs, __wasi_size_t iovs_len)
{
__wasi_errno_t err;
__wasi_size_t i;
for (i = 0; i < iovs_len; i++) {
err = wasi_serdes_read_iovec_t(ptr, end, offset, &iovs[i]);
if (err != __WASI_ERRNO_SUCCESS) return err;
offset += WASI_SERDES_SIZE_iovec_t;
}
return __WASI_ERRNO_SUCCESS;
}
static inline int
wasi_serdes_check_array_bounds(size_t offset, size_t end, size_t size, size_t count)
{
return end > offset && ((count * size) / size == count) && (count * size <= end - offset);
}
#endif /* __WASI_SERDES_H__ */

@ -37,7 +37,7 @@ static INLINE uint32_t wasm_memory_get_page_count(struct wasm_memory *wasm_memor
/* Reading and writing to wasm_memory */
static INLINE void
wasm_memory_initialize_region(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t region_size, uint8_t region[]);
static INLINE void * wasm_memory_get_ptr_void(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE void *wasm_memory_get_ptr_void(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE int8_t wasm_memory_get_i8(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE int16_t wasm_memory_get_i16(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE int32_t wasm_memory_get_i32(struct wasm_memory *wasm_memory, uint32_t offset);
@ -45,7 +45,7 @@ static INLINE int64_t wasm_memory_get_i64(struct wasm_memory *wasm_memory, uint3
static INLINE float wasm_memory_get_f32(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE double wasm_memory_get_f64(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE char wasm_memory_get_char(struct wasm_memory *wasm_memory, uint32_t offset);
static INLINE char * wasm_memory_get_string(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE char *wasm_memory_get_string(struct wasm_memory *wasm_memory, uint32_t offset, uint32_t size);
static INLINE void wasm_memory_set_i8(struct wasm_memory *wasm_memory, uint32_t offset, int8_t value);
static INLINE void wasm_memory_set_i16(struct wasm_memory *wasm_memory, uint32_t offset, int16_t value);
static INLINE void wasm_memory_set_i32(struct wasm_memory *wasm_memory, uint32_t offset, int32_t value);

@ -7,7 +7,10 @@
* Currently this is not spec-compliant, as it only supports a single table and a single memory and it excludes many
* entities https://webassembly.github.io/spec/core/exec/runtime.html#module-instances
*/
struct wasm_module_instance {
/* Public */
struct sledge_abi__wasm_module_instance abi;
/* Private */
void *wasi_context;
};

@ -23,9 +23,9 @@
struct wasm_stack {
struct ps_list list; /* Linked List Node used for object pool */
uint64_t capacity; /* Usable capacity. Excludes size of guard page that we need to free */
uint8_t * high; /* The highest address of the stack. Grows down from here */
uint8_t * low; /* The address of the lowest useabe address. Above guard page */
uint8_t * buffer; /* Points base address of backing heap allocation (Guard Page) */
uint8_t *high; /* The highest address of the stack. Grows down from here */
uint8_t *low; /* The address of the lowest useabe address. Above guard page */
uint8_t *buffer; /* Points base address of backing heap allocation (Guard Page) */
};
static struct wasm_stack *wasm_stack_alloc(uint64_t capacity);

@ -4,7 +4,8 @@
#include <stdint.h>
#include <stdlib.h>
#include "types.h"
#include "sledge_abi.h"
#include "wasm_types.h"
/* memory also provides the table access functions */
#define INDIRECT_TABLE_SIZE (1 << 10)
@ -78,8 +79,7 @@ wasm_table_get(struct sledge_abi__wasm_table *wasm_table, uint32_t idx, uint32_t
assert(idx < wasm_table->capacity);
struct sledge_abi__wasm_table_entry f = wasm_table->buffer[idx];
// FIXME: Commented out function type check because of gocr
// assert(f.type_id == type_id);
assert(f.type_id == type_id);
assert(f.func_pointer != NULL);

@ -47,7 +47,7 @@ admissions_info_update(struct admissions_info *admissions_info, uint64_t executi
uint64_t estimated_execution = perf_window_get_percentile(perf_window, admissions_info->percentile,
admissions_info->control_index);
admissions_info->estimate = admissions_control_calculate_estimate(estimated_execution,
admissions_info->relative_deadline);
admissions_info->relative_deadline);
LOCK_UNLOCK(&admissions_info->perf_window.lock);
#endif
}

@ -10,12 +10,16 @@
#include "sandbox_set_as_complete.h"
#include "sandbox_set_as_running_user.h"
#include "sandbox_set_as_running_sys.h"
#include "sandbox_setup_arguments.h"
#include "scheduler.h"
#include "software_interrupt.h"
#include "wasi.h"
thread_local struct sandbox *worker_thread_current_sandbox = NULL;
// TODO: Propagate arguments from *.json spec file
const int dummy_argc = 1;
const char *dummy_argv[] = { "Test" };
/**
* @brief Switches from an executing sandbox to the worker thread base context
*
@ -80,12 +84,14 @@ current_sandbox_init()
assert(sandbox != NULL);
assert(sandbox->state == SANDBOX_RUNNING_SYS);
int rc = 0;
int rc = 0;
char *error_message = NULL;
sandbox_open_http(sandbox);
rc = sandbox_receive_request(sandbox);
if (rc == -2) {
error_message = "Request size exceeded Buffer\n";
/* Request size exceeded Buffer, send 413 Payload Too Large */
client_socket_send(sandbox->client_socket_descriptor, http_header_build(413), http_header_len(413),
current_sandbox_sleep);
@ -100,12 +106,22 @@ current_sandbox_init()
struct module *current_module = sandbox_get_module(sandbox);
module_initialize_globals(current_module);
module_initialize_memory(current_module);
sandbox_setup_arguments(sandbox);
/* Initialize WASI */
wasi_options_t options;
wasi_options_init(&options);
options.argc = dummy_argc;
options.argv = dummy_argv;
sandbox->wasi_context = wasi_context_init(&options);
sledge_abi__current_wasm_module_instance.wasi_context = sandbox->wasi_context;
assert(sandbox->wasi_context != NULL);
sandbox_return(sandbox);
return sandbox;
err:
debuglog("%s", error_message);
sandbox_close_http(sandbox);
generic_thread_dump_lock_overhead();
current_sandbox_exit();
@ -161,8 +177,7 @@ void
current_sandbox_start(void)
{
struct sandbox *sandbox = current_sandbox_init();
struct module * current_module = sandbox_get_module(sandbox);
int32_t argument_count = 0;
sandbox->return_value = module_entrypoint(current_module, argument_count, sandbox->arguments_offset);
struct module *current_module = sandbox_get_module(sandbox);
sandbox->return_value = module_entrypoint(current_module);
current_sandbox_fini();
}

@ -12,6 +12,7 @@ thread_local struct wasm_module_instance sledge_abi__current_wasm_module_instanc
.capacity = 0,
.buffer = NULL,
},
.abi.table = NULL,
.abi.wasmg_0 = 0xDEADBEEF,
.abi.table = NULL,
.abi.wasmg_0 = 0xDEADBEEF,
.wasi_context = NULL,
};

@ -1,158 +0,0 @@
#include <assert.h>
#include <ck_pr.h>
#include <math.h>
#include "arch/getcycles.h"
#include "worker_thread.h"
#include "current_sandbox.h"
extern int32_t inner_syscall_handler(int32_t n, int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f);
int32_t
env_syscall_handler(int32_t n, int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f)
{
int32_t i = inner_syscall_handler(n, a, b, c, d, e, f);
return i;
}
int32_t
env___syscall(int32_t n, int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f)
{
return env_syscall_handler(n, a, b, c, d, e, f);
}
void
env___unmapself(uint32_t base, uint32_t size)
{
/* Just do some no op */
}
int32_t
env_a_ctz_64(uint64_t x)
{
return __builtin_ctzll(x);
}
INLINE void
env_a_and_64(int32_t p_off, uint64_t v)
{
uint64_t *p = current_sandbox_get_ptr_void(p_off, sizeof(uint64_t));
ck_pr_and_64(p, v);
}
INLINE void
env_a_or_64(int32_t p_off, int64_t v)
{
assert(sizeof(int64_t) == sizeof(uint64_t));
uint64_t *p = current_sandbox_get_ptr_void(p_off, sizeof(int64_t));
ck_pr_or_64(p, v);
}
int32_t
env_a_cas(int32_t p_off, int32_t t, int32_t s)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *p = current_sandbox_get_ptr_void(p_off, sizeof(int32_t));
return ck_pr_cas_int(p, t, s);
}
void
env_a_or(int32_t p_off, int32_t v)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *p = current_sandbox_get_ptr_void(p_off, sizeof(int32_t));
ck_pr_or_int(p, v);
}
int32_t
env_a_swap(int32_t x_off, int32_t v)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *x = current_sandbox_get_ptr_void(x_off, sizeof(int32_t));
int p;
do {
p = ck_pr_load_int(x);
} while (!ck_pr_cas_int(x, p, v));
v = p;
return v;
}
int32_t
env_a_fetch_add(int32_t x_off, int32_t v)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *x = current_sandbox_get_ptr_void(x_off, sizeof(int32_t));
return ck_pr_faa_int(x, v);
}
void
env_a_inc(int32_t x_off)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *x = current_sandbox_get_ptr_void(x_off, sizeof(int32_t));
ck_pr_inc_int(x);
}
void
env_a_dec(int32_t x_off)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *x = (int *)current_sandbox_get_ptr_void(x_off, sizeof(int32_t));
ck_pr_dec_int(x);
}
void
env_a_store(int32_t p_off, int32_t x)
{
assert(sizeof(int32_t) == sizeof(volatile int));
int *p = (int *)current_sandbox_get_ptr_void(p_off, sizeof(int32_t));
ck_pr_store_int(p, x);
}
int
env_a_ctz_32(int32_t x)
{
return __builtin_ctz(x);
}
void
env_do_spin(int32_t i)
{
ck_pr_stall();
}
void
env_do_crash(int32_t i)
{
printf("crashing: %d\n", i);
assert(0);
}
void
env_do_barrier(int32_t x)
{
ck_pr_barrier();
}
/* Floating point routines */
INLINE double
env_sin(double d)
{
return sin(d);
}
INLINE double
env_cos(double d)
{
return cos(d);
}
INLINE unsigned long long
env_getcycles(void)
{
return __getcycles();
}

@ -42,7 +42,7 @@ http_parser_settings_on_url(http_parser *parser, const char *at, size_t length)
int
http_parser_settings_on_message_begin(http_parser *parser)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
assert(!sandbox->http_request.message_end);
@ -70,7 +70,7 @@ http_parser_settings_on_message_begin(http_parser *parser)
int
http_parser_settings_on_header_field(http_parser *parser, const char *at, size_t length)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
#ifdef LOG_HTTP_PARSER
@ -113,7 +113,7 @@ http_parser_settings_on_header_field(http_parser *parser, const char *at, size_t
int
http_parser_settings_on_header_value(http_parser *parser, const char *at, size_t length)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
@ -145,7 +145,7 @@ http_parser_settings_on_header_value(http_parser *parser, const char *at, size_t
int
http_parser_settings_on_header_end(http_parser *parser)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
assert(!sandbox->http_request.message_end);
@ -160,7 +160,7 @@ http_parser_settings_on_header_end(http_parser *parser)
}
const size_t http_methods_len = 8;
const char * http_methods[http_methods_len] = { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT" };
const char *http_methods[http_methods_len] = { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT" };
/**
* http-parser callback called for HTTP Bodies
@ -174,7 +174,7 @@ const char * http_methods[http_methods_len] = { "OPTIONS", "GET", "HEAD", "POST"
int
http_parser_settings_on_body(http_parser *parser, const char *at, size_t length)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
assert(sandbox->http_request.header_end);
@ -216,7 +216,7 @@ http_parser_settings_on_body(http_parser *parser, const char *at, size_t length)
int
http_parser_settings_on_msg_end(http_parser *parser)
{
struct sandbox * sandbox = (struct sandbox *)parser->data;
struct sandbox *sandbox = (struct sandbox *)parser->data;
struct http_request *http_request = &sandbox->http_request;
assert(sandbox->http_request.header_end);

@ -1,454 +0,0 @@
/*
* This code originally came from the aWsm compiler
* It has since been updated
* https://github.com/gwsystems/aWsm/blob/master/runtime/libc/libc_backing.c
*/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include "current_sandbox.h"
#include "scheduler.h"
#include "sandbox_functions.h"
#include "worker_thread.h"
#include "wasm_module_instance.h"
// What should we tell the child program its UID and GID are?
#define UID 0xFF
#define GID 0xFE
// Elf auxilary vector values (see google for what those are)
#define AT_PHENT 4
#define AT_PAGESZ 6
#define AT_BASE 7
#define AT_FLAGS 8
#define AT_ENTRY 9
#define AT_NOTELF 10
#define AT_UID 11
#define AT_EUID 12
#define AT_GID 13
#define AT_EGID 14
#define AT_CLKTCK 17
#define AT_SECURE 23
#define AT_BASE_PLATFORM 24
#define AT_RANDOM 25
// offset = a WASM ptr to memory the runtime can use
void
stub_init(int32_t offset)
{
struct sandbox *current_sandbox = current_sandbox_get();
// What program name will we put in the auxiliary vectors
char *program_name = current_sandbox->module->name;
// Copy the program name into WASM accessible memory
int32_t program_name_offset = offset;
strcpy(wasm_memory_get_ptr_void(current_sandbox->memory, offset, sizeof(program_name)), program_name);
offset += sizeof(program_name);
// The construction of this is:
// evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL
int32_t env_vec[] = {
// Env variables would live here, but we don't supply any
0,
// We supply only the bare minimum AUX vectors
AT_PAGESZ,
WASM_PAGE_SIZE,
AT_UID,
UID,
AT_EUID,
UID,
AT_GID,
GID,
AT_EGID,
GID,
AT_SECURE,
0,
AT_RANDOM,
(int32_t)rand(), // It's pretty stupid to use rand here, but w/e
0,
};
int32_t env_vec_offset = offset;
memcpy(wasm_memory_get_ptr_void(current_sandbox->memory, env_vec_offset, sizeof(env_vec)), env_vec,
sizeof(env_vec));
module_initialize_libc(current_sandbox_get()->module, env_vec_offset, program_name_offset);
}
// Emulated syscall implementations
// We define our own syscall numbers, because WASM uses x86_64 values even on systems that are not x86_64
#define SYS_READ 0
/**
* @param filedes to read
* @param buf_offset offset into wasm linear memory
* @param nbyte number of bytes to read
* @returns returns bytes read or -errno
*/
uint32_t
wasm_read(int32_t filedes, int32_t buf_offset, int32_t nbyte)
{
struct sandbox *current_sandbox = current_sandbox_get();
/* Non-blocking copy on stdin */
if (filedes == 0) {
char * buffer = current_sandbox_get_ptr_void(buf_offset, nbyte);
struct http_request *current_request = &current_sandbox->http_request;
if (current_request->body_length <= 0) return 0;
int bytes_to_read = nbyte > current_request->body_length ? current_request->body_length : nbyte;
memcpy(buffer, current_request->body + current_request->body_read_length, bytes_to_read);
current_request->body_read_length += bytes_to_read;
current_request->body_length -= bytes_to_read;
return bytes_to_read;
}
char *buf = current_sandbox_get_ptr_void(buf_offset, nbyte);
int32_t res = 0;
while (res < nbyte) {
/* Read from the Socket */
int32_t length_read = (int32_t)read(filedes, buf, nbyte);
if (length_read < 0) {
if (errno == EAGAIN)
current_sandbox_sleep();
else {
/* All other errors */
debuglog("Error reading socket %d - %s\n", filedes, strerror(errno));
goto err;
}
}
res += length_read;
}
done:
return res;
err:
res = -errno;
goto done;
}
#define SYS_WRITE 1
int32_t
wasm_write(int32_t fd, int32_t buf_offset, int32_t buf_size)
{
struct sandbox *s = current_sandbox_get();
char * buffer = current_sandbox_get_ptr_void(buf_offset, buf_size);
struct vec_u8 * response = &s->response;
if (fd == STDERR_FILENO) { write(STDERR_FILENO, buffer, buf_size); }
if (fd == STDOUT_FILENO) {
int buffer_remaining = response->capacity - response->length;
int to_write = buffer_remaining > buf_size ? buf_size : buffer_remaining;
if (to_write == 0) return 0;
memcpy(&response->buffer[response->length], buffer, to_write);
response->length += to_write;
return to_write;
}
int res = ENOTSUP;
done:
return res;
err:
res = -errno;
goto done;
}
#define WO_RDONLY 00
#define WO_WRONLY 01
#define WO_RDWR 02
#define WO_CREAT 0100
#define WO_EXCL 0200
#define WO_APPEND 02000
#define WO_RSYNC 04010000
#define WO_DIRECTORY 0200000
#define WO_NOFOLLOW 0400000
#define WO_CLOEXEC 02000000
#define SYS_OPEN 2
int32_t
wasm_open(int32_t path_off, int32_t flags, int32_t mode)
{
char *path = current_sandbox_get_string(path_off, MODULE_MAX_PATH_LENGTH);
int res = ENOTSUP;
return res;
}
#define SYS_CLOSE 3
int32_t
wasm_close(int32_t fd)
{
// Silently disregard client requests to close STDIN, STDOUT, or STDERR
if (fd <= STDERR_FILENO) return 0;
int res = ENOTSUP;
return res;
}
#define SYS_LSEEK 8
int32_t
wasm_lseek(int32_t filedes, int32_t file_offset, int32_t whence)
{
int32_t res = (int32_t)lseek(filedes, file_offset, whence);
if (res == -1) return -errno;
return res;
}
#define SYS_MMAP 9
uint32_t
wasm_mmap(int32_t addr, int32_t len, int32_t prot, int32_t flags, int32_t fd, int32_t offset)
{
if (addr != 0) {
printf("parameter void *addr is not supported!\n");
assert(0);
}
if (fd != -1) {
printf("file mapping is not supported!\n");
assert(0);
}
assert(len % WASM_PAGE_SIZE == 0);
int32_t result = wasm_memory_get_size(
(struct wasm_memory *)&sledge_abi__current_wasm_module_instance.abi.memory);
if (wasm_memory_expand((struct wasm_memory *)&sledge_abi__current_wasm_module_instance.abi.memory, len) == -1) {
result = (uint32_t)-1;
}
return result;
}
#define SYS_MUNMAP 11
#define SYS_BRK 12
#define SYS_RT_SIGACTION 13
#define SYS_RT_SIGPROGMASK 14
#define SYS_IOCTL 16
int32_t
wasm_ioctl(int32_t fd, int32_t request, int32_t data_offet)
{
// musl libc does some ioctls to stdout, so just allow these to silently go through
// FIXME: The above is idiotic
return 0;
}
#define SYS_READV 19
struct wasm_iovec {
int32_t base_offset;
int32_t len;
};
int32_t
wasm_readv(int32_t fd, int32_t iov_offset, int32_t iovcnt)
{
int32_t read = 0;
struct wasm_iovec *iov = current_sandbox_get_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec));
for (int i = 0; i < iovcnt; i++) { read += wasm_read(fd, iov[i].base_offset, iov[i].len); }
return read;
}
#define SYS_WRITEV 20
int32_t
wasm_writev(int32_t fd, int32_t iov_offset, int32_t iovcnt)
{
struct sandbox *s = current_sandbox_get();
if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
// both 1 and 2 go to client.
int len = 0;
struct wasm_iovec *iov = current_sandbox_get_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec));
for (int i = 0; i < iovcnt; i++) { len += wasm_write(fd, iov[i].base_offset, iov[i].len); }
return len;
}
// TODO: Implement below
assert(0);
struct wasm_iovec *iov = current_sandbox_get_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec));
// If we aren't on MUSL, pass writev to printf if possible
#if defined(__GLIBC__)
if (fd == 1) {
int sum = 0;
for (int i = 0; i < iovcnt; i++) {
int32_t len = iov[i].len;
void * ptr = current_sandbox_get_ptr_void(iov[i].base_offset, len);
printf("%.*s", len, (char *)ptr);
sum += len;
}
return sum;
}
#endif
struct iovec vecs[iovcnt];
for (int i = 0; i < iovcnt; i++) {
int32_t len = iov[i].len;
void * ptr = current_sandbox_get_ptr_void(iov[i].base_offset, len);
vecs[i] = (struct iovec){ ptr, len };
}
int32_t res = (int32_t)writev(fd, vecs, iovcnt);
if (res == -1) return -errno;
return res;
}
#define SYS_MREMAP 25
int32_t
wasm_mremap(int32_t offset, int32_t old_size, int32_t new_size, int32_t flags)
{
assert(offset >= 0);
assert(offset + old_size <= INT32_MAX);
// We do not implement compaction yet, so just return immediately if shrinking
if (new_size <= old_size) return offset;
// If at end of linear memory, just expand and return same address
if (offset + old_size == sledge_abi__current_wasm_module_instance.abi.memory.size) {
int32_t amount_to_expand = new_size - old_size;
wasm_memory_expand((struct wasm_memory *)&sledge_abi__current_wasm_module_instance.abi.memory,
amount_to_expand);
return offset;
}
// Otherwise allocate at end of address space and copy
int32_t new_offset = sledge_abi__current_wasm_module_instance.abi.memory.size;
wasm_memory_expand((struct wasm_memory *)&sledge_abi__current_wasm_module_instance.abi.memory, new_size);
// Get pointer of old offset and pointer of new offset
uint8_t *linear_mem = sledge_abi__current_wasm_module_instance.abi.memory.buffer;
uint8_t *src = &linear_mem[offset];
uint8_t *dest = &linear_mem[new_offset];
// Copy Values. We can use memcpy because we don't overlap
memcpy((void *)dest, (void *)src, old_size);
return new_offset;
}
#define SYS_MADVISE 28
#define SYS_GETPID 39
uint32_t
wasm_getpid()
{
return (uint32_t)getpid();
}
#define WF_SETFD 2
#define WF_GETSIG 11
#define WF_SETLK 6
#define WF_SETLKW 7
#define SYS_SET_THREAD_AREA 205
#define SYS_SET_TID_ADDRESS 218
#define SYS_GET_TIME 228
struct wasm_time_spec {
uint64_t sec;
uint32_t nanosec;
};
int32_t
wasm_get_time(int32_t clock_id, int32_t timespec_off)
{
clockid_t real_clock;
switch (clock_id) {
case 0:
real_clock = CLOCK_REALTIME;
break;
case 1:
real_clock = CLOCK_MONOTONIC;
break;
case 2:
real_clock = CLOCK_PROCESS_CPUTIME_ID;
break;
default:
assert(0);
}
struct wasm_time_spec *timespec = current_sandbox_get_ptr_void(timespec_off, sizeof(struct wasm_time_spec));
struct timespec native_timespec = { 0, 0 };
int res = clock_gettime(real_clock, &native_timespec);
if (res == -1) return -errno;
timespec->sec = native_timespec.tv_sec;
timespec->nanosec = native_timespec.tv_nsec;
return res;
}
#define SYS_EXIT 60
#define SYS_EXIT_GROUP 231
int32_t
wasm_exit_group(int32_t status)
{
debuglog("Called wasm_exit_group");
// I believe that if a sandbox called this, it would cause the runtime to exit
// exit(status);
return 0;
}
int32_t
inner_syscall_handler(int32_t n, int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f)
{
switch (n) {
case SYS_READ:
return wasm_read(a, b, c);
case SYS_WRITE:
return wasm_write(a, b, c);
case SYS_WRITEV:
return wasm_writev(a, b, c);
case SYS_CLOSE:
return wasm_close(a);
case SYS_LSEEK:
return wasm_lseek(a, b, c);
case SYS_EXIT:
case SYS_EXIT_GROUP:
return wasm_exit_group(a);
case SYS_MMAP:
return wasm_mmap(a, b, c, d, e, f);
case SYS_GET_TIME:
return wasm_get_time(a, b);
case SYS_READV:
return wasm_readv(a, b, c);
case SYS_MUNMAP:
case SYS_IOCTL:
case SYS_SET_THREAD_AREA:
case SYS_SET_TID_ADDRESS:
case SYS_BRK:
case SYS_MREMAP:
return wasm_mremap(a, b, c, b);
case SYS_MADVISE:
/* Note: These are called, but are unimplemented and fail silently */
return 0;
case SYS_RT_SIGACTION:
case SYS_RT_SIGPROGMASK:
default:
/* This is a general catch all for the other functions below */
debuglog("Call to unknown or implemented syscall %d\n", n);
debuglog("syscall %d (%d, %d, %d, %d, %d, %d)\n", n, a, b, c, d, e, f);
errno = ENOSYS;
return -1;
}
}

File diff suppressed because it is too large Load Diff

@ -334,6 +334,16 @@ log_compiletime_config()
#endif
}
void
check_versions()
{
// Additional functions have become async signal safe over time. Validate latest
static_assert(_POSIX_VERSION >= 200809L, "Requires POSIX 2008 or higher\n");
// We use C18 features
static_assert(__STDC_VERSION__ >= 201710, "Requires C18 or higher\n");
static_assert(__linux__ == 1, "Requires epoll, a Linux-only feature");
}
int
main(int argc, char **argv)
{
@ -344,6 +354,7 @@ main(int argc, char **argv)
printf("Starting the Sledge runtime\n");
log_compiletime_config();
runtime_process_debug_log_behavior();

@ -29,7 +29,7 @@
**************************/
pthread_t *runtime_worker_threads;
int * runtime_worker_threads_argument;
int *runtime_worker_threads_argument;
/* The active deadline of the sandbox running on each worker thread */
uint64_t *runtime_worker_threads_deadline;
@ -63,7 +63,7 @@ runtime_set_resource_limits_to_max()
char max[uint64_t_max_digits + 1];
uint64_t resources[] = { RLIMIT_DATA, RLIMIT_NOFILE };
char * resource_names[] = { "RLIMIT_DATA", "RLIMIT_NOFILE" };
char *resource_names[] = { "RLIMIT_DATA", "RLIMIT_NOFILE" };
for (int i = 0; i < sizeof(resources) / sizeof(resources[0]); i++) {
int resource = resources[i];

@ -112,7 +112,7 @@ sandbox_prepare_execution_environment(struct sandbox *sandbox)
{
assert(sandbox != NULL);
char * error_message = "";
char *error_message = "";
uint64_t now = __getcycles();
int rc;
@ -202,7 +202,8 @@ sandbox_alloc(struct module *module, int socket_descriptor, const struct sockadd
{
struct sandbox *sandbox = NULL;
size_t page_aligned_sandbox_size = round_up_to_page(sizeof(struct sandbox));
sandbox = calloc(1, page_aligned_sandbox_size);
sandbox = aligned_alloc(PAGE_SIZE, page_aligned_sandbox_size);
memset(sandbox, 0, page_aligned_sandbox_size);
if (unlikely(sandbox == NULL)) return NULL;
sandbox_set_as_allocated(sandbox);
@ -225,7 +226,6 @@ sandbox_deinit(struct sandbox *sandbox)
/* Linear Memory and Guard Page should already have been munmaped and set to NULL */
assert(sandbox->memory == NULL);
/* Free Sandbox Struct*/
if (likely(sandbox->stack != NULL)) sandbox_free_stack(sandbox);
if (likely(sandbox->globals.buffer != NULL)) sandbox_free_globals(sandbox);

File diff suppressed because it is too large Load Diff

@ -110,7 +110,7 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
assert(handler_depth == 0);
atomic_fetch_add(&handler_depth, 1);
ucontext_t * interrupted_context = (ucontext_t *)interrupted_context_raw;
ucontext_t *interrupted_context = (ucontext_t *)interrupted_context_raw;
struct sandbox *current_sandbox = current_sandbox_get();
switch (signal_type) {
@ -128,10 +128,8 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
/* We transition the sandbox to an interrupted state to exclude time propagating signals and
* running the scheduler from per-sandbox accounting */
sandbox_state_t interrupted_state = current_sandbox->state;
sandbox_interrupt(current_sandbox);
propagate_sigalrm(signal_info);
atomic_fetch_add(&deferred_sigalrm, 1);
sandbox_interrupt_return(current_sandbox, interrupted_state);
}
break;

@ -133,6 +133,6 @@ declare -Ar port=(
)
# Sort the images by the number of labeled plates
declare -a cifar10_images=(./images/bmp/*)
declare -a cifar10_images=(../../../applications/wasm_apps/CMSIS_5_NN/images/bmp/*)
framework_init "$@"

@ -53,7 +53,7 @@ experiment_client() {
# Copy data if not here
if [[ ! -f "$__run_sh__base_path/initial_state.dat" ]]; then
pushd "$__run_sh__base_path" || exit 1
pushd "../../../applications/wasmception_apps/TinyEKF/extras/c/" || exit 1
pushd "../../../applications/wasm_apps/TinyEKF/extras/c/" || exit 1
cp ekf_raw.dat "$__run_sh__base_path/initial_state.dat" || exit 1
popd || exit 1
popd || exit 1

@ -56,7 +56,7 @@ validate_dependencies curl compare
# Copy Flower Image if not here
if [[ ! -f "./flower.jpg" ]]; then
cp "$__run_sh__project_base_absolute_path/applications/wasmception_apps/sod/samples/flower.jpg" ./flower.jpg
cp "$__run_sh__project_base_absolute_path/applications/wasm_apps/sod/samples/flower.jpg" ./flower.jpg
fi
framework_init "$@"

@ -1,7 +1,7 @@
RUNTIME_DIR=../../../../runtime/
SLEDGE_BINARY_DIR=${RUNTIME_DIR}/bin
HOSTNAME=localhost
IMAGE=./images/Cars0.png
IMAGE=../../../../applications/wasm_apps/sod/samples/plates/Cars0.png
.PHONY: all
all: run

@ -148,6 +148,6 @@ while IFS= read -r image_data; do
4) lpd4_images+=("$image_file") ;;
*) panic "Unexpected number of plates" ;;
esac
done < <(ls ./images/*.csv)
done < <(ls ../../../../applications/wasm_apps/sod/samples/plates/*.csv)
framework_init "$@"

Loading…
Cancel
Save