From: Luke Lau Date: Tue, 4 Dec 2018 15:47:56 +0000 (+0000) Subject: Initial commit X-Git-Url: https://git.lukelau.me/?p=wasm.git;a=commitdiff_plain;h=3ef5cb466b695cba27e45bbb273af1a9aa71bad9 Initial commit --- 3ef5cb466b695cba27e45bbb273af1a9aa71bad9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..05df33d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +toolchain/build +sysroot +*.swp +.DS_Store +test.wasm diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a778183 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,15 @@ +[submodule "toolchain/src/llvm"] + path = toolchain/src/llvm + url = https://git.llvm.org/git/llvm +[submodule "toolchain/src/musl"] + path = toolchain/src/musl + url = https://github.com/jfbastien/musl.git +[submodule "toolchain/src/libcxxabi"] + path = toolchain/src/libcxxabi + url = http://llvm.org/git/libcxxabi +[submodule "toolchain/src/compiler-rt"] + path = toolchain/src/compiler-rt + url = http://llvm.org/git/compiler-rt +[submodule "toolchain/src/libcxx"] + path = toolchain/src/libcxx + url = http://llvm.org/git/libcxx diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5bfb9ad --- /dev/null +++ b/Makefile @@ -0,0 +1,54 @@ +# build llvm and clang (for wasm only) +toolchain/build/llvm/bin/clang: + mkdir -p toolchain/build/llvm + cmake -G "Unix Makefiles" \ + -DLLVM_TARGETS_TO_BUILD= \ + -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly \ + -S toolchain/src/llvm -B toolchain/build/llvm + # install the tools we need + $(MAKE) -C toolchain/build/llvm clang lld llvm-ar llvm-config llvm-ranlib + +ROOT_DIR=${CURDIR} +# now build libc +sysroot/lib/libc.a: toolchain/build/llvm/bin/clang + mkdir -p toolchain/build/musl + cd toolchain/build/musl; $(ROOT_DIR)/toolchain/src/musl/configure \ + CC=$(ROOT_DIR)/toolchain/build/llvm/bin/clang \ + CFLAGS="--target=wasm32-unknown-unknown-wasm -O3" \ + --prefix=$(ROOT_DIR)/sysroot \ + wasm32 + $(MAKE) -C toolchain/build/musl install \ + CROSS_COMPILE=$(ROOT_DIR)/toolchain/build/llvm/bin/llvm- + # need to copy over musl's list of javascript function imports + cp toolchain/src/musl/arch/wasm32/libc.imports sysroot/lib + +# build the wasm32 builtins +toolchain/build/llvm/lib/clang/8.0.0/lib/libclang_rt.builtins-wasm32.a: toolchain/build/llvm/bin/clang + mkdir -p toolchain/build/compiler-rt + cmake -G "Unix Makefiles" \ + -DCMAKE_TOOLCHAIN_FILE=$(ROOT_DIR)/toolchain/compiler-rt.cmake \ + -S toolchain/src/compiler-rt/lib/builtins -B toolchain/build/compiler-rt + $(MAKE) -C toolchain/build/compiler-rt/ install + +sysroot/lib/libc++.a: toolchain/build/llvm/bin/clang toolchain/build/llvm/lib/clang/8.0.0/lib/libclang_rt.builtins-wasm32.a sysroot/lib/libc.a + mkdir -p toolchain/build/libcxx + cmake -G "Unix Makefiles" \ + -DCMAKE_TOOLCHAIN_FILE=$(ROOT_DIR)/toolchain/libcxx.cmake \ + -S toolchain/src/libcxx/ -B toolchain/build/libcxx + $(MAKE) -C toolchain/build/libcxx install + +sysroot/lib/libc++abi.a: toolchain/build/llvm/bin/clang sysroot/lib/libc++.a + mkdir -p toolchain/build/libcxxabi + cmake -G "Unix Makefiles" \ + -DCMAKE_TOOLCHAIN_FILE=$(ROOT_DIR)/toolchain/libcxxabi.cmake \ + -S toolchain/src/libcxxabi -B toolchain/build/libcxxabi + $(MAKE) -C toolchain/build/libcxxabi install + + +sysroot: sysroot/lib/libc.a sysroot/lib/libc++.a sysroot/lib/libc++abi.a + +test.wasm: test.cpp sysroot + clang++ --target=wasm32-unknown-unknown-wasm -g \ + -fno-exceptions --sysroot=sysroot -nostartfiles \ + -Wl,--export=foo,--demangle,--no-entry \ + test.cpp -o test.wasm diff --git a/Server.hs b/Server.hs new file mode 100644 index 0000000..a1ec3da --- /dev/null +++ b/Server.hs @@ -0,0 +1,11 @@ +{-# LANGUAGE OverloadedStrings #-} +module Main where +import Data.Text (Text) + +import qualified Network.WebSockets as WS + +main :: IO () +main = do + WS.runServer "127.0.0.1" 8889 $ \pending -> do + conn <- WS.acceptRequest pending + WS.sendTextData conn ("Hello there" :: Text) diff --git a/index.html b/index.html new file mode 100644 index 0000000..33cf2d3 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + diff --git a/main.js b/main.js new file mode 100644 index 0000000..5ee3c09 --- /dev/null +++ b/main.js @@ -0,0 +1,23 @@ +const memory = new WebAssembly.Memory( { initial: 2, maximum: 8 }) +const imports = { + env: { + __syscall1: (n, a) => console.log(n), + __syscall3: (n, a, b, c) => console.log(n), + __syscall5: (n, a, b, c, d, e) => console.log(n) + } +} + +const sock = new WebSocket('ws://localhost:8889') +sock.onmessage = function (e) { + console.log(e.data) +} + +function instantiate(bytes) { + return WebAssembly.compile(bytes). + then(m => new WebAssembly.Instance(m, imports)); +} + +fetch('test.wasm') + .then(response => response.arrayBuffer()) + .then(bytes => instantiate(bytes)) + .then(instance => console.log(instance.exports.foo())); diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..da73b69 --- /dev/null +++ b/test.cpp @@ -0,0 +1,6 @@ +#include +extern "C" int foo() { + std::vector *xs = new std::vector(); + xs->push_back(42); + return (*xs)[0]; +} diff --git a/toolchain/compiler-rt.cmake b/toolchain/compiler-rt.cmake new file mode 100644 index 0000000..1e21c25 --- /dev/null +++ b/toolchain/compiler-rt.cmake @@ -0,0 +1,13 @@ +include(${CMAKE_CURRENT_LIST_DIR}/settings.cmake) + +# compiler-rt options +set(COMPILER_RT_DEFAULT_TARGET_ONLY ON CACHE STRING "wasm") +set(COMPILER_RT_INCLUDE_TESTS OFF CACHE STRING "wasm") +set(COMPILER_RT_BAREMETAL_BUILD ON CACHE STRING "wasm") +set(COMPILER_RT_ENABLE_IOS OFF CACHE STRING "wasm") +set(COMPILER_RT_BUILD_XRAY OFF CACHE STRING "wasm") + +# install into the clang lib folder +set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_LIST_DIR}/build/llvm/lib/clang/8.0.0 CACHE STRING "wasm") +set(COMPILER_RT_OS_DIR . CACHE STRING "wasm") + diff --git a/toolchain/libcxx.cmake b/toolchain/libcxx.cmake new file mode 100644 index 0000000..936558b --- /dev/null +++ b/toolchain/libcxx.cmake @@ -0,0 +1,24 @@ +include(${CMAKE_CURRENT_LIST_DIR}/settings.cmake) + +set(CMAKE_CXX_FLAGS "--target=wasm32-unknown-unknown-wasm -D_LIBCPP_HAS_MUSL_LIBC" CACHE STRING "wasm") + +# no fancy stuff por favor +set(LIBCXX_ENABLE_THREADS OFF CACHE STRING "wasm") +set(LIBCXX_ENABLE_EXCEPTIONS OFF CACHE STRING "wasm") + +# no libc++.dylib, all static linking +set(LIBCXX_ENABLE_SHARED OFF CACHE STRING "wasm") + +# don't bother building libc++experimental.a +set(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY OFF CACHE STRING "wasm") +# same for libc++fs.a +set(LIBCXX_ENABLE_FILESYSTEM OFF CACHE STRING "wasm") + +# set(LIBCXX_ENABLE_STDIN OFF) +# set(LIBCXX_ENABLE_STDOUT OFF CACHE STRING "wasm") + +# set(CMAKE_EXE_LINKER_FLAGS "-Wl,--allow-undefined-file=${CMAKE_CURRENT_LIST_DIR}/../sysroot/lib/libc.imports,--no-threads" CACHE STRING "wasm") + +set(LIBCXX_CXX_ABI libcxxabi CACHE STRING "wasm") +set(LIBCXX_CXX_ABI_INCLUDE_PATHS ${CMAKE_CURRENT_LIST_DIR}/src/libcxxabi/include CACHE STRING "wasm") + diff --git a/toolchain/libcxxabi.cmake b/toolchain/libcxxabi.cmake new file mode 100644 index 0000000..fdb7268 --- /dev/null +++ b/toolchain/libcxxabi.cmake @@ -0,0 +1,19 @@ +include(${CMAKE_CURRENT_LIST_DIR}/settings.cmake) + +set(CMAKE_CXX_FLAGS "--target=wasm32-unknown-unknown-wasm -D_LIBCPP_HAS_MUSL_LIBC" CACHE STRING "wasm") + +# no fancy stuff +set(LIBCXXABI_ENABLE_THREADS OFF CACHE STRING "wasm") +set(LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE STRING "wasm") + +# no libc++abi.dylib +set(LIBCXXABI_ENABLE_SHARED OFF CACHE STRING "wasm") + +set(CXX_SUPPORTS_CXX11 ON CACHE STRING "wasm") +set(LLVM_COMPILER_CHECKED ON CACHE STRING "wasm") +set(UNIX ON CACHE STRING "wasm") + +set(LIBCXXABI_LIBCXX_PATH ${CMAKE_CURRENT_LIST_DIR}/src/libcxx CACHE STRING "wasm") +set(LIBCXXABI_LIBCXX_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/../sysroot/include/c++/v1 CACHE STRING "wasm") + + diff --git a/toolchain/settings.cmake b/toolchain/settings.cmake new file mode 100644 index 0000000..5e1badd --- /dev/null +++ b/toolchain/settings.cmake @@ -0,0 +1,23 @@ +set(CMAKE_SYSTEM_NAME Wasm) +set(CMAKE_SYSTEM_PROCESSOR wasm32) + +set(CMAKE_BUILD_TYPE RelWithDebInfo) + +set(LLVM_CONFIG_PATH ${CMAKE_CURRENT_LIST_DIR}/build/llvm/bin/llvm-config) + +set(CMAKE_C_COMPILER ${CMAKE_CURRENT_LIST_DIR}/build/llvm/bin/clang) +set(CMAKE_C_COMPILER_TARGET wasm32-unknown-unknown-wasm) +set(CMAKE_C_FLAGS "--target=wasm32-unknown-unknown-wasm -O3") + +set(CMAKE_CXX_COMPILER ${CMAKE_CURRENT_LIST_DIR}/build/llvm/bin/clang++) +set(CMAKE_CXX_COMPILER_TARGET wasm32-unknown-unknown-wasm) + +set(CMAKE_SYSROOT ${CMAKE_CURRENT_LIST_DIR}/../sysroot CACHE STRING "wasm") +# install all the libs and includes into the sysroot folder, not /usr/local +set(CMAKE_STAGING_PREFIX ${CMAKE_CURRENT_LIST_DIR}/../sysroot CACHE STRING "wasm") + +set(CMAKE_AR ${CMAKE_CURRENT_LIST_DIR}/build/llvm/bin/llvm-ar) + +set(CMAKE_C_COMPILER_WORKS ON) +set(CMAKE_CXX_COMPILER_WORKS ON) + diff --git a/toolchain/src/compiler-rt b/toolchain/src/compiler-rt new file mode 160000 index 0000000..84a39fa --- /dev/null +++ b/toolchain/src/compiler-rt @@ -0,0 +1 @@ +Subproject commit 84a39fa8a9e89e1bd7d5c241863bc6042deeaa41 diff --git a/toolchain/src/libcxx b/toolchain/src/libcxx new file mode 160000 index 0000000..a815a3f --- /dev/null +++ b/toolchain/src/libcxx @@ -0,0 +1 @@ +Subproject commit a815a3f8ccb1c9346dab7b8a55c6e96073200a63 diff --git a/toolchain/src/libcxxabi b/toolchain/src/libcxxabi new file mode 160000 index 0000000..307bb62 --- /dev/null +++ b/toolchain/src/libcxxabi @@ -0,0 +1 @@ +Subproject commit 307bb62985575b2e3216a8cfd7e122e0574f33a9 diff --git a/toolchain/src/llvm b/toolchain/src/llvm new file mode 160000 index 0000000..8a38ce8 --- /dev/null +++ b/toolchain/src/llvm @@ -0,0 +1 @@ +Subproject commit 8a38ce8063b0e96461f7abbf450d4111f6886247 diff --git a/toolchain/src/musl b/toolchain/src/musl new file mode 160000 index 0000000..65f7253 --- /dev/null +++ b/toolchain/src/musl @@ -0,0 +1 @@ +Subproject commit 65f7253c1e16fe6b274bf6c24c2c0c33800d00d6