diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d643fd4..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "wasm3-sys/wasm3"] - path = wasm3-sys/wasm3 - url = https://github.com/wasm3/wasm3 diff --git a/wasm3-sys/wasm3 b/wasm3-sys/wasm3 deleted file mode 160000 index 6b8bcb1..0000000 --- a/wasm3-sys/wasm3 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6b8bcb1e07bf26ebef09a7211b0a37a446eafd52 diff --git a/wasm3-sys/wasm3/.codespellrc b/wasm3-sys/wasm3/.codespellrc new file mode 100644 index 0000000..5a26d39 --- /dev/null +++ b/wasm3-sys/wasm3/.codespellrc @@ -0,0 +1,5 @@ +[codespell] +skip = ./test/wasi/brotli/alice29.txt,./test/.spec-*,./build* +quiet-level = 2 +ignore-words-list = gameboy,iif,strng,woh + diff --git a/wasm3-sys/wasm3/.github/workflows/publish.yml b/wasm3-sys/wasm3/.github/workflows/publish.yml new file mode 100644 index 0000000..5b9ba1e --- /dev/null +++ b/wasm3-sys/wasm3/.github/workflows/publish.yml @@ -0,0 +1,180 @@ +name: publish + +on: + push: + tags: + - "v*.*.*" + +env: + draft: true + +jobs: + wasm3-windows: + runs-on: windows-latest + name: ${{ matrix.config.target }} + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + config: + - {target: wasm3-win-x64, platform: "-A x64", toolset: "-T ClangCL" } + - {target: wasm3-win-x86, platform: "-A Win32", toolset: "-T ClangCL" } + - {target: wasm3-strace-win-x64, platform: "-A x64", toolset: "-T ClangCL", cflags: "-DDEBUG -Dd_m3EnableStrace=2 -Dd_m3RecordBacktraces=1" } + + env: + LDFLAGS: -s + steps: + - uses: actions/checkout@v2 + - name: Configure + env: + CFLAGS: ${{ matrix.config.cflags }} + run: | + mkdir build + cd build + cmake ${{ matrix.config.platform }} ${{ matrix.config.toolset }} .. + - name: Build + run: | + cmake --build build --config Release + cp ./build/Release/wasm3.exe ./${{ matrix.config.target }}.exe + - name: Publish + uses: softprops/action-gh-release@v1 + with: + draft: ${{ env.draft }} + files: "*.exe" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + wasm3-linux-x64: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Setup musl + run: | + sudo apt update + sudo apt install musl-tools + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1.9 + with: + cmake-version: '3.16.x' + - name: Configure + env: + CC: musl-gcc + LDFLAGS: "-static -s" + run: | + mkdir build + cd build + cmake --version + cmake .. + - name: Build + run: | + cmake --build build --verbose + cp ./build/wasm3 ./wasm3-linux-x64.elf + - name: Publish + uses: softprops/action-gh-release@v1 + with: + draft: ${{ env.draft }} + files: "*.elf" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + wasm3-cosmopolitan: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Build αcτµαlly pδrταblε εxεcµταblε + run: | + cd platforms/cosmopolitan + ./build.sh + cp ./wasm3.com ../../wasm3-cosmopolitan.com + cp ./wasm3.com.dbg ../../wasm3-cosmopolitan.com.dbg + - name: Publish + uses: softprops/action-gh-release@v1 + with: + draft: ${{ env.draft }} + files: | + *.com + *.com.dbg + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + wasm3-wasi: + runs-on: ubuntu-latest + timeout-minutes: 10 + + env: + LDFLAGS: -s + steps: + - uses: actions/checkout@v2 + - name: Install Python dependencies + run: | + python3 -m pip install pip==20.1.1 + python3 -m pip install --upgrade setuptools wheel + pip3 --version + - name: Install Wasienv + env: + WASMER_RELEASE_TAG: "1.0.2" + run: curl https://raw.githubusercontent.com/wasienv/wasienv/master/install.sh | sh + - name: Configure + run: | + source $HOME/.wasienv/wasienv.sh + mkdir build + cd build + wasimake cmake .. + - name: Build + run: | + source $HOME/.wasienv/wasienv.sh + cmake --build build + cp ./build/wasm3.wasm ./wasm3-wasi.wasm + - name: Configure, Build wasm3-strace + env: + CFLAGS: -DDEBUG -Dd_m3EnableStrace=2 -Dd_m3RecordBacktraces=1 + run: | + source $HOME/.wasienv/wasienv.sh + mkdir build-strace + cd build-strace + wasimake cmake .. + cmake --build . + cp ./wasm3.wasm ../wasm3-strace.wasm + - name: Publish + uses: softprops/action-gh-release@v1 + with: + draft: ${{ env.draft }} + files: "*.wasm" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + wasm3-android-coremark: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - uses: seanmiddleditch/gha-setup-ninja@master + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Install NDK + run: | + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;22.1.7171670" + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --uninstall "cmake;3.18.1" + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.10.2.4988404" + - name: Build + run: | + cd platforms/android + ./gradlew build + - name: Copy + run: | + cp ./platforms/android/app/build/outputs/apk/debug/app-debug.apk ./wasm3-android-coremark.apk + - name: Publish + uses: softprops/action-gh-release@v1 + with: + draft: ${{ env.draft }} + files: "*.apk" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/wasm3-sys/wasm3/.github/workflows/tests.yml b/wasm3-sys/wasm3/.github/workflows/tests.yml new file mode 100644 index 0000000..c0ed423 --- /dev/null +++ b/wasm3-sys/wasm3/.github/workflows/tests.yml @@ -0,0 +1,607 @@ +name: tests + +on: + push: + paths-ignore: ['**.md', '**.svg', '**.png'] + pull_request: + paths-ignore: ['**.md', '**.svg', '**.png'] + +jobs: + linux: + runs-on: ubuntu-latest + name: linux-${{ matrix.config.target }} + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + config: + - {target: clang, cc: clang, } + - {target: clang-x86, cc: clang, flags: -DCMAKE_C_FLAGS="-m32", install: "gcc-multilib" } + - {target: gcc, cc: gcc, } + # Builds without uvwasi + - {target: gcc-no-uvwasi, cc: gcc, flags: -DBUILD_WASI=simple } + - {target: clang-no-uvwasi, cc: clang, flags: -DBUILD_WASI=simple } + # Debug builds + - {target: gcc-debug, cc: gcc, flags: -DCMAKE_BUILD_TYPE=Debug } + - {target: clang-no-uvwasi-debug, cc: clang, flags: -DCMAKE_BUILD_TYPE=Debug -DBUILD_WASI=simple } + + # TODO: fails on numeric operations + #- {target: gcc-x86, cc: gcc, flags: "-m32", install: "gcc-multilib" } + + steps: + - uses: actions/checkout@v2 + - name: Install ${{ matrix.config.install }} + if: ${{ matrix.config.install }} + run: | + sudo apt update + sudo apt install ${{ matrix.config.install }} + - name: Configure + env: + CC: ${{ matrix.config.cc }} + CFLAGS: ${{ matrix.config.cflags }} + run: | + mkdir build + cd build + cmake ${{ matrix.config.flags }} .. + - name: Build + run: | + cmake --build build + - name: Test WebAssembly spec + run: cd test && python3 run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python3 run-spec-test.py --spec=v1.1 + - name: Test WASI apps + run: cd test && python3 run-wasi-test.py + + linux-alpine: + runs-on: ubuntu-latest + container: alpine:3.10 + + steps: + - uses: actions/checkout@v2 + - name: Prepare + run: apk add build-base cmake python3 git --update-cache + - name: Configure + run: | + mkdir build + cd build + cmake .. + - name: Build + run: cmake --build build + - name: Test WebAssembly spec + run: cd test && python3 run-spec-test.py + - name: Test WASI apps + run: cd test && python3 run-wasi-test.py + + macos: + runs-on: macos-latest + name: macos-${{ matrix.config.target }} + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + config: + - {target: uvwasi, } + - {target: no-uvwasi, flags: -DBUILD_WASI=simple } + + steps: + - uses: actions/checkout@v2 + - name: Configure + run: | + mkdir build + cd build + cmake ${{ matrix.config.flags }} .. + - name: Build + run: | + cmake --build build + - name: Test WebAssembly spec + run: cd test && python3 run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python3 run-spec-test.py --spec=v1.1 + - name: Test WASI apps + run: cd test && python3 run-wasi-test.py + + windows: + runs-on: windows-latest + name: windows-${{ matrix.config.target }} + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + config: + - {target: clang-x64, platform: "-A x64", toolset: "-T ClangCL" } + - {target: msvc-x64, platform: "-A x64", toolset: "" } + - {target: clang-x86, platform: "-A Win32", toolset: "-T ClangCL" } + - {target: msvc-x86, platform: "-A Win32", toolset: "" } + # Builds without uvwasi + - {target: clang-x64-no-uvwasi, platform: "-A x64", toolset: "-T ClangCL", flags: "-DBUILD_WASI=simple" } + - {target: msvc-x64-no-uvwasi, platform: "-A x64", toolset: "", flags: "-DBUILD_WASI=simple" } + - {target: clang-x86-no-uvwasi, platform: "-A Win32", toolset: "-T ClangCL", flags: "-DBUILD_WASI=simple" } + - {target: msvc-x86-no-uvwasi, platform: "-A Win32", toolset: "", flags: "-DBUILD_WASI=simple" } + + defaults: + run: + shell: cmd + + steps: + - uses: actions/checkout@v2 + - name: Configure + run: | + mkdir build + cd build + cmake ${{ matrix.config.platform }} ${{ matrix.config.toolset }} ${{ matrix.config.flags }} .. + - name: Build + run: | + cmake --build build --config Release + cp ./build/Release/wasm3.exe ./build/ + - name: Test WebAssembly spec + run: | + cd test + python run-spec-test.py + - name: Test previous WebAssembly specs + run: | + cd test + python run-spec-test.py --spec=v1.1 + - name: Test WASI apps + run: | + cd test + python run-wasi-test.py + + wasi: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Install Python dependencies + run: | + python3 -m pip install pip==20.1.1 + python3 -m pip install --upgrade setuptools wheel + pip3 --version + - name: Install Wasienv + env: + WASMER_RELEASE_TAG: "1.0.2" + run: curl https://raw.githubusercontent.com/wasienv/wasienv/master/install.sh | sh + - name: Configure + run: | + source $HOME/.wasienv/wasienv.sh + mkdir build-wasi + cd build-wasi + wasimake cmake .. + - name: Build + run: | + source $HOME/.wasienv/wasienv.sh + cmake --build build-wasi + - name: Test WebAssembly spec (in Wasmer) + run: | + source $HOME/.wasmer/wasmer.sh + cd test + python3 run-spec-test.py --exec "wasmer run --mapdir=/:. ../build-wasi/wasm3.wasm -- --repl" + + - name: Test WASI apps (in Wasmer) + run: | + source $HOME/.wasmer/wasmer.sh + cd test + python3 run-wasi-test.py --exec "wasmer run --mapdir=/:. ../build-wasi/wasm3.wasm --" --fast + + - name: Configure (native) + run: | + mkdir build + cd build + cmake .. + - name: Build (native) + run: | + cmake --build build + - name: Test WebAssembly spec (in Wasm3, self-hosting) + run: | + cd test + cp ../build-wasi/wasm3.wasm ./ + python3 run-spec-test.py --exec "../build/wasm3 --stack-size 2097152 ../build-wasi/wasm3.wasm --repl" + - name: Test WASI apps (in Wasm3, self-hosting) + run: | + cd test + python3 run-wasi-test.py --fast --exec "../build/wasm3 --stack-size 2097152 ../build-wasi/wasm3.wasm" + + ios: + runs-on: macos-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: List Xcode versions + run: ls /Applications | grep Xcode + - name: Select Xcode 11 + run: sudo xcode-select -switch /Applications/Xcode_11.3.app + - name: Build (iPhone 11) + run: | + cd platforms/ios + xcodebuild build -scheme wasm3 -project wasm3.xcodeproj -configuration Release -destination 'platform=iOS Simulator,name=iPhone 11,OS=13.3' + + android: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - uses: seanmiddleditch/gha-setup-ninja@master + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Install NDK + run: | + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "ndk;22.1.7171670" + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --uninstall "cmake;3.18.1" + sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmake;3.10.2.4988404" + - name: Build + run: | + cd platforms/android + ./gradlew build + + python: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + path: wasm3 + - name: Checkout pywasm3 + uses: actions/checkout@v2 + with: + repository: wasm3/pywasm3 + path: pywasm3 + - name: Set up Python + uses: actions/setup-python@v2 + - name: Update and Build Python module + run: | + rm -rf ./pywasm3/wasm3 + cp -r wasm3/source ./pywasm3/wasm3 + pip install ./pywasm3 + - name: Install WABT + run: | + sudo apt update + sudo apt install wabt + - name: Test + run: | + pip install pytest + cd ./pywasm3 + pytest + + cosmopolitan: + runs-on: ubuntu-20.04 + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Build αcτµαlly pδrταblε εxεcµταblε + run: | + cd platforms/cosmopolitan + gcc -v + ./build.sh + - name: Prepare tests + run: | + cd test + cp ../platforms/cosmopolitan/wasm3.com ./wasm3-lin.com + cp ../platforms/cosmopolitan/wasm3.com ./wasm3-win.com + sudo sh -c "echo ':APE:M::MZqFpD::/bin/sh:' >/proc/sys/fs/binfmt_misc/register" + - name: Test WebAssembly spec + run: | + cd test + python3 run-spec-test.py --exec "./wasm3-lin.com --repl" + - name: Test WASI apps + run: | + cd test + python3 run-wasi-test.py --fast --exec "./wasm3-lin.com" + - name: Install Wine64 + run: | + sudo apt update + sudo apt install wine64 + wine --version + - name: Test WebAssembly spec (in Wine) + run: | + cd test + python3 run-spec-test.py --exec "wine ./wasm3-win.com --repl" + - name: Test WASI apps (in Wine) + run: | + cd test + python3 run-wasi-test.py --fast --exec "wine ./wasm3-win.com" + + cross-qemu: + runs-on: ubuntu-20.04 + name: cross-qemu-${{ matrix.config.target }} + timeout-minutes: 10 + + strategy: + fail-fast: false + matrix: + config: + #- {target: i386, toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static } + - {target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static } + - {target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static } + - {target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static } + - {target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static } + - {target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static } + - {target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static } + #- {target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static } + - {target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static } + - {target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static } + - {target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static } + - {target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static } + - {target: mips64el,toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc,qemu: qemu-mips64el-static } + - {target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static } + - {target: sparc64, toolchain: gcc-sparc64-linux-gnu, cc: sparc64-linux-gnu-gcc, qemu: qemu-sparc64-static, skip_wasi: true } + + #- {target: i386 (u64 slots), toolchain: gcc-multilib, cc: clang -m32, qemu: qemu-i386-static, cflags: -Dd_m3Use32BitSlots=0 } + - {target: arm (u64 slots), toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static, cflags: -Dd_m3Use32BitSlots=0 } + - {target: aarch64 (u64 slots), toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static, cflags: -Dd_m3Use32BitSlots=0 } + - {target: ppc (u64 slots), toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static, cflags: -Dd_m3Use32BitSlots=0 } + - {target: ppc64 (u64 slots), toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static, cflags: -Dd_m3Use32BitSlots=0 } + + steps: + - uses: actions/checkout@v2 + - name: Install QEMU + run: | + sudo apt update + sudo apt install qemu-user-static + - name: Install ${{ matrix.config.toolchain }} + run: | + sudo apt install ${{ matrix.config.toolchain }} + - name: Build + run: | + mkdir build + cd build + ${{ matrix.config.cc }} -DASSERTS -Dd_m3HasWASI ${{ matrix.config.cflags }} \ + -I../source ../source/*.c ../platforms/app/main.c \ + -O3 -g0 -flto -lm -static \ + -o wasm3 + - name: Test WebAssembly spec + run: | + cd test + python3 run-spec-test.py --exec "${{ matrix.config.qemu }} ../build/wasm3 --repl" + - name: Test WASI apps + if: ${{ !matrix.config.skip_wasi }} + run: | + cd test + python3 run-wasi-test.py --fast --exec "${{ matrix.config.qemu }} ../build/wasm3" + + platformio: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install -U platformio + - name: Build AVR ATmega1284 + run: | + cd platforms/embedded/arduino + pio run -e mega1284 + ! nm .pio/build/mega1284/firmware.elf | grep printf + - name: Build ESP8266 + run: | + cd platforms/embedded/esp8266 + pio run + # TODO: + #- name: Build ESP32 + # run: | + # cd platforms/embedded/esp32-pio + # pio run + + platformio-arm: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install -U platformio + - name: Build Arduino MKR1000 + run: | + cd platforms/embedded/arduino + pio run -e mkr1000 + - name: Build Blue Pill (JeeH) + run: | + cd platforms/embedded/bluepill + pio run + - name: Build TinyBLE + run: | + cd platforms/embedded/arduino + pio run -e tinyBLE + - name: Build MXChip AZ3166 + run: | + cd platforms/embedded/arduino + pio run -e az3166 + + platformio-riscv: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install -U platformio + - name: Build HiFive1 + run: | + cd platforms/embedded/hifive1 + pio run + - name: Build Sipeed MAIX + run: | + cd platforms/embedded/arduino + pio run -e maix + + particle: + runs-on: ubuntu-latest + timeout-minutes: 10 + if: "github.event_name == 'push'" + + steps: + - uses: actions/checkout@v2 + - name: Set up Particle CLI + run: sudo npm install -g particle-cli + - name: Log in + env: + PARTICLE_TOKEN: ${{ secrets.PARTICLE_TOKEN }} + run: particle login --token $PARTICLE_TOKEN + - name: Build Photon + run: | + cd platforms/embedded/particle + particle compile --followSymlinks photon + particle compile --followSymlinks argon + particle compile --followSymlinks pi + + esp32-idf: + runs-on: ubuntu-latest + container: igrr/idf-qemu:release-v4.0-esp-develop-20191228 + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Build for ESP32 (IDF v4.0) + run: | + . $IDF_PATH/export.sh + cd platforms/embedded/esp32-idf + export EXTRA_CFLAGS="-Werror" + idf.py build + shell: bash + - name: Test for ESP32 in QEMU + run: | + cd platforms/embedded/esp32-idf + make-flash-img.sh wasm3 flash_img.bin + qemu-system-xtensa -machine esp32 -nographic -drive file=flash_img.bin,if=mtd,format=raw -no-reboot | tee out.txt + grep "Result: 46368" out.txt + grep "Elapsed: " out.txt + grep "Restarting..." out.txt + test $(($(grep "ets Jun 8 2016" out.txt | wc -l))) -eq 1 + - name: Check that IDF and PIO examples are in sync + run: | + diff -q platforms/embedded/esp32-idf/main/main.cpp platforms/embedded/esp32-pio/src/main.cpp + # TODO: also check that the build flags are in sync + + cpp: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Configure + run: | + cd platforms/cpp + mkdir build + cd build + cmake .. + - name: Build + run: | + cd platforms/cpp + cmake --build build + - name: Run + run: | + cd platforms/cpp/build + ./wasm3_cpp_example + + as-cpp: + name: maintenance (build as C++) + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Build + run: | + mkdir build + cd build + clang -xc++ -Dd_m3HasWASI \ + -I../source ../source/*.c ../platforms/app/main.c \ + -O3 -g0 -lm \ + -o wasm3 + - name: Test + run: ./build/wasm3 ./test/wasi/simple/test.wasm + + with-logs: + name: maintenance (debug logs) + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Build + run: | + mkdir build + cd build + clang -xc++ -Dd_m3HasWASI -DDEBUG \ + -Dd_m3EnableOpTracing=1 \ + -Dd_m3EnableStrace=1 \ + -Dd_m3LogParse=1 \ + -Dd_m3LogModule=1 \ + -Dd_m3LogCompile=1 \ + -Dd_m3LogWasmStack=1 \ + -Dd_m3LogEmit=1 \ + -Dd_m3LogCodePages=1 \ + -Dd_m3LogRuntime=1 \ + -Dd_m3LogNativeStack=1 \ + -I../source ../source/*.c ../platforms/app/main.c \ + -O3 -g0 -lm \ + -o wasm3 + - name: Test + run: ./build/wasm3 ./test/wasi/simple/test.wasm > /dev/null + + preprocessed-ops: + name: maintenance (preprocess ops) + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v2 + - name: Install sponge + run: | + sudo apt update + sudo apt install moreutils + - name: Build + run: | + make -f extra/utils.mk preprocess + mkdir build + cd build + gcc -Dd_m3HasWASI \ + -I../source ../source/*.c ../platforms/app/main.c \ + -O3 -g0 -lm \ + -o wasm3 + - name: Test + run: ./build/wasm3 ./test/wasi/simple/test.wasm + + spellcheck: + runs-on: ubuntu-latest + steps: + - name: Set up Python + uses: actions/setup-python@v2 + - name: Install codespell + run: | + pip install codespell + - name: Spellcheck + run: | + codespell diff --git a/wasm3-sys/wasm3/.gitignore b/wasm3-sys/wasm3/.gitignore new file mode 100644 index 0000000..c5e6674 --- /dev/null +++ b/wasm3-sys/wasm3/.gitignore @@ -0,0 +1,12 @@ +/build* +/source-* +test/.spec-* +test/*.log +test/tailcall/*.S +node_modules/ +__pycache__/ +.project +.cproject +.settings +.vscode +.DS_Store diff --git a/wasm3-sys/wasm3/CMakeLists.txt b/wasm3-sys/wasm3/CMakeLists.txt new file mode 100755 index 0000000..92ba950 --- /dev/null +++ b/wasm3-sys/wasm3/CMakeLists.txt @@ -0,0 +1,223 @@ +cmake_minimum_required(VERSION 3.11) + +# Detect WasiEnv +if(DEFINED ENV{WASI_CC}) + set(WASIENV 1) +endif() + +# Detect MinGW +if(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "GNU") + set(MINGW 1) +endif() + +# Set options + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "set build type to Release") +endif() + +if(WASIENV) + set(BUILD_WASI "metawasi" CACHE STRING "WASI implementation") +elseif(EMSCRIPTEN OR EMSCRIPTEN_LIB) + set(BUILD_WASI "none" CACHE STRING "WASI implementation") +else() + set(BUILD_WASI "uvwasi" CACHE STRING "WASI implementation") +endif() +set_property(CACHE BUILD_WASI PROPERTY STRINGS none simple uvwasi metawasi) + +option(BUILD_NATIVE "Build with machine-specific optimisations" ON) + +set(OUT_FILE "wasm3") + +if(NOT APP_DIR) + set(APP_DIR "platforms/app") +endif() + +# Configure the toolchain + +if(CLANG OR CLANG_SUFFIX) + set(CMAKE_C_COMPILER "clang${CLANG_SUFFIX}") + set(CMAKE_CXX_COMPILER "clang++${CLANG_SUFFIX}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=lld") + + if(BUILD_FUZZ) + set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + set(OUT_FILE "wasm3-fuzzer") + set(APP_DIR "platforms/app_fuzz") + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "set build type to Debug") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=fuzzer,address") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=fuzzer,address") + endif() +endif() + +if(CLANG_CL) + set(CMAKE_C_COMPILER "clang-cl") + set(CMAKE_CXX_COMPILER "clang-cl") + set(CMAKE_LINKER "lld-link") +endif() + +if(EMSCRIPTEN OR EMSCRIPTEN_LIB) + set(CMAKE_C_COMPILER "emcc") + set(CMAKE_CXX_COMPILER "em++") + + if (EMSCRIPTEN_LIB) + set(APP_DIR "platforms/emscripten_lib") + set(OUT_FILE "wasm3.wasm") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s STANDALONE_WASM") + else() + set(APP_DIR "platforms/emscripten") + set(OUT_FILE "wasm3.html") + endif() +endif() + +if(BUILD_32BIT) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") +endif() + + + +project(wasm3) + +message("----") +message("Generator: ${CMAKE_GENERATOR}") +message("Compiler: ${CMAKE_C_COMPILER_ID}") +message("Build Type: ${CMAKE_BUILD_TYPE}") + + +include(CheckIPOSupported) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED YES) +set(CMAKE_C_EXTENSIONS NO) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED YES) +set(CMAKE_CXX_EXTENSIONS NO) + + +file(GLOB app_srcs "${APP_DIR}/*.c") +add_executable(${OUT_FILE} ${app_srcs}) + +#-fno-optimize-sibling-calls + +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG=1") + +if(EMSCRIPTEN OR EMSCRIPTEN_LIB) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s GLOBAL_BASE=1024 -s TOTAL_STACK=2MB -s INITIAL_MEMORY=4MB -s ALLOW_MEMORY_GROWTH") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s EXPORTED_FUNCTIONS=\"[\\\"_malloc\\\",\\\"_free\\\",\\\"_main\\\"]\"") + + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -flto -Wfatal-errors -s ASSERTIONS=0") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} --strip-all --gc-sections") + + if(WASM_EXT) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbulk-memory -mnontrapping-fptoint -msign-ext -mtail-call") + endif() + +elseif(WASIENV) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasTracer") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -Wfatal-errors -fomit-frame-pointer -fno-stack-check -fno-stack-protector") + + if(WASM_EXT) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mbulk-memory -mnontrapping-fptoint -msign-ext -mtail-call") + endif() + + # TODO: LTO breaks wasm imports currently: + # https://www.mail-archive.com/llvm-bugs@lists.llvm.org/msg36273.html + + #-flto -Wl,--lto-O3 + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=8388608") + +elseif(WIN32 AND NOT MINGW) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasTracer -D_CRT_SECURE_NO_WARNINGS /WX- /diagnostics:column") + + string(REGEX REPLACE "/W[0-4]" "/W0" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + + if (CMAKE_C_COMPILER_ID MATCHES "MSVC") + + if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /d2noftol3") + endif() + + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oxs /Oy /GS- /Zi /Zo /arch:AVX2") + + # Uncomment this if you want to disassemble the release build, + # for example: dumpbin /DISASM wasm3.exe /out:wasm3.S + #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG:FULL") + + else() + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Oxs /Oy /GS- /Qvec -Clang -O3") + endif() + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") # stack size + +else() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasTracer") #-Dd_m3FixedHeap=1048576 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wparentheses -Wundef -Wpointer-arith -Wstrict-aliasing=2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration") # -Werror=cast-align + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers") + if (CMAKE_C_COMPILER_ID MATCHES "Clang") + # TODO: Place clang-specific options here + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wjump-misses-init") + endif() + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -O0") + + set(CMAKE_C_FLAGS_RELEASE "-O3 -Wfatal-errors -fomit-frame-pointer -fno-stack-check -fno-stack-protector") #-fno-inline + + if(BUILD_NATIVE) + if(APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mcpu=native") + else() + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native") + endif() + endif() + + set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-O0") + set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-O3") + + target_link_libraries(${OUT_FILE} m) + +endif() + +if(BUILD_WASI MATCHES "simple") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasWASI") +elseif(BUILD_WASI MATCHES "metawasi") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasMetaWASI") +elseif(BUILD_WASI MATCHES "uvwasi") + include(FetchContent) + FetchContent_Declare( + uvwasi + GIT_REPOSITORY https://github.com/vshymanskyy/uvwasi.git + GIT_TAG b063d686848c32a26119513056874f051c74258a + ) + + FetchContent_GetProperties(uvwasi) + if(NOT uvwasi_POPULATED) + FetchContent_Populate(uvwasi) + include_directories("${uvwasi_SOURCE_DIR}/include") + add_subdirectory(${uvwasi_SOURCE_DIR} ${uvwasi_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Dd_m3HasUVWASI") + target_link_libraries(${OUT_FILE} uvwasi_a uv_a) +endif() + +check_ipo_supported(RESULT result) +if(result AND NOT WASIENV) # TODO: LTO breaks wasm imports + set_property(TARGET ${OUT_FILE} PROPERTY INTERPROCEDURAL_OPTIMIZATION True) + message("LTO: ON") +else() + message("LTO: OFF") +endif() + +add_subdirectory(source) +target_link_libraries(${OUT_FILE} m3) + +message("Flags: ${CMAKE_C_FLAGS}") +message("Debug flags: ${CMAKE_C_FLAGS_DEBUG}") +message("Release flags: ${CMAKE_C_FLAGS_RELEASE}") + +message("----") diff --git a/wasm3-sys/wasm3/LICENSE b/wasm3-sys/wasm3/LICENSE new file mode 100644 index 0000000..e580601 --- /dev/null +++ b/wasm3-sys/wasm3/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Steven Massey, Volodymyr Shymanskyy + +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. diff --git a/wasm3-sys/wasm3/README.md b/wasm3-sys/wasm3/README.md new file mode 100644 index 0000000..f43e895 --- /dev/null +++ b/wasm3-sys/wasm3/README.md @@ -0,0 +1,113 @@ + + +# Wasm3 + +[![WAPM](https://wapm.io/package/vshymanskyy/wasm3/badge.svg)](https://wapm.io/package/vshymanskyy/wasm3) +[![GitHub issues](https://img.shields.io/github/issues-raw/wasm3/wasm3?style=flat-square&label=issues&color=success)](https://github.com/wasm3/wasm3/issues) +[![Tests status](https://img.shields.io/github/workflow/status/wasm3/wasm3/tests/main?style=flat-square&logo=github&label=tests)](https://github.com/wasm3/wasm3/actions) +[![Fuzzing Status](https://img.shields.io/badge/oss--fuzz-fuzzing-success?style=flat-square)](https://bugs.chromium.org/p/oss-fuzz/issues/list?can=1&q=proj:wasm3) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](https://github.com/wasm3/wasm3) + +The fastest WebAssembly interpreter, and the most universal runtime. +Based on [**CoreMark 1.0**](./docs/Performance.md) and [**independent**](https://00f.net/2021/02/22/webassembly-runtimes-benchmarks) benchmarks. Your mileage may vary. + + +[![Twitter](https://img.shields.io/twitter/follow/wasm3_engine?style=flat-square&color=1da1f2&label=twitter&logo=twitter)](https://twitter.com/wasm3_engine) +[![Discord](https://img.shields.io/discord/671415645073702925?style=flat-square&logo=discord&color=7289da&label=discord)](https://discord.gg/qmZjgnd) +[![Telegram](https://img.shields.io/badge/telegram-chat-0088cc?style=flat-square&logo=telegram)](https://t.me/joinchat/DD8s3xVG8Vj_LxRDm52eTQ) + +## Getting Started + +Here's a small [getting started guide](https://wapm.io/package/vshymanskyy/wasm3). Click here to start: + +[![LIVE DEMO](extra/button.png)](https://webassembly.sh/?run-command=wasm3) + + +## Installation + +**Please follow the [installation instructions](./docs/Installation.md).** + +Wasm3 can also be used as a library for: + +[ Python3](https://github.com/wasm3/pywasm3) │ +[ Rust](https://github.com/Veykril/wasm3-rs) │ +[ C/C++](https://github.com/wasm3/wasm3) │ +[ GoLang](https://github.com/matiasinsaurralde/go-wasm3) │ +[ Zig](https://github.com/alichay/zig-wasm3) +[ Swift](https://github.com/shareup/wasm-interpreter-apple) │ +[ .Net](https://github.com/tana/Wasm3DotNet) │ +[ Arduino, PlatformIO, Particle](https://github.com/wasm3/wasm3-arduino) + + +## Status + +`wasm3` passes the [WebAssembly spec testsuite](https://github.com/WebAssembly/spec/tree/master/test/core) and is able to run many `WASI` apps. + +Minimum useful system requirements: **~64Kb** for code and **~10Kb** RAM + +`wasm3` runs on a wide range of architectures (`x86`, `x86_64`, `ARM`, `RISC-V`, `PowerPC`, `MIPS`, `Xtensa`, `ARC32`, ...) and [platforms](/platforms): +- Linux, + Windows, + OS X, + FreeBSD, + Android, + iOS +- OpenWrt, Yocto, Buildroot (routers, modems, etc.) +- Raspberry Pi, Orange Pi and other SBCs +- MCUs: Arduino, ESP8266, ESP32, Particle, ... [see full list](./docs/Hardware.md) +- Browsers. Yes, using WebAssembly itself! +- `wasm3` can execute `wasm3` (self-hosting) + +## Advanced features and [post-mvp proposals](https://github.com/WebAssembly/proposals) support + +☑ Sign-extension operators +☑ Non-trapping float-to-int conversions +☑ Import/Export of Mutable Globals +☑ Structured execution tracing +☑ Big-Endian systems support +☑ Self-hosting +☑ Gas metering +☑ Multi-value +☐ Reference types +☐ Bulk memory operations +☐ Tail call optimization + +## Motivation + +**Why use a "slow interpreter" versus a "fast JIT"?** + +In many situations, speed is not the main concern. Runtime executable size, memory usage, startup latency can be improved with the interpreter approach. Portability and security are much easier to achieve and maintain. Additionally, development impedance is much lower. A simple library like Wasm3 is easy to compile and integrate into an existing project. (Wasm3 builds in a just few seconds). Finally, on some platforms (i.e. iOS and WebAssembly itself) you can't generate executable code pages in runtime, so JIT is unavailable. + +**Why would you want to run WASM on embedded devices?** + +Wasm3 started as a research project and remains so by many means. Evaluating the engine in different environments is part of the research. Given that we have `Lua`, `JS`, `Python`, `Lisp`, `...` running on MCUs, `WebAssembly` is actually a promising alternative. It provides toolchain decoupling as well as a completely sandboxed, well-defined, predictable environment. Among practical use cases we can list `edge computing`, `scripting`, running `IoT rules`, `smart contracts`, etc. + +## Used by + +[](https://wasmcloud.dev/) +[](https://wowcube.com/) +[](https://scailable.net/) +[](https://blynk.io/) +[](https://www.iden3.io/) +[](https://github.com/kateinoigakukun/wasmic-ios) +[](https://github.com/balena-io-playground/balena-wasm3) +[](https://github.com/deislabs/krustlet-wasm3) +[](https://shareup.app/blog/introducing-shareup/) +[](https://github.com/saghul/txiki.js) + +## Further Resources + +[Demos](./docs/Demos.md) +[Installation instructions](./docs/Installation.md) +[Cookbook](./docs/Cookbook.md) +[Troubleshooting](./docs/Troubleshooting.md) +[Build and Development instructions](./docs/Development.md) +[Supported Hardware](./docs/Hardware.md) +[Testing & Fuzzing](./docs/Testing.md) +[Performance](./docs/Performance.md) +[Interpreter Architecture](./docs/Interpreter.md) +[Logging](./docs/Diagnostics.md) +[Awesome WebAssembly Tools](https://github.com/vshymanskyy/awesome-wasm-tools/blob/main/README.md) + +### License +This project is released under The MIT License (MIT) diff --git a/wasm3-sys/wasm3/docs/Cookbook.md b/wasm3-sys/wasm3/docs/Cookbook.md new file mode 100644 index 0000000..8dd9241 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Cookbook.md @@ -0,0 +1,409 @@ +# WASM module examples + +### Rust WASI app + +Create a new project: +```sh +$ cargo new --bin hello +$ cd hello +$ rustup target add wasm32-wasi +``` + +Build and run: +```sh +$ cargo build --release --target wasm32-wasi + +$ wasm3 ./target/wasm32-wasi/release/hello.wasm +Hello, world! +``` + +### AssemblyScript WASI app + +Create `hello.ts`: +```ts +import "wasi" +import {Console} from "as-wasi" + +Console.log('Hello World!'); +``` + +Create `package.json`: +```json +{ + "scripts": { + "asbuild:debug": "asc hello.ts -b hello.wasm --debug", + "asbuild:optimized": "asc hello.ts -b hello.wasm -O3s --noAssert", + "asbuild:tiny": "asc hello.ts -b hello.wasm -O3z --noAssert --runtime stub --use abort=", + "build": "npm run asbuild:optimized" + }, + "devDependencies": { + "assemblyscript": "*", + "as-wasi": "*" + } +} +``` + +Build and run: +```sh +$ npm install +$ npm run build + +$ wasm3 hello.wasm +Hello World! +``` + +### TinyGo WASI app + +Create `hello.go`: +```go +package main + +import "fmt" + +func main() { + fmt.Printf("Hello, %s!\n", "world") +} +``` + +Build and run: +```sh +$ tinygo build -o hello.wasm -target wasi -no-debug hello.go + +$ wasm3 hello.wasm +Hello, world! +``` + +### Zig WASI app + +Create `hello.zig`: +```zig +const std = @import("std"); + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + try stdout.print("Hello, {s}!\n", .{"world"}); +} +``` + +Build and run: +```sh +$ zig build-exe -O ReleaseSmall -target wasm32-wasi hello.zig + +$ wasm3 hello.wasm +Hello, world! +``` + +## Zig library + +Create `add.zig`: +```zig +export fn add(a: i32, b: i32) i64 { + return a + b; +} +``` + +Build and run: +```sh +$ zig build-lib add.zig -O ReleaseSmall -target wasm32-freestanding + +$ wasm3 --repl add.wasm +wasm3> add 1 2 +Result: 3 +``` + +### C/C++ WASI app + +The easiest way to start is to use [Wasienv](https://github.com/wasienv/wasienv). + +Create `hello.cpp`: +```cpp +#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return 0; +} +``` + +Or `hello.c`: +```c +#include + +int main() { + printf("Hello, %s!\n", "world"); + return 0; +} +``` + +Build and run: +```sh +$ wasic++ -O3 hello.cpp -o hello.wasm +$ wasicc -O3 hello.c -o hello.wasm + +$ wasm3 hello.wasm +Hello World! +``` + +Limitations: +- `setjmp/longjmp` and `C++ exceptions` are not available +- no support for `threads` and `atomics` +- no support for `dynamic libraries` + +### Grain WASI app + +Create `hello.gr`: +``` +print("Hello, world!") +``` + +Build and run: +```sh +$ grain compile hello.gr -o hello.wasm + +$ wasm3 hello.wasm +Hello, world! +``` + +### WAT WASI app + +Create `hello.wat`: +```wat +(module + ;; wasi_snapshot_preview1!fd_write(file_descriptor, *iovs, iovs_len, nwritten) -> status_code + (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32))) + + (memory 1) + (export "memory" (memory 0)) + + ;; Put a message to linear memory at offset 32 + (data (i32.const 32) "Hello, world!\n") + + (func $main (export "_start") + ;; Create a new io vector at address 0x4 + (i32.store (i32.const 4) (i32.const 32)) ;; iov.iov_base - pointer to the start of the message + (i32.store (i32.const 8) (i32.const 14)) ;; iov.iov_len - length of the message + + (call $fd_write + (i32.const 1) ;; file_descriptor - 1 for stdout + (i32.const 4) ;; *iovs - pointer to the io vector + (i32.const 1) ;; iovs_len - count of items in io vector + (i32.const 20) ;; nwritten - where to store the number of bytes written + ) + drop ;; discard the WASI status code + ) +) +``` + + +Build and run: +```sh +$ wat2wasm hello.wat -o hello.wasm + +$ wasm3 hello.wasm +Hello, world! +``` + +### WAT library + +Create `swap.wat`: +```wat +(module + (func (export "swap") (param i32 i32) (result i32 i32) + (get_local 1) + (get_local 0) + ) +) +``` + +Build and run: +```sh +$ wat2wasm swap.wat -o swap.wasm + +$ wasm3 --repl swap.wasm +wasm3> :invoke swap 123 456 +Result: 456:i32, 123:i32 +``` + +# Tracing + +Drag'n'drop any of the WASI apps to [`WebAssembly.sh`](https://webassembly.sh/) and run: +```sh +$ wasm3-strace /tmp/hello.wasm +``` + +The execution trace will be produced: +```js +_start () { + __wasilibc_init_preopen () { + malloc (i32: 16) { + dlmalloc (i32: 16) { + sbrk (i32: 0) { + } = 131072 + sbrk (i32: 65536) { +``` + + Click to expand! + +```js + } = 131072 + } = 131088 + } = 131088 + calloc (i32: 24, i32: 0) { + dlmalloc (i32: 96) { + } = 131120 + memset (i32: 131120, i32: 65504, i32: 0) { + } = 131120 + } = 131120 + po_map_assertvalid (i32: 131088) { + } + po_map_assertvalid (i32: 131088) { + } + } + wasi_unstable!fd_prestat_get(3, 65528) { } = 0 + malloc (i32: 2) { + dlmalloc (i32: 2) { + } = 131232 + } = 131232 + wasi_unstable!fd_prestat_dir_name(3, 131232, 1) { } = 0 + __wasilibc_register_preopened_fd (i32: 3, i32: 131120) { + po_map_assertvalid (i32: 131088) { + } + po_map_assertvalid (i32: 131088) { + } + strdup (i32: 131232) { + strlen (i32: 131232) { + } = 1 + malloc (i32: 2) { + dlmalloc (i32: 2) { + } = 131248 + } = 131248 + memcpy (i32: 131248, i32: 131233, i32: 131232) { + } = 131248 + } = 131248 + wasi_unstable!fd_fdstat_get(3, 65496) { } = 0 + po_map_assertvalid (i32: 131088) { + } + po_map_assertvalid (i32: 131088) { + } + } = 0 + free (i32: 131232) { + dlfree (i32: 131232) { + } + } + wasi_unstable!fd_prestat_get(4, 65528) { } = 0 + malloc (i32: 2) { + dlmalloc (i32: 2) { + } = 131232 + } = 131232 + wasi_unstable!fd_prestat_dir_name(4, 131232, 1) { } = 0 + __wasilibc_register_preopened_fd (i32: 4, i32: 131120) { + po_map_assertvalid (i32: 131088) { + } + po_map_assertvalid (i32: 131088) { + } + strdup (i32: 131232) { + strlen (i32: 131232) { + } = 1 + malloc (i32: 2) { + dlmalloc (i32: 2) { + } = 131264 + } = 131264 + memcpy (i32: 131264, i32: 131233, i32: 131232) { + } = 131264 + } = 131264 + wasi_unstable!fd_fdstat_get(4, 65496) { } = 0 + po_map_assertvalid (i32: 131088) { + } + po_map_assertvalid (i32: 131088) { + } + } = 0 + free (i32: 131232) { + dlfree (i32: 131232) { + } + } + wasi_unstable!fd_prestat_get(5, 65528) { } = 8 + __wasm_call_ctors () { + } + __original_main () { + printf (i32: 65536, i32: 0) { + vfprintf (i32: 69512, i32: 0, i32: 65536) { + printf_core (i32: 0, i32: -1, i32: 65536, i32: -16, i32: 65480) { + } = 0 + __towrite (i32: 69512) { + } = 0 + printf_core (i32: 69512, i32: 8, i32: 65536, i32: -1, i32: 65480) { + __fwritex (i32: 65536, i32: 0, i32: 7) { + memcpy (i32: 68472, i32: 0, i32: 65536) { + } = 68472 + } = 7 + __fwritex (i32: 65543, i32: 0, i32: 0) { + memcpy (i32: 68479, i32: 0, i32: 65543) { + } = 68479 + } = 0 + pop_arg (i32: 64456, i32: 0, i32: 9) { + } + strnlen (i32: 65548, i32: 0) { + memchr (i32: 65548, i32: 4, i32: 0) { + } = 65553 + } = 5 + __fwritex (i32: 67222, i32: 65553, i32: 0) { + memcpy (i32: 68479, i32: 0, i32: 67222) { + } = 68479 + } = 0 + __fwritex (i32: 65548, i32: 65553, i32: 5) { + memcpy (i32: 68479, i32: 0, i32: 65548) { + } = 68479 + } = 5 + __fwritex (i32: 65545, i32: 0, i32: 2) { + __stdout_write (i32: 69512, i32: 0, i32: 65545) { + __isatty (i32: 1) { + wasi_unstable!fd_fdstat_get(1, 64376) { } = 0 + } = 1 + __stdio_write (i32: 69512, i32: 64368, i32: 65545) { + writev (i32: 1, i32: -16, i32: 64384) { +Hello, world! + wasi_unstable!fd_write(1, 64384, 2, 64380) { } = 0 + } = 14 + } = 2 + } = 2 + memcpy (i32: 68472, i32: -1, i32: 65547) { + } = 68472 + } = 2 + } = 14 + } = 14 + } = 14 + } = 0 + __prepare_for_exit () { + dummy () { + } + __stdio_exit () { + __ofl_lock () { + } = 69504 + } + } +} +``` + + +# Gas Metering + +```sh +$ npm install -g wasm-metering + +$ wasm-meter hello.wasm hello-metered.wasm + +$ wasm3 hello-metered.wasm +Warning: Gas is limited to 500000000.0000 +Hello, world! +Gas used: 20.8950 + +$ wasm3 --gas-limit 10 hello-metered.wasm +Warning: Gas is limited to 10.0000 +Gas used: 10.0309 +Error: [trap] Out of gas +``` + +# Other resources + +- [WebAssembly by examples](https://wasmbyexample.dev/home.en-us.html) by Aaron Turner +- [Writing WebAssembly](https://docs.wasmtime.dev/wasm.html) in Wasmtime docs diff --git a/wasm3-sys/wasm3/docs/Demos.md b/wasm3-sys/wasm3/docs/Demos.md new file mode 100644 index 0000000..1a19548 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Demos.md @@ -0,0 +1,15 @@ +# Wasm3 demos + +- **In-browser Wasm3 (with MetaWASI support) on Webassembly.sh** │ [try it](https://webassembly.sh/?run-command=wasm3) +- **PyGame + pywasm3 examples** | [github](https://github.com/wasm3/pywasm3/tree/main/examples) +- **DOOM compiled to WASI, running on pywasm3** | [video](https://twitter.com/wasm3_engine/status/1393588527863144450), [github](https://github.com/wasm3/pywasm3-doom-demo) +- **Wasm3 self-compilation using `clang.wasm`** | [github](https://github.com/wasm3/wasm3-self-compiling) +- **Dino game** + - on PyBadge/Arduino | [video](https://twitter.com/vshymanskyy/status/1345048053041029121), [github](https://github.com/wasm3/wasm3-arduino/tree/main/examples/Wasm_Dino_PyBadge) + - on Raspberry Pi Pico | [github](https://github.com/vshymanskyy/wasm3_dino_rpi_pico) + - on ESP32 TTGO TDisplay | [github](https://github.com/wasm3/wasm3-arduino/tree/main/examples/Wasm_Dino_ESP32_TDisplay) +- **Basic WiFi/Gpio access, updating `wasm` file over-the-air** │ [video](https://twitter.com/alvaroviebrantz/status/1221618910803513344), [github](https://github.com/alvarowolfx/wasm-arduino-wifi) [ESP32 / Web] +- **RGB lamp animation using WebAssembly** │ [video](https://twitter.com/wasm3_engine/status/1222835097289752576), [github](https://github.com/vshymanskyy/Wasm3_RGB_Lamp) [nRF51 / nRF52 / ESP8266 / ESP32] +- **LCD display rendering with AssemblyScript** │ [video](https://twitter.com/h1romas4/status/1228581467850100736), [github](https://github.com/h1romas4/m5stack-wasm3-testing) [M5Stack / ESP32] +- **Conway's Game Of Life with AssemblyScript** │ [video](https://www.youtube.com/watch?v=Hc2sbhGMrig), [github](https://github.com/h1romas4/maixduino-wasm3-testing) [Maixduino / K210] + diff --git a/wasm3-sys/wasm3/docs/Development.md b/wasm3-sys/wasm3/docs/Development.md new file mode 100644 index 0000000..0008221 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Development.md @@ -0,0 +1,151 @@ +# Wasm3 development notes + +This project uses CMake. +General build steps look like: +```sh +mkdir -p build +cd build +cmake .. +make -j8 +``` + +Wasm3 is continuously tested with Clang, GCC, MSVC compilers, and on multiple platforms. +It can be easily integrated into any build system, as shown in `platforms`. + +## Build on Linux, OS X + +### Clang + +```sh +mkdir build +cd build +cmake -GNinja -DCLANG_SUFFIX="-9" .. +ninja +``` + +### GCC + +```sh +mkdir build +cd build +cmake -GNinja .. +ninja +``` + +## Build on Windows + +Prerequisites: +- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) +- [CMake](https://cmake.org/download/) +- [Ninja](https://github.com/ninja-build/ninja/releases) +- [Clang 9](https://releases.llvm.org/download.html#9.0.0) + +Recommended tools: +- [Cmder](https://cmder.net/) +- [Python3](https://www.python.org/downloads/) +- [ptime](http://www.pc-tools.net/win32/ptime/) + +```sh +# Prepare environment (if needed): +"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" +set PATH=C:\Python36-32\;C:\Python36-32\Scripts\;%PATH% +``` + +### Build with MSBuild + +```sh +# Create a build directory as usual, then build a specific configuration +mkdir build +cd build + +# Configure Clang, x64 +cmake -G"Visual Studio 16 2019" -A x64 -T ClangCL .. + +# Configure Clang, x86 +cmake -G"Visual Studio 16 2019" -A Win32 -T ClangCL .. + +# Configure MSVC, x64 +cmake -G"Visual Studio 16 2019" -A x64 .. + +# Configure MSVC, x86 +cmake -G"Visual Studio 16 2019" -A Win32 .. + +# Build +cmake --build . --config Release +cp ./Release/wasm3.exe ./ +``` + +### Build with Ninja + +```sh +set PATH=C:\Program Files\CMake\bin;%PATH% +set PATH=C:\Program Files\LLVM\bin;%PATH% + +# Clang +cmake -GNinja -DCLANG_CL=1 .. +ninja + +# MSVC +cmake -GNinja .. +ninja +``` + +## Build using compiler directly + +This can be useful for cross-compilation, quick builds or when a build system (CMake, Ninja, etc.) is not available. + +### gcc/clang +```sh +gcc -O3 -g0 -s -Isource -Dd_m3HasWASI source/*.c platforms/app/main.c -lm -o wasm3 +``` + +### msvc/clang-cl +```sh +cl source/*.c platforms/app/main.c /Isource /MD /Ox /Oy /Gw /GS- /W0 /Dd_m3HasWASI /Fewasm3.exe /link advapi32.lib +``` + +### mingw-w64 +```sh +x86_64-w64-mingw32-gcc -O3 -g0 -s -Isource -Dd_m3HasWASI source/*.c platforms/app/main.c -lm -lpthread -static -o wasm3.exe +``` + +## Build for microcontrollers + +In `./platforms/` folder you can find projects for different targets. Some of them are using Platformio, so you can follow the regular pio build process. Others have custom instructions in respective `README.md` files. + +## Build with WasiEnv + +```sh +wasimake cmake -GNinja .. +ninja +``` + +If you want to enable experimental WASM features during the build: + +```sh +export CFLAGS="-Xclang -target-feature -Xclang +tail-call" +wasimake cmake -GNinja .. +ninja +``` + +Here's how some options can be used with different tools: + +```log +Clang target-feature option WABT option Chromium --js-flags option +---------------------------------------------------------------------------------------------------------------- ++multivalue --enable-multi-value --experimental-wasm-mv ++tail-call --enable-tail-call --experimental-wasm-return-call ++bulk-memory --enable-bulk-memory --experimental-wasm-bulk-memory ++nontrapping-fptoint --enable-saturating-float-to-int --experimental-wasm-sat-f2i-conversions ++sign-ext --enable-sign-extension --experimental-wasm-se ++simd128, +unimplemented-simd128 --enable-simd --experimental-wasm-simd +``` + +```sh +# List clang options: +llc -march=wasm32 -mattr=help + +# List Chromium options: +chromium-browser --single-process --js-flags="--help" 2>&1 | grep wasm +``` + diff --git a/wasm3-sys/wasm3/docs/Diagnostics.md b/wasm3-sys/wasm3/docs/Diagnostics.md new file mode 100644 index 0000000..5f9b947 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Diagnostics.md @@ -0,0 +1,57 @@ + +## Logs + +To enable various logs, modify the defines in `m3_config.h`. These are only enabled when compiled in debug mode. + +```C +# define d_m3LogParse 0 // .wasm binary decoding info +# define d_m3LogModule 0 // Wasm module info +# define d_m3LogCompile 0 // wasm -> metacode generation phase +# define d_m3LogWasmStack 0 // dump the wasm stack when pushed or popped +# define d_m3LogEmit 0 // metacode-generation info +# define d_m3LogCodePages 0 // dump metacode pages when released +# define d_m3LogRuntime 0 // higher-level runtime information +# define d_m3LogNativeStack 0 // track the memory usage of the C-stack +``` + + +## Operation Profiling + +To profile the interpreter's operations enable `d_m3EnableOpProfiling` in `m3_config.h`. This profiling option works in either release or debug builds. + +When a runtime is released or `m3_PrintProfilerInfo ()` is called, a table of the executed operations and +their instance counts will be printed to stderr. + +``` + 23199904 op_SetSlot_i32 + 12203917 op_i32_Add_ss + 6682992 op_u32_GreaterThan_sr + 2021555 op_u32_ShiftLeft_sr + 1136577 op_u32_ShiftLeft_ss + 1019725 op_CopySlot_32 + 775431 op_i32_Subtract_ss + 703307 op_i32_Store_i32_rs + 337656 op_i32_Multiply_rs + 146383 op_u32_Or_rs + 99168 op_u64_Or_rs + 50311 op_u32_ShiftRight_rs + 43319 op_u32_ShiftLeft_rs + 21104 op_i64_Load_i64_s + 17450 op_i32_LessThan_sr + 7129 op_If_s + 5574 op_i32_Wrap_i64_r + 1630 op_f64_Load_f64_r + 1116 op_u32_Divide_sr + 903 op_i32_GreaterThan_ss + 390 op_u64_And_rs + 108 op_Select_f64_rss + 77 op_u64_ShiftLeft_sr + 64 op_Select_i32_ssr + 11 op_f64_Store_f64_ss + 10 op_MemGrow + 8 op_f64_GreaterThan_sr + 4 op_u64_LessThan_rs + 1 op_u32_Xor_ss + 1 op_i64_Subtract_ss +``` + diff --git a/wasm3-sys/wasm3/docs/Hardware.md b/wasm3-sys/wasm3/docs/Hardware.md new file mode 100644 index 0000000..498224d --- /dev/null +++ b/wasm3-sys/wasm3/docs/Hardware.md @@ -0,0 +1,60 @@ +# Wasm3 hardware support + +## Recommended devices (ideal for beginners) + +- ESP32-based + - **LilyGO TTGO T7 V1.4** │ [AliExpress](https://www.aliexpress.com/item/32977375539.html) + - **M5Stack Fire** │ [AliExpress](https://www.aliexpress.com/item/32847906756.html) +- nRF52840-based + - **Adafruit CLUE** │ [Adafruit](https://www.adafruit.com/clue) + - **Arduino Nano 33 BLE (or BLE Sense)** │ [Arduino](https://store.arduino.cc/arduino-nano-33-ble) + - **Particle Argon** │ [Particle](https://store.particle.io/collections/bluetooth/products/argon) + - **Adafruit Feather nRF52840** | [Adafruit](https://www.adafruit.com/product/4062) +- Other + - **Raspberry Pi Pico** | [Raspberry Pi](https://www.raspberrypi.org/products/raspberry-pi-pico) + - **Adafruit PyGamer/PyBadge/PyBadge LC** │ [Adafruit](https://www.adafruit.com/product/4242) + - **SparkFun Artemis** | [SparkFun](https://www.sparkfun.com/search/results?term=Artemis) + - **Teensy 4.0** │ [PJRC](https://www.pjrc.com/store/teensy40.html) + - **Wemos W600 PICO** │ [AliExpress](https://www.aliexpress.com/item/4000314757449.html) + +## Compatibility table + +Device | Chipset | Architecture | Clock | Flash | RAM +--- |:---: | --- | -----:| --- | --- +Espressif ESP32 | | Xtensa LX6 ⚠️ | 240MHz | 4 MB | 520KB +Particle Argon, Boron, Xenon | nRF52840 | Cortex-M4F | 64MHz | 1 MB | 256KB +Particle Photon, Electron | STM32F205 | Cortex-M3 | 120Mhz | 1 MB | 128KB +Sparkfun Photon RedBoard | STM32F205 | Cortex-M3 | 120Mhz | 1 MB | 128KB +Air602 | WM W600 | Cortex-M3 | 80MHz | 1 MB | 160KB+128KB +Adafruit PyBadge | ATSAMD51J19 | Cortex-M4F | 120MHz | 512KB | 192KB +Realtek RTL8711 | | Cortex-M3 | 166MHz | 2 MB | 2 MB+512KB +Nordic nRF52840 | | Cortex-M4F | 64MHz | 1 MB | 256KB +Nordic nRF52833 | | Cortex-M4F | 64MHz | 512KB | 128KB +P-Nucleo WB55RG | STM32WB55RG | Cortex-M4F | 64MHz | 1 MB | 256KB +Teensy 4.0 | NXP iMXRT1062 | Cortex-M7 | 600MHz | 2 MB | 1 MB +Teensy 3.5 | MK64FX512 | Cortex-M4F | 120MHz | 512KB | 192KB +MXChip AZ3166 | EMW3166 | Cortex-M4 | 100MHz | 1 MB+2 MB | 256KB +Arduino Due | AT91SAM3X8E | Cortex-M3 | 84MHz | 512KB | 96KB +Sipeed MAIX | Kendryte K210 | RV64IMAFDC | 400MHz | 16 MB | 8 MB +Fomu (soft CPU) | Lattice ICE40UP5K | RV32I | 12MHz | 2 MB | 128KB + +## Limited support + +The following devices can run Wasm3, however they cannot afford to allocate even a single Linear Memory page (64KB). +This means `memoryLimit` should be set to the actual amount of RAM available, and that in turn usually breaks the allocator of the hosted Wasm application (which still assumes the page is 64KB and performs OOB access). + +Device | Chipset | Architecture | Clock | Flash | RAM +--- |:---: | --- | -----:| --- | --- +Espressif ESP8266 | | Xtensa L106 ⚠️ | 160MHz | 4 MB | ~50KB (available) +Teensy 3.1/3.2 | NXP MK20DX256 | Cortex-M4 | 72MHz | 288KB | 64KB +Blue Pill | STM32F103 | Cortex-M3 | 72MHz | 64KB | 20KB +Arduino MKR* | SAMD21 | Cortex-M0+ ⚠️ | 48MHz | 256KB | 32KB +Arduino 101 | Intel Curie | ARC32 | 32MHz | 196KB | 24KB +SiFive HiFive1 | Freedom E310 | RV32IMAC | 320MHz | 16 MB | 16KB +Nordic nRF52832 | | Cortex-M4F | 64MHz | 256/512KB | 32/64KB +Nordic nRF51822 | | Cortex-M0 ⚠️ | 16MHz | 128/256KB | 16/32KB +Wicked Device WildFire | ATmega1284 | 8-bit AVR ⚠️ | 20MHz | 128KB | 16KB + +### Legend: + ⚠️ This architecture/compiler currently fails to perform TCO (Tail Call Optimization/Elimination), which leads to sub-optimal interpreter behaviour (intense native stack usage, lower performance). +There are plans to improve this in future 🦄. diff --git a/wasm3-sys/wasm3/docs/Installation.md b/wasm3-sys/wasm3/docs/Installation.md new file mode 100644 index 0000000..651cdf3 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Installation.md @@ -0,0 +1,26 @@ +# Wasm3 installation + +## Windows +Download `wasm3-win-x64.exe` or `wasm3-win-x86.exe` from the [latest release page](https://github.com/wasm3/wasm3/releases/latest). + +## macOS +Use [Homebrew](https://brew.sh) to build and install automatically: +```sh +brew install wasm3 +``` + +## Cosmopolitan / Actually Portable Executable +[APE](https://justine.lol/cosmopolitan/index.html) is a polyglot format that runs natively on Linux + Mac + Windows + FreeBSD + OpenBSD + NetBSD + BIOS. +Download `wasm3-cosmopolitan.com` from the [latest release page](https://github.com/wasm3/wasm3/releases/latest) + +## OpenWRT +Follow instructions [here](https://github.com/wasm3/wasm3-openwrt-packages). + +## Arduino / PlatformIO / Particle.io library +Find `Wasm3` in the `Library Manager` and install it. + +## Python module +```sh +pip3 install pywasm3 +``` + diff --git a/wasm3-sys/wasm3/docs/Interpreter.md b/wasm3-sys/wasm3/docs/Interpreter.md new file mode 100644 index 0000000..67f2688 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Interpreter.md @@ -0,0 +1,166 @@ +# M3 + +This is a WebAssembly interpreter written in C using a novel, high performance interpreter topology. The interpreter strategy (named M3) was developed prior to this particular Wasm project and is described some below. + +## Purpose + +I don't know. I just woke up one day and started hacking this out after realizing my interpreter was well suited for the Wasm bytecode structure. Some ideas: + +* It could be useful for embedded systems. +* It might be a good start-up, pre-JIT interpreter in a more complex Wasm compiler system. +* It could serve as a Wasm validation library. +* The interpreter topology might be inspiring to others. + + +## Benchmarks + +It's at least fleshed out enough to run some simple benchmarks. + +Tested on a 4 GHz Intel Core i7 iMac (Retina 5K, 27-inch, Late 2014). M3 was compiled with Clang -Os. C benchmarks were compiled with gcc with -O3 + +### Mandelbrot + +C code lifted from: https://github.com/ColinEberhardt/wasm-mandelbrot + +|Interpreter|Execution Time|Relative to GCC| | +|-----------|--------------|---------------|----| +|Life |547 s |133 x | https://github.com/perlin-network/life +|Lua |122 s |30 x | This isn't Lua running some weird Wasm transcoding; a manual Lua conversion of the C benchmark as an additional reference point. +|M3 |17.9 s |4.4 x | (3.7 x on my 2016 MacBook Pro) +|GCC |4.1 s | | + +### CRC32 + +|Interpreter|Execution Time|Relative to GCC| +|-----------|--------------|---------------| +|Life |153 s |254 x | +|M3 |5.1 s |8.5 x | +|GCC |600 ms | | + + +In general, the M3 strategy seems capable of executing code around 4-15X slower than compiled code on a modern x86 processor. (Older CPUs don't fare as well. I suspect branch predictor differences.) I have yet to test on anything ARM. + +## M3: Massey Meta Machine + +Over the years, I've mucked around with creating my own personal programming language. It's called Gestalt. The yet unreleased repository will be here: https://github.com/soundandform/gestalt + +Early on I decided I needed an efficient interpreter to achieve the instant-feedback, live-coding environment I desire. Deep traditional compilation is too slow and totally unnecessary during development. And, most importantly, compilation latency destroys creative flow. + +I briefly considered retooling something extant. The Lua virtual machine, one of the faster interpreters, is too Lua centric. And everything else is too slow. + +I've also always felt that the "spin in a loop around a giant switch statement" thing most interpreters do was clumsy and boring. My intuition said there was something more elegant to be found. + +The structure that emerged I named a "meta machine" since it mirrors the execution of compiled code much more closely than the switch-based virtual machine. + +I set out with a goal of approximating Lua's performance. But this interpreter appears to beat Lua by 3X and more on basic benchmarks -- whatever they're worth! + +### How it works + +This rough information might not be immediately intelligible without referencing the source code. + +#### Reduce bytecode decoding overhead + +* Bytecode/opcodes are translated into more efficient "operations" during a compilation pass, generating pages of meta-machine code + * M3 trades some space for time. Opcodes map to up to 3 different operations depending on the number of source operands and commutative-ness. +* Commonly occurring sequences of operations can can also be optimized into a "fused" operation. This *sometimes* results in improved performance. + * the modern CPU pipeline is a mysterious beast +* In M3/Wasm, the stack machine model is translated into a more direct and efficient "register file" approach. + +#### Tightly Chained Operations + +* M3 operations are C functions with a single, fixed function signature. + + ```C + void * Operation_Whatever (pc_t pc, u64 * sp, u8 * mem, reg_t r0, f64 fp0); + ``` + +* The arguments of the operation are the M3's virtual machine registers + * program counter, stack pointer, etc. +* The return argument is a trap/exception and program flow control signal +* The M3 program code is traversed by each operation calling the next. The operations themselves drive execution forward. There is no outer control structure. + * Because operations end with a call to the next function, the C compiler will tail-call optimize most operations. +* Finally, note that x86/ARM calling conventions pass initial arguments through registers, and the indirect jumps between operations are branch predicted. + +#### The End Result + +Since operations all have a standardized signature and arguments are tail-call passed through to the next, the M3 "virtual" machine registers end up mapping directly to real CPU registers. It's not virtual! Instead, it's a meta machine with very low execution impedance. + +|M3 Register |x86 Register| +|-----------------------------|------------| +|program counter (pc) |rdi | +|stack pointer (sp) |rsi | +|linear memory (mem) |rdx | +|integer register (r0) |rcx | +|floating-point register (fp0)|xmm0 | + + +For example, here's a bitwise-or operation in the M3 compiled on x86. + +```assembly +m3`op_u64_Or_sr: + 0x1000062c0 <+0>: movslq (%rdi), %rax ; load operand stack offset + 0x1000062c3 <+3>: orq (%rsi,%rax,8), %rcx ; or r0 with stack operand + 0x1000062c7 <+7>: movq 0x8(%rdi), %rax ; fetch next operation + 0x1000062cb <+11>: addq $0x10, %rdi ; increment program counter + 0x1000062cf <+15>: jmpq *%rax ; jump to next operation +``` + + +#### Registers and Operational Complexity + +* The conventional Windows calling convention isn't compatible with M3, as-is, since it only passes 4 arguments through registers. Applying the vectorcall calling convention (https://docs.microsoft.com/en-us/cpp/cpp/vectorcall) resolves this problem. + +* It's possible to use more CPU registers. For example, adding an additional floating-point register to the meta-machine did marginally increase performance in prior tests. However, the operation space increases exponentially. With one register, there are up to 3 operations per opcode (e.g. a non-commutative math operation). Adding another register increases the operation count to 10. However, as you can see above, operations tend to be tiny. + +#### Stack Usage + +* Looking at the above assembly code, you'll notice that once an M3 operation is optimized, it doesn't need the regular stack (no mucking with the ebp/esp registers). This is the case for 90% of the opcodes. Branching and call operations do require stack variables. Therefore, execution can't march forward indefinitely; the stack would eventually overflow. + + Therefore, loops unwind the stack. When a loop is continued, the Continue operation returns, unwinding the stack. Its return value is a pointer to the loop opcode it wants to unwind to. The Loop operations checks for its pointer and responds appropriately, either calling back into the loop code or returning the loop pointer back down the call stack. + +* Traps/Exceptions work similarly. A trap pointer is returned from the trap operation which has the effect of unwinding the entire stack. + +* Returning from a Wasm function also unwinds the stack, back to the point of the Call operation. + +* But, because M3 execution leans heavily on the native stack, this does create one runtime usage issue. + + A conventional interpreter can save its state, break out of its processing loop and return program control to the client code. This is not the case in M3 since the C stack might be wound up in a loop for long periods of time. + + With Gestalt, I resolved this problem with fibers (built with Boost Context). M3 execution occurs in a fiber so that control can effortlessly switch to the "main" fiber. No explicit saving of state is necessary since that's the whole purpose of a fiber. + + More simplistically, the interpreter runtime can also periodically call back to the client (in the either the Loop or LoopContinue operation). This is necessary, regardless, to detect hangs and break out of infinite loops. + + +## The M3 strategy for other languages (is rad) + +The Gestalt M3 interpreter works slightly differently than this Wasm version. With Gestalt, blocks of all kind (if/else/try), not just loops, unwind the native stack. (This somewhat degrades raw x86 performance.) + +But, this adds a really beautiful property to the interpreter. The lexical scoping of a block in the language source code maps directly into the interpreter. All opcodes/operations end up having an optional prologue/epilogue structure. This made things like reference-counting objects in Gestalt effortless. Without this property, the compiler itself would have to track scope and insert dererence opcodes intentionally. Instead, the "CreateObject" operation is also the "DestroyObject" operation on the exit/return pathway. + +Here's some pseudocode to make this more concrete: + +``` +return_t Operation_NewObject (registers...) +{ + Object o = runtime->CreateObject (registers...); + + * stack [index] = o; + + return_t r = CallNextOperation (registers...); // executes to the end of the scope/block/curly-brace & returns + + if (o->ReferenceCount () == 0) + runtime->DestroyObject (registers..., o); // calls o's destructor and frees memory + + return r; +} +``` + +Likewise, a "defer" function (like in Go) becomes absolutely effortless to implement. Exceptions (try/catch) as well. + + +## Prior Art + +After the Wasm3 project was posted to Hacker News (https://news.ycombinator.com/item?id=22024758), I finally discovered precedent for this tail-call interpreter design. It has previously been called "threaded code". See the "Continuation-passing style" section: http://www.complang.tuwien.ac.at/forth/threaded-code.html). + +If this style of interpreter was discussed back in the 70's, why hasn't it been more popular? I suspect because there was no benefit until more recently. Older calling conventions only used the stack to pass arguments, older CPUs didn't have branch prediction and compiler tail-call optimization maybe weren't ubiqutous. + diff --git a/wasm3-sys/wasm3/docs/Performance.md b/wasm3-sys/wasm3/docs/Performance.md new file mode 100644 index 0000000..4b52a74 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Performance.md @@ -0,0 +1,91 @@ +# Performance + +## CoreMark 1.0 results + +```log +# Intel i5-8250U x64 (1.6-3.4GHz) + +Node v13.0.1 (interpreter) 28.544923 57.0x +wac (wax) 101.864113 16.0x +wasm-micro-runtime 201.612903 8.1x ▲ slower +wasm3 1627.869119 1.0 +Wasmer 0.13.1 singlepass 4065.591544 2.5x ▼ faster +wasmtime 0.8.0 (--optimize) 6453.505427 4.0x +Wasmer 0.13.1 cranelift 6467.164442 4.0x +Webassembly.sh (Chromium 78) 6914.325225 4.2x +Webassembly.sh (Firefox 70) 7251.153593 4.5x +wasmer-js (Node v13.0.1) 10043.827611 6.2x +Wasmer 0.13.1 llvm 12450.199203 7.6x +WAVM 14946.566026 9.2x +Native (GCC 7.4.0, 32-bit) 18070.112035 11.1x +Native (GCC 7.4.0, 64-bit) 19144.862795 11.8x +``` + +**Note:** Here is more info on [how to run CoreMark benchmark](https://github.com/wasm3/wasm-coremark). + +## Simple recursive Fibonacci calculation test + +```log + fib(40) +----------------------------------------------------------------------------------------- +# Intel i5-8250U x64 (1.6-3.4GHz) +Native C implementation 0.23s +Linux 3.83s +Win 10 5.35s +wasm3 on V8 (Emscripten 1.38, node v13.0.1) 17.98s + +# Raspberry Pi 4 BCM2711B0 armv7l (A72 @ 1.5GHz) +Native C implementation 1.11s +Linux 22.97s + +# Orange Pi Zero Plus2 H5 aarch64 (A53 @ 1GHz) +Native C implementation 2.55s +Linux 50.00s + +# VoCore2 mips32r2 (MT7628AN @ 580MHz) +Native C implementation 6.21s +OpenWRT 2m 38s + +# Xiaomi Mi Router 3G mips32r2 (MT7621AT @ 880MHz) +Native C implementation 8.83s +OpenWRT 3m 20s +``` + +## Wasm3 on MCUs + +```log + fib(24) comments +----------------------------------------------------------------------------------------- +Maix (K210) rv64imafc @ 400MHz 77ms +ESP8266 LX106 @ 160MHz 308ms TCO failed, stack used: 9024 +ESP32 LX6 @ 240MHz 297ms TCO failed, stack used: 10600 +ESP32-s2 (beta) LX6 @ 240MHz 297ms TCO failed +Particle Photon Arm M3 @ 120MHz 536ms +MXChip AZ3166 Arm M4 @ 100MHz ms +WM W600 Arm M3 @ 80MHz 698ms TCO enabled, stack used: 1325 +WM W600 Arm M3 @ 80MHz 826ms TCO disabled, stack used: 8109 +Arduino DUE (SAM3X8E) Arm M3 @ 84MHz 754ms +BleNano2 (nRF52) Arm M4 @ 64MHz 1.19s +Arduino MKR1000 Arm M0+ @ 48MHz 1.93s TCO failed +TinyBLE (nRF51) Arm M0 @ 16MHz 5.69s TCO failed +BluePill Arm M3 @ 72MHz 7.62s +HiFive1 (FE310) rv32imac @ 320MHz 9.10s <- something wrong here? +ATmega1284 avr @ 16MHz 12.99s TCO failed +Fomu rv32i @ 12MHz 25.20s +``` + +## Wasm3 vs other languages + +```log + fib(40) +----------------------------------------------------------------------------------------- +LuaJIT jit 1.15s +Node v10.15 jit 2.97s ▲ faster +Wasm3 interp 3.83s +Lua 5.1 interp 16.65s ▼ slower +Python 2.7 interp 34.08s +Python 3.4 interp 35.67s +Micropython v1.11 interp 85,00s +Espruino 2v04 interp >20m +``` + diff --git a/wasm3-sys/wasm3/docs/Testing.md b/wasm3-sys/wasm3/docs/Testing.md new file mode 100644 index 0000000..b38820c --- /dev/null +++ b/wasm3-sys/wasm3/docs/Testing.md @@ -0,0 +1,61 @@ +# Wasm3 tests + +## Running WebAssembly spec tests + +To run spec tests, you need `python3` + +```sh +# In test directory: +python3 ./run-spec-test.py +``` + +It will automatically download, extract, run the WebAssembly core test suite. + +## Running WASI test + +Wasm3 comes with a set of benchmarks and test programs (prebuilt as `WASI` apps) including `CoreMark`, `C-Ray`, `Brotli`, `mandelbrot`, `smallpt` and `wasm3` itself. + +This test will run all of them and verify the output: + +```sh +# In test directory: +python3 ./run-wasi-test.py +``` + +It can be run against other engines as well: + +```sh +./run-wasi-test.py --exec wasmtime # [PASS] +./run-wasi-test.py --exec "wavm run" # [PASS] +./run-wasi-test.py --exec "wasmer run" # [PASS] +./run-wasi-test.py --exec "wasmer-js run" # [PASS] +./run-wasi-test.py --exec $WAMR/iwasm --timeout=300 # [PASS, but very slow] +./run-wasi-test.py --exec $WAC/wax --timeout=300 # [FAIL, crashes on most tests] +``` + +## Running coverage-guided fuzz testing with libFuzzer + +You need to produce a fuzzer build first (use your version of Clang): + +```sh +# In wasm3 root: +mkdir build-fuzzer +cd build-fuzzer +cmake -GNinja -DCLANG_SUFFIX="-9" .. +cmake -DBUILD_FUZZ:BOOL=TRUE .. +ninja +``` + +```sh +# In test directory: +../build-fuzzer/wasm3-fuzzer -detect_leaks=0 ./fuzz/corpus +``` + +Read [more on libFuzzer](https://llvm.org/docs/LibFuzzer.html) and it's options. + +Note: to catch fuzzer errors in debugger, you need to define: +```sh +export ASAN_OPTIONS=abort_on_error=1 +export UBSAN_OPTIONS=abort_on_error=1 +``` + diff --git a/wasm3-sys/wasm3/docs/Troubleshooting.md b/wasm3-sys/wasm3/docs/Troubleshooting.md new file mode 100644 index 0000000..9b95b12 --- /dev/null +++ b/wasm3-sys/wasm3/docs/Troubleshooting.md @@ -0,0 +1,26 @@ +# Wasm3 troubleshooting + +### `Error: [trap] stack overflow` + +Increase the stack size: +```sh +wasm3 --stack-size 1000000 file.wasm +``` + +### `Error: missing imported function` + +This means that the runtime doesn't provide a specific function, needed for your module execution. +You need to implement the required functions, and re-build Wasm3. +Alternatively, you can use Python to define your environment. Check out [`pywasm3`](https://pypi.org/project/pywasm3/) module. + +**Note:** If this happens with `WASI` functions like `wasi_unstable.*` or `wasi_snapshot_preview1.*`, please report as a bug. + +### `Error: compiling function overran its stack height limit` + +Try increasing `d_m3MaxFunctionStackHeight` in `m3_config.h` and rebuilding Wasm3. + +### `Error: [Fatal] repl_load: unallocated linear memory` + +Your module requires some `Memory`, but doesn't define/export it by itself. +This happens if module is built by `Emscripten`, or it's a library that is intended to be linked to some other modules. +Wasm3 currently doesn't support running such modules directly, but you can remove this limitation when embedding Wasm3 into your own app. diff --git a/wasm3-sys/wasm3/extra/blynk.png b/wasm3-sys/wasm3/extra/blynk.png new file mode 100644 index 0000000..000fde8 Binary files /dev/null and b/wasm3-sys/wasm3/extra/blynk.png differ diff --git a/wasm3-sys/wasm3/extra/button.png b/wasm3-sys/wasm3/extra/button.png new file mode 100644 index 0000000..85bceaf Binary files /dev/null and b/wasm3-sys/wasm3/extra/button.png differ diff --git a/wasm3-sys/wasm3/extra/disasm-func.sh b/wasm3-sys/wasm3/extra/disasm-func.sh new file mode 100755 index 0000000..188f3ff --- /dev/null +++ b/wasm3-sys/wasm3/extra/disasm-func.sh @@ -0,0 +1,17 @@ +# +# Utility to disassemble a specific function. +# Usage: +# ./disasm-func.sh ../build/wasm3 i32_Divide_sr +# + +FILE="$1" +FUNC="$2" + +# get starting address and size of function fact from nm +ADDR=$(nm --print-size --radix=d $FILE | grep $FUNC | cut -d ' ' -f 1,2) +# strip leading 0's to avoid being interpreted by objdump as octal addresses +STARTADDR=$(echo $ADDR | cut -d ' ' -f 1 | sed 's/^0*\(.\)/\1/') +SIZE=$(echo $ADDR | cut -d ' ' -f 2 | sed 's/^0*//') +STOPADDR=$(( $STARTADDR + $SIZE )) + +objdump --disassemble $FILE --start-address=$STARTADDR --stop-address=$STOPADDR -M suffix diff --git a/wasm3-sys/wasm3/extra/iden3.svg b/wasm3-sys/wasm3/extra/iden3.svg new file mode 100644 index 0000000..975144f --- /dev/null +++ b/wasm3-sys/wasm3/extra/iden3.svg @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/wasm3-sys/wasm3/extra/logo.png b/wasm3-sys/wasm3/extra/logo.png new file mode 100644 index 0000000..c1cf38d Binary files /dev/null and b/wasm3-sys/wasm3/extra/logo.png differ diff --git a/wasm3-sys/wasm3/extra/scailable.png b/wasm3-sys/wasm3/extra/scailable.png new file mode 100644 index 0000000..eb997b8 Binary files /dev/null and b/wasm3-sys/wasm3/extra/scailable.png differ diff --git a/wasm3-sys/wasm3/extra/screenshot-android.png b/wasm3-sys/wasm3/extra/screenshot-android.png new file mode 100644 index 0000000..885bbdd Binary files /dev/null and b/wasm3-sys/wasm3/extra/screenshot-android.png differ diff --git a/wasm3-sys/wasm3/extra/screenshot-ios.png b/wasm3-sys/wasm3/extra/screenshot-ios.png new file mode 100644 index 0000000..8bfe5b4 Binary files /dev/null and b/wasm3-sys/wasm3/extra/screenshot-ios.png differ diff --git a/wasm3-sys/wasm3/extra/shareup_app.svg b/wasm3-sys/wasm3/extra/shareup_app.svg new file mode 100644 index 0000000..875a8b1 --- /dev/null +++ b/wasm3-sys/wasm3/extra/shareup_app.svg @@ -0,0 +1 @@ +Shareup \ No newline at end of file diff --git a/wasm3-sys/wasm3/extra/testutils.py b/wasm3-sys/wasm3/extra/testutils.py new file mode 100755 index 0000000..97eccc6 --- /dev/null +++ b/wasm3-sys/wasm3/extra/testutils.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +# Author: Volodymyr Shymanskyy + +import os +import re, fnmatch +import pathlib + +class ansi: + ENDC = '\033[0m' + HEADER = '\033[94m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + +class dotdict(dict): + def __init__(self, *args, **kwargs): + super(dotdict, self).__init__(*args, **kwargs) + for arg in args: + if isinstance(arg, dict): + for k, v in arg.items(): + self[k] = v + if kwargs: + for k, v in kwargs.items(): + self[k] = v + + __getattr__ = dict.get + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + +class Blacklist(): + def __init__(self, patterns): + self._patterns = list(map(fnmatch.translate, patterns)) + self.update() + + def add(self, patterns): + self._patterns += list(map(fnmatch.translate, patterns)) + self.update() + + def update(self): + self._regex = re.compile('|'.join(self._patterns)) + + def __contains__(self, item): + return self._regex.match(item) is not None + +def filename(p): + _, fn = os.path.split(p) + return fn + +def pathname(p): + pn, _ = os.path.split(p) + return pn + +def ensure_path(p): + pathlib.Path(p).mkdir(parents=True, exist_ok=True) diff --git a/wasm3-sys/wasm3/extra/txiki_js.png b/wasm3-sys/wasm3/extra/txiki_js.png new file mode 100644 index 0000000..45cdb91 Binary files /dev/null and b/wasm3-sys/wasm3/extra/txiki_js.png differ diff --git a/wasm3-sys/wasm3/extra/utils.mk b/wasm3-sys/wasm3/extra/utils.mk new file mode 100644 index 0000000..f5ce9ea --- /dev/null +++ b/wasm3-sys/wasm3/extra/utils.mk @@ -0,0 +1,39 @@ +.PHONY: format + +all: + +format: + # Convert tabs to spaces + find ./source -type f -iname '*.[cpp\|c\|h]' -exec bash -c 'expand -t 4 "$$0" | sponge "$$0"' {} \; + # Remove trailing whitespaces + find ./source -type f -iname '*.[cpp\|c\|h]' -exec sed -i 's/ *$$//' {} \; + +preprocess: preprocess_restore + cp ./source/m3_exec.h ./source/m3_exec.h.bak + cp ./source/m3_compile.c ./source/m3_compile.c.bak + awk 'BEGIN {RS=""}{gsub(/\\\n/,"\\\n__NL__ ")}1' ./source/m3_exec.h | sponge ./source/m3_exec.h + cpp -I./source -P ./source/m3_compile.c | sponge ./source/m3_compile.c + awk '{gsub(/__NL__/,"\n")}1' ./source/m3_compile.c | sponge ./source/m3_compile.c + mv ./source/m3_exec.h.bak ./source/m3_exec.h + +preprocess_restore: + -mv source/m3_compile.c.bak source/m3_compile.c + touch source/m3_compile.c + + +test_rv64: + riscv64-linux-gnu-gcc -DDEBUG -Dd_m3HasWASI \ + -I./source ./source/*.c ./platforms/app/main.c \ + -O3 -g0 -flto -lm -static \ + -o wasm3-rv64 + + cd test; python3 run-wasi-test.py --fast --exec "qemu-riscv64-static ../wasm3-rv64" + rm ./wasm3-rv64 + +test_cpp: + clang -xc++ -Dd_m3HasWASI \ + -I./source ./source/*.c ./platforms/app/main.c \ + -O3 -g0 -flto -lm -static \ + -o wasm3-cpp + cd test; python3 run-wasi-test.py --fast --exec "../wasm3-cpp" + rm ./wasm3-cpp diff --git a/wasm3-sys/wasm3/extra/wapm-package/README.md b/wasm3-sys/wasm3/extra/wapm-package/README.md new file mode 100644 index 0000000..0174c86 --- /dev/null +++ b/wasm3-sys/wasm3/extra/wapm-package/README.md @@ -0,0 +1,105 @@ +# Wasm3 + +[Wasm3](https://github.com/wasm3/wasm3) is the fastest WebAssembly interpreter, and the most universal runtime. +It's packaged into a `WebAssembly` package, so you can finally run `WebAssembly` on `WebAssembly` 😆 + +## Running on WebAssembly.sh + +Open [**WebAssembly.sh**](https://webassembly.sh) + +First you need to fetch a wasm file you'd like to run: + +```sh +$ curl https://raw.githubusercontent.com/wasm3/wasm3/main/test/lang/fib32.wasm -o /tmp/fib32.wasm + +$ ls -l /tmp/fib32.wasm +---------- 1 somebody somegroup 62 1970-01-19 05:45 /tmp/fib32.wasm +``` + +Now we can run `wasm3` in interactive mode: + +```sh +$ wasm3 --repl /tmp/fib32.wasm +wasm3> fib 20 +Result: 6765 +wasm3> fib 30 +Result: 832040 +wasm3> ^C +$ +``` + +Or run a specific function directly: + +```sh +$ wasm3 --func fib /tmp/fib32.wasm 30 +Result: 832040 +``` + +`wasm3` also supports `WASI`, so you can run: + +```sh +$ curl https://raw.githubusercontent.com/wasm3/wasm3/main/test/wasi/simple/test.wasm -o /tmp/test.wasm +$ wasm3 /tmp/test.wasm +``` + +or even... run wasm3 inside wasm3: + +```sh +$ curl https://registry-cdn.wapm.io/contents/vshymanskyy/wasm3/0.5.0/build/wasm3-wasi.wasm -o /tmp/wasm3.wasm +$ wasm3 --stack-size 100000 /tmp/wasm3.wasm /tmp/test.wasm +``` + +## Tracing + +You can also get structured traces of arbitrary WASM file execution (and this requires no specific support from the runtime): + +```sh +$ wasm3-strace --repl /tmp/fib32.wasm +wasm3> fib 3 +fib (i32: 3) { + fib (i32: 1) { + } = 1 + fib (i32: 2) { + fib (i32: 0) { + } = 0 + fib (i32: 1) { + } = 1 + } = 1 +} = 2 +Result: 2 +``` + +WASI apps tracing is also supported: + +```sh +$ wasm3-strace /tmp/test.wasm trap +_start () { + __wasm_call_ctors () { + __wasilibc_populate_preopens () { + wasi_snapshot_preview1!fd_prestat_get(3, 65528) { } = 0 + malloc (i32: 2) { + dlmalloc (i32: 2) { + sbrk (i32: 0) { + } = 131072 + } = 70016 + } = 70016 +... + strcmp (i32: 70127, i32: 32) { + } = 0 + test_trap () { + a () { + b () { + c () { + } !trap = [trap] unreachable executed +... +==== wasm backtrace: + 0: 0x000c59 - .unnamed!c + 1: 0x000c5e - .unnamed!b + 2: 0x000c68 - .unnamed!a + 3: 0x000c72 - .unnamed!test_trap + 4: 0x000d2c - .unnamed!main + 5: 0x0037c9 - .unnamed!__main_void + 6: 0x000edb - .unnamed!__original_main + 7: 0x0002f3 - .unnamed!_start +Error: [trap] unreachable executed +``` diff --git a/wasm3-sys/wasm3/extra/wapm-package/build/.gitignore b/wasm3-sys/wasm3/extra/wapm-package/build/.gitignore new file mode 100644 index 0000000..86d0cb2 --- /dev/null +++ b/wasm3-sys/wasm3/extra/wapm-package/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/wasm3-sys/wasm3/extra/wapm-package/wapm.toml b/wasm3-sys/wasm3/extra/wapm-package/wapm.toml new file mode 100644 index 0000000..54b6b27 --- /dev/null +++ b/wasm3-sys/wasm3/extra/wapm-package/wapm.toml @@ -0,0 +1,25 @@ +[package] +name = "vshymanskyy/wasm3" +version = "0.5.0" +description = "🚀 The fastest WebAssembly interpreter. You can finally run WebAssembly on WebAssembly 😆" +readme = "README.md" +repository = "https://github.com/wasm3/wasm3" +homepage = "https://github.com/wasm3/wasm3" + +[[module]] +name = "wasm3" +source = "build/wasm3-wasi.wasm" +abi = "wasi" + +[[module]] +name = "wasm3-strace" +source = "build/wasm3-strace.wasm" +abi = "wasi" + +[[command]] +name = "wasm3" +module = "wasm3" + +[[command]] +name = "wasm3-strace" +module = "wasm3-strace" diff --git a/wasm3-sys/wasm3/extra/wasm-symbol.svg b/wasm3-sys/wasm3/extra/wasm-symbol.svg new file mode 100644 index 0000000..1323482 --- /dev/null +++ b/wasm3-sys/wasm3/extra/wasm-symbol.svg @@ -0,0 +1,71 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/wasm3-sys/wasm3/extra/wowcube.png b/wasm3-sys/wasm3/extra/wowcube.png new file mode 100644 index 0000000..f6c069c Binary files /dev/null and b/wasm3-sys/wasm3/extra/wowcube.png differ diff --git a/wasm3-sys/wasm3/platforms/android/.gitignore b/wasm3-sys/wasm3/platforms/android/.gitignore new file mode 100644 index 0000000..11b5322 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/.gitignore @@ -0,0 +1,9 @@ +.gradle +# Build output directies +*/.externalNativeBuild +/target +*/target +/build +*/build +*/.cxx + diff --git a/wasm3-sys/wasm3/platforms/android/README.md b/wasm3-sys/wasm3/platforms/android/README.md new file mode 100644 index 0000000..0d6c852 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/README.md @@ -0,0 +1,26 @@ +## Build for Android + + + +Install Android SDK Tools, then: + +```sh +export ANDROID_HOME=/opt/android-sdk/ +export PATH=$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH +``` + +Install NDK: +```sh +sdkmanager --install ndk-bundle +``` + +Build: +```sh +./gradlew build +``` + +Install on device: +``` +adb install -r ./app/build/outputs/apk/debug/app-debug.apk +``` + diff --git a/wasm3-sys/wasm3/platforms/android/app/build.gradle b/wasm3-sys/wasm3/platforms/android/app/build.gradle new file mode 100644 index 0000000..e48af94 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 29 + ndkVersion '22.1.7171670' + + defaultConfig { + applicationId 'com.example.hellojni' + minSdkVersion 23 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), + 'proguard-rules.pro' + } + } + externalNativeBuild { + cmake { + version '3.10.2+' + path "src/main/cpp/CMakeLists.txt" + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' +} diff --git a/wasm3-sys/wasm3/platforms/android/app/proguard-rules.pro b/wasm3-sys/wasm3/platforms/android/app/proguard-rules.pro new file mode 100644 index 0000000..b7420a7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/gfan/dev/sdk_current/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/AndroidManifest.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2081ab0 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/CMakeLists.txt b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..d4d63ec --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.4.1) + +add_definitions(-DANDROID -Wno-format-security -O3 + #-fno-optimize-sibling-calls + -flto -fomit-frame-pointer -fno-stack-check -fno-stack-protector) + +file(GLOB M3_SRC FOLLOW_SYMLINKS "m3/*.c" "*.c") + +add_library(wasm3-jni SHARED ${M3_SRC}) + +set_target_properties(wasm3-jni PROPERTIES LINK_FLAGS "-flto -O3") + +# Include libraries needed for wasm3-jni lib +target_link_libraries(wasm3-jni + android + log) diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/jni.c b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/jni.c new file mode 100644 index 0000000..115c6a4 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/jni.c @@ -0,0 +1,96 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include + +extern int main(); + +/* + * JNI init + */ + +JavaVM* javaVM; +JNIEnv* jniEnv; +jclass activityClz; +jobject activityObj; + +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM* vm, void* reserved) +{ + if ((*vm)->GetEnv(vm, (void**)&jniEnv, JNI_VERSION_1_6) != JNI_OK) { + return JNI_ERR; // JNI version not supported + } + javaVM = vm; + return JNI_VERSION_1_6; +} + +static int pfd[2]; +static pthread_t pumpThread; +static pthread_t mainThread; + +static void* runOutputPump(void* ctx) +{ + int readSize; + char buff[128]; + + JNIEnv* env; + (*javaVM)->AttachCurrentThread(javaVM, &env, NULL); + + jmethodID outputTextId = (*env)->GetMethodID(env, activityClz, + "outputText", + "(Ljava/lang/String;)V"); + + while ((readSize = read(pfd[0], buff, sizeof(buff) - 1)) > 0) + { + buff[readSize] = '\0'; + + jstring javaMsg = (*env)->NewStringUTF(env, buff); + (*env)->CallVoidMethod(env, activityObj, outputTextId, javaMsg); + (*env)->DeleteLocalRef(env, javaMsg); + } + + return 0; +} + +static void* runMain(void* ctx) +{ + (*javaVM)->AttachCurrentThread(javaVM, &jniEnv, NULL); + main(); + return NULL; +} + +JNIEXPORT void JNICALL +Java_com_example_wasm3_MainActivity_runMain(JNIEnv* env, jobject instance) +{ + setvbuf(stdout, 0, _IOLBF, 0); // stdout: line-buffered + setvbuf(stderr, 0, _IONBF, 0); // stderr: unbuffered + + // create the pipe and redirect stdout and stderr + pipe(pfd); + dup2(pfd[1], 1); + dup2(pfd[1], 2); + + jclass clz = (*env)->GetObjectClass(env, instance); + activityClz = (*env)->NewGlobalRef(env, clz); + activityObj = (*env)->NewGlobalRef(env, instance); + + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); + + pthread_create( &pumpThread, &threadAttr, runOutputPump, NULL); + + pthread_create( &mainThread, &threadAttr, runMain, NULL); + + pthread_attr_destroy(&threadAttr); +} diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/m3 b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/m3 new file mode 120000 index 0000000..f70c2e0 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/m3 @@ -0,0 +1 @@ +../../../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/main.c b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/main.c new file mode 100644 index 0000000..a1bb331 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/cpp/main.c @@ -0,0 +1,70 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include + +#include "m3/wasm3.h" +#include "m3/m3_api_libc.h" + +#include "m3/extra/coremark_minimal.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)coremark_minimal_wasm; + size_t fsize = coremark_minimal_wasm_len; + + printf("Loading WebAssembly...\n"); + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 8192, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + result = m3_LinkLibC (module); + if (result) FATAL("m3_LinkLibC: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "run"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running CoreMark 1.0...\n"); + + result = m3_CallV (f); + if (result) FATAL("m3_Call: %s", result); + + float value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %0.3f\n", value); +} + +int main() +{ + printf("Wasm3 v" M3_VERSION " on Android (" M3_ARCH ")\n"); + printf("Build " __DATE__ " " __TIME__ "\n"); + + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC); +} diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/java/com/example/wasm3/MainActivity.java b/wasm3-sys/wasm3/platforms/android/app/src/main/java/com/example/wasm3/MainActivity.java new file mode 100644 index 0000000..88e3326 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/java/com/example/wasm3/MainActivity.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.wasm3; + +import androidx.annotation.Keep; +import androidx.appcompat.app.AppCompatActivity; +import android.os.Bundle; +import android.widget.TextView; + +public class MainActivity extends AppCompatActivity { + + TextView tv; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_main); + tv = (TextView)findViewById(R.id.console); + + runMain(); + } + + @Keep + private void outputText(final String s) { + runOnUiThread(new Runnable() { + @Override + public void run() { + MainActivity.this.tv.append(s); + } + }); + } + + static { + System.loadLibrary("wasm3-jni"); + } + public native void runMain(); +} + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/drawable/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/drawable/ic_launcher.png new file mode 100644 index 0000000..842fcc8 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/drawable/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/layout/activity_main.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..15e83f8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..c68f603 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..ae9968a Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..7ed0c12 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..68bb899 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..f51427e Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..85c1d06 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/values-w820dp/dimens.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..63fc816 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ + + + 64dp + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/colors.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..932a251 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #654ff0 + #4b3bb3 + #bfd9cc + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/dimens.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..47c8224 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/strings.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..8d2f0bf --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Wasm3 + diff --git a/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/styles.xml b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/wasm3-sys/wasm3/platforms/android/build.gradle b/wasm3-sys/wasm3/platforms/android/build.gradle new file mode 100644 index 0000000..4dc1795 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/build.gradle @@ -0,0 +1,25 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:4.0.0' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/wasm3-sys/wasm3/platforms/android/gradle.properties b/wasm3-sys/wasm3/platforms/android/gradle.properties new file mode 100644 index 0000000..8c31d11 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +android.enableJetifier=true +android.useAndroidX=true + diff --git a/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.jar b/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..490fda8 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.properties b/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8cf6eb5 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/wasm3-sys/wasm3/platforms/android/gradlew b/wasm3-sys/wasm3/platforms/android/gradlew new file mode 100755 index 0000000..2fe81a7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/wasm3-sys/wasm3/platforms/android/gradlew.bat b/wasm3-sys/wasm3/platforms/android/gradlew.bat new file mode 100644 index 0000000..9109989 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/wasm3-sys/wasm3/platforms/android/override.txt b/wasm3-sys/wasm3/platforms/android/override.txt new file mode 100644 index 0000000..670531e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/override.txt @@ -0,0 +1,43 @@ + +/* + * Override printf, puts, putchar + */ + +JNIEnv* jniEnv; + +void callOutputText(const char* text) { + JNIEnv *env = jniEnv; + + jstring javaMsg = (*env)->NewStringUTF(env, text); + (*env)->CallVoidMethod(env, activityObj, outputTextId, javaMsg); + (*env)->DeleteLocalRef(env, javaMsg); +} + +int printf(const char * format, ... ) +{ + char buff[256] = {}; + + va_list args; + va_start (args, format); + const int result = vsnprintf(buff, sizeof(buff), format, args); + va_end (args); + + if (result > 0) { + callOutputText(buff); + } + return result; +} + +int puts(const char *s) +{ + callOutputText(s); + callOutputText("\n"); + return strlen(s); +} + +int putchar(int c) +{ + char buff[2] = { c, '\0' }; + callOutputText(buff); + return c; +} diff --git a/wasm3-sys/wasm3/platforms/android/settings.gradle b/wasm3-sys/wasm3/platforms/android/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/wasm3-sys/wasm3/platforms/android/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/wasm3-sys/wasm3/platforms/app/README.md b/wasm3-sys/wasm3/platforms/app/README.md new file mode 100644 index 0000000..17587ba --- /dev/null +++ b/wasm3-sys/wasm3/platforms/app/README.md @@ -0,0 +1 @@ +This is the main file for Linux, Windows, Mac OS, OpenWRT builds diff --git a/wasm3-sys/wasm3/platforms/app/main.c b/wasm3-sys/wasm3/platforms/app/main.c new file mode 100644 index 0000000..84e77db --- /dev/null +++ b/wasm3-sys/wasm3/platforms/app/main.c @@ -0,0 +1,714 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include +#include + +#include "wasm3.h" +#include "m3_api_libc.h" + +#if defined(d_m3HasWASI) || defined(d_m3HasMetaWASI) || defined(d_m3HasUVWASI) +#include "m3_api_wasi.h" +#define LINK_WASI +#endif + +#if defined(d_m3HasTracer) +#include "m3_api_tracer.h" +#endif + +// TODO: remove +#include "m3_env.h" + +/* + * NOTE: Gas metering/limit only applies to pre-instrumented modules. + * You can generate a metered version from any wasm file automatically, using + * https://github.com/ewasm/wasm-metering + */ +#define GAS_LIMIT 500000000 +#define GAS_FACTOR 10000LL + +#define MAX_MODULES 16 + +#define FATAL(msg, ...) { fprintf(stderr, "Error: [Fatal] " msg "\n", ##__VA_ARGS__); goto _onfatal; } + + +static IM3Environment env; +static IM3Runtime runtime; + +static u8* wasm_bins[MAX_MODULES]; +static int wasm_bins_qty = 0; + +#if defined(GAS_LIMIT) + +static int64_t initial_gas = GAS_FACTOR * GAS_LIMIT; +static int64_t current_gas = GAS_FACTOR * GAS_LIMIT; +static bool is_gas_metered = false; + +m3ApiRawFunction(metering_usegas) +{ + m3ApiGetArg (int32_t, gas) + + current_gas -= gas; + + if (UNLIKELY(current_gas < 0)) { + m3ApiTrap("[trap] Out of gas"); + } + m3ApiSuccess(); +} + +#endif // GAS_LIMIT + + +M3Result link_all (IM3Module module) +{ + M3Result res; + res = m3_LinkSpecTest (module); + if (res) return res; + + res = m3_LinkLibC (module); + if (res) return res; + +#if defined(LINK_WASI) + res = m3_LinkWASI (module); + if (res) return res; +#endif + +#if defined(d_m3HasTracer) + res = m3_LinkTracer (module); + if (res) return res; +#endif + +#if defined(GAS_LIMIT) + res = m3_LinkRawFunction (module, "metering", "usegas", "v(i)", &metering_usegas); + if (!res) { + fprintf(stderr, "Warning: Gas is limited to %0.4f\n", (double)(current_gas) / GAS_FACTOR); + is_gas_metered = true; + } + if (res == m3Err_functionLookupFailed) { res = NULL; } +#endif + + return res; +} + +const char* modname_from_fn(const char* fn) +{ + const char* sep = "/\\:*?"; + char c; + while ((c = *sep++)) { + const char* off = strrchr(fn, c) + 1; + fn = (fn < off) ? off : fn; + } + return fn; +} + +M3Result repl_load (const char* fn) +{ + M3Result result = m3Err_none; + IM3Module module = NULL; + + u8* wasm = NULL; + u32 fsize = 0; + + FILE* f = fopen (fn, "rb"); + if (!f) { + return "cannot open file"; + } + fseek (f, 0, SEEK_END); + fsize = ftell(f); + fseek (f, 0, SEEK_SET); + + if (fsize < 8) { + result = "file is too small"; + goto on_error; + } else if (fsize > 64*1024*1024) { + result = "file is too big"; + goto on_error; + } + + wasm = (u8*) malloc(fsize); + if (!wasm) { + result = "cannot allocate memory for wasm binary"; + goto on_error; + } + + if (fread (wasm, 1, fsize, f) != fsize) { + result = "cannot read file"; + goto on_error; + } + fclose (f); + f = NULL; + + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) goto on_error; + + result = m3_LoadModule (runtime, module); + if (result) goto on_error; + + m3_SetModuleName(module, modname_from_fn(fn)); + + result = link_all (module); + if (result) goto on_error; + + if (wasm_bins_qty < MAX_MODULES) { + wasm_bins[wasm_bins_qty++] = wasm; + } + + return result; + +on_error: + m3_FreeModule(module); + if (wasm) free(wasm); + if (f) fclose(f); + + return result; +} + +M3Result repl_load_hex (u32 fsize) +{ + M3Result result = m3Err_none; + + if (fsize < 8) { + return "file is too small"; + } else if (fsize > 10*1024*1024) { + return "file too big"; + } + + u8* wasm = (u8*) malloc(fsize); + if (!wasm) { + return "cannot allocate memory for wasm binary"; + } + + { // Load hex data from stdin + u32 wasm_idx = 0; + char hex[3] = { 0, }; + int hex_idx = 0; + while (wasm_idx < fsize) { + int c = fgetc(stdin); + if (!isxdigit(c)) continue; // Skip non-hex chars + hex[hex_idx++] = c; + if (hex_idx == 2) { + int val = strtol(hex, NULL, 16); + wasm[wasm_idx++] = val; + hex_idx = 0; + } + } + if (!fgets(hex, 3, stdin)) // Consume a newline + return "cannot read EOL"; + } + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) return result; + + result = m3_LoadModule (runtime, module); + if (result) return result; + + result = link_all (module); + + return result; +} + +void print_gas_used() +{ +#if defined(GAS_LIMIT) + if (is_gas_metered) { + fprintf(stderr, "Gas used: %0.4f\n", (double)(initial_gas - current_gas) / GAS_FACTOR); + } +#endif +} + +void print_backtrace() +{ + IM3BacktraceInfo info = m3_GetBacktrace(runtime); + if (!info) { + return; + } + + fprintf(stderr, "==== wasm backtrace:"); + + int frameCount = 0; + IM3BacktraceFrame curr = info->frames; + while (curr) + { + fprintf(stderr, "\n %d: 0x%06x - %s!%s", + frameCount, curr->moduleOffset, + m3_GetModuleName (m3_GetFunctionModule(curr->function)), + m3_GetFunctionName (curr->function) + ); + curr = curr->next; + frameCount++; + } + if (info->lastFrame == M3_BACKTRACE_TRUNCATED) { + fprintf(stderr, "\n (truncated)"); + } + fprintf(stderr, "\n"); +} + +M3Result repl_call (const char* name, int argc, const char* argv[]) +{ + IM3Function func; + M3Result result = m3_FindFunction (&func, runtime, name); + if (result) return result; + + if (argc && (!strcmp(name, "main") || !strcmp(name, "_main"))) { + return "passing arguments to libc main() not implemented"; + } + + if (!strcmp(name, "_start")) { +#if defined(LINK_WASI) + // Strip wasm file path + if (argc > 0) { + argv[0] = modname_from_fn(argv[0]); + } + + m3_wasi_context_t* wasi_ctx = m3_GetWasiContext(); + wasi_ctx->argc = argc; + wasi_ctx->argv = argv; + + result = m3_CallArgv(func, 0, NULL); + + print_gas_used(); + + if (result == m3Err_trapExit) { + exit(wasi_ctx->exit_code); + } + + return result; +#else + return "WASI not linked"; +#endif + } + + int arg_count = m3_GetArgCount(func); + int ret_count = m3_GetRetCount(func); + if (argc < arg_count) { + return "not enough arguments"; + } else if (argc > arg_count) { + return "too many arguments"; + } + + result = m3_CallArgv (func, argc, argv); + + print_gas_used(); + + if (result) return result; + + static uint64_t valbuff[128]; + static const void* valptrs[128]; + memset(valbuff, 0, sizeof(valbuff)); + for (int i = 0; i < ret_count; i++) { + valptrs[i] = &valbuff[i]; + } + result = m3_GetResults (func, ret_count, valptrs); + if (result) return result; + + if (ret_count <= 0) { + fprintf (stderr, "Result: \n"); + } + for (int i = 0; i < ret_count; i++) { + switch (m3_GetRetType(func, i)) { + case c_m3Type_i32: fprintf (stderr, "Result: %" PRIi32 "\n", *(i32*)valptrs[i]); break; + case c_m3Type_i64: fprintf (stderr, "Result: %" PRIi64 "\n", *(i64*)valptrs[i]); break; +# if d_m3HasFloat + case c_m3Type_f32: fprintf (stderr, "Result: %" PRIf32 "\n", *(f32*)valptrs[i]); break; + case c_m3Type_f64: fprintf (stderr, "Result: %" PRIf64 "\n", *(f64*)valptrs[i]); break; +# endif + default: return "unknown return type"; + } + } + + return result; +} + +// :invoke is used by spec tests, so it treats floats as raw data +M3Result repl_invoke (const char* name, int argc, const char* argv[]) +{ + IM3Function func; + M3Result result = m3_FindFunction (&func, runtime, name); + if (result) return result; + + int arg_count = m3_GetArgCount(func); + int ret_count = m3_GetRetCount(func); + + if (argc > 128) { + return "arguments limit reached"; + } else if (argc < arg_count) { + return "not enough arguments"; + } else if (argc > arg_count) { + return "too many arguments"; + } + + static uint64_t valbuff[128]; + static const void* valptrs[128]; + memset(valbuff, 0, sizeof(valbuff)); + memset(valptrs, 0, sizeof(valptrs)); + + for (int i = 0; i < argc; i++) { + u64* s = &valbuff[i]; + valptrs[i] = s; + switch (m3_GetArgType(func, i)) { + case c_m3Type_i32: + case c_m3Type_f32: *(u32*)(s) = strtoul(argv[i], NULL, 10); break; + case c_m3Type_i64: + case c_m3Type_f64: *(u64*)(s) = strtoull(argv[i], NULL, 10); break; + default: return "unknown argument type"; + } + } + + result = m3_Call (func, argc, valptrs); + if (result) return result; + + // reuse valbuff for return values + memset(valbuff, 0, sizeof(valbuff)); + for (int i = 0; i < ret_count; i++) { + valptrs[i] = &valbuff[i]; + } + result = m3_GetResults (func, ret_count, valptrs); + if (result) return result; + + fprintf (stderr, "Result: "); + if (ret_count <= 0) { + fprintf (stderr, ""); + } + for (int i = 0; i < ret_count; i++) { + switch (m3_GetRetType(func, i)) { + case c_m3Type_i32: fprintf (stderr, "%" PRIu32 ":i32", *(u32*)valptrs[i]); break; + case c_m3Type_f32: fprintf (stderr, "%" PRIu32 ":f32", *(u32*)valptrs[i]); break; + case c_m3Type_i64: fprintf (stderr, "%" PRIu64 ":i64", *(u64*)valptrs[i]); break; + case c_m3Type_f64: fprintf (stderr, "%" PRIu64 ":f64", *(u64*)valptrs[i]); break; + default: return "unknown return type"; + } + if (i != ret_count-1) { + fprintf (stderr, ", "); + } + } + fprintf (stderr, "\n"); + + return result; +} + +M3Result repl_global_get (const char* name) +{ + IM3Global g = m3_FindGlobal(runtime->modules, name); + + M3TaggedValue tagged; + M3Result err = m3_GetGlobal (g, &tagged); + if (err) return err; + + switch (tagged.type) { + case c_m3Type_i32: fprintf (stderr, "%" PRIu32 ":i32\n", tagged.value.i32); break; + case c_m3Type_i64: fprintf (stderr, "%" PRIu64 ":i64\n", tagged.value.i64); break; + case c_m3Type_f32: fprintf (stderr, "%" PRIf32 ":f32\n", tagged.value.f32); break; + case c_m3Type_f64: fprintf (stderr, "%" PRIf64 ":f64\n", tagged.value.f64); break; + default: return m3Err_invalidTypeId; + } + return m3Err_none; +} + +M3Result repl_global_set (const char* name, const char* value) +{ + IM3Global g = m3_FindGlobal(runtime->modules, name); + + M3TaggedValue tagged = { + .type = m3_GetGlobalType(g) + }; + + switch (tagged.type) { + case c_m3Type_i32: tagged.value.i32 = strtoul(value, NULL, 10); break; + case c_m3Type_i64: tagged.value.i64 = strtoull(value, NULL, 10); break; + case c_m3Type_f32: tagged.value.f32 = strtod(value, NULL); break; + case c_m3Type_f64: tagged.value.f64 = strtod(value, NULL); break; + default: return m3Err_invalidTypeId; + } + + return m3_SetGlobal (g, &tagged); +} + +M3Result repl_compile () +{ + return m3_CompileModule(runtime->modules); +} + +M3Result repl_dump () +{ + uint32_t len; + uint8_t* mem = m3_GetMemory(runtime, &len, 0); + if (mem) { + FILE* f = fopen ("wasm3_dump.bin", "wb"); + if (!f) { + return "cannot open file"; + } + if (fwrite (mem, 1, len, f) != len) { + return "cannot write file"; + } + fclose (f); + } + return m3Err_none; +} + +void repl_free () +{ + if (runtime) { + m3_FreeRuntime (runtime); + runtime = NULL; + } + + for (int i = 0; i < wasm_bins_qty; i++) { + free (wasm_bins[i]); + wasm_bins[i] = NULL; + } +} + +M3Result repl_init (unsigned stack) +{ + repl_free(); + runtime = m3_NewRuntime (env, stack, NULL); + if (runtime == NULL) { + return "m3_NewRuntime failed"; + } + return m3Err_none; +} + +static +void unescape(char* buff) +{ + char* outp = buff; + while (*buff) { + if (*buff == '\\') { + switch (*(buff+1)) { + case '0': *outp++ = '\0'; break; + case 'b': *outp++ = '\b'; break; + case 'n': *outp++ = '\n'; break; + case 'r': *outp++ = '\r'; break; + case 't': *outp++ = '\t'; break; + case 'x': { + char hex[3] = { *(buff+2), *(buff+3), '\0' }; + *outp = strtol(hex, NULL, 16); + buff += 2; outp += 1; + break; + } + // Otherwise just pass the letter + // Also handles '\\' + default: *outp++ = *(buff+1); break; + } + buff += 2; + } else { + *outp++ = *buff++; + } + } + *outp = '\0'; +} + +static +int split_argv(char *str, char** argv) +{ + int result = 0; + char* curr = str; + int len = 0; + for (int i = 0; str[i] != '\0'; i++) { + if (strchr(" \n\r\t", str[i])) { + if (len) { // Found space after non-space + str[i] = '\0'; + //unescape(curr); // TODO: breaks windows build? + argv[result++] = curr; + len = 0; + } + } else { + if (!len) { // Found non-space after space + curr = &str[i]; + } + len++; + } + } + argv[result] = NULL; + return result; +} + +void print_version() { + const char* wasm3_env = getenv("WASM3"); + const char* wasm3_arch = getenv("WASM3_ARCH"); + + printf("Wasm3 v" M3_VERSION "%s on %s\n", + (wasm3_arch || wasm3_env) ? " self-hosting" : "", + wasm3_arch ? wasm3_arch : M3_ARCH); + + printf("Build: " __DATE__ " " __TIME__ ", " M3_COMPILER_VER "\n"); +} + +void print_usage() { + puts("Usage:"); + puts(" wasm3 [options] [args...]"); + puts(" wasm3 --repl [file]"); + puts("Options:"); + puts(" --func function to run default: _start"); + puts(" --stack-size stack size in bytes default: 64KB"); + puts(" --dump-on-trap dump wasm memory"); +} + +#define ARGV_SHIFT() { i_argc--; i_argv++; } +#define ARGV_SET(x) { if (i_argc > 0) { x = i_argv[0]; ARGV_SHIFT(); } } + +int main (int i_argc, const char* i_argv[]) +{ + M3Result result = m3Err_none; + env = m3_NewEnvironment (); + runtime = NULL; + + bool argRepl = false; + bool argDumpOnTrap = false; + const char* argFile = NULL; + const char* argFunc = "_start"; + unsigned argStackSize = 64*1024; + +// m3_PrintM3Info (); + + ARGV_SHIFT(); // Skip executable name + + while (i_argc > 0) + { + const char* arg = i_argv[0]; + if (arg[0] != '-') break; + + ARGV_SHIFT(); + if (!strcmp("--help", arg) or !strcmp("-h", arg)) { + print_usage(); + return 0; + } else if (!strcmp("--version", arg)) { + print_version(); + return 0; + } else if (!strcmp("--repl", arg)) { + argRepl = true; + } else if (!strcmp("--dump-on-trap", arg)) { + argDumpOnTrap = true; + } else if (!strcmp("--stack-size", arg)) { + const char* tmp = "65536"; + ARGV_SET(tmp); + argStackSize = atol(tmp); + } else if (!strcmp("--gas-limit", arg)) { + const char* tmp = "0"; + ARGV_SET(tmp); + initial_gas = current_gas = GAS_FACTOR * atol(tmp); + } else if (!strcmp("--dir", arg)) { + const char* argDir; + ARGV_SET(argDir); + (void)argDir; + } else if (!strcmp("--func", arg) or !strcmp("-f", arg)) { + ARGV_SET(argFunc); + } + } + + if ((argRepl and (i_argc > 1)) or // repl supports 0 or 1 args + (not argRepl and (i_argc < 1)) // normal expects at least 1 + ) { + print_usage(); + return 1; + } + + ARGV_SET(argFile); + + result = repl_init(argStackSize); + if (result) FATAL("repl_init: %s", result); + + if (argFile) { + result = repl_load(argFile); + if (result) FATAL("repl_load: %s", result); + + if (argFunc and not argRepl) { + if (!strcmp(argFunc, "_start")) { + // When passing args to WASI, include wasm filename as argv[0] + result = repl_call(argFunc, i_argc+1, i_argv-1); + } else { + result = repl_call(argFunc, i_argc, i_argv); + } + + if (result) { + if (argDumpOnTrap) { + repl_dump(); + } + print_backtrace(); + goto _onfatal; + } + } + } + + while (argRepl) + { + char cmd_buff[2048] = { 0, }; + char* argv[32] = { 0, }; + fprintf(stdout, "wasm3> "); + fflush(stdout); + if (!fgets(cmd_buff, sizeof(cmd_buff), stdin)) { + return 0; + } + int argc = split_argv(cmd_buff, argv); + if (argc <= 0) { + continue; + } + result = m3Err_none; + if (!strcmp(":init", argv[0])) { + result = repl_init(argStackSize); + } else if (!strcmp(":version", argv[0])) { + print_version(); + } else if (!strcmp(":exit", argv[0])) { + repl_free(); + return 0; + } else if (!strcmp(":load", argv[0])) { // :load + result = repl_load(argv[1]); + } else if (!strcmp(":load-hex", argv[0])) { // :load-hex \n + result = repl_load_hex(atol(argv[1])); + } else if (!strcmp(":get-global", argv[0])) { + result = repl_global_get(argv[1]); + } else if (!strcmp(":set-global", argv[0])) { + result = repl_global_set(argv[1], argv[2]); + } else if (!strcmp(":dump", argv[0])) { + result = repl_dump(); + } else if (!strcmp(":compile", argv[0])) { + result = repl_compile(); + } else if (!strcmp(":invoke", argv[0])) { + unescape(argv[1]); + result = repl_invoke(argv[1], argc-2, (const char**)(argv+2)); + } else if (argv[0][0] == ':') { + result = "no such command"; + } else { + unescape(argv[0]); + result = repl_call(argv[0], argc-1, (const char**)(argv+1)); + if (result) { + print_backtrace(); + } + } + + if (result == m3Err_trapExit) { + //TODO: fprintf(stderr, M3_ARCH "-wasi: exit(%d)\n", runtime->exit_code); + } else if (result) { + fprintf (stderr, "Error: %s", result); + M3ErrorInfo info; + m3_GetErrorInfo (runtime, &info); + fprintf (stderr, " (%s)\n", info.message); + } + } + +_onfatal: + if (result) { + fprintf (stderr, "Error: %s", result); + if (runtime) + { + M3ErrorInfo info; + m3_GetErrorInfo (runtime, &info); + if (strlen(info.message)) { + fprintf (stderr, " (%s)", info.message); + } + } + fprintf (stderr, "\n"); + } + + m3_FreeRuntime (runtime); + m3_FreeEnvironment (env); + + return result ? 1 : 0; +} diff --git a/wasm3-sys/wasm3/platforms/app_fuzz/fuzzer.c b/wasm3-sys/wasm3/platforms/app_fuzz/fuzzer.c new file mode 100644 index 0000000..b97d649 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/app_fuzz/fuzzer.c @@ -0,0 +1,49 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include + +#include "wasm3.h" + +#define FATAL(...) __builtin_trap() + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + M3Result result = m3Err_none; + + if (size < 8 || size > 256*1024) { + return 0; + } + + IM3Environment env = m3_NewEnvironment (); + if (env) { + IM3Runtime runtime = m3_NewRuntime (env, 128, NULL); + if (runtime) { + IM3Module module = NULL; + result = m3_ParseModule (env, &module, data, size); + if (module) { + result = m3_LoadModule (runtime, module); + if (result == 0) { + IM3Function f = NULL; + result = m3_FindFunction (&f, runtime, "fib"); + /* TODO: + if (f) { + m3_CallV (f, 10); + }*/ + } else { + m3_FreeModule (module); + } + } + + m3_FreeRuntime(runtime); + } + m3_FreeEnvironment(env); + } + + return 0; +} diff --git a/wasm3-sys/wasm3/platforms/cosmopolitan/.gitignore b/wasm3-sys/wasm3/platforms/cosmopolitan/.gitignore new file mode 100644 index 0000000..8352c97 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cosmopolitan/.gitignore @@ -0,0 +1,4 @@ +cosmopolitan/ +wasm3.com +wasm3.com.dbg + diff --git a/wasm3-sys/wasm3/platforms/cosmopolitan/build.sh b/wasm3-sys/wasm3/platforms/cosmopolitan/build.sh new file mode 100755 index 0000000..b84f995 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cosmopolitan/build.sh @@ -0,0 +1,41 @@ + +COSMOPOLITAN_VERSION=1.0 +COSMOPOLITAN_URL=https://github.com/jart/cosmopolitan/releases/download/$COSMOPOLITAN_VERSION/cosmopolitan-amalgamation-$COSMOPOLITAN_VERSION.zip + +SOURCE_DIR=../../source + +EXTRA_FLAGS="-Dd_m3PreferStaticAlloc -Dd_m3HasWASI" + +STD=./cosmopolitan/std + +if [ ! -d "./cosmopolitan" ]; then + echo "Downloading Cosmopolitan..." + curl -L -o cosmopolitan.zip $COSMOPOLITAN_URL + unzip cosmopolitan.zip -d cosmopolitan + rm cosmopolitan.zip +fi + +if [ ! -d "$STD/sys" ]; then + # Generate header stubs + mkdir -p $STD/sys + touch $STD/assert.h $STD/limits.h $STD/ctype.h $STD/time.h $STD/errno.h \ + $STD/inttypes.h $STD/fcntl.h $STD/math.h $STD/stdarg.h $STD/stdbool.h \ + $STD/stdint.h $STD/stdio.h $STD/stdlib.h $STD/string.h $STD/stddef.h \ + $STD/sys/types.h $STD/sys/stat.h $STD/unistd.h $STD/sys/uio.h \ + $STD/sys/random.h +fi + +echo "Building Wasm3..." + +# TODO: remove -fno-strict-aliasing + +gcc -g -Os -static -nostdlib -nostdinc -fno-pie -no-pie -mno-red-zone \ + -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -fuse-ld=bfd \ + -Wl,-T,cosmopolitan/ape.lds -include cosmopolitan/cosmopolitan.h \ + -Wno-format-security -Wfatal-errors -fno-strict-aliasing $EXTRA_FLAGS \ + -fomit-frame-pointer -fno-stack-check -fno-stack-protector \ + -o wasm3.com.dbg -DAPE -I$STD -I$SOURCE_DIR $SOURCE_DIR/*.c ../app/main.c \ + cosmopolitan/crt.o cosmopolitan/ape.o cosmopolitan/cosmopolitan.a + +objcopy -SO binary wasm3.com.dbg wasm3.com + diff --git a/wasm3-sys/wasm3/platforms/cpp/.gitignore b/wasm3-sys/wasm3/platforms/cpp/.gitignore new file mode 100644 index 0000000..6be3b8f --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/.gitignore @@ -0,0 +1,2 @@ +build +cmake-build-debug diff --git a/wasm3-sys/wasm3/platforms/cpp/CMakeLists.txt b/wasm3-sys/wasm3/platforms/cpp/CMakeLists.txt new file mode 100644 index 0000000..1230a33 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.9) +project(wasm3_cpp_example) + +set(target ${CMAKE_PROJECT_NAME}) + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../source ${CMAKE_BINARY_DIR}/m3) + +add_executable(${target} main.cpp) +target_link_libraries(${target} PRIVATE m3) + +add_subdirectory(wasm3_cpp) +target_link_libraries(${target} PRIVATE wasm3_cpp) + +target_compile_options(${target} PUBLIC -g) +target_compile_options(m3 PUBLIC -g) + +# Copy the 'wasm' directory into the build directory, so that +# wasm/test_prog.wasm is found even if wasm3_cpp_example is executed +# from the build directory. +add_custom_target(copy_wasm ALL + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_LIST_DIR}/wasm + ${CMAKE_BINARY_DIR}/wasm +) +add_dependencies(${CMAKE_PROJECT_NAME} copy_wasm) diff --git a/wasm3-sys/wasm3/platforms/cpp/README.md b/wasm3-sys/wasm3/platforms/cpp/README.md new file mode 100644 index 0000000..3ab4ecc --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/README.md @@ -0,0 +1,77 @@ +## C++ wrapper + +This example shows how to embed WASM3 into a C++ application. It uses a header-only library, `wasm3_cpp.h`, provided in `wasm3_cpp` subdirectory. Like WASM3 itself, this library can be included into CMake projects using `add_subdirectory` function. + +The main code of the example in `main.cpp` initializes WASM3, loads a WebAssembly module, links two external functions to the module, and executes two functions defined in WebAssembly. + +The WebAssembly module source code is inside `wasm` subdirectory. + +### `wasm3_cpp.h` reference + +All the classes are located in `wasm3` namespace. + +#### Class `environment` + +`environment::environment()` — create a new WASM3 environment. Runtimes, modules are owned by an environment. + +`runtime environment::new_runtime(size_t stack_size_bytes)` — create new runtime inside the environment. + +`module environment::parse_module(std::istream &in)` or `module environment::parse_module(const uint8_t *data, size_t size)` — parse a WASM binary module. + +#### Class `runtime` + +`runtime` objects are created using `environment::new_runtime` method, see above. + +`void runtime::load(module &m)` — load a parsed module into the runtime. + +`function runtime::find_function(const char *name)` — find a function defined in one of the loaded modules, by name. Raises a `wasm3::error` exception if the function is not found. + +#### Class `module` + +`module` objects are created by `environment::parse_module`. Parsed modules can be loaded into a `runtime` object. One module can only be loaded into one runtime. + +Before loading a module, you may need to link some external functions to it: + +`template void module::link(const char *mod, Func *function, const char *function_name)` — link a function `function` to module named `mod` under the name `function_name`. To link to any module, use `mod="*"`. + +`function` has to be either a non-member function or a static member function. + +Currently, the following types of arguments can be passed to functions linked this way: + +* int32_t +* int64_t +* float +* double +* const/non-const pointers + +Automatic conversion of other integral types may be implemented in the future. + +If the module doesn't reference an imported function named `func`, an exception is thrown. To link a function "optionally", i.e. without throwing an exception if the function is not imported, use `module::link_optional` instead. + +#### Class `function` + +`function` object can be obtained from a `runtime`, looking up the function by name. Function objects are used to call WebAssembly functions. + +`template Ret function::call()` — call a WebAssembly function which doesn't take any arguments. The return value of the function is automatically converted to the type `Ret`. Note that you need to specify the return type when using this template function, and the type has to match the type returned by the WebAssembly function. + +`template Ret function::call(Args...)` — same as above, but also allows passing arguments to the WebAssembly function. + +`template Ret function::call_argv(Args...)` — same as above, except that this function takes arguments as C strings (`const char*`). + +### Building and running + +This directory is a CMake project, and can be built as follows: + +```bash +mkdir build +cd build +cmake .. +cmake --build . +``` + +Then run the example: + +```bash +./wasm3_cpp_example +``` + diff --git a/wasm3-sys/wasm3/platforms/cpp/main.cpp b/wasm3-sys/wasm3/platforms/cpp/main.cpp new file mode 100644 index 0000000..25f8ba8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/main.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +#include "wasm3_cpp.h" +#include "wasm/test_prog.wasm.h" + +int sum(int a, int b) +{ + return a + b; +} + +void * ext_memcpy (void* dst, const void* arg, int32_t size) +{ + return memcpy(dst, arg, (size_t) size); +} + +int main(void) +{ + std::cout << "Loading WebAssembly..." << std::endl; + + /* Wasm module can be loaded from a file */ + try { + wasm3::environment env; + wasm3::runtime runtime = env.new_runtime(1024); + const char* file_name = "wasm/test_prog.wasm"; + std::ifstream wasm_file(file_name, std::ios::binary | std::ios::in); + if (!wasm_file.is_open()) { + throw std::runtime_error("Failed to open wasm file"); + } + wasm3::module mod = env.parse_module(wasm_file); + runtime.load(mod); + } + catch(std::runtime_error &e) { + std::cerr << "WASM3 error: " << e.what() << std::endl; + return 1; + } + + /* Wasm module can also be loaded from an array */ + try { + wasm3::environment env; + wasm3::runtime runtime = env.new_runtime(1024); + wasm3::module mod = env.parse_module(test_prog_wasm, test_prog_wasm_len); + runtime.load(mod); + + mod.link("*", "sum", sum); + mod.link("*", "ext_memcpy", ext_memcpy); + + { + wasm3::function test_fn = runtime.find_function("test"); + auto res = test_fn.call(20, 10); + std::cout << "result: " << res << std::endl; + } + { + wasm3::function memcpy_test_fn = runtime.find_function("test_memcpy"); + auto res = memcpy_test_fn.call(); + std::cout << "result: 0x" << std::hex << res << std::dec << std::endl; + } + } + catch(wasm3::error &e) { + std::cerr << "WASM3 error: " << e.what() << std::endl; + return 1; + } + + return 0; +} diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm/Makefile b/wasm3-sys/wasm3/platforms/cpp/wasm/Makefile new file mode 100644 index 0000000..acdf6e1 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/wasm/Makefile @@ -0,0 +1,18 @@ +NAME=test_prog +SRC=$(NAME).c +WASM=$(NAME).wasm +HEADER=$(NAME).wasm.h +EMCC_FLAGS=-s STANDALONE_WASM -s ERROR_ON_UNDEFINED_SYMBOLS=0 -O3 + +all: $(HEADER) + +clean: + rm -f $(HEADER) $(WASM) + +.PHONY: all clean + +$(WASM): $(SRC) + emcc $< -o $@ $(EMCC_FLAGS) + +$(HEADER): $(WASM) + xxd -i $< >$@ diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.c b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.c new file mode 100644 index 0000000..a2250c8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.c @@ -0,0 +1,24 @@ +#include +#include + +extern int sum(int, int); +extern int ext_memcpy(void*, const void*, size_t); + +#define WASM_EXPORT __attribute__((used)) __attribute__((visibility ("default"))) + +int WASM_EXPORT test(int32_t arg1, int32_t arg2) +{ + int x = arg1 + arg2; + int y = arg1 - arg2; + return sum(x, y) / 2; +} + +int64_t WASM_EXPORT test_memcpy(void) +{ + int64_t x = 0; + int32_t low = 0x01234567; + int32_t high = 0x89abcdef; + ext_memcpy(&x, &low, 4); + ext_memcpy(((uint8_t*)&x) + 4, &high, 4); + return x; +} diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm new file mode 100644 index 0000000..eeb49b0 Binary files /dev/null and b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm differ diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm.h b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm.h new file mode 100644 index 0000000..cfc8003 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/wasm/test_prog.wasm.h @@ -0,0 +1,25 @@ +unsigned char test_prog_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x15, 0x04, 0x60, + 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x00, 0x60, 0x03, 0x7f, 0x7f, + 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7e, 0x02, 0x1c, 0x02, 0x03, 0x65, + 0x6e, 0x76, 0x0a, 0x65, 0x78, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x63, 0x70, + 0x79, 0x00, 0x02, 0x03, 0x65, 0x6e, 0x76, 0x03, 0x73, 0x75, 0x6d, 0x00, + 0x00, 0x03, 0x04, 0x03, 0x01, 0x03, 0x00, 0x05, 0x06, 0x01, 0x01, 0x80, + 0x02, 0x80, 0x02, 0x06, 0x09, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x8c, 0xc0, + 0x02, 0x0b, 0x07, 0x28, 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x02, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x00, 0x04, 0x0b, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x00, 0x03, 0x06, + 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x02, 0x0a, 0x71, 0x03, 0x03, + 0x00, 0x01, 0x0b, 0x59, 0x02, 0x01, 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, + 0x10, 0x6b, 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, + 0x08, 0x20, 0x00, 0x41, 0xe7, 0x8a, 0x8d, 0x09, 0x36, 0x02, 0x04, 0x20, + 0x00, 0x41, 0xef, 0x9b, 0xaf, 0xcd, 0x78, 0x36, 0x02, 0x00, 0x20, 0x00, + 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x41, 0x04, 0x10, 0x00, + 0x1a, 0x20, 0x00, 0x41, 0x08, 0x6a, 0x41, 0x04, 0x72, 0x20, 0x00, 0x41, + 0x04, 0x10, 0x00, 0x1a, 0x20, 0x00, 0x29, 0x03, 0x08, 0x21, 0x01, 0x20, + 0x00, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x20, 0x01, 0x0b, 0x11, 0x00, 0x20, + 0x00, 0x20, 0x01, 0x6a, 0x20, 0x00, 0x20, 0x01, 0x6b, 0x10, 0x01, 0x41, + 0x02, 0x6d, 0x0b, 0x0b, 0x0a, 0x01, 0x00, 0x41, 0x80, 0x0c, 0x0b, 0x03, + 0xa0, 0x06, 0x50 +}; +unsigned int test_prog_wasm_len = 255; diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/CMakeLists.txt b/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/CMakeLists.txt new file mode 100644 index 0000000..1cd3216 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 3.5) +add_library(wasm3_cpp INTERFACE) +target_include_directories(wasm3_cpp INTERFACE include) +target_compile_features(wasm3_cpp INTERFACE cxx_std_17) diff --git a/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h b/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h new file mode 100644 index 0000000..4f00505 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/cpp/wasm3_cpp/include/wasm3_cpp.h @@ -0,0 +1,398 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wasm3.h" + + +namespace wasm3 { + /** @cond */ + namespace detail { + typedef uint64_t *stack_type; + typedef void *mem_type; + template struct first_type { typedef T type; }; + + typedef const void *(*m3_api_raw_fn)(IM3Runtime, uint64_t *, void *); + + template + void arg_from_stack(T &dest, stack_type &_sp, mem_type mem) { + m3ApiGetArg(T, tmp); + dest = tmp; + } + + template + void arg_from_stack(T* &dest, stack_type &_sp, mem_type _mem) { + m3ApiGetArgMem(T*, tmp); + dest = tmp; + }; + + template + void arg_from_stack(const T* &dest, stack_type &_sp, mem_type _mem) { + m3ApiGetArgMem(const T*, tmp); + dest = tmp; + }; + + template + struct m3_sig { + static const char value = c; + }; + template struct m3_type_to_sig; + template<> struct m3_type_to_sig : m3_sig<'i'> {}; + template<> struct m3_type_to_sig : m3_sig<'I'> {}; + template<> struct m3_type_to_sig : m3_sig<'f'> {}; + template<> struct m3_type_to_sig : m3_sig<'F'> {}; + template<> struct m3_type_to_sig : m3_sig<'v'> {}; + template<> struct m3_type_to_sig : m3_sig<'*'> {}; + template<> struct m3_type_to_sig : m3_sig<'*'> {}; + + + template + struct m3_signature { + constexpr static size_t n_args = sizeof...(Args); + constexpr static const char value[n_args + 4] = { + m3_type_to_sig::value, + '(', + m3_type_to_sig::value..., + ')', + 0 + }; + }; + + template + static void get_args_from_stack(stack_type &sp, mem_type mem, std::tuple &tuple) { + std::apply([&](auto &... item) { + (arg_from_stack(item, sp, mem), ...); + }, tuple); + } + + template + struct wrap_helper; + + template + struct wrap_helper { + using Func = Ret(Args...); + static const void *wrap_fn(IM3Runtime rt, IM3ImportContext _ctx, stack_type _sp, mem_type mem) { + std::tuple args; + // The order here matters: m3ApiReturnType should go before calling get_args_from_stack, + // since both modify `_sp`, and the return value on the stack is reserved before the arguments. + m3ApiReturnType(Ret); + get_args_from_stack(_sp, mem, args); + Func* function = reinterpret_cast(_ctx->userdata); + Ret r = std::apply(function, args); + m3ApiReturn(r); + } + }; + + template + struct wrap_helper { + using Func = void(Args...); + static const void *wrap_fn(IM3Runtime rt, IM3ImportContext _ctx, stack_type sp, mem_type mem) { + std::tuple args; + get_args_from_stack(sp, mem, args); + Func* function = reinterpret_cast(_ctx->userdata); + std::apply(function, args); + m3ApiSuccess(); + } + }; + + template + class m3_wrapper; + + template + class m3_wrapper { + public: + static M3Result link(IM3Module io_module, + const char *const i_moduleName, + const char *const i_functionName, + Ret (*function)(Args...)) { + + return m3_LinkRawFunctionEx(io_module, i_moduleName, i_functionName, + m3_signature::value, + &wrap_helper::wrap_fn, + reinterpret_cast(function)); + } + }; + } // namespace detail + /** @endcond */ + + class module; + class runtime; + class function; + + /** + * Exception thrown for wasm3 errors. + * + * Use error:what() to get the reason as a string. + */ + class error : public std::runtime_error { + public: + explicit error(M3Result err) : std::runtime_error(err) {} + }; + + /** @cond */ + namespace detail { + void check_error(M3Result err) { + if (err != m3Err_none) { + throw error(err); + } + } + } // namespace detail + /** @endcond */ + + + /** + * Wrapper for WASM3 environment. + * + * Runtimes, modules are owned by an environment. + */ + class environment { + public: + environment() { + m_env.reset(m3_NewEnvironment(), m3_FreeEnvironment); + if (m_env == nullptr) { + throw std::bad_alloc(); + } + } + + /** + * Create new runtime + * + * @param stack_size_bytes size of the WASM stack for this runtime + * @return runtime object + */ + runtime new_runtime(size_t stack_size_bytes); + + /** + * Parse a WASM module from file + * + * The parsed module is not loaded into any runtime. Use runtime::load to + * load the module after parsing it. + * + * @param in file (WASM binary) + * @return module object + */ + module parse_module(std::istream &in); + + /** + * Parse a WASM module from binary data + * + * @param data pointer to the start of the binary + * @param size size of the binary + * @return module object + */ + module parse_module(const uint8_t *data, size_t size); + + protected: + std::shared_ptr m_env; + }; + + /** + * Wrapper for the runtime, where modules are loaded and executed. + */ + class runtime { + public: + /** + * Load the module into runtime + * @param mod module parsed by environment::parse_module + */ + void load(module &mod); + + /** + * Get a function handle by name + * + * If the function is not found, throws an exception. + * @param name name of a function, c-string + * @return function object + */ + function find_function(const char *name); + + protected: + friend class environment; + + runtime(const std::shared_ptr &env, size_t stack_size_bytes) + : m_env(env) { + m_runtime.reset(m3_NewRuntime(env.get(), stack_size_bytes, nullptr), &m3_FreeRuntime); + if (m_runtime == nullptr) { + throw std::bad_alloc(); + } + } + + /* runtime extends the lifetime of the environment */ + std::shared_ptr m_env; + std::shared_ptr m_runtime; + }; + + /** + * Module object holds a webassembly module + * + * It can be constructed by parsing a WASM binary using environment::parse_module. + * Functions can be linked to the loaded module. + * Once constructed, modules can be loaded into the runtime. + */ + class module { + public: + /** + * Link an external function. + * + * Throws an exception if the module doesn't reference a function with the given name. + * + * @tparam Func Function type (signature) + * @param module Name of the module to link the function to, or "*" to link to any module + * @param function_name Name of the function (as referenced by the module) + * @param function Function to link (a function pointer) + */ + template + void link(const char *module, const char *function_name, Func *function); + + /** + * Same as module::link, but doesn't throw an exception if the function is not referenced. + */ + template + void link_optional(const char *module, const char *function_name, Func *function); + + + protected: + friend class environment; + friend class runtime; + + module(const std::shared_ptr &env, std::istream &in_wasm) { + in_wasm.unsetf(std::ios::skipws); + std::vector in_bytes; + std::copy(std::istream_iterator(in_wasm), + std::istream_iterator(), + std::back_inserter(in_bytes)); + parse(env.get(), in_bytes.data(), in_bytes.size()); + } + + module(const std::shared_ptr &env, const uint8_t *data, size_t size) : m_env(env) { + parse(env.get(), data, size); + } + + void parse(IM3Environment env, const uint8_t *data, size_t size) { + IM3Module p; + M3Result err = m3_ParseModule(env, &p, data, size); + detail::check_error(err); + m_module.reset(p, [this](IM3Module module) { + if (!m_loaded) { + m3_FreeModule(module); + } + }); + } + + void load_into(IM3Runtime runtime) { + M3Result err = m3_LoadModule(runtime, m_module.get()); + detail::check_error(err); + m_loaded = true; + } + + std::shared_ptr m_env; + std::shared_ptr m_module; + bool m_loaded = false; + }; + + + /** + * Handle of a function. Can be obtained from runtime::find_function method by name. + */ + class function { + public: + /** + * Call the function with the provided arguments, expressed as strings. + * + * Arguments are passed as strings. WASM3 automatically converts them into the types expected + * by the function being called. + * + * Note that the type of the return value must be explicitly specified as a template argument. + * + * @return the return value of the function. + */ + template + typename detail::first_type::value>::type...>::type + call_argv(Args... args) { + /* std::enable_if above checks that all argument types are convertible const char* */ + const char* argv[] = {args...}; + M3Result res = m3_CallArgv(m_func, sizeof...(args), argv); + detail::check_error(res); + Ret ret; + res = m3_GetResults(m_func, 1, &ret); + detail::check_error(res); + return ret; + } + + /** + * Call the function with the provided arguments (int/float types). + * + * Note that the type of the return value must be explicitly specified as a template argument. + * + * @return the return value of the function. + */ + template + Ret call(Args... args) { + const void *arg_ptrs[] = { reinterpret_cast(&args)... }; + M3Result res = m3_Call(m_func, sizeof...(args), arg_ptrs); + detail::check_error(res); + Ret ret; + const void* ret_ptrs[] = { &ret }; + res = m3_GetResults(m_func, 1, ret_ptrs); + detail::check_error(res); + return ret; + } + + protected: + friend class runtime; + + function(const std::shared_ptr &runtime, const char *name) : m_runtime(runtime) { + M3Result err = m3_FindFunction(&m_func, runtime.get(), name); + detail::check_error(err); + assert(m_func != nullptr); + } + + std::shared_ptr m_runtime; + M3Function *m_func = nullptr; + }; + + runtime environment::new_runtime(size_t stack_size_bytes) { + return runtime(m_env, stack_size_bytes); + } + + module environment::parse_module(std::istream &in) { + return module(m_env, in); + } + + module environment::parse_module(const uint8_t *data, size_t size) { + return module(m_env, data, size); + } + + void runtime::load(module &mod) { + mod.load_into(m_runtime.get()); + } + + function runtime::find_function(const char *name) { + return function(m_runtime, name); + } + + template + void module::link(const char *module, const char *function_name, Func *function) { + M3Result ret = detail::m3_wrapper::link(m_module.get(), module, function_name, function); + detail::check_error(ret); + } + + template + void module::link_optional(const char *module, const char *function_name, Func *function) { + M3Result ret = detail::m3_wrapper::link(m_module.get(), module, function_name, function); + if (ret == m3Err_functionLookupFailed) { + return; + } + detail::check_error(ret); + } + +} // namespace wasm3 diff --git a/wasm3-sys/wasm3/platforms/embedded/arduino/.gitignore b/wasm3-sys/wasm3/platforms/embedded/arduino/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/arduino/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/wasm3-sys/wasm3/platforms/embedded/arduino/lib/wasm3 b/wasm3-sys/wasm3/platforms/embedded/arduino/lib/wasm3 new file mode 120000 index 0000000..17056a9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/arduino/lib/wasm3 @@ -0,0 +1 @@ +../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/arduino/platformio.ini b/wasm3-sys/wasm3/platforms/embedded/arduino/platformio.ini new file mode 100644 index 0000000..dceda85 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/arduino/platformio.ini @@ -0,0 +1,137 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +default_envs = + mkr1000 + due + mega1284 + tinyBLE + blenano + blenano2 + teensy31 + bluepill-mapple + bluepill + az3166 + maix + #titiva TODO: undefined reference to `_exit' + +[env] +framework = arduino +monitor_speed = 115200 + +src_filter = + +<*> + - + +[env:mkr1000] +platform = atmelsam +board = mkr1000USB + +src_build_flags = + -O3 -Wfatal-errors + -flto + #-fPIC -fomit-frame-pointer -foptimize-sibling-calls + +[env:due] +platform = atmelsam +board = due + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:mega1284] +platform = atmelavr +board = wildfirev3 + +src_build_flags = + -Dd_m3CodePageAlignSize=512 + -Os -Wfatal-errors + -flto + +[env:tinyBLE] +platform = nordicnrf51 +board = seeedTinyBLE + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:blenano] +platform = nordicnrf51 +board = redBearLabBLENano + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:blenano2] +platform = nordicnrf52 +board = redbear_blenano2 + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:teensy31] +platform = teensy +board = teensy31 +upload_protocol = teensy-cli + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:bluepill-mapple] +platform = ststm32 +board = bluepill_f103c8_128k +board_build.core = maple +upload_protocol = stlink +#upload_protocol = dfu + +src_build_flags = + -Dd_m3FixedHeap=8192 + -Os -Wfatal-errors + -flto + +[env:bluepill] +platform = ststm32 +board = bluepill_f103c8 +upload_protocol = stlink + +src_build_flags = + -Dd_m3FixedHeap=8192 + -Os -Wfatal-errors + -flto + +[env:az3166] +platform = ststm32 +board = mxchip_az3166 + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:maix] +platform = kendryte210 +board = sipeed-maix-one-dock + +src_build_flags = + -O3 -Wfatal-errors + -flto + +[env:titiva] +platform = titiva +board = lptm4c1294ncpdt + +src_build_flags = + -DLED_BUILTIN=13 + -O3 -Wfatal-errors diff --git a/wasm3-sys/wasm3/platforms/embedded/arduino/src/main.cpp b/wasm3-sys/wasm3/platforms/embedded/arduino/src/main.cpp new file mode 100644 index 0000000..f14d4f6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/arduino/src/main.cpp @@ -0,0 +1,82 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "Arduino.h" + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(func, msg) { \ + Serial.print("Fatal: " func ": "); \ + Serial.println(msg); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + size_t fsize = fib32_wasm_len; + + Serial.println("Loading WebAssembly..."); + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment", "failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime", "failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction", result); + + Serial.println("Running..."); + + result = m3_CallV(f, 24); + if (result) FATAL("m3_Call", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + Serial.print("Result: "); + Serial.println(value); +} + +void setup() +{ + pinMode(LED_BUILTIN, OUTPUT); + + Serial.begin(115200); + delay(10); + while (!Serial) {} + + Serial.println(); + Serial.println("Wasm3 v" M3_VERSION " on Arduino (" M3_ARCH "), build " __DATE__ " " __TIME__); + + digitalWrite(LED_BUILTIN, HIGH); + uint32_t start = millis(); + run_wasm(); + uint32_t end = millis(); + digitalWrite(LED_BUILTIN, LOW); + + Serial.print("Elapsed: "); + Serial.print(end - start); + Serial.println(" ms"); +} + +void loop() +{ + delay(100); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/bluepill/.gitignore b/wasm3-sys/wasm3/platforms/embedded/bluepill/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/bluepill/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/library.json b/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/library.json new file mode 100644 index 0000000..38cdf08 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/library.json @@ -0,0 +1,7 @@ +{ + "build" : { + "flags": "-Os -fomit-frame-pointer -fno-stack-check -fno-stack-protector -Wfatal-errors -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers", + "srcFilter": ["+<*>", "-"], + "libArchive": false + } +} diff --git a/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/src b/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/src new file mode 120000 index 0000000..e3e41d7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/bluepill/lib/wasm3/src @@ -0,0 +1 @@ +../../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/bluepill/platformio.ini b/wasm3-sys/wasm3/platforms/embedded/bluepill/platformio.ini new file mode 100644 index 0000000..6b3199b --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/bluepill/platformio.ini @@ -0,0 +1,10 @@ +[env:bluepill] +platform = ststm32 +board = bluepill_f103c8 +framework = stm32cube +upload_protocol = stlink +lib_deps = jeeh + +build_flags = + -Dd_m3FixedHeap=8192 + -Os -Wfatal-errors diff --git a/wasm3-sys/wasm3/platforms/embedded/bluepill/src/main.cpp b/wasm3-sys/wasm3/platforms/embedded/bluepill/src/main.cpp new file mode 100644 index 0000000..120af16 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/bluepill/src/main.cpp @@ -0,0 +1,75 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#include +#include + +#define FATAL(func, msg) { \ + puts("Fatal: " func ": "); \ + puts(msg); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + size_t fsize = fib32_wasm_len; + + puts("Loading WebAssembly..."); + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment", "failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime", "failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction", result); + + puts("Running..."); + + result = m3_CallV (f, 24); + if (result) FATAL("m3_Call", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults", result); + + char buff[32]; + itoa(value, buff, 10); + + puts("Result: "); + puts(buff); + puts("\n"); +} + +PinC<13> led; + +int main() +{ + enableSysTick(); + led.mode(Pinmode::out); + + puts("Wasm3 v" M3_VERSION " on BluePill, build " __DATE__ " " __TIME__ "\n"); + + led = 0; + run_wasm(); + led = 1; + +} diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.gitignore b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.gitignore new file mode 100644 index 0000000..d054d84 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.gitignore @@ -0,0 +1,3 @@ +build +sdkconfig +sdkconfig.old diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/Makefile b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/Makefile new file mode 100644 index 0000000..2f23716 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := wasm3 + +include $(IDF_PATH)/make/project.mk + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/component.mk b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/component.mk new file mode 100644 index 0000000..0b9d758 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/.old/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/CMakeLists.txt b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/CMakeLists.txt new file mode 100644 index 0000000..d88e541 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(wasm3) diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/README.md b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/README.md new file mode 100644 index 0000000..616de06 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/README.md @@ -0,0 +1,24 @@ +## Build for ESP-IDF, with minimal WASI support + +**Note:** Currently, to run this example you need a PSRAM-enabled ESP32 module (this might be improved in future). + +Download and install ESP-IDF v4.0 + +```sh +export IDF_PATH=/opt/esp32/esp-idf + +# Set tools path if needed: +#export IDF_TOOLS_PATH=/opt/esp32 + +source $IDF_PATH/export.sh + +idf.py menuconfig + +# Select target: +idf.py set-target esp32s2beta # or esp32 + +idf.py build + +idf.py -p /dev/ttyUSB0 flash monitor + +``` diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/CMakeLists.txt b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/CMakeLists.txt new file mode 100644 index 0000000..59c8747 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/CMakeLists.txt @@ -0,0 +1,11 @@ +file(GLOB_RECURSE M3_SOURCES "m3/*.c") + +set(APP_SOURCES "main.cpp" "m3_api_esp_wasi.c") + +idf_component_register(SRCS ${APP_SOURCES} ${M3_SOURCES} + INCLUDE_DIRS "") + +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error -O3 -DESP32 -Dd_m3MaxFunctionStackHeight=256) + +# Disable harmless warnings +target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers) diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3 b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3 new file mode 120000 index 0000000..17056a9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3 @@ -0,0 +1 @@ +../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.c b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.c new file mode 100644 index 0000000..c90e3f9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.c @@ -0,0 +1,536 @@ +// +// m3_api_esp_wasi.c +// +// Created by Volodymyr Shymanskyy on 01/07/20. +// Copyright © 2019 Volodymyr Shymanskyy. All rights reserved. +// + +#define _POSIX_C_SOURCE 200809L + +#include "m3_api_esp_wasi.h" + +#include "m3/m3_env.h" +#include "m3/m3_exception.h" + +#if defined(ESP32) + +typedef uint32_t __wasi_size_t; +#include "m3/extra/wasi_core.h" + +#include +#include +#include +#include +#include +#include +#include + +typedef struct wasi_iovec_t +{ + __wasi_size_t buf; + __wasi_size_t buf_len; +} wasi_iovec_t; + +#define PREOPEN_CNT 3 + +typedef struct Preopen { + int fd; + char* path; +} Preopen; + +Preopen preopen[PREOPEN_CNT] = { + { 0, "" }, + { 1, "" }, + { 2, "" }, +}; + +static +__wasi_errno_t errno_to_wasi(int errnum) { + switch (errnum) { + case EPERM: return __WASI_EPERM; break; + case ENOENT: return __WASI_ENOENT; break; + case ESRCH: return __WASI_ESRCH; break; + case EINTR: return __WASI_EINTR; break; + case EIO: return __WASI_EIO; break; + case ENXIO: return __WASI_ENXIO; break; + case E2BIG: return __WASI_E2BIG; break; + case ENOEXEC: return __WASI_ENOEXEC; break; + case EBADF: return __WASI_EBADF; break; + case ECHILD: return __WASI_ECHILD; break; + case EAGAIN: return __WASI_EAGAIN; break; + case ENOMEM: return __WASI_ENOMEM; break; + case EACCES: return __WASI_EACCES; break; + case EFAULT: return __WASI_EFAULT; break; + case EBUSY: return __WASI_EBUSY; break; + case EEXIST: return __WASI_EEXIST; break; + case EXDEV: return __WASI_EXDEV; break; + case ENODEV: return __WASI_ENODEV; break; + case ENOTDIR: return __WASI_ENOTDIR; break; + case EISDIR: return __WASI_EISDIR; break; + case EINVAL: return __WASI_EINVAL; break; + case ENFILE: return __WASI_ENFILE; break; + case EMFILE: return __WASI_EMFILE; break; + case ENOTTY: return __WASI_ENOTTY; break; + case ETXTBSY: return __WASI_ETXTBSY; break; + case EFBIG: return __WASI_EFBIG; break; + case ENOSPC: return __WASI_ENOSPC; break; + case ESPIPE: return __WASI_ESPIPE; break; + case EROFS: return __WASI_EROFS; break; + case EMLINK: return __WASI_EMLINK; break; + case EPIPE: return __WASI_EPIPE; break; + case EDOM: return __WASI_EDOM; break; + case ERANGE: return __WASI_ERANGE; break; + default: return __WASI_EINVAL; + } +} + +static inline +int convert_clockid(__wasi_clockid_t in) { + switch (in) { + case __WASI_CLOCK_MONOTONIC: return CLOCK_MONOTONIC; + //case __WASI_CLOCK_PROCESS_CPUTIME_ID: return CLOCK_PROCESS_CPUTIME_ID; + case __WASI_CLOCK_REALTIME: return CLOCK_REALTIME; + //case __WASI_CLOCK_THREAD_CPUTIME_ID: return CLOCK_THREAD_CPUTIME_ID; + default: return -1; + } +} + +static inline +__wasi_timestamp_t convert_timespec(const struct timespec *ts) { + if (ts->tv_sec < 0) + return 0; + if ((__wasi_timestamp_t)ts->tv_sec >= UINT64_MAX / 1000000000) + return UINT64_MAX; + return (__wasi_timestamp_t)ts->tv_sec * 1000000000 + ts->tv_nsec; +} + + +/* + * WASI API implementation + */ + +m3ApiRawFunction(m3_wasi_unstable_args_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArgMem (uint32_t * , argv) + m3ApiGetArgMem (char * , argv_buf) + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + + for (u32 i = 0; i < runtime->argc; ++i) + { + m3ApiWriteMem32(&argv[i], m3ApiPtrToOffset(argv_buf)); + + size_t len = strlen (runtime->argv[i]); + memcpy (argv_buf, runtime->argv[i], len); + argv_buf += len; + * argv_buf++ = 0; + } + + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_args_sizes_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArgMem (__wasi_size_t * , argc) + m3ApiGetArgMem (__wasi_size_t * , argv_buf_size) + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + + __wasi_size_t buflen = 0; + for (u32 i = 0; i < runtime->argc; ++i) + { + buflen += strlen (runtime->argv[i]) + 1; + } + + m3ApiWriteMem32(argc, runtime->argc); + m3ApiWriteMem32(argv_buf_size, buflen); + + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_environ_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArgMem (uint32_t * , env) + m3ApiGetArgMem (char * , env_buf) + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + // TODO + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_environ_sizes_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArgMem (__wasi_size_t * , env_count) + m3ApiGetArgMem (__wasi_size_t * , env_buf_size) + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + + // TODO + m3ApiWriteMem32(env_count, 0); + m3ApiWriteMem32(env_buf_size, 0); + + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_prestat_dir_name) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (char * , path) + m3ApiGetArg (__wasi_size_t , path_len) + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); } + size_t slen = strlen(preopen[fd].path); + memcpy(path, preopen[fd].path, M3_MIN(slen, path_len)); + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_prestat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (uint32_t * , buf) // TODO: use actual struct + + if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } + if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); } + m3ApiWriteMem32(buf, __WASI_PREOPENTYPE_DIR); + m3ApiWriteMem32(buf+1, strlen(preopen[fd].path)); + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (__wasi_fdstat_t * , fdstat) + + if (runtime == NULL || fdstat == NULL) { m3ApiReturn(__WASI_EINVAL); } + + struct stat fd_stat; + int fl = fcntl(fd, F_GETFL); + if (fl < 0) { m3ApiReturn(errno_to_wasi(errno)); } + fstat(fd, &fd_stat); + int mode = fd_stat.st_mode; + fdstat->fs_filetype = (S_ISBLK(mode) ? __WASI_FILETYPE_BLOCK_DEVICE : 0) | + (S_ISCHR(mode) ? __WASI_FILETYPE_CHARACTER_DEVICE : 0) | + (S_ISDIR(mode) ? __WASI_FILETYPE_DIRECTORY : 0) | + (S_ISREG(mode) ? __WASI_FILETYPE_REGULAR_FILE : 0) | + //(S_ISSOCK(mode) ? __WASI_FILETYPE_SOCKET_STREAM : 0) | + (S_ISLNK(mode) ? __WASI_FILETYPE_SYMBOLIC_LINK : 0); + m3ApiWriteMem16(&fdstat->fs_flags, + ((fl & O_APPEND) ? __WASI_FDFLAG_APPEND : 0) | + //((fl & O_DSYNC) ? __WASI_FDFLAG_DSYNC : 0) | + ((fl & O_NONBLOCK) ? __WASI_FDFLAG_NONBLOCK : 0) | + //((fl & O_RSYNC) ? __WASI_FDFLAG_RSYNC : 0) | + ((fl & O_SYNC) ? __WASI_FDFLAG_SYNC : 0)); + fdstat->fs_rights_base = (uint64_t)-1; // all rights + fdstat->fs_rights_inheriting = (uint64_t)-1; // all rights + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_fdstat_set_flags) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArg (__wasi_fdflags_t , flags) + + // TODO + + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_seek) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArg (__wasi_filedelta_t , offset) + m3ApiGetArg (__wasi_whence_t , wasi_whence) + m3ApiGetArgMem (__wasi_filesize_t * , result) + + if (runtime == NULL || result == NULL) { m3ApiReturn(__WASI_EINVAL); } + + int whence; + switch (wasi_whence) { + case __WASI_WHENCE_CUR: whence = SEEK_CUR; break; + case __WASI_WHENCE_END: whence = SEEK_END; break; + case __WASI_WHENCE_SET: whence = SEEK_SET; break; + default: m3ApiReturn(__WASI_EINVAL); + } + + int64_t ret; + ret = lseek(fd, offset, whence); + if (ret < 0) { m3ApiReturn(errno_to_wasi(errno)); } + m3ApiWriteMem64(result, ret); + m3ApiReturn(__WASI_ESUCCESS); +} + + +m3ApiRawFunction(m3_wasi_unstable_path_open) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , dirfd) + m3ApiGetArg (__wasi_lookupflags_t , dirflags) + m3ApiGetArgMem (const char * , path) + m3ApiGetArg (__wasi_size_t , path_len) + m3ApiGetArg (__wasi_oflags_t , oflags) + m3ApiGetArg (__wasi_rights_t , fs_rights_base) + m3ApiGetArg (__wasi_rights_t , fs_rights_inheriting) + m3ApiGetArg (__wasi_fdflags_t , fs_flags) + m3ApiGetArgMem (__wasi_fd_t * , fd) + + if (path_len >= 512) + m3ApiReturn(__WASI_EINVAL); + + // copy path so we can ensure it is NULL terminated + char host_path [path_len+1]; + + memcpy (host_path, path, path_len); + host_path[path_len] = '\0'; // NULL terminator + + // TODO + m3ApiReturn(__WASI_ENOSYS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_read) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (wasi_iovec_t * , wasi_iovs) + m3ApiGetArg (__wasi_size_t , iovs_len) + m3ApiGetArgMem (__wasi_size_t * , nread) + + if (runtime == NULL || nread == NULL) { m3ApiReturn(__WASI_EINVAL); } + + ssize_t res = 0; + for (__wasi_size_t i = 0; i < iovs_len; i++) { + void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); + size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + if (len == 0) continue; + + int ret = read (fd, addr, len); + if (ret < 0) m3ApiReturn(errno_to_wasi(errno)); + res += ret; + if ((size_t)ret < len) break; + } + m3ApiWriteMem32(nread, res); + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_write) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t , fd) + m3ApiGetArgMem (wasi_iovec_t * , wasi_iovs) + m3ApiGetArg (__wasi_size_t , iovs_len) + m3ApiGetArgMem (__wasi_size_t * , nwritten) + + if (runtime == NULL || nwritten == NULL) { m3ApiReturn(__WASI_EINVAL); } + + ssize_t res = 0; + for (__wasi_size_t i = 0; i < iovs_len; i++) { + void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); + size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + if (len == 0) continue; + + int ret = write (fd, addr, len); + if (ret < 0) m3ApiReturn(errno_to_wasi(errno)); + res += ret; + if ((size_t)ret < len) break; + } + m3ApiWriteMem32(nwritten, res); + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_close) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t, fd) + + int ret = close(fd); + m3ApiReturn(ret == 0 ? __WASI_ESUCCESS : ret); +} + +m3ApiRawFunction(m3_wasi_unstable_fd_datasync) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_fd_t, fd) + + // TODO + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_random_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArgMem (uint8_t * , buf) + m3ApiGetArg (__wasi_size_t , buflen) + + while (1) { + ssize_t retlen = 0; + +#if defined(__wasi__) || defined(__APPLE__) || defined(__ANDROID_API__) || defined(__OpenBSD__) + size_t reqlen = M3_MIN (buflen, 256); +# if defined(__APPLE__) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) + retlen = SecRandomCopyBytes(kSecRandomDefault, reqlen, buf) < 0 ? -1 : reqlen; +# else + retlen = getentropy(buf, reqlen) < 0 ? -1 : reqlen; +# endif +#elif defined(__FreeBSD__) || defined(__linux__) + retlen = getrandom(buf, buflen, 0); +#elif defined(_WIN32) + if (RtlGenRandom(buf, buflen) == TRUE) { + m3ApiReturn(__WASI_ESUCCESS); + } +#else + m3ApiReturn(__WASI_ENOSYS); +#endif + if (retlen < 0) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } + m3ApiReturn(errno_to_wasi(errno)); + } else if (retlen == buflen) { + m3ApiReturn(__WASI_ESUCCESS); + } else { + buf += retlen; + buflen -= retlen; + } + } +} + +m3ApiRawFunction(m3_wasi_unstable_clock_res_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_clockid_t , wasi_clk_id) + m3ApiGetArgMem (__wasi_timestamp_t * , resolution) + + if (runtime == NULL || resolution == NULL) { m3ApiReturn(__WASI_EINVAL); } + + int clk = convert_clockid(wasi_clk_id); + if (clk < 0) m3ApiReturn(__WASI_EINVAL); + + struct timespec tp; + if (clock_getres(clk, &tp) != 0) { + m3ApiWriteMem64(resolution, 1000000); + } else { + m3ApiWriteMem64(resolution, convert_timespec(&tp)); + } + + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_clock_time_get) +{ + m3ApiReturnType (uint32_t) + m3ApiGetArg (__wasi_clockid_t , wasi_clk_id) + m3ApiGetArg (__wasi_timestamp_t , precision) + m3ApiGetArgMem (__wasi_timestamp_t * , time) + + if (runtime == NULL || time == NULL) { m3ApiReturn(__WASI_EINVAL); } + + int clk = convert_clockid(wasi_clk_id); + if (clk < 0) m3ApiReturn(__WASI_EINVAL); + + struct timespec tp; + if (clock_gettime(clk, &tp) != 0) { + m3ApiReturn(errno_to_wasi(errno)); + } + + m3ApiWriteMem64(time, convert_timespec(&tp)); + m3ApiReturn(__WASI_ESUCCESS); +} + +m3ApiRawFunction(m3_wasi_unstable_proc_exit) +{ + m3ApiGetArg (uint32_t, code) + + runtime->exit_code = code; + + m3ApiTrap(m3Err_trapExit); +} + + +static +M3Result SuppressLookupFailure(M3Result i_result) +{ + if (i_result == m3Err_functionLookupFailed) + return m3Err_none; + else + return i_result; +} + + +M3Result m3_LinkEspWASI (IM3Module module) +{ + M3Result result = m3Err_none; + + // TODO: Preopen dirs + + static const char* namespaces[2] = { "wasi_unstable", "wasi_snapshot_preview1" }; + + for (int i=0; i<2; i++) + { + const char* wasi = namespaces[i]; + +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_get", "i(**)", &m3_wasi_unstable_args_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "args_sizes_get", "i(**)", &m3_wasi_unstable_args_sizes_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_res_get", "i(i*)", &m3_wasi_unstable_clock_res_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "clock_time_get", "i(iI*)", &m3_wasi_unstable_clock_time_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_get", "i(**)", &m3_wasi_unstable_environ_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "environ_sizes_get", "i(**)", &m3_wasi_unstable_environ_sizes_get))); + +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_advise", "i(iIIi)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_allocate", "i(iII)", ))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_close", "i(i)", &m3_wasi_unstable_fd_close))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_datasync", "i(i)", &m3_wasi_unstable_fd_datasync))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_get", "i(i*)", &m3_wasi_unstable_fd_fdstat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_flags", "i(ii)", &m3_wasi_unstable_fd_fdstat_set_flags))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_fdstat_set_rights", "i(iII)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_get", "i(i*)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_size", "i(iI)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_filestat_set_times","i(iIIi)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pread", "i(i*iI*)",))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_get", "i(i*)", &m3_wasi_unstable_fd_prestat_get))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_prestat_dir_name", "i(i*i)", &m3_wasi_unstable_fd_prestat_dir_name))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_pwrite", "i(i*iI*)",))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_read", "i(i*i*)", &m3_wasi_unstable_fd_read))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_readdir", "i(i*iI*)",))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_renumber", "i(ii)", ))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_seek", "i(iIi*)", &m3_wasi_unstable_fd_seek))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_sync", "i(i)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_tell", "i(i*)", ))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "fd_write", "i(i*i*)", &m3_wasi_unstable_fd_write))); + +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_create_directory", "i(i*i)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_get", "i(ii*i*)", &m3_wasi_unstable_path_filestat_get))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_filestat_set_times", "i(ii*iIIi)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_link", "i(ii*ii*i)", ))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_open", "i(ii*iiIIi*)", &m3_wasi_unstable_path_open))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_readlink", "i(i*i*i*)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_remove_directory", "i(i*i)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_rename", "i(i*ii*i)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_symlink", "i(*ii*i)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "path_unlink_file", "i(i*i)", ))); + +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "poll_oneoff", "i(**i*)", &m3_wasi_unstable_poll_oneoff))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_exit", "v(i)", &m3_wasi_unstable_proc_exit))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "proc_raise", "i(i)", ))); +_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "random_get", "i(*i)", &m3_wasi_unstable_random_get))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sched_yield", "i()", ))); + +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_recv", "i(i*ii**)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_send", "i(i*ii*)", ))); +//_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasi, "sock_shutdown", "i(ii)", ))); + } + +_catch: + return result; +} + +#endif // ESP32 + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.h b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.h new file mode 100644 index 0000000..838129a --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/m3_api_esp_wasi.h @@ -0,0 +1,23 @@ +// +// m3_api_esp_wasi.h +// +// Created by Volodymyr Shymanskyy on 01/07/20. +// Copyright © 2019 Volodymyr Shymanskyy. All rights reserved. +// + +#ifndef m3_api_esp_wasi_h +#define m3_api_esp_wasi_h + +#include "m3/m3_core.h" + +# if defined(__cplusplus) +extern "C" { +# endif + + M3Result m3_LinkEspWASI (IM3Module io_module); + +#if defined(__cplusplus) +} +# endif + +#endif /* m3_api_esp_wasi_h */ diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/main.cpp b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/main.cpp new file mode 100644 index 0000000..1213420 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/main.cpp @@ -0,0 +1,69 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "esp_system.h" + +#include +#include +#include + +#include "m3/wasm3.h" + +#include "m3_api_esp_wasi.h" +#include "wasi_test.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +static void run_wasm(void) +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)wasi_test_wasm; + uint32_t fsize = wasi_test_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 8*1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + result = m3_LinkEspWASI (runtime->modules); + if (result) FATAL("m3_LinkEspWASI: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "_start"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + const char* i_argv[2] = { "test.wasm", NULL }; + result = m3_CallArgv (f, 1, i_argv); + if (result) FATAL("m3_Call: %s", result); +} + +extern "C" void app_main(void) +{ + printf("\nWasm3 v" M3_VERSION " on " CONFIG_IDF_TARGET ", build " __DATE__ " " __TIME__ "\n"); + + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC); + + sleep(3); + printf("Restarting...\n\n\n"); + esp_restart(); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/wasi_test.wasm.h b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/wasi_test.wasm.h new file mode 100644 index 0000000..6dbdab3 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/main/wasi_test.wasm.h @@ -0,0 +1,2307 @@ +unsigned char wasi_test_wasm[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x5f, 0x0e, 0x60, + 0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, + 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7e, + 0x60, 0x00, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x02, 0x7f, 0x7f, 0x00, + 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x00, 0x60, 0x04, 0x7f, 0x7f, 0x7f, 0x7f, + 0x01, 0x7f, 0x60, 0x05, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, + 0x09, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x01, 0x7f, + 0x60, 0x03, 0x7f, 0x7e, 0x7f, 0x01, 0x7f, 0x60, 0x04, 0x7f, 0x7e, 0x7f, + 0x7f, 0x01, 0x7f, 0x60, 0x02, 0x7c, 0x7f, 0x01, 0x7c, 0x02, 0xa8, 0x03, + 0x0f, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x0e, 0x66, 0x64, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, 0x61, 0x73, + 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x13, 0x66, + 0x64, 0x5f, 0x70, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x64, 0x69, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x00, 0x0d, 0x77, 0x61, 0x73, + 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x11, 0x65, + 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, + 0x5f, 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, + 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0b, 0x65, 0x6e, 0x76, + 0x69, 0x72, 0x6f, 0x6e, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, + 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, + 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, + 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x61, 0x72, 0x67, 0x73, + 0x5f, 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, + 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0e, 0x63, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x67, 0x65, 0x74, 0x00, + 0x0b, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, + 0x74, 0x00, 0x05, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x00, 0x01, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x07, 0x66, 0x64, 0x5f, 0x72, 0x65, + 0x61, 0x64, 0x00, 0x08, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, + 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0d, 0x66, 0x64, 0x5f, 0x66, 0x64, + 0x73, 0x74, 0x61, 0x74, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x02, 0x0d, 0x77, + 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x09, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x00, 0x0a, + 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x0a, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x5f, 0x67, 0x65, + 0x74, 0x00, 0x02, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x07, 0x66, 0x64, 0x5f, 0x73, 0x65, 0x65, + 0x6b, 0x00, 0x0c, 0x0d, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x75, 0x6e, 0x73, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x08, 0x66, 0x64, 0x5f, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x00, 0x08, 0x03, 0x32, 0x31, 0x04, 0x01, 0x04, 0x05, 0x02, + 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, 0x02, 0x02, 0x01, 0x06, 0x05, 0x04, + 0x02, 0x01, 0x06, 0x01, 0x01, 0x06, 0x09, 0x07, 0x04, 0x02, 0x04, 0x01, + 0x03, 0x03, 0x01, 0x00, 0x04, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x07, 0x01, 0x02, 0x02, 0x02, 0x0d, 0x04, 0x05, 0x01, 0x70, + 0x01, 0x05, 0x05, 0x05, 0x03, 0x01, 0x00, 0x02, 0x06, 0x08, 0x01, 0x7f, + 0x01, 0x41, 0xa0, 0xaa, 0x04, 0x0b, 0x07, 0x19, 0x03, 0x06, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x00, 0x0f, 0x03, 0x66, 0x69, 0x62, 0x00, 0x10, 0x09, 0x0a, 0x01, + 0x00, 0x41, 0x01, 0x0b, 0x04, 0x2b, 0x2f, 0x2d, 0x36, 0x0a, 0xd2, 0xbf, + 0x01, 0x31, 0xf7, 0x02, 0x01, 0x04, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, + 0x22, 0x01, 0x24, 0x00, 0x10, 0x1f, 0x41, 0x03, 0x21, 0x00, 0x02, 0x40, + 0x03, 0x40, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x22, 0x02, 0x41, 0x08, + 0x4b, 0x0d, 0x01, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x01, 0x6b, + 0x0e, 0x08, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x0b, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x20, 0x01, 0x28, 0x02, + 0x04, 0x41, 0x01, 0x6a, 0x10, 0x14, 0x22, 0x02, 0x45, 0x0d, 0x03, 0x20, + 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x10, 0x01, 0x04, 0x40, + 0x20, 0x02, 0x10, 0x15, 0x0c, 0x04, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x28, + 0x02, 0x04, 0x6a, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x20, 0x02, + 0x10, 0x20, 0x20, 0x02, 0x10, 0x15, 0x0d, 0x03, 0x0b, 0x20, 0x00, 0x41, + 0x01, 0x6a, 0x22, 0x02, 0x20, 0x00, 0x49, 0x20, 0x02, 0x21, 0x00, 0x45, + 0x0d, 0x01, 0x0b, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, + 0x20, 0x01, 0x41, 0x0c, 0x6a, 0x10, 0x02, 0x0d, 0x00, 0x41, 0xe8, 0x1f, + 0x20, 0x01, 0x28, 0x02, 0x00, 0x41, 0x02, 0x74, 0x41, 0x04, 0x6a, 0x10, + 0x14, 0x36, 0x02, 0x00, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x10, 0x14, 0x22, + 0x00, 0x45, 0x0d, 0x00, 0x41, 0xe8, 0x1f, 0x28, 0x02, 0x00, 0x22, 0x02, + 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x41, 0x02, + 0x74, 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0xe8, 0x1f, 0x28, 0x02, + 0x00, 0x20, 0x00, 0x10, 0x03, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x0c, 0x6a, + 0x20, 0x01, 0x10, 0x04, 0x0d, 0x01, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x22, + 0x00, 0x04, 0x40, 0x20, 0x00, 0x41, 0x02, 0x74, 0x41, 0x04, 0x6a, 0x10, + 0x14, 0x21, 0x00, 0x20, 0x01, 0x28, 0x02, 0x00, 0x10, 0x14, 0x21, 0x02, + 0x20, 0x00, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x00, + 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x02, 0x10, 0x05, 0x0d, + 0x02, 0x0b, 0x41, 0xe8, 0x1b, 0x41, 0x88, 0x08, 0x29, 0x03, 0x00, 0x37, + 0x03, 0x00, 0x41, 0xe0, 0x1b, 0x41, 0x80, 0x08, 0x29, 0x03, 0x00, 0x37, + 0x03, 0x00, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x20, 0x00, 0x10, 0x13, 0x21, + 0x00, 0x10, 0x30, 0x20, 0x00, 0x0d, 0x02, 0x20, 0x01, 0x41, 0x10, 0x6a, + 0x24, 0x00, 0x0f, 0x0b, 0x41, 0xc7, 0x00, 0x10, 0x18, 0x00, 0x0b, 0x41, + 0xc7, 0x00, 0x10, 0x18, 0x00, 0x0b, 0x20, 0x00, 0x10, 0x18, 0x00, 0x0b, + 0x41, 0xc7, 0x00, 0x10, 0x18, 0x00, 0x0b, 0x1c, 0x00, 0x20, 0x00, 0x41, + 0x02, 0x4f, 0x04, 0x40, 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x10, 0x10, 0x20, + 0x00, 0x41, 0x7e, 0x6a, 0x10, 0x10, 0x6a, 0x0f, 0x0b, 0x20, 0x00, 0x0b, + 0xb0, 0x01, 0x02, 0x04, 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, 0x40, 0x6a, + 0x22, 0x00, 0x24, 0x00, 0x20, 0x00, 0x41, 0x14, 0x36, 0x02, 0x10, 0x41, + 0xe0, 0x08, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x10, 0x22, 0x41, 0xd8, 0x1b, + 0x28, 0x02, 0x00, 0x10, 0x23, 0x1a, 0x20, 0x00, 0x41, 0x30, 0x6a, 0x10, + 0x17, 0x41, 0x14, 0x10, 0x10, 0x21, 0x03, 0x20, 0x00, 0x41, 0x20, 0x6a, + 0x10, 0x17, 0x20, 0x00, 0x29, 0x03, 0x20, 0x20, 0x00, 0x29, 0x03, 0x30, + 0x7d, 0x21, 0x04, 0x02, 0x7f, 0x20, 0x00, 0x28, 0x02, 0x28, 0x22, 0x01, + 0x20, 0x00, 0x28, 0x02, 0x38, 0x22, 0x02, 0x48, 0x04, 0x40, 0x20, 0x04, + 0x42, 0x7f, 0x7c, 0x21, 0x04, 0x20, 0x01, 0x20, 0x02, 0x6b, 0x41, 0x80, + 0x94, 0xeb, 0xdc, 0x03, 0x6a, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x20, 0x02, + 0x6b, 0x0b, 0x21, 0x01, 0x20, 0x00, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, + 0x00, 0x20, 0x04, 0xb9, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8f, + 0x40, 0xa2, 0x20, 0x01, 0xb7, 0x44, 0x00, 0x00, 0x00, 0x00, 0x80, 0x84, + 0x2e, 0x41, 0xa3, 0xa0, 0x39, 0x03, 0x08, 0x41, 0xeb, 0x08, 0x20, 0x00, + 0x10, 0x22, 0x20, 0x00, 0x41, 0x40, 0x6b, 0x24, 0x00, 0x0b, 0x75, 0x01, + 0x02, 0x7f, 0x23, 0x00, 0x41, 0x20, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x02, + 0x40, 0x20, 0x00, 0x10, 0x1c, 0x22, 0x02, 0x41, 0x00, 0x4e, 0x04, 0x40, + 0x20, 0x01, 0x41, 0x00, 0x3a, 0x00, 0x1f, 0x20, 0x02, 0x20, 0x01, 0x41, + 0x1f, 0x6a, 0x10, 0x1a, 0x41, 0x01, 0x4e, 0x04, 0x40, 0x03, 0x40, 0x20, + 0x01, 0x20, 0x01, 0x2c, 0x00, 0x1f, 0x36, 0x02, 0x00, 0x41, 0xf9, 0x08, + 0x20, 0x01, 0x10, 0x22, 0x20, 0x02, 0x20, 0x01, 0x41, 0x1f, 0x6a, 0x10, + 0x1a, 0x41, 0x00, 0x4a, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x10, 0x19, + 0x1a, 0x10, 0x28, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x36, 0x02, + 0x10, 0x41, 0xff, 0x08, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x10, 0x22, 0x0b, + 0x20, 0x01, 0x41, 0x20, 0x6a, 0x24, 0x00, 0x0b, 0xdd, 0x02, 0x02, 0x02, + 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, 0xd0, 0x00, 0x6b, 0x22, 0x02, 0x24, + 0x00, 0x41, 0x90, 0x08, 0x41, 0x0c, 0x41, 0xd8, 0x1b, 0x28, 0x02, 0x00, + 0x22, 0x03, 0x10, 0x34, 0x1a, 0x41, 0xe0, 0x1b, 0x41, 0x0f, 0x20, 0x03, + 0x10, 0x34, 0x1a, 0x20, 0x02, 0x41, 0xa8, 0x08, 0x36, 0x02, 0x30, 0x41, + 0x9d, 0x08, 0x20, 0x02, 0x41, 0x30, 0x6a, 0x10, 0x22, 0x41, 0xaf, 0x08, + 0x41, 0x00, 0x10, 0x22, 0x20, 0x00, 0x41, 0x01, 0x4e, 0x04, 0x40, 0x20, + 0x01, 0x21, 0x03, 0x03, 0x40, 0x20, 0x02, 0x20, 0x03, 0x28, 0x02, 0x00, + 0x36, 0x02, 0x20, 0x41, 0xb6, 0x08, 0x20, 0x02, 0x41, 0x20, 0x6a, 0x10, + 0x22, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x7f, + 0x6a, 0x22, 0x00, 0x0d, 0x00, 0x0b, 0x0b, 0x10, 0x28, 0x20, 0x02, 0x41, + 0x40, 0x6b, 0x10, 0x17, 0x20, 0x02, 0x20, 0x02, 0x29, 0x03, 0x40, 0x37, + 0x03, 0x10, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x48, 0x36, 0x02, 0x18, + 0x41, 0xc9, 0x08, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x10, 0x22, 0x20, 0x02, + 0x41, 0x40, 0x6b, 0x41, 0x04, 0x10, 0x0c, 0x22, 0x00, 0x04, 0x40, 0x41, + 0xe0, 0x1f, 0x20, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x41, 0xa8, 0x28, 0x20, + 0x02, 0x28, 0x02, 0x40, 0x41, 0x7f, 0x6a, 0xad, 0x37, 0x03, 0x00, 0x41, + 0xa8, 0x28, 0x41, 0xa8, 0x28, 0x29, 0x03, 0x00, 0x42, 0xad, 0xfe, 0xd5, + 0xe4, 0xd4, 0x85, 0xfd, 0xa8, 0xd8, 0x00, 0x7e, 0x42, 0x01, 0x7c, 0x22, + 0x04, 0x37, 0x03, 0x00, 0x20, 0x04, 0x42, 0x21, 0x88, 0xa7, 0x21, 0x00, + 0x41, 0xa8, 0x28, 0x41, 0xa8, 0x28, 0x29, 0x03, 0x00, 0x42, 0xad, 0xfe, + 0xd5, 0xe4, 0xd4, 0x85, 0xfd, 0xa8, 0xd8, 0x00, 0x7e, 0x42, 0x01, 0x7c, + 0x22, 0x04, 0x37, 0x03, 0x00, 0x20, 0x04, 0x42, 0x21, 0x88, 0xa7, 0x21, + 0x03, 0x20, 0x02, 0x20, 0x00, 0x41, 0xbb, 0xd1, 0x8b, 0xdd, 0x00, 0x6d, + 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x03, 0x41, 0xbb, 0xd1, + 0x8b, 0xdd, 0x00, 0x6d, 0x22, 0x03, 0x36, 0x02, 0x04, 0x20, 0x02, 0x20, + 0x00, 0x20, 0x03, 0x6a, 0x36, 0x02, 0x08, 0x41, 0xbb, 0x08, 0x20, 0x02, + 0x10, 0x22, 0x10, 0x11, 0x20, 0x01, 0x28, 0x02, 0x04, 0x10, 0x3b, 0x45, + 0x04, 0x40, 0x20, 0x01, 0x28, 0x02, 0x08, 0x10, 0x12, 0x0b, 0x10, 0x32, + 0x20, 0x02, 0x41, 0xd0, 0x00, 0x6a, 0x24, 0x00, 0x41, 0x00, 0x0b, 0xb9, + 0x2e, 0x01, 0x0b, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x0b, 0x24, + 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x00, 0x41, 0xec, 0x01, 0x4d, 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x28, 0x02, + 0x00, 0x22, 0x05, 0x41, 0x10, 0x20, 0x00, 0x41, 0x13, 0x6a, 0x41, 0x70, + 0x71, 0x20, 0x00, 0x41, 0x0b, 0x49, 0x1b, 0x22, 0x06, 0x41, 0x03, 0x76, + 0x22, 0x00, 0x76, 0x22, 0x01, 0x41, 0x03, 0x71, 0x04, 0x40, 0x20, 0x01, + 0x41, 0x01, 0x71, 0x20, 0x00, 0x72, 0x41, 0x01, 0x73, 0x22, 0x02, 0x41, + 0x03, 0x74, 0x22, 0x04, 0x41, 0xa0, 0x1c, 0x6a, 0x28, 0x02, 0x00, 0x22, + 0x01, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, + 0x08, 0x22, 0x03, 0x20, 0x04, 0x41, 0x98, 0x1c, 0x6a, 0x22, 0x04, 0x46, + 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x05, 0x41, 0x7e, 0x20, 0x02, 0x77, + 0x71, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x41, 0x80, 0x1c, 0x28, 0x02, + 0x00, 0x1a, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, + 0x04, 0x36, 0x02, 0x0c, 0x0b, 0x20, 0x01, 0x20, 0x02, 0x41, 0x03, 0x74, + 0x22, 0x02, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, 0x01, 0x20, 0x02, + 0x6a, 0x22, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x41, 0x01, 0x72, 0x36, + 0x02, 0x04, 0x0c, 0x0c, 0x0b, 0x20, 0x06, 0x41, 0xf8, 0x1b, 0x28, 0x02, + 0x00, 0x22, 0x08, 0x4d, 0x0d, 0x01, 0x20, 0x01, 0x04, 0x40, 0x02, 0x40, + 0x41, 0x02, 0x20, 0x00, 0x74, 0x22, 0x02, 0x41, 0x00, 0x20, 0x02, 0x6b, + 0x72, 0x20, 0x01, 0x20, 0x00, 0x74, 0x71, 0x22, 0x00, 0x41, 0x00, 0x20, + 0x00, 0x6b, 0x71, 0x41, 0x7f, 0x6a, 0x22, 0x00, 0x20, 0x00, 0x41, 0x0c, + 0x76, 0x41, 0x10, 0x71, 0x22, 0x00, 0x76, 0x22, 0x01, 0x41, 0x05, 0x76, + 0x41, 0x08, 0x71, 0x22, 0x02, 0x20, 0x00, 0x72, 0x20, 0x01, 0x20, 0x02, + 0x76, 0x22, 0x00, 0x41, 0x02, 0x76, 0x41, 0x04, 0x71, 0x22, 0x01, 0x72, + 0x20, 0x00, 0x20, 0x01, 0x76, 0x22, 0x00, 0x41, 0x01, 0x76, 0x41, 0x02, + 0x71, 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, 0x76, 0x22, 0x00, 0x41, + 0x01, 0x76, 0x41, 0x01, 0x71, 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, + 0x76, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x74, 0x22, 0x03, 0x41, 0xa0, 0x1c, + 0x6a, 0x28, 0x02, 0x00, 0x22, 0x01, 0x28, 0x02, 0x08, 0x22, 0x00, 0x20, + 0x03, 0x41, 0x98, 0x1c, 0x6a, 0x22, 0x03, 0x46, 0x04, 0x40, 0x41, 0xf0, + 0x1b, 0x20, 0x05, 0x41, 0x7e, 0x20, 0x02, 0x77, 0x71, 0x22, 0x05, 0x36, + 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, 0x1a, + 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x00, 0x20, 0x03, 0x36, + 0x02, 0x0c, 0x0b, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x20, 0x01, + 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, 0x01, 0x20, 0x02, + 0x41, 0x03, 0x74, 0x22, 0x02, 0x6a, 0x20, 0x02, 0x20, 0x06, 0x6b, 0x22, + 0x04, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x06, 0x6a, 0x22, 0x06, 0x20, + 0x04, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x08, 0x04, 0x40, 0x20, + 0x08, 0x41, 0x03, 0x76, 0x22, 0x03, 0x41, 0x03, 0x74, 0x41, 0x98, 0x1c, + 0x6a, 0x21, 0x01, 0x41, 0x84, 0x1c, 0x28, 0x02, 0x00, 0x21, 0x02, 0x02, + 0x7f, 0x20, 0x05, 0x41, 0x01, 0x20, 0x03, 0x74, 0x22, 0x03, 0x71, 0x45, + 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x03, 0x20, 0x05, 0x72, 0x36, 0x02, + 0x00, 0x20, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x08, 0x0b, + 0x22, 0x03, 0x20, 0x02, 0x36, 0x02, 0x0c, 0x20, 0x01, 0x20, 0x02, 0x36, + 0x02, 0x08, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, + 0x03, 0x36, 0x02, 0x08, 0x0b, 0x41, 0x84, 0x1c, 0x20, 0x06, 0x36, 0x02, + 0x00, 0x41, 0xf8, 0x1b, 0x20, 0x04, 0x36, 0x02, 0x00, 0x0c, 0x0c, 0x0b, + 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, 0x22, 0x0a, 0x45, 0x0d, 0x01, 0x20, + 0x0a, 0x41, 0x00, 0x20, 0x0a, 0x6b, 0x71, 0x41, 0x7f, 0x6a, 0x22, 0x00, + 0x20, 0x00, 0x41, 0x0c, 0x76, 0x41, 0x10, 0x71, 0x22, 0x00, 0x76, 0x22, + 0x01, 0x41, 0x05, 0x76, 0x41, 0x08, 0x71, 0x22, 0x02, 0x20, 0x00, 0x72, + 0x20, 0x01, 0x20, 0x02, 0x76, 0x22, 0x00, 0x41, 0x02, 0x76, 0x41, 0x04, + 0x71, 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, 0x76, 0x22, 0x00, 0x41, + 0x01, 0x76, 0x41, 0x02, 0x71, 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, + 0x76, 0x22, 0x00, 0x41, 0x01, 0x76, 0x41, 0x01, 0x71, 0x22, 0x01, 0x72, + 0x20, 0x00, 0x20, 0x01, 0x76, 0x6a, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, + 0x6a, 0x28, 0x02, 0x00, 0x22, 0x01, 0x28, 0x02, 0x04, 0x41, 0x78, 0x71, + 0x20, 0x06, 0x6b, 0x21, 0x02, 0x20, 0x01, 0x21, 0x04, 0x03, 0x40, 0x02, + 0x40, 0x20, 0x04, 0x28, 0x02, 0x10, 0x22, 0x00, 0x45, 0x04, 0x40, 0x20, + 0x04, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, 0x0d, 0x01, + 0x0b, 0x20, 0x00, 0x28, 0x02, 0x04, 0x41, 0x78, 0x71, 0x20, 0x06, 0x6b, + 0x22, 0x03, 0x20, 0x02, 0x20, 0x03, 0x20, 0x02, 0x49, 0x22, 0x03, 0x1b, + 0x21, 0x02, 0x20, 0x00, 0x20, 0x01, 0x20, 0x03, 0x1b, 0x21, 0x01, 0x20, + 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x18, + 0x21, 0x09, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x22, 0x03, 0x47, + 0x04, 0x40, 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, 0x20, 0x01, 0x28, 0x02, + 0x08, 0x22, 0x00, 0x4d, 0x04, 0x40, 0x20, 0x00, 0x28, 0x02, 0x0c, 0x1a, + 0x0b, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x00, 0x20, 0x03, + 0x36, 0x02, 0x0c, 0x0c, 0x0b, 0x0b, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x22, + 0x04, 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, 0x04, 0x40, 0x20, 0x01, 0x28, + 0x02, 0x10, 0x22, 0x00, 0x45, 0x0d, 0x03, 0x20, 0x01, 0x41, 0x10, 0x6a, + 0x21, 0x04, 0x0b, 0x03, 0x40, 0x20, 0x04, 0x21, 0x07, 0x20, 0x00, 0x22, + 0x03, 0x41, 0x14, 0x6a, 0x22, 0x04, 0x28, 0x02, 0x00, 0x22, 0x00, 0x0d, + 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x28, 0x02, + 0x10, 0x22, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x07, 0x41, 0x00, 0x36, 0x02, + 0x00, 0x0c, 0x0a, 0x0b, 0x41, 0x7f, 0x21, 0x06, 0x20, 0x00, 0x41, 0xbf, + 0x7f, 0x4b, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x13, 0x6a, 0x22, 0x00, 0x41, + 0x70, 0x71, 0x21, 0x06, 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, 0x22, 0x08, + 0x45, 0x0d, 0x00, 0x41, 0x00, 0x20, 0x06, 0x6b, 0x21, 0x04, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x7f, 0x41, 0x00, 0x20, 0x00, 0x41, 0x08, + 0x76, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x41, 0x1f, 0x20, 0x06, 0x41, + 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x1a, 0x20, 0x00, 0x20, 0x00, + 0x41, 0x80, 0xfe, 0x3f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x08, 0x71, 0x22, + 0x00, 0x74, 0x22, 0x01, 0x20, 0x01, 0x41, 0x80, 0xe0, 0x1f, 0x6a, 0x41, + 0x10, 0x76, 0x41, 0x04, 0x71, 0x22, 0x01, 0x74, 0x22, 0x02, 0x20, 0x02, + 0x41, 0x80, 0x80, 0x0f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x02, 0x71, 0x22, + 0x02, 0x74, 0x41, 0x0f, 0x76, 0x20, 0x00, 0x20, 0x01, 0x72, 0x20, 0x02, + 0x72, 0x6b, 0x22, 0x00, 0x41, 0x01, 0x74, 0x20, 0x06, 0x20, 0x00, 0x41, + 0x15, 0x6a, 0x76, 0x41, 0x01, 0x71, 0x72, 0x41, 0x1c, 0x6a, 0x0b, 0x22, + 0x07, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, 0x28, 0x02, 0x00, 0x22, + 0x02, 0x45, 0x04, 0x40, 0x41, 0x00, 0x21, 0x00, 0x0c, 0x01, 0x0b, 0x20, + 0x06, 0x41, 0x00, 0x41, 0x19, 0x20, 0x07, 0x41, 0x01, 0x76, 0x6b, 0x20, + 0x07, 0x41, 0x1f, 0x46, 0x1b, 0x74, 0x21, 0x01, 0x41, 0x00, 0x21, 0x00, + 0x03, 0x40, 0x02, 0x40, 0x20, 0x02, 0x28, 0x02, 0x04, 0x41, 0x78, 0x71, + 0x20, 0x06, 0x6b, 0x22, 0x05, 0x20, 0x04, 0x4f, 0x0d, 0x00, 0x20, 0x02, + 0x21, 0x03, 0x20, 0x05, 0x22, 0x04, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x04, + 0x20, 0x02, 0x21, 0x00, 0x0c, 0x03, 0x0b, 0x20, 0x00, 0x20, 0x02, 0x41, + 0x14, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x05, 0x20, 0x05, 0x20, 0x02, 0x20, + 0x01, 0x41, 0x1d, 0x76, 0x41, 0x04, 0x71, 0x6a, 0x41, 0x10, 0x6a, 0x28, + 0x02, 0x00, 0x22, 0x02, 0x46, 0x1b, 0x20, 0x00, 0x20, 0x05, 0x1b, 0x21, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0x00, 0x47, 0x74, 0x21, 0x01, 0x20, + 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x20, 0x03, 0x72, 0x45, 0x04, + 0x40, 0x41, 0x02, 0x20, 0x07, 0x74, 0x22, 0x00, 0x41, 0x00, 0x20, 0x00, + 0x6b, 0x72, 0x20, 0x08, 0x71, 0x22, 0x00, 0x45, 0x0d, 0x03, 0x20, 0x00, + 0x41, 0x00, 0x20, 0x00, 0x6b, 0x71, 0x41, 0x7f, 0x6a, 0x22, 0x00, 0x20, + 0x00, 0x41, 0x0c, 0x76, 0x41, 0x10, 0x71, 0x22, 0x00, 0x76, 0x22, 0x01, + 0x41, 0x05, 0x76, 0x41, 0x08, 0x71, 0x22, 0x02, 0x20, 0x00, 0x72, 0x20, + 0x01, 0x20, 0x02, 0x76, 0x22, 0x00, 0x41, 0x02, 0x76, 0x41, 0x04, 0x71, + 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, 0x76, 0x22, 0x00, 0x41, 0x01, + 0x76, 0x41, 0x02, 0x71, 0x22, 0x01, 0x72, 0x20, 0x00, 0x20, 0x01, 0x76, + 0x22, 0x00, 0x41, 0x01, 0x76, 0x41, 0x01, 0x71, 0x22, 0x01, 0x72, 0x20, + 0x00, 0x20, 0x01, 0x76, 0x6a, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, + 0x28, 0x02, 0x00, 0x21, 0x00, 0x0b, 0x20, 0x00, 0x45, 0x0d, 0x01, 0x0b, + 0x03, 0x40, 0x20, 0x00, 0x28, 0x02, 0x04, 0x41, 0x78, 0x71, 0x20, 0x06, + 0x6b, 0x22, 0x05, 0x20, 0x04, 0x49, 0x21, 0x01, 0x20, 0x05, 0x20, 0x04, + 0x20, 0x01, 0x1b, 0x21, 0x04, 0x20, 0x00, 0x20, 0x03, 0x20, 0x01, 0x1b, + 0x21, 0x03, 0x20, 0x00, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x7f, 0x20, + 0x02, 0x05, 0x20, 0x00, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x0b, 0x22, + 0x00, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x04, + 0x41, 0xf8, 0x1b, 0x28, 0x02, 0x00, 0x20, 0x06, 0x6b, 0x4f, 0x0d, 0x00, + 0x20, 0x03, 0x28, 0x02, 0x18, 0x21, 0x07, 0x20, 0x03, 0x20, 0x03, 0x28, + 0x02, 0x0c, 0x22, 0x01, 0x47, 0x04, 0x40, 0x41, 0x80, 0x1c, 0x28, 0x02, + 0x00, 0x20, 0x03, 0x28, 0x02, 0x08, 0x22, 0x00, 0x4d, 0x04, 0x40, 0x20, + 0x00, 0x28, 0x02, 0x0c, 0x1a, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x36, 0x02, + 0x08, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x0c, 0x09, 0x0b, 0x20, + 0x03, 0x41, 0x14, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, + 0x04, 0x40, 0x20, 0x03, 0x28, 0x02, 0x10, 0x22, 0x00, 0x45, 0x0d, 0x03, + 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x02, 0x0b, 0x03, 0x40, 0x20, 0x02, + 0x21, 0x05, 0x20, 0x00, 0x22, 0x01, 0x41, 0x14, 0x6a, 0x22, 0x02, 0x28, + 0x02, 0x00, 0x22, 0x00, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x21, + 0x02, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x00, 0x0d, 0x00, 0x0b, 0x20, + 0x05, 0x41, 0x00, 0x36, 0x02, 0x00, 0x0c, 0x08, 0x0b, 0x41, 0xf8, 0x1b, + 0x28, 0x02, 0x00, 0x22, 0x01, 0x20, 0x06, 0x4f, 0x04, 0x40, 0x41, 0x84, + 0x1c, 0x28, 0x02, 0x00, 0x21, 0x00, 0x02, 0x40, 0x20, 0x01, 0x20, 0x06, + 0x6b, 0x22, 0x02, 0x41, 0x10, 0x4f, 0x04, 0x40, 0x20, 0x00, 0x20, 0x06, + 0x6a, 0x22, 0x03, 0x20, 0x02, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x41, + 0xf8, 0x1b, 0x20, 0x02, 0x36, 0x02, 0x00, 0x41, 0x84, 0x1c, 0x20, 0x03, + 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x20, 0x02, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x0c, + 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, + 0x20, 0x00, 0x20, 0x01, 0x6a, 0x22, 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, + 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x41, 0x84, 0x1c, 0x41, 0x00, 0x36, + 0x02, 0x00, 0x41, 0xf8, 0x1b, 0x41, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, + 0x00, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x0c, 0x0a, 0x0b, 0x41, 0xfc, 0x1b, + 0x28, 0x02, 0x00, 0x22, 0x01, 0x20, 0x06, 0x4b, 0x04, 0x40, 0x41, 0x88, + 0x1c, 0x28, 0x02, 0x00, 0x22, 0x00, 0x20, 0x06, 0x6a, 0x22, 0x02, 0x20, + 0x01, 0x20, 0x06, 0x6b, 0x22, 0x01, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, + 0x41, 0xfc, 0x1b, 0x20, 0x01, 0x36, 0x02, 0x00, 0x41, 0x88, 0x1c, 0x20, + 0x02, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, + 0x02, 0x04, 0x20, 0x00, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x0c, 0x0a, 0x0b, + 0x41, 0x00, 0x21, 0x00, 0x20, 0x06, 0x41, 0xc7, 0x00, 0x6a, 0x22, 0x04, + 0x02, 0x7f, 0x41, 0xc8, 0x1f, 0x28, 0x02, 0x00, 0x04, 0x40, 0x41, 0xd0, + 0x1f, 0x28, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x41, 0xd4, 0x1f, 0x42, 0x7f, + 0x37, 0x02, 0x00, 0x41, 0xcc, 0x1f, 0x42, 0x80, 0x80, 0x84, 0x80, 0x80, + 0x80, 0xc0, 0x00, 0x37, 0x02, 0x00, 0x41, 0xc8, 0x1f, 0x20, 0x0b, 0x41, + 0x0c, 0x6a, 0x41, 0x70, 0x71, 0x41, 0xd8, 0xaa, 0xd5, 0xaa, 0x05, 0x73, + 0x36, 0x02, 0x00, 0x41, 0xdc, 0x1f, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, + 0xac, 0x1f, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0x80, 0x80, 0x04, 0x0b, + 0x22, 0x02, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x20, 0x02, 0x6b, 0x22, 0x07, + 0x71, 0x22, 0x02, 0x20, 0x06, 0x4d, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, + 0x30, 0x36, 0x02, 0x00, 0x0c, 0x0a, 0x0b, 0x02, 0x40, 0x41, 0xa8, 0x1f, + 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x41, 0xa0, 0x1f, 0x28, + 0x02, 0x00, 0x22, 0x03, 0x20, 0x02, 0x6a, 0x22, 0x08, 0x20, 0x03, 0x4b, + 0x41, 0x00, 0x20, 0x08, 0x20, 0x00, 0x4d, 0x1b, 0x0d, 0x00, 0x41, 0x00, + 0x21, 0x00, 0x41, 0xe0, 0x1f, 0x41, 0x30, 0x36, 0x02, 0x00, 0x0c, 0x0a, + 0x0b, 0x41, 0xac, 0x1f, 0x2d, 0x00, 0x00, 0x41, 0x04, 0x71, 0x0d, 0x04, + 0x02, 0x40, 0x02, 0x40, 0x41, 0x88, 0x1c, 0x28, 0x02, 0x00, 0x22, 0x03, + 0x04, 0x40, 0x41, 0xb0, 0x1f, 0x21, 0x00, 0x03, 0x40, 0x20, 0x00, 0x28, + 0x02, 0x00, 0x22, 0x08, 0x20, 0x03, 0x4d, 0x04, 0x40, 0x20, 0x08, 0x20, + 0x00, 0x28, 0x02, 0x04, 0x6a, 0x20, 0x03, 0x4b, 0x0d, 0x03, 0x0b, 0x20, + 0x00, 0x28, 0x02, 0x08, 0x22, 0x00, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, + 0x10, 0x21, 0x22, 0x01, 0x41, 0x7f, 0x46, 0x0d, 0x05, 0x20, 0x02, 0x21, + 0x05, 0x41, 0xcc, 0x1f, 0x28, 0x02, 0x00, 0x22, 0x00, 0x41, 0x7f, 0x6a, + 0x22, 0x03, 0x20, 0x01, 0x71, 0x04, 0x40, 0x20, 0x02, 0x20, 0x01, 0x6b, + 0x20, 0x01, 0x20, 0x03, 0x6a, 0x41, 0x00, 0x20, 0x00, 0x6b, 0x71, 0x6a, + 0x21, 0x05, 0x0b, 0x20, 0x05, 0x20, 0x06, 0x4d, 0x0d, 0x05, 0x20, 0x05, + 0x41, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x05, 0x41, 0xa8, 0x1f, + 0x28, 0x02, 0x00, 0x22, 0x00, 0x04, 0x40, 0x41, 0xa0, 0x1f, 0x28, 0x02, + 0x00, 0x22, 0x03, 0x20, 0x05, 0x6a, 0x22, 0x07, 0x20, 0x03, 0x4d, 0x0d, + 0x06, 0x20, 0x07, 0x20, 0x00, 0x4b, 0x0d, 0x06, 0x0b, 0x20, 0x05, 0x10, + 0x21, 0x22, 0x00, 0x20, 0x01, 0x47, 0x0d, 0x01, 0x0c, 0x07, 0x0b, 0x20, + 0x05, 0x20, 0x01, 0x6b, 0x20, 0x07, 0x71, 0x22, 0x05, 0x41, 0xfe, 0xff, + 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x04, 0x20, 0x05, 0x10, 0x21, 0x22, 0x01, + 0x20, 0x00, 0x28, 0x02, 0x00, 0x20, 0x00, 0x28, 0x02, 0x04, 0x6a, 0x46, + 0x0d, 0x03, 0x20, 0x01, 0x21, 0x00, 0x0b, 0x20, 0x00, 0x21, 0x01, 0x02, + 0x40, 0x20, 0x06, 0x41, 0xc8, 0x00, 0x6a, 0x20, 0x05, 0x4d, 0x0d, 0x00, + 0x20, 0x05, 0x41, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x20, + 0x01, 0x41, 0x7f, 0x46, 0x0d, 0x00, 0x41, 0xd0, 0x1f, 0x28, 0x02, 0x00, + 0x22, 0x00, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x6a, 0x41, 0x00, 0x20, 0x00, + 0x6b, 0x71, 0x22, 0x00, 0x41, 0xfe, 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, + 0x06, 0x20, 0x00, 0x10, 0x21, 0x41, 0x7f, 0x47, 0x04, 0x40, 0x20, 0x00, + 0x20, 0x05, 0x6a, 0x21, 0x05, 0x0c, 0x07, 0x0b, 0x41, 0x00, 0x20, 0x05, + 0x6b, 0x10, 0x21, 0x1a, 0x0c, 0x04, 0x0b, 0x20, 0x01, 0x41, 0x7f, 0x47, + 0x0d, 0x05, 0x0c, 0x03, 0x0b, 0x41, 0x00, 0x21, 0x03, 0x0c, 0x07, 0x0b, + 0x41, 0x00, 0x21, 0x01, 0x0c, 0x05, 0x0b, 0x20, 0x01, 0x41, 0x7f, 0x47, + 0x0d, 0x02, 0x0b, 0x41, 0xac, 0x1f, 0x41, 0xac, 0x1f, 0x28, 0x02, 0x00, + 0x41, 0x04, 0x72, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x41, 0xfe, 0xff, + 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x01, 0x20, 0x02, 0x10, 0x21, 0x22, 0x01, + 0x41, 0x00, 0x10, 0x21, 0x22, 0x00, 0x4f, 0x0d, 0x01, 0x20, 0x01, 0x41, + 0x7f, 0x46, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x7f, 0x46, 0x0d, 0x01, 0x20, + 0x00, 0x20, 0x01, 0x6b, 0x22, 0x05, 0x20, 0x06, 0x41, 0x38, 0x6a, 0x4d, + 0x0d, 0x01, 0x0b, 0x41, 0xa0, 0x1f, 0x41, 0xa0, 0x1f, 0x28, 0x02, 0x00, + 0x20, 0x05, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, 0xa4, + 0x1f, 0x28, 0x02, 0x00, 0x4b, 0x04, 0x40, 0x41, 0xa4, 0x1f, 0x20, 0x00, + 0x36, 0x02, 0x00, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x41, 0x88, + 0x1c, 0x28, 0x02, 0x00, 0x22, 0x07, 0x04, 0x40, 0x41, 0xb0, 0x1f, 0x21, + 0x00, 0x03, 0x40, 0x20, 0x01, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x02, + 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, 0x03, 0x6a, 0x46, 0x0d, 0x02, 0x20, + 0x00, 0x28, 0x02, 0x08, 0x22, 0x00, 0x0d, 0x00, 0x0b, 0x0c, 0x02, 0x0b, + 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, 0x22, 0x00, 0x41, 0x00, 0x20, 0x01, + 0x20, 0x00, 0x4f, 0x1b, 0x45, 0x04, 0x40, 0x41, 0x80, 0x1c, 0x20, 0x01, + 0x36, 0x02, 0x00, 0x0b, 0x41, 0x00, 0x21, 0x00, 0x41, 0xb4, 0x1f, 0x20, + 0x05, 0x36, 0x02, 0x00, 0x41, 0xb0, 0x1f, 0x20, 0x01, 0x36, 0x02, 0x00, + 0x41, 0x90, 0x1c, 0x41, 0x7f, 0x36, 0x02, 0x00, 0x41, 0x94, 0x1c, 0x41, + 0xc8, 0x1f, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x41, 0xbc, 0x1f, 0x41, + 0x00, 0x36, 0x02, 0x00, 0x03, 0x40, 0x20, 0x00, 0x41, 0xa0, 0x1c, 0x6a, + 0x20, 0x00, 0x41, 0x98, 0x1c, 0x6a, 0x22, 0x02, 0x36, 0x02, 0x00, 0x20, + 0x00, 0x41, 0xa4, 0x1c, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x00, + 0x41, 0x08, 0x6a, 0x22, 0x00, 0x41, 0x80, 0x02, 0x47, 0x0d, 0x00, 0x0b, + 0x20, 0x01, 0x41, 0x78, 0x20, 0x01, 0x6b, 0x41, 0x0f, 0x71, 0x41, 0x00, + 0x20, 0x01, 0x41, 0x08, 0x6a, 0x41, 0x0f, 0x71, 0x1b, 0x22, 0x00, 0x6a, + 0x22, 0x02, 0x20, 0x05, 0x41, 0x48, 0x6a, 0x22, 0x03, 0x20, 0x00, 0x6b, + 0x22, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x41, 0x8c, 0x1c, 0x41, + 0xd8, 0x1f, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x41, 0xfc, 0x1b, 0x20, + 0x00, 0x36, 0x02, 0x00, 0x41, 0x88, 0x1c, 0x20, 0x02, 0x36, 0x02, 0x00, + 0x20, 0x01, 0x20, 0x03, 0x6a, 0x41, 0x38, 0x36, 0x02, 0x04, 0x0c, 0x02, + 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x0c, 0x41, 0x08, 0x71, 0x0d, 0x00, 0x20, + 0x01, 0x20, 0x07, 0x4d, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x07, 0x4b, 0x0d, + 0x00, 0x20, 0x07, 0x41, 0x78, 0x20, 0x07, 0x6b, 0x41, 0x0f, 0x71, 0x41, + 0x00, 0x20, 0x07, 0x41, 0x08, 0x6a, 0x41, 0x0f, 0x71, 0x1b, 0x22, 0x01, + 0x6a, 0x22, 0x02, 0x41, 0xfc, 0x1b, 0x28, 0x02, 0x00, 0x20, 0x05, 0x6a, + 0x22, 0x04, 0x20, 0x01, 0x6b, 0x22, 0x01, 0x41, 0x01, 0x72, 0x36, 0x02, + 0x04, 0x20, 0x00, 0x20, 0x03, 0x20, 0x05, 0x6a, 0x36, 0x02, 0x04, 0x41, + 0x8c, 0x1c, 0x41, 0xd8, 0x1f, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x41, + 0xfc, 0x1b, 0x20, 0x01, 0x36, 0x02, 0x00, 0x41, 0x88, 0x1c, 0x20, 0x02, + 0x36, 0x02, 0x00, 0x20, 0x04, 0x20, 0x07, 0x6a, 0x41, 0x38, 0x36, 0x02, + 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, + 0x22, 0x03, 0x49, 0x04, 0x40, 0x41, 0x80, 0x1c, 0x20, 0x01, 0x36, 0x02, + 0x00, 0x20, 0x01, 0x21, 0x03, 0x0b, 0x20, 0x01, 0x20, 0x05, 0x6a, 0x21, + 0x02, 0x41, 0xb0, 0x1f, 0x21, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x03, 0x40, 0x20, 0x02, 0x20, 0x00, + 0x28, 0x02, 0x00, 0x47, 0x04, 0x40, 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, + 0x00, 0x0d, 0x01, 0x0c, 0x02, 0x0b, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x0c, + 0x41, 0x08, 0x71, 0x45, 0x0d, 0x01, 0x0b, 0x41, 0xb0, 0x1f, 0x21, 0x00, + 0x03, 0x40, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x02, 0x20, 0x07, 0x4d, + 0x04, 0x40, 0x20, 0x02, 0x20, 0x00, 0x28, 0x02, 0x04, 0x6a, 0x22, 0x03, + 0x20, 0x07, 0x4b, 0x0d, 0x03, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x08, 0x21, + 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x04, 0x20, 0x05, 0x6a, 0x36, + 0x02, 0x04, 0x20, 0x01, 0x41, 0x78, 0x20, 0x01, 0x6b, 0x41, 0x0f, 0x71, + 0x41, 0x00, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x41, 0x0f, 0x71, 0x1b, 0x6a, + 0x22, 0x08, 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, 0x02, + 0x41, 0x78, 0x20, 0x02, 0x6b, 0x41, 0x0f, 0x71, 0x41, 0x00, 0x20, 0x02, + 0x41, 0x08, 0x6a, 0x41, 0x0f, 0x71, 0x1b, 0x6a, 0x22, 0x01, 0x20, 0x08, + 0x6b, 0x20, 0x06, 0x6b, 0x21, 0x00, 0x20, 0x06, 0x20, 0x08, 0x6a, 0x21, + 0x04, 0x20, 0x01, 0x20, 0x07, 0x46, 0x04, 0x40, 0x41, 0x88, 0x1c, 0x20, + 0x04, 0x36, 0x02, 0x00, 0x41, 0xfc, 0x1b, 0x41, 0xfc, 0x1b, 0x28, 0x02, + 0x00, 0x20, 0x00, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x04, 0x20, + 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x01, + 0x41, 0x84, 0x1c, 0x28, 0x02, 0x00, 0x46, 0x04, 0x40, 0x41, 0x84, 0x1c, + 0x20, 0x04, 0x36, 0x02, 0x00, 0x41, 0xf8, 0x1b, 0x41, 0xf8, 0x1b, 0x28, + 0x02, 0x00, 0x20, 0x00, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x04, + 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x00, 0x20, 0x04, + 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x0c, 0x03, 0x0b, 0x20, 0x01, 0x28, + 0x02, 0x04, 0x22, 0x06, 0x41, 0x03, 0x71, 0x41, 0x01, 0x46, 0x04, 0x40, + 0x20, 0x06, 0x41, 0x78, 0x71, 0x21, 0x09, 0x02, 0x40, 0x20, 0x06, 0x41, + 0xff, 0x01, 0x4d, 0x04, 0x40, 0x20, 0x01, 0x28, 0x02, 0x08, 0x22, 0x03, + 0x20, 0x06, 0x41, 0x03, 0x76, 0x22, 0x06, 0x41, 0x03, 0x74, 0x41, 0x98, + 0x1c, 0x6a, 0x47, 0x1a, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x22, + 0x02, 0x46, 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x41, 0xf0, 0x1b, 0x28, 0x02, + 0x00, 0x41, 0x7e, 0x20, 0x06, 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, 0x02, + 0x0b, 0x20, 0x02, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, 0x02, + 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x18, 0x21, + 0x07, 0x02, 0x40, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x22, 0x05, + 0x47, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x08, 0x22, 0x02, + 0x4d, 0x04, 0x40, 0x20, 0x02, 0x28, 0x02, 0x0c, 0x1a, 0x0b, 0x20, 0x05, + 0x20, 0x02, 0x36, 0x02, 0x08, 0x20, 0x02, 0x20, 0x05, 0x36, 0x02, 0x0c, + 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x22, 0x02, + 0x28, 0x02, 0x00, 0x22, 0x06, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x10, 0x6a, + 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x06, 0x0d, 0x00, 0x41, 0x00, 0x21, + 0x05, 0x0c, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x02, 0x21, 0x03, 0x20, 0x06, + 0x22, 0x05, 0x41, 0x14, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x06, + 0x0d, 0x00, 0x20, 0x05, 0x41, 0x10, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x28, + 0x02, 0x10, 0x22, 0x06, 0x0d, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x00, 0x36, + 0x02, 0x00, 0x0b, 0x20, 0x07, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x01, + 0x20, 0x01, 0x28, 0x02, 0x1c, 0x22, 0x02, 0x41, 0x02, 0x74, 0x41, 0xa0, + 0x1e, 0x6a, 0x22, 0x03, 0x28, 0x02, 0x00, 0x46, 0x04, 0x40, 0x20, 0x03, + 0x20, 0x05, 0x36, 0x02, 0x00, 0x20, 0x05, 0x0d, 0x01, 0x41, 0xf4, 0x1b, + 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, 0x41, 0x7e, 0x20, 0x02, 0x77, 0x71, + 0x36, 0x02, 0x00, 0x0c, 0x02, 0x0b, 0x20, 0x07, 0x41, 0x10, 0x41, 0x14, + 0x20, 0x07, 0x28, 0x02, 0x10, 0x20, 0x01, 0x46, 0x1b, 0x6a, 0x20, 0x05, + 0x36, 0x02, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x05, 0x20, + 0x07, 0x36, 0x02, 0x18, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, + 0x40, 0x20, 0x05, 0x20, 0x02, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x05, + 0x36, 0x02, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x14, 0x22, 0x02, 0x45, + 0x0d, 0x00, 0x20, 0x05, 0x41, 0x14, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, + 0x20, 0x02, 0x20, 0x05, 0x36, 0x02, 0x18, 0x0b, 0x20, 0x01, 0x20, 0x09, + 0x6a, 0x21, 0x01, 0x20, 0x00, 0x20, 0x09, 0x6a, 0x21, 0x00, 0x0b, 0x20, + 0x01, 0x20, 0x01, 0x28, 0x02, 0x04, 0x41, 0x7e, 0x71, 0x36, 0x02, 0x04, + 0x20, 0x00, 0x20, 0x04, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x04, + 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x00, 0x41, 0xff, + 0x01, 0x4d, 0x04, 0x40, 0x20, 0x00, 0x41, 0x03, 0x76, 0x22, 0x01, 0x41, + 0x03, 0x74, 0x41, 0x98, 0x1c, 0x6a, 0x21, 0x00, 0x02, 0x7f, 0x41, 0xf0, + 0x1b, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x01, 0x20, 0x01, 0x74, 0x22, + 0x01, 0x71, 0x45, 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x01, 0x20, 0x02, + 0x72, 0x36, 0x02, 0x00, 0x20, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x28, + 0x02, 0x08, 0x0b, 0x22, 0x02, 0x20, 0x04, 0x36, 0x02, 0x0c, 0x20, 0x00, + 0x20, 0x04, 0x36, 0x02, 0x08, 0x20, 0x04, 0x20, 0x00, 0x36, 0x02, 0x0c, + 0x20, 0x04, 0x20, 0x02, 0x36, 0x02, 0x08, 0x0c, 0x03, 0x0b, 0x20, 0x04, + 0x02, 0x7f, 0x41, 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x22, 0x01, 0x45, + 0x0d, 0x00, 0x1a, 0x41, 0x1f, 0x20, 0x00, 0x41, 0xff, 0xff, 0xff, 0x07, + 0x4b, 0x0d, 0x00, 0x1a, 0x20, 0x01, 0x20, 0x01, 0x41, 0x80, 0xfe, 0x3f, + 0x6a, 0x41, 0x10, 0x76, 0x41, 0x08, 0x71, 0x22, 0x01, 0x74, 0x22, 0x02, + 0x20, 0x02, 0x41, 0x80, 0xe0, 0x1f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x04, + 0x71, 0x22, 0x02, 0x74, 0x22, 0x03, 0x20, 0x03, 0x41, 0x80, 0x80, 0x0f, + 0x6a, 0x41, 0x10, 0x76, 0x41, 0x02, 0x71, 0x22, 0x03, 0x74, 0x41, 0x0f, + 0x76, 0x20, 0x01, 0x20, 0x02, 0x72, 0x20, 0x03, 0x72, 0x6b, 0x22, 0x01, + 0x41, 0x01, 0x74, 0x20, 0x00, 0x20, 0x01, 0x41, 0x15, 0x6a, 0x76, 0x41, + 0x01, 0x71, 0x72, 0x41, 0x1c, 0x6a, 0x0b, 0x22, 0x02, 0x36, 0x02, 0x1c, + 0x20, 0x04, 0x42, 0x00, 0x37, 0x02, 0x10, 0x20, 0x02, 0x41, 0x02, 0x74, + 0x41, 0xa0, 0x1e, 0x6a, 0x21, 0x01, 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, + 0x22, 0x03, 0x41, 0x01, 0x20, 0x02, 0x74, 0x22, 0x06, 0x71, 0x45, 0x04, + 0x40, 0x20, 0x01, 0x20, 0x04, 0x36, 0x02, 0x00, 0x41, 0xf4, 0x1b, 0x20, + 0x03, 0x20, 0x06, 0x72, 0x36, 0x02, 0x00, 0x20, 0x04, 0x20, 0x01, 0x36, + 0x02, 0x18, 0x20, 0x04, 0x20, 0x04, 0x36, 0x02, 0x08, 0x20, 0x04, 0x20, + 0x04, 0x36, 0x02, 0x0c, 0x0c, 0x03, 0x0b, 0x20, 0x00, 0x41, 0x00, 0x41, + 0x19, 0x20, 0x02, 0x41, 0x01, 0x76, 0x6b, 0x20, 0x02, 0x41, 0x1f, 0x46, + 0x1b, 0x74, 0x21, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x21, 0x01, 0x03, + 0x40, 0x20, 0x01, 0x22, 0x03, 0x28, 0x02, 0x04, 0x41, 0x78, 0x71, 0x20, + 0x00, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x1d, 0x76, 0x21, 0x01, 0x20, + 0x02, 0x41, 0x01, 0x74, 0x21, 0x02, 0x20, 0x03, 0x20, 0x01, 0x41, 0x04, + 0x71, 0x6a, 0x41, 0x10, 0x6a, 0x22, 0x06, 0x28, 0x02, 0x00, 0x22, 0x01, + 0x0d, 0x00, 0x0b, 0x20, 0x06, 0x20, 0x04, 0x36, 0x02, 0x00, 0x20, 0x04, + 0x20, 0x03, 0x36, 0x02, 0x18, 0x20, 0x04, 0x20, 0x04, 0x36, 0x02, 0x0c, + 0x20, 0x04, 0x20, 0x04, 0x36, 0x02, 0x08, 0x0c, 0x02, 0x0b, 0x20, 0x01, + 0x41, 0x78, 0x20, 0x01, 0x6b, 0x41, 0x0f, 0x71, 0x41, 0x00, 0x20, 0x01, + 0x41, 0x08, 0x6a, 0x41, 0x0f, 0x71, 0x1b, 0x22, 0x00, 0x6a, 0x22, 0x04, + 0x20, 0x05, 0x41, 0x48, 0x6a, 0x22, 0x02, 0x20, 0x00, 0x6b, 0x22, 0x00, + 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x41, + 0x38, 0x36, 0x02, 0x04, 0x20, 0x07, 0x20, 0x03, 0x41, 0x37, 0x20, 0x03, + 0x6b, 0x41, 0x0f, 0x71, 0x41, 0x00, 0x20, 0x03, 0x41, 0x49, 0x6a, 0x41, + 0x0f, 0x71, 0x1b, 0x6a, 0x41, 0x41, 0x6a, 0x22, 0x02, 0x20, 0x02, 0x20, + 0x07, 0x41, 0x10, 0x6a, 0x49, 0x1b, 0x22, 0x02, 0x41, 0x23, 0x36, 0x02, + 0x04, 0x41, 0x8c, 0x1c, 0x41, 0xd8, 0x1f, 0x28, 0x02, 0x00, 0x36, 0x02, + 0x00, 0x41, 0xfc, 0x1b, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0x88, 0x1c, + 0x20, 0x04, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x41, 0xb8, + 0x1f, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x02, 0x41, 0xb0, 0x1f, + 0x29, 0x02, 0x00, 0x37, 0x02, 0x08, 0x41, 0xb8, 0x1f, 0x20, 0x02, 0x41, + 0x08, 0x6a, 0x36, 0x02, 0x00, 0x41, 0xb4, 0x1f, 0x20, 0x05, 0x36, 0x02, + 0x00, 0x41, 0xb0, 0x1f, 0x20, 0x01, 0x36, 0x02, 0x00, 0x41, 0xbc, 0x1f, + 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x24, 0x6a, 0x21, 0x00, + 0x03, 0x40, 0x20, 0x00, 0x41, 0x07, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, + 0x04, 0x6a, 0x22, 0x00, 0x20, 0x03, 0x49, 0x0d, 0x00, 0x0b, 0x20, 0x02, + 0x20, 0x07, 0x46, 0x0d, 0x03, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x04, + 0x41, 0x7e, 0x71, 0x36, 0x02, 0x04, 0x20, 0x02, 0x20, 0x02, 0x20, 0x07, + 0x6b, 0x22, 0x03, 0x36, 0x02, 0x00, 0x20, 0x07, 0x20, 0x03, 0x41, 0x01, + 0x72, 0x36, 0x02, 0x04, 0x20, 0x03, 0x41, 0xff, 0x01, 0x4d, 0x04, 0x40, + 0x20, 0x03, 0x41, 0x03, 0x76, 0x22, 0x01, 0x41, 0x03, 0x74, 0x41, 0x98, + 0x1c, 0x6a, 0x21, 0x00, 0x02, 0x7f, 0x41, 0xf0, 0x1b, 0x28, 0x02, 0x00, + 0x22, 0x02, 0x41, 0x01, 0x20, 0x01, 0x74, 0x22, 0x01, 0x71, 0x45, 0x04, + 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x01, 0x20, 0x02, 0x72, 0x36, 0x02, 0x00, + 0x20, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x08, 0x0b, 0x22, + 0x04, 0x20, 0x07, 0x36, 0x02, 0x0c, 0x20, 0x00, 0x20, 0x07, 0x36, 0x02, + 0x08, 0x20, 0x07, 0x20, 0x00, 0x36, 0x02, 0x0c, 0x20, 0x07, 0x20, 0x04, + 0x36, 0x02, 0x08, 0x0c, 0x04, 0x0b, 0x20, 0x07, 0x42, 0x00, 0x37, 0x02, + 0x10, 0x20, 0x07, 0x41, 0x1c, 0x6a, 0x02, 0x7f, 0x41, 0x00, 0x20, 0x03, + 0x41, 0x08, 0x76, 0x22, 0x01, 0x45, 0x0d, 0x00, 0x1a, 0x41, 0x1f, 0x20, + 0x03, 0x41, 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x1a, 0x20, 0x01, + 0x20, 0x01, 0x41, 0x80, 0xfe, 0x3f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x08, + 0x71, 0x22, 0x00, 0x74, 0x22, 0x01, 0x20, 0x01, 0x41, 0x80, 0xe0, 0x1f, + 0x6a, 0x41, 0x10, 0x76, 0x41, 0x04, 0x71, 0x22, 0x01, 0x74, 0x22, 0x02, + 0x20, 0x02, 0x41, 0x80, 0x80, 0x0f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x02, + 0x71, 0x22, 0x02, 0x74, 0x41, 0x0f, 0x76, 0x20, 0x00, 0x20, 0x01, 0x72, + 0x20, 0x02, 0x72, 0x6b, 0x22, 0x00, 0x41, 0x01, 0x74, 0x20, 0x03, 0x20, + 0x00, 0x41, 0x15, 0x6a, 0x76, 0x41, 0x01, 0x71, 0x72, 0x41, 0x1c, 0x6a, + 0x0b, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, 0x02, 0x74, 0x41, + 0xa0, 0x1e, 0x6a, 0x21, 0x01, 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, 0x22, + 0x02, 0x41, 0x01, 0x20, 0x00, 0x74, 0x22, 0x04, 0x71, 0x45, 0x04, 0x40, + 0x20, 0x01, 0x20, 0x07, 0x36, 0x02, 0x00, 0x41, 0xf4, 0x1b, 0x20, 0x02, + 0x20, 0x04, 0x72, 0x36, 0x02, 0x00, 0x20, 0x07, 0x41, 0x18, 0x6a, 0x20, + 0x01, 0x36, 0x02, 0x00, 0x20, 0x07, 0x20, 0x07, 0x36, 0x02, 0x08, 0x20, + 0x07, 0x20, 0x07, 0x36, 0x02, 0x0c, 0x0c, 0x04, 0x0b, 0x20, 0x03, 0x41, + 0x00, 0x41, 0x19, 0x20, 0x00, 0x41, 0x01, 0x76, 0x6b, 0x20, 0x00, 0x41, + 0x1f, 0x46, 0x1b, 0x74, 0x21, 0x00, 0x20, 0x01, 0x28, 0x02, 0x00, 0x21, + 0x01, 0x03, 0x40, 0x20, 0x01, 0x22, 0x02, 0x28, 0x02, 0x04, 0x41, 0x78, + 0x71, 0x20, 0x03, 0x46, 0x0d, 0x03, 0x20, 0x00, 0x41, 0x1d, 0x76, 0x21, + 0x01, 0x20, 0x00, 0x41, 0x01, 0x74, 0x21, 0x00, 0x20, 0x02, 0x20, 0x01, + 0x41, 0x04, 0x71, 0x6a, 0x41, 0x10, 0x6a, 0x22, 0x04, 0x28, 0x02, 0x00, + 0x22, 0x01, 0x0d, 0x00, 0x0b, 0x20, 0x04, 0x20, 0x07, 0x36, 0x02, 0x00, + 0x20, 0x07, 0x41, 0x18, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x07, + 0x20, 0x07, 0x36, 0x02, 0x0c, 0x20, 0x07, 0x20, 0x07, 0x36, 0x02, 0x08, + 0x0c, 0x03, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x08, 0x21, 0x00, 0x20, 0x03, + 0x20, 0x04, 0x36, 0x02, 0x08, 0x20, 0x00, 0x20, 0x04, 0x36, 0x02, 0x0c, + 0x20, 0x04, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x04, 0x20, 0x00, 0x36, + 0x02, 0x08, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x0c, 0x0b, 0x20, 0x08, + 0x41, 0x08, 0x6a, 0x21, 0x00, 0x0c, 0x05, 0x0b, 0x20, 0x02, 0x28, 0x02, + 0x08, 0x21, 0x00, 0x20, 0x02, 0x20, 0x07, 0x36, 0x02, 0x08, 0x20, 0x00, + 0x20, 0x07, 0x36, 0x02, 0x0c, 0x20, 0x07, 0x41, 0x18, 0x6a, 0x41, 0x00, + 0x36, 0x02, 0x00, 0x20, 0x07, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x07, + 0x20, 0x02, 0x36, 0x02, 0x0c, 0x0b, 0x41, 0xfc, 0x1b, 0x28, 0x02, 0x00, + 0x22, 0x01, 0x20, 0x06, 0x4d, 0x0d, 0x00, 0x41, 0x88, 0x1c, 0x28, 0x02, + 0x00, 0x22, 0x00, 0x20, 0x06, 0x6a, 0x22, 0x02, 0x20, 0x01, 0x20, 0x06, + 0x6b, 0x22, 0x01, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x41, 0xfc, 0x1b, + 0x20, 0x01, 0x36, 0x02, 0x00, 0x41, 0x88, 0x1c, 0x20, 0x02, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, + 0x00, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x0c, 0x03, 0x0b, 0x41, 0x00, 0x21, + 0x00, 0x41, 0xe0, 0x1f, 0x41, 0x30, 0x36, 0x02, 0x00, 0x0c, 0x02, 0x0b, + 0x02, 0x40, 0x20, 0x07, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x03, 0x28, + 0x02, 0x1c, 0x22, 0x00, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, 0x22, + 0x02, 0x28, 0x02, 0x00, 0x20, 0x03, 0x46, 0x04, 0x40, 0x20, 0x02, 0x20, + 0x01, 0x36, 0x02, 0x00, 0x20, 0x01, 0x0d, 0x01, 0x41, 0xf4, 0x1b, 0x20, + 0x08, 0x41, 0x7e, 0x20, 0x00, 0x77, 0x71, 0x22, 0x08, 0x36, 0x02, 0x00, + 0x0c, 0x02, 0x0b, 0x20, 0x07, 0x41, 0x10, 0x41, 0x14, 0x20, 0x07, 0x28, + 0x02, 0x10, 0x20, 0x03, 0x46, 0x1b, 0x6a, 0x20, 0x01, 0x36, 0x02, 0x00, + 0x20, 0x01, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x20, 0x07, 0x36, 0x02, + 0x18, 0x20, 0x03, 0x28, 0x02, 0x10, 0x22, 0x00, 0x04, 0x40, 0x20, 0x01, + 0x20, 0x00, 0x36, 0x02, 0x10, 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x18, + 0x0b, 0x20, 0x03, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, + 0x0d, 0x00, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, + 0x20, 0x00, 0x20, 0x01, 0x36, 0x02, 0x18, 0x0b, 0x02, 0x40, 0x20, 0x04, + 0x41, 0x0f, 0x4d, 0x04, 0x40, 0x20, 0x03, 0x20, 0x04, 0x20, 0x06, 0x6a, + 0x22, 0x00, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, 0x00, 0x20, 0x03, + 0x6a, 0x22, 0x00, 0x20, 0x00, 0x28, 0x02, 0x04, 0x41, 0x01, 0x72, 0x36, + 0x02, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x20, 0x06, 0x6a, 0x22, 0x05, + 0x20, 0x04, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x03, 0x20, 0x06, + 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, 0x04, 0x20, 0x05, 0x6a, 0x20, + 0x04, 0x36, 0x02, 0x00, 0x20, 0x04, 0x41, 0xff, 0x01, 0x4d, 0x04, 0x40, + 0x20, 0x04, 0x41, 0x03, 0x76, 0x22, 0x01, 0x41, 0x03, 0x74, 0x41, 0x98, + 0x1c, 0x6a, 0x21, 0x00, 0x02, 0x7f, 0x41, 0xf0, 0x1b, 0x28, 0x02, 0x00, + 0x22, 0x02, 0x41, 0x01, 0x20, 0x01, 0x74, 0x22, 0x01, 0x71, 0x45, 0x04, + 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x01, 0x20, 0x02, 0x72, 0x36, 0x02, 0x00, + 0x20, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x08, 0x0b, 0x22, + 0x02, 0x20, 0x05, 0x36, 0x02, 0x0c, 0x20, 0x00, 0x20, 0x05, 0x36, 0x02, + 0x08, 0x20, 0x05, 0x20, 0x00, 0x36, 0x02, 0x0c, 0x20, 0x05, 0x20, 0x02, + 0x36, 0x02, 0x08, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x02, 0x7f, 0x41, 0x00, + 0x20, 0x04, 0x41, 0x08, 0x76, 0x22, 0x01, 0x45, 0x0d, 0x00, 0x1a, 0x41, + 0x1f, 0x20, 0x04, 0x41, 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x1a, + 0x20, 0x01, 0x20, 0x01, 0x41, 0x80, 0xfe, 0x3f, 0x6a, 0x41, 0x10, 0x76, + 0x41, 0x08, 0x71, 0x22, 0x00, 0x74, 0x22, 0x01, 0x20, 0x01, 0x41, 0x80, + 0xe0, 0x1f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x04, 0x71, 0x22, 0x01, 0x74, + 0x22, 0x02, 0x20, 0x02, 0x41, 0x80, 0x80, 0x0f, 0x6a, 0x41, 0x10, 0x76, + 0x41, 0x02, 0x71, 0x22, 0x02, 0x74, 0x41, 0x0f, 0x76, 0x20, 0x00, 0x20, + 0x01, 0x72, 0x20, 0x02, 0x72, 0x6b, 0x22, 0x00, 0x41, 0x01, 0x74, 0x20, + 0x04, 0x20, 0x00, 0x41, 0x15, 0x6a, 0x76, 0x41, 0x01, 0x71, 0x72, 0x41, + 0x1c, 0x6a, 0x0b, 0x22, 0x00, 0x36, 0x02, 0x1c, 0x20, 0x05, 0x42, 0x00, + 0x37, 0x02, 0x10, 0x20, 0x00, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, + 0x21, 0x01, 0x20, 0x08, 0x41, 0x01, 0x20, 0x00, 0x74, 0x22, 0x02, 0x71, + 0x45, 0x04, 0x40, 0x20, 0x01, 0x20, 0x05, 0x36, 0x02, 0x00, 0x41, 0xf4, + 0x1b, 0x20, 0x02, 0x20, 0x08, 0x72, 0x36, 0x02, 0x00, 0x20, 0x05, 0x20, + 0x01, 0x36, 0x02, 0x18, 0x20, 0x05, 0x20, 0x05, 0x36, 0x02, 0x08, 0x20, + 0x05, 0x20, 0x05, 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x41, + 0x00, 0x41, 0x19, 0x20, 0x00, 0x41, 0x01, 0x76, 0x6b, 0x20, 0x00, 0x41, + 0x1f, 0x46, 0x1b, 0x74, 0x21, 0x00, 0x20, 0x01, 0x28, 0x02, 0x00, 0x21, + 0x06, 0x02, 0x40, 0x03, 0x40, 0x20, 0x06, 0x22, 0x01, 0x28, 0x02, 0x04, + 0x41, 0x78, 0x71, 0x20, 0x04, 0x46, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x1d, + 0x76, 0x21, 0x02, 0x20, 0x00, 0x41, 0x01, 0x74, 0x21, 0x00, 0x20, 0x01, + 0x20, 0x02, 0x41, 0x04, 0x71, 0x6a, 0x41, 0x10, 0x6a, 0x22, 0x02, 0x28, + 0x02, 0x00, 0x22, 0x06, 0x0d, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x05, 0x36, + 0x02, 0x00, 0x20, 0x05, 0x20, 0x01, 0x36, 0x02, 0x18, 0x20, 0x05, 0x20, + 0x05, 0x36, 0x02, 0x0c, 0x20, 0x05, 0x20, 0x05, 0x36, 0x02, 0x08, 0x0c, + 0x01, 0x0b, 0x20, 0x01, 0x28, 0x02, 0x08, 0x21, 0x00, 0x20, 0x01, 0x20, + 0x05, 0x36, 0x02, 0x08, 0x20, 0x00, 0x20, 0x05, 0x36, 0x02, 0x0c, 0x20, + 0x05, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x05, 0x20, 0x00, 0x36, 0x02, + 0x08, 0x20, 0x05, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x0b, 0x20, 0x03, 0x41, + 0x08, 0x6a, 0x21, 0x00, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x09, 0x45, + 0x0d, 0x00, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x22, 0x00, 0x41, + 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, 0x22, 0x04, 0x28, 0x02, 0x00, 0x20, + 0x01, 0x46, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, + 0x03, 0x0d, 0x01, 0x41, 0xf4, 0x1b, 0x20, 0x0a, 0x41, 0x7e, 0x20, 0x00, + 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, 0x02, 0x0b, 0x20, 0x09, 0x41, 0x10, + 0x41, 0x14, 0x20, 0x09, 0x28, 0x02, 0x10, 0x20, 0x01, 0x46, 0x1b, 0x6a, + 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x03, 0x45, 0x0d, 0x01, 0x0b, 0x20, + 0x03, 0x20, 0x09, 0x36, 0x02, 0x18, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, + 0x00, 0x04, 0x40, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x10, 0x20, 0x00, + 0x20, 0x03, 0x36, 0x02, 0x18, 0x0b, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x28, + 0x02, 0x00, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x41, 0x14, 0x6a, + 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x03, 0x36, 0x02, 0x18, + 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x0f, 0x4d, 0x04, 0x40, 0x20, 0x01, + 0x20, 0x02, 0x20, 0x06, 0x6a, 0x22, 0x00, 0x41, 0x03, 0x72, 0x36, 0x02, + 0x04, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x22, 0x00, 0x20, 0x00, 0x28, 0x02, + 0x04, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x01, + 0x20, 0x06, 0x6a, 0x22, 0x07, 0x20, 0x02, 0x41, 0x01, 0x72, 0x36, 0x02, + 0x04, 0x20, 0x01, 0x20, 0x06, 0x41, 0x03, 0x72, 0x36, 0x02, 0x04, 0x20, + 0x02, 0x20, 0x07, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x08, 0x04, + 0x40, 0x20, 0x08, 0x41, 0x03, 0x76, 0x22, 0x03, 0x41, 0x03, 0x74, 0x41, + 0x98, 0x1c, 0x6a, 0x21, 0x00, 0x41, 0x84, 0x1c, 0x28, 0x02, 0x00, 0x21, + 0x04, 0x02, 0x7f, 0x41, 0x01, 0x20, 0x03, 0x74, 0x22, 0x03, 0x20, 0x05, + 0x71, 0x45, 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x20, 0x03, 0x20, 0x05, 0x72, + 0x36, 0x02, 0x00, 0x20, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x28, 0x02, + 0x08, 0x0b, 0x22, 0x03, 0x20, 0x04, 0x36, 0x02, 0x0c, 0x20, 0x00, 0x20, + 0x04, 0x36, 0x02, 0x08, 0x20, 0x04, 0x20, 0x00, 0x36, 0x02, 0x0c, 0x20, + 0x04, 0x20, 0x03, 0x36, 0x02, 0x08, 0x0b, 0x41, 0x84, 0x1c, 0x20, 0x07, + 0x36, 0x02, 0x00, 0x41, 0xf8, 0x1b, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0b, + 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x00, 0x0b, 0x20, 0x0b, 0x41, 0x10, + 0x6a, 0x24, 0x00, 0x20, 0x00, 0x0b, 0x9e, 0x0d, 0x01, 0x07, 0x7f, 0x02, + 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x78, 0x6a, 0x22, + 0x03, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, + 0x78, 0x71, 0x22, 0x00, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x01, 0x41, + 0x01, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, + 0x20, 0x03, 0x20, 0x03, 0x28, 0x02, 0x00, 0x22, 0x02, 0x6b, 0x22, 0x03, + 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, 0x22, 0x04, 0x49, 0x0d, 0x01, 0x20, + 0x00, 0x20, 0x02, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x41, 0x84, 0x1c, 0x28, + 0x02, 0x00, 0x47, 0x04, 0x40, 0x20, 0x02, 0x41, 0xff, 0x01, 0x4d, 0x04, + 0x40, 0x20, 0x03, 0x28, 0x02, 0x08, 0x22, 0x04, 0x20, 0x02, 0x41, 0x03, + 0x76, 0x22, 0x02, 0x41, 0x03, 0x74, 0x41, 0x98, 0x1c, 0x6a, 0x47, 0x1a, + 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x22, 0x01, 0x46, 0x04, 0x40, + 0x41, 0xf0, 0x1b, 0x41, 0xf0, 0x1b, 0x28, 0x02, 0x00, 0x41, 0x7e, 0x20, + 0x02, 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, 0x03, 0x0b, 0x20, 0x01, 0x20, + 0x04, 0x36, 0x02, 0x08, 0x20, 0x04, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x0c, + 0x02, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x18, 0x21, 0x06, 0x02, 0x40, 0x20, + 0x03, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x22, 0x01, 0x47, 0x04, 0x40, 0x20, + 0x04, 0x20, 0x03, 0x28, 0x02, 0x08, 0x22, 0x02, 0x4d, 0x04, 0x40, 0x20, + 0x02, 0x28, 0x02, 0x0c, 0x1a, 0x0b, 0x20, 0x01, 0x20, 0x02, 0x36, 0x02, + 0x08, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x02, + 0x40, 0x20, 0x03, 0x41, 0x14, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, + 0x04, 0x0d, 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x22, 0x02, 0x28, 0x02, + 0x00, 0x22, 0x04, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x01, 0x0c, 0x01, 0x0b, + 0x03, 0x40, 0x20, 0x02, 0x21, 0x07, 0x20, 0x04, 0x22, 0x01, 0x41, 0x14, + 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x04, 0x0d, 0x00, 0x20, 0x01, + 0x41, 0x10, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x04, + 0x0d, 0x00, 0x0b, 0x20, 0x07, 0x41, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, + 0x06, 0x45, 0x0d, 0x01, 0x02, 0x40, 0x20, 0x03, 0x20, 0x03, 0x28, 0x02, + 0x1c, 0x22, 0x02, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, 0x22, 0x04, + 0x28, 0x02, 0x00, 0x46, 0x04, 0x40, 0x20, 0x04, 0x20, 0x01, 0x36, 0x02, + 0x00, 0x20, 0x01, 0x0d, 0x01, 0x41, 0xf4, 0x1b, 0x41, 0xf4, 0x1b, 0x28, + 0x02, 0x00, 0x41, 0x7e, 0x20, 0x02, 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, + 0x03, 0x0b, 0x20, 0x06, 0x41, 0x10, 0x41, 0x14, 0x20, 0x06, 0x28, 0x02, + 0x10, 0x20, 0x03, 0x46, 0x1b, 0x6a, 0x20, 0x01, 0x36, 0x02, 0x00, 0x20, + 0x01, 0x45, 0x0d, 0x02, 0x0b, 0x20, 0x01, 0x20, 0x06, 0x36, 0x02, 0x18, + 0x20, 0x03, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x40, 0x20, 0x01, 0x20, + 0x02, 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x18, 0x0b, + 0x20, 0x03, 0x28, 0x02, 0x14, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x01, + 0x41, 0x14, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x01, + 0x36, 0x02, 0x18, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x28, 0x02, 0x04, 0x22, + 0x01, 0x41, 0x03, 0x71, 0x41, 0x03, 0x47, 0x0d, 0x00, 0x20, 0x05, 0x20, + 0x01, 0x41, 0x7e, 0x71, 0x36, 0x02, 0x04, 0x41, 0xf8, 0x1b, 0x20, 0x00, + 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x03, 0x6a, 0x20, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x0f, + 0x0b, 0x20, 0x05, 0x20, 0x03, 0x4d, 0x0d, 0x00, 0x20, 0x05, 0x28, 0x02, + 0x04, 0x22, 0x01, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, + 0x01, 0x41, 0x02, 0x71, 0x45, 0x04, 0x40, 0x20, 0x05, 0x41, 0x88, 0x1c, + 0x28, 0x02, 0x00, 0x46, 0x04, 0x40, 0x41, 0x88, 0x1c, 0x20, 0x03, 0x36, + 0x02, 0x00, 0x41, 0xfc, 0x1b, 0x41, 0xfc, 0x1b, 0x28, 0x02, 0x00, 0x20, + 0x00, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x00, 0x41, + 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x03, 0x41, 0x84, 0x1c, 0x28, 0x02, + 0x00, 0x47, 0x0d, 0x03, 0x41, 0xf8, 0x1b, 0x41, 0x00, 0x36, 0x02, 0x00, + 0x41, 0x84, 0x1c, 0x41, 0x00, 0x36, 0x02, 0x00, 0x0f, 0x0b, 0x20, 0x05, + 0x41, 0x84, 0x1c, 0x28, 0x02, 0x00, 0x46, 0x04, 0x40, 0x41, 0x84, 0x1c, + 0x20, 0x03, 0x36, 0x02, 0x00, 0x41, 0xf8, 0x1b, 0x41, 0xf8, 0x1b, 0x28, + 0x02, 0x00, 0x20, 0x00, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, 0x00, 0x20, 0x03, + 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x78, + 0x71, 0x20, 0x00, 0x6a, 0x21, 0x00, 0x02, 0x40, 0x20, 0x01, 0x41, 0xff, + 0x01, 0x4d, 0x04, 0x40, 0x20, 0x05, 0x28, 0x02, 0x0c, 0x21, 0x02, 0x20, + 0x05, 0x28, 0x02, 0x08, 0x22, 0x04, 0x20, 0x01, 0x41, 0x03, 0x76, 0x22, + 0x01, 0x41, 0x03, 0x74, 0x41, 0x98, 0x1c, 0x6a, 0x22, 0x07, 0x47, 0x04, + 0x40, 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, 0x1a, 0x0b, 0x20, 0x02, 0x20, + 0x04, 0x46, 0x04, 0x40, 0x41, 0xf0, 0x1b, 0x41, 0xf0, 0x1b, 0x28, 0x02, + 0x00, 0x41, 0x7e, 0x20, 0x01, 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, 0x02, + 0x0b, 0x20, 0x02, 0x20, 0x07, 0x47, 0x04, 0x40, 0x41, 0x80, 0x1c, 0x28, + 0x02, 0x00, 0x1a, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x36, 0x02, 0x08, 0x20, + 0x04, 0x20, 0x02, 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x28, + 0x02, 0x18, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x20, 0x05, 0x28, 0x02, + 0x0c, 0x22, 0x01, 0x47, 0x04, 0x40, 0x41, 0x80, 0x1c, 0x28, 0x02, 0x00, + 0x20, 0x05, 0x28, 0x02, 0x08, 0x22, 0x02, 0x4d, 0x04, 0x40, 0x20, 0x02, + 0x28, 0x02, 0x0c, 0x1a, 0x0b, 0x20, 0x01, 0x20, 0x02, 0x36, 0x02, 0x08, + 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x02, 0x40, + 0x20, 0x05, 0x41, 0x14, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x04, + 0x0d, 0x00, 0x20, 0x05, 0x41, 0x10, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, + 0x22, 0x04, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x01, 0x0c, 0x01, 0x0b, 0x03, + 0x40, 0x20, 0x02, 0x21, 0x07, 0x20, 0x04, 0x22, 0x01, 0x41, 0x14, 0x6a, + 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x04, 0x0d, 0x00, 0x20, 0x01, 0x41, + 0x10, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x28, 0x02, 0x10, 0x22, 0x04, 0x0d, + 0x00, 0x0b, 0x20, 0x07, 0x41, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x06, + 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x05, 0x20, 0x05, 0x28, 0x02, 0x1c, + 0x22, 0x02, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, 0x6a, 0x22, 0x04, 0x28, + 0x02, 0x00, 0x46, 0x04, 0x40, 0x20, 0x04, 0x20, 0x01, 0x36, 0x02, 0x00, + 0x20, 0x01, 0x0d, 0x01, 0x41, 0xf4, 0x1b, 0x41, 0xf4, 0x1b, 0x28, 0x02, + 0x00, 0x41, 0x7e, 0x20, 0x02, 0x77, 0x71, 0x36, 0x02, 0x00, 0x0c, 0x02, + 0x0b, 0x20, 0x06, 0x41, 0x10, 0x41, 0x14, 0x20, 0x06, 0x28, 0x02, 0x10, + 0x20, 0x05, 0x46, 0x1b, 0x6a, 0x20, 0x01, 0x36, 0x02, 0x00, 0x20, 0x01, + 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x20, 0x06, 0x36, 0x02, 0x18, 0x20, + 0x05, 0x28, 0x02, 0x10, 0x22, 0x02, 0x04, 0x40, 0x20, 0x01, 0x20, 0x02, + 0x36, 0x02, 0x10, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x18, 0x0b, 0x20, + 0x05, 0x28, 0x02, 0x14, 0x22, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x41, + 0x14, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x01, 0x36, + 0x02, 0x18, 0x0b, 0x20, 0x00, 0x20, 0x03, 0x6a, 0x20, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, 0x02, 0x04, 0x20, + 0x03, 0x41, 0x84, 0x1c, 0x28, 0x02, 0x00, 0x47, 0x0d, 0x01, 0x41, 0xf8, + 0x1b, 0x20, 0x00, 0x36, 0x02, 0x00, 0x0f, 0x0b, 0x20, 0x05, 0x20, 0x01, + 0x41, 0x7e, 0x71, 0x36, 0x02, 0x04, 0x20, 0x00, 0x20, 0x03, 0x6a, 0x20, + 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x00, 0x41, 0x01, 0x72, 0x36, + 0x02, 0x04, 0x0b, 0x20, 0x00, 0x41, 0xff, 0x01, 0x4d, 0x04, 0x40, 0x20, + 0x00, 0x41, 0x03, 0x76, 0x22, 0x01, 0x41, 0x03, 0x74, 0x41, 0x98, 0x1c, + 0x6a, 0x21, 0x00, 0x02, 0x7f, 0x41, 0xf0, 0x1b, 0x28, 0x02, 0x00, 0x22, + 0x02, 0x41, 0x01, 0x20, 0x01, 0x74, 0x22, 0x01, 0x71, 0x45, 0x04, 0x40, + 0x41, 0xf0, 0x1b, 0x20, 0x01, 0x20, 0x02, 0x72, 0x36, 0x02, 0x00, 0x20, + 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x08, 0x0b, 0x22, 0x02, + 0x20, 0x03, 0x36, 0x02, 0x0c, 0x20, 0x00, 0x20, 0x03, 0x36, 0x02, 0x08, + 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x0c, 0x20, 0x03, 0x20, 0x02, 0x36, + 0x02, 0x08, 0x0f, 0x0b, 0x20, 0x03, 0x42, 0x00, 0x37, 0x02, 0x10, 0x20, + 0x03, 0x41, 0x1c, 0x6a, 0x02, 0x7f, 0x41, 0x00, 0x20, 0x00, 0x41, 0x08, + 0x76, 0x22, 0x01, 0x45, 0x0d, 0x00, 0x1a, 0x41, 0x1f, 0x20, 0x00, 0x41, + 0xff, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x1a, 0x20, 0x01, 0x20, 0x01, + 0x41, 0x80, 0xfe, 0x3f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x08, 0x71, 0x22, + 0x01, 0x74, 0x22, 0x02, 0x20, 0x02, 0x41, 0x80, 0xe0, 0x1f, 0x6a, 0x41, + 0x10, 0x76, 0x41, 0x04, 0x71, 0x22, 0x02, 0x74, 0x22, 0x04, 0x20, 0x04, + 0x41, 0x80, 0x80, 0x0f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x02, 0x71, 0x22, + 0x04, 0x74, 0x41, 0x0f, 0x76, 0x20, 0x01, 0x20, 0x02, 0x72, 0x20, 0x04, + 0x72, 0x6b, 0x22, 0x01, 0x41, 0x01, 0x74, 0x20, 0x00, 0x20, 0x01, 0x41, + 0x15, 0x6a, 0x76, 0x41, 0x01, 0x71, 0x72, 0x41, 0x1c, 0x6a, 0x0b, 0x22, + 0x02, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x02, 0x74, 0x41, 0xa0, 0x1e, + 0x6a, 0x21, 0x01, 0x02, 0x40, 0x41, 0xf4, 0x1b, 0x28, 0x02, 0x00, 0x22, + 0x04, 0x41, 0x01, 0x20, 0x02, 0x74, 0x22, 0x07, 0x71, 0x45, 0x04, 0x40, + 0x20, 0x01, 0x20, 0x03, 0x36, 0x02, 0x00, 0x41, 0xf4, 0x1b, 0x20, 0x04, + 0x20, 0x07, 0x72, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, + 0x01, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, + 0x03, 0x20, 0x03, 0x36, 0x02, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x41, + 0x00, 0x41, 0x19, 0x20, 0x02, 0x41, 0x01, 0x76, 0x6b, 0x20, 0x02, 0x41, + 0x1f, 0x46, 0x1b, 0x74, 0x21, 0x02, 0x20, 0x01, 0x28, 0x02, 0x00, 0x21, + 0x01, 0x02, 0x40, 0x03, 0x40, 0x20, 0x01, 0x22, 0x04, 0x28, 0x02, 0x04, + 0x41, 0x78, 0x71, 0x20, 0x00, 0x46, 0x0d, 0x01, 0x20, 0x02, 0x41, 0x1d, + 0x76, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x74, 0x21, 0x02, 0x20, 0x04, + 0x20, 0x01, 0x41, 0x04, 0x71, 0x6a, 0x41, 0x10, 0x6a, 0x22, 0x07, 0x28, + 0x02, 0x00, 0x22, 0x01, 0x0d, 0x00, 0x0b, 0x20, 0x07, 0x20, 0x03, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x20, 0x03, 0x36, 0x02, 0x0c, 0x20, 0x03, 0x41, + 0x18, 0x6a, 0x20, 0x04, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x03, 0x36, + 0x02, 0x08, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x28, 0x02, 0x08, 0x21, 0x00, + 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, 0x00, 0x20, 0x03, 0x36, + 0x02, 0x0c, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, + 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, 0x04, 0x36, + 0x02, 0x0c, 0x0b, 0x41, 0x90, 0x1c, 0x41, 0x90, 0x1c, 0x28, 0x02, 0x00, + 0x41, 0x7f, 0x6a, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, 0x0d, 0x00, + 0x41, 0xb8, 0x1f, 0x21, 0x03, 0x03, 0x40, 0x20, 0x03, 0x28, 0x02, 0x00, + 0x22, 0x00, 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x0d, 0x00, 0x0b, + 0x41, 0x90, 0x1c, 0x41, 0x7f, 0x36, 0x02, 0x00, 0x0b, 0x0b, 0x4c, 0x01, + 0x01, 0x7f, 0x02, 0x40, 0x02, 0x7f, 0x20, 0x00, 0x41, 0x18, 0x6c, 0x22, + 0x01, 0x20, 0x00, 0x41, 0x18, 0x72, 0x41, 0x80, 0x80, 0x04, 0x49, 0x0d, + 0x00, 0x1a, 0x20, 0x01, 0x41, 0x7f, 0x20, 0x01, 0x41, 0x18, 0x6e, 0x20, + 0x00, 0x46, 0x1b, 0x0b, 0x22, 0x01, 0x10, 0x14, 0x22, 0x00, 0x45, 0x0d, + 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x03, 0x71, + 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x00, 0x20, 0x01, 0x10, 0x3a, 0x0b, + 0x20, 0x00, 0x0b, 0x5d, 0x02, 0x02, 0x7f, 0x02, 0x7e, 0x23, 0x00, 0x41, + 0x10, 0x6b, 0x22, 0x01, 0x24, 0x00, 0x02, 0x40, 0x41, 0xa0, 0x09, 0x28, + 0x02, 0x00, 0x42, 0x01, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x10, 0x06, 0x22, + 0x02, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, + 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x29, 0x03, 0x08, 0x22, 0x03, 0x42, + 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x80, 0x22, 0x04, 0x37, 0x03, 0x00, 0x20, + 0x00, 0x20, 0x03, 0x20, 0x04, 0x42, 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x7e, + 0x7d, 0x3e, 0x02, 0x08, 0x0b, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x24, 0x00, + 0x0b, 0x07, 0x00, 0x20, 0x00, 0x10, 0x07, 0x00, 0x0b, 0x19, 0x00, 0x20, + 0x00, 0x10, 0x08, 0x22, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x0f, 0x0b, + 0x41, 0xe0, 0x1f, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0x7f, 0x0b, 0x54, + 0x01, 0x01, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x02, 0x24, 0x00, + 0x20, 0x02, 0x41, 0x01, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x20, 0x01, 0x36, + 0x02, 0x08, 0x02, 0x7f, 0x20, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x41, + 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x10, 0x09, 0x22, 0x00, 0x04, 0x40, + 0x41, 0xe0, 0x1f, 0x41, 0x08, 0x20, 0x00, 0x20, 0x00, 0x41, 0xcc, 0x00, + 0x46, 0x1b, 0x36, 0x02, 0x00, 0x41, 0x7f, 0x0c, 0x01, 0x0b, 0x20, 0x02, + 0x28, 0x02, 0x04, 0x0b, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x0b, + 0xaa, 0x01, 0x02, 0x02, 0x7f, 0x01, 0x7e, 0x23, 0x00, 0x41, 0x20, 0x6b, + 0x22, 0x03, 0x24, 0x00, 0x02, 0x40, 0x20, 0x00, 0x20, 0x03, 0x41, 0x08, + 0x6a, 0x10, 0x0a, 0x22, 0x02, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x20, 0x02, + 0x36, 0x02, 0x00, 0x41, 0x7f, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, + 0x2d, 0x00, 0x08, 0x41, 0x03, 0x47, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, + 0x36, 0x36, 0x02, 0x00, 0x41, 0x7f, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, + 0x03, 0x29, 0x03, 0x18, 0x22, 0x04, 0x42, 0x02, 0x83, 0x42, 0x02, 0x52, + 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, 0xcc, 0x00, 0x36, 0x02, 0x00, 0x41, + 0x7f, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x41, 0x7f, 0x21, 0x02, 0x20, 0x00, + 0x41, 0x01, 0x20, 0x01, 0x20, 0x01, 0x10, 0x38, 0x41, 0x00, 0x20, 0x04, + 0x42, 0xbe, 0xfd, 0xff, 0x7d, 0x83, 0x20, 0x04, 0x41, 0x00, 0x20, 0x03, + 0x41, 0x04, 0x6a, 0x10, 0x0b, 0x22, 0x00, 0x04, 0x40, 0x41, 0xe0, 0x1f, + 0x20, 0x00, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, + 0x04, 0x21, 0x02, 0x0c, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x20, 0x6a, 0x24, + 0x00, 0x20, 0x02, 0x0b, 0x54, 0x01, 0x02, 0x7f, 0x23, 0x00, 0x41, 0x20, + 0x6b, 0x22, 0x01, 0x24, 0x00, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x20, 0x00, + 0x10, 0x1d, 0x41, 0x7f, 0x21, 0x00, 0x02, 0x40, 0x20, 0x01, 0x28, 0x02, + 0x10, 0x22, 0x02, 0x41, 0x7f, 0x46, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, + 0xcc, 0x00, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x28, 0x02, + 0x14, 0x21, 0x00, 0x20, 0x01, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, + 0x20, 0x00, 0x10, 0x1b, 0x21, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x20, 0x6a, + 0x24, 0x00, 0x20, 0x00, 0x0b, 0x94, 0x04, 0x01, 0x0e, 0x7f, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x41, 0xe4, 0x1f, 0x28, 0x02, 0x00, 0x22, 0x03, + 0x45, 0x0d, 0x00, 0x20, 0x03, 0x10, 0x1e, 0x41, 0xe4, 0x1f, 0x28, 0x02, + 0x00, 0x22, 0x03, 0x10, 0x1e, 0x20, 0x01, 0x45, 0x04, 0x40, 0x41, 0x7f, + 0x21, 0x06, 0x0c, 0x03, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, 0x22, 0x0b, + 0x45, 0x04, 0x40, 0x41, 0x7f, 0x21, 0x06, 0x0c, 0x02, 0x0b, 0x20, 0x03, + 0x28, 0x02, 0x04, 0x21, 0x0c, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x09, + 0x41, 0x52, 0x6a, 0x22, 0x0d, 0x41, 0x01, 0x4b, 0x21, 0x0e, 0x41, 0x7f, + 0x21, 0x06, 0x03, 0x40, 0x20, 0x0c, 0x20, 0x0a, 0x41, 0x18, 0x6c, 0x6a, + 0x22, 0x07, 0x28, 0x02, 0x00, 0x22, 0x04, 0x10, 0x38, 0x21, 0x03, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x0e, 0x45, 0x04, 0x40, 0x20, 0x0d, 0x41, 0x01, 0x6b, 0x45, 0x0d, 0x01, + 0x20, 0x01, 0x2d, 0x00, 0x01, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02, + 0x41, 0x2f, 0x46, 0x0d, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x02, 0x4f, 0x04, + 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x22, 0x02, 0x41, 0x2e, 0x47, 0x0d, + 0x03, 0x41, 0x2e, 0x21, 0x02, 0x20, 0x04, 0x2d, 0x00, 0x01, 0x41, 0x2f, + 0x47, 0x0d, 0x03, 0x20, 0x03, 0x41, 0x7e, 0x6a, 0x21, 0x03, 0x20, 0x04, + 0x41, 0x02, 0x6a, 0x21, 0x04, 0x0c, 0x02, 0x0b, 0x20, 0x03, 0x41, 0x01, + 0x47, 0x0d, 0x00, 0x20, 0x04, 0x41, 0x01, 0x6a, 0x20, 0x04, 0x20, 0x04, + 0x2d, 0x00, 0x00, 0x22, 0x03, 0x41, 0x2e, 0x46, 0x1b, 0x21, 0x04, 0x20, + 0x03, 0x41, 0x2e, 0x47, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x45, + 0x0d, 0x06, 0x0b, 0x20, 0x09, 0x41, 0x2f, 0x47, 0x04, 0x40, 0x41, 0x00, + 0x21, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x03, 0x0b, 0x20, 0x03, 0x45, 0x04, + 0x40, 0x41, 0x00, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x04, 0x2d, 0x00, + 0x00, 0x21, 0x02, 0x0b, 0x20, 0x09, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, + 0x47, 0x0d, 0x02, 0x41, 0x01, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20, + 0x03, 0x46, 0x04, 0x40, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, + 0x02, 0x20, 0x04, 0x6a, 0x21, 0x08, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x20, + 0x02, 0x41, 0x01, 0x6a, 0x21, 0x02, 0x2d, 0x00, 0x00, 0x20, 0x08, 0x2d, + 0x00, 0x00, 0x46, 0x0d, 0x00, 0x0b, 0x0c, 0x02, 0x0b, 0x20, 0x04, 0x41, + 0x7f, 0x6a, 0x21, 0x08, 0x20, 0x02, 0x21, 0x03, 0x03, 0x40, 0x20, 0x03, + 0x22, 0x05, 0x04, 0x40, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, + 0x05, 0x20, 0x08, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x2f, 0x46, 0x0d, 0x01, + 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x05, 0x6a, 0x2d, 0x00, 0x00, 0x22, 0x03, + 0x41, 0x2f, 0x46, 0x0d, 0x00, 0x20, 0x03, 0x0d, 0x01, 0x0b, 0x20, 0x07, + 0x29, 0x03, 0x08, 0x42, 0x7f, 0x85, 0x42, 0x80, 0xc0, 0x00, 0x83, 0x42, + 0x00, 0x52, 0x0d, 0x00, 0x20, 0x07, 0x29, 0x03, 0x10, 0x42, 0x7f, 0x85, + 0x42, 0x00, 0x83, 0x42, 0x00, 0x52, 0x0d, 0x00, 0x20, 0x07, 0x28, 0x02, + 0x04, 0x21, 0x06, 0x20, 0x02, 0x21, 0x0f, 0x0b, 0x20, 0x0b, 0x20, 0x0a, + 0x41, 0x01, 0x6a, 0x22, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, + 0x00, 0x0b, 0x20, 0x01, 0x20, 0x0f, 0x6a, 0x21, 0x02, 0x03, 0x40, 0x20, + 0x02, 0x2d, 0x00, 0x00, 0x22, 0x01, 0x41, 0x2f, 0x46, 0x04, 0x40, 0x20, + 0x02, 0x41, 0x01, 0x6a, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x0b, 0x20, 0x01, + 0x0d, 0x00, 0x41, 0xa4, 0x09, 0x21, 0x02, 0x0b, 0x20, 0x00, 0x20, 0x02, + 0x36, 0x02, 0x04, 0x20, 0x00, 0x20, 0x06, 0x36, 0x02, 0x00, 0x0b, 0x63, + 0x01, 0x02, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x41, 0x00, 0x4c, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x0c, 0x22, 0x01, + 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, 0x02, 0x4b, 0x0d, 0x00, 0x41, 0x00, + 0x20, 0x02, 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, 0x00, 0x1b, 0x0d, 0x00, + 0x20, 0x01, 0x45, 0x0d, 0x01, 0x03, 0x40, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x41, + 0x7f, 0x4c, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x18, 0x6a, 0x21, 0x00, 0x20, + 0x01, 0x41, 0x7f, 0x6a, 0x22, 0x01, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, + 0x00, 0x0b, 0x0b, 0x4a, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x41, 0x10, 0x10, + 0x14, 0x22, 0x00, 0x04, 0x40, 0x20, 0x00, 0x41, 0x04, 0x10, 0x16, 0x22, + 0x01, 0x36, 0x02, 0x04, 0x20, 0x01, 0x0d, 0x01, 0x20, 0x00, 0x10, 0x15, + 0x0b, 0x41, 0xe4, 0x1f, 0x41, 0x00, 0x36, 0x02, 0x00, 0x00, 0x0b, 0x20, + 0x00, 0x42, 0x04, 0x37, 0x02, 0x08, 0x20, 0x00, 0x41, 0x01, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x10, 0x1e, 0x41, 0xe4, 0x1f, 0x20, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x10, 0x1e, 0x0b, 0xfd, 0x01, 0x01, 0x05, 0x7f, 0x23, + 0x00, 0x41, 0x20, 0x6b, 0x22, 0x04, 0x24, 0x00, 0x41, 0xe4, 0x1f, 0x28, + 0x02, 0x00, 0x10, 0x1e, 0x41, 0x7f, 0x21, 0x06, 0x02, 0x40, 0x20, 0x01, + 0x45, 0x0d, 0x00, 0x41, 0xe4, 0x1f, 0x28, 0x02, 0x00, 0x22, 0x02, 0x10, + 0x1e, 0x20, 0x00, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x02, + 0x28, 0x02, 0x0c, 0x22, 0x05, 0x20, 0x02, 0x28, 0x02, 0x08, 0x47, 0x04, + 0x40, 0x20, 0x02, 0x28, 0x02, 0x04, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, + 0x05, 0x41, 0x01, 0x74, 0x10, 0x16, 0x22, 0x03, 0x45, 0x0d, 0x01, 0x20, + 0x03, 0x20, 0x02, 0x28, 0x02, 0x04, 0x20, 0x02, 0x28, 0x02, 0x0c, 0x41, + 0x18, 0x6c, 0x10, 0x39, 0x1a, 0x20, 0x02, 0x28, 0x02, 0x04, 0x10, 0x15, + 0x20, 0x02, 0x20, 0x03, 0x36, 0x02, 0x04, 0x20, 0x02, 0x20, 0x02, 0x28, + 0x02, 0x08, 0x41, 0x01, 0x74, 0x36, 0x02, 0x08, 0x20, 0x02, 0x28, 0x02, + 0x0c, 0x21, 0x05, 0x0b, 0x20, 0x02, 0x20, 0x05, 0x41, 0x01, 0x6a, 0x36, + 0x02, 0x0c, 0x20, 0x01, 0x10, 0x37, 0x21, 0x01, 0x20, 0x03, 0x20, 0x05, + 0x41, 0x18, 0x6c, 0x6a, 0x22, 0x03, 0x20, 0x00, 0x36, 0x02, 0x04, 0x20, + 0x03, 0x20, 0x01, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x04, 0x41, 0x08, + 0x6a, 0x10, 0x0a, 0x22, 0x00, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x20, 0x00, + 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x20, 0x04, 0x29, 0x03, + 0x10, 0x37, 0x03, 0x08, 0x20, 0x03, 0x20, 0x04, 0x29, 0x03, 0x18, 0x37, + 0x03, 0x10, 0x20, 0x02, 0x10, 0x1e, 0x20, 0x02, 0x10, 0x1e, 0x41, 0x00, + 0x21, 0x06, 0x41, 0xe4, 0x1f, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0b, 0x20, + 0x04, 0x41, 0x20, 0x6a, 0x24, 0x00, 0x20, 0x06, 0x0b, 0x36, 0x00, 0x02, + 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x00, + 0x41, 0x7f, 0x4c, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x10, 0x76, 0x40, 0x00, + 0x22, 0x00, 0x41, 0x7f, 0x46, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, 0x30, + 0x36, 0x02, 0x00, 0x41, 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0x10, 0x74, + 0x0f, 0x0b, 0x00, 0x0b, 0x21, 0x01, 0x01, 0x7f, 0x23, 0x00, 0x41, 0x10, + 0x6b, 0x22, 0x02, 0x24, 0x00, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x0c, + 0x20, 0x00, 0x20, 0x01, 0x10, 0x25, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x24, + 0x00, 0x0b, 0x9e, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x00, 0x45, 0x04, 0x40, + 0x41, 0xa0, 0x29, 0x28, 0x02, 0x00, 0x04, 0x40, 0x41, 0xa0, 0x29, 0x28, + 0x02, 0x00, 0x10, 0x23, 0x21, 0x01, 0x0b, 0x41, 0x98, 0x2a, 0x28, 0x02, + 0x00, 0x04, 0x40, 0x41, 0x98, 0x2a, 0x28, 0x02, 0x00, 0x10, 0x23, 0x20, + 0x01, 0x72, 0x21, 0x01, 0x0b, 0x41, 0xec, 0x1f, 0x28, 0x02, 0x00, 0x22, + 0x00, 0x04, 0x40, 0x03, 0x40, 0x20, 0x00, 0x28, 0x02, 0x14, 0x20, 0x00, + 0x28, 0x02, 0x18, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, 0x00, 0x41, 0x00, + 0x20, 0x00, 0x28, 0x02, 0x20, 0x11, 0x00, 0x00, 0x1a, 0x02, 0x7f, 0x41, + 0x7f, 0x20, 0x00, 0x28, 0x02, 0x14, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x00, + 0x28, 0x02, 0x04, 0x22, 0x02, 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, 0x03, + 0x47, 0x04, 0x40, 0x20, 0x00, 0x20, 0x02, 0x20, 0x03, 0x6b, 0xac, 0x41, + 0x00, 0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x03, 0x00, 0x1a, 0x0b, 0x20, + 0x00, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x00, 0x42, 0x00, 0x37, 0x03, + 0x10, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x41, 0x00, 0x0b, 0x20, + 0x01, 0x72, 0x21, 0x01, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x34, 0x22, 0x00, + 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x00, + 0x28, 0x02, 0x14, 0x20, 0x00, 0x28, 0x02, 0x18, 0x46, 0x0d, 0x00, 0x20, + 0x00, 0x41, 0x00, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x20, 0x11, 0x00, + 0x00, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x14, 0x0d, 0x00, 0x41, 0x7f, 0x0f, + 0x0b, 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, + 0x08, 0x22, 0x02, 0x47, 0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, + 0x6b, 0xac, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x03, 0x00, + 0x1a, 0x0b, 0x20, 0x00, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x00, 0x42, + 0x00, 0x37, 0x03, 0x10, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x41, + 0x00, 0x0b, 0x84, 0x01, 0x01, 0x04, 0x7f, 0x41, 0x88, 0x20, 0x28, 0x02, + 0x00, 0x22, 0x02, 0x45, 0x04, 0x40, 0x41, 0x88, 0x20, 0x41, 0xf0, 0x1f, + 0x36, 0x02, 0x00, 0x41, 0xf0, 0x1f, 0x21, 0x02, 0x0b, 0x02, 0x40, 0x02, + 0x40, 0x03, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0xb0, 0x09, 0x6a, 0x2d, + 0x00, 0x00, 0x47, 0x04, 0x40, 0x41, 0xcd, 0x00, 0x21, 0x03, 0x20, 0x01, + 0x41, 0x01, 0x6a, 0x22, 0x01, 0x41, 0xcd, 0x00, 0x47, 0x0d, 0x01, 0x0c, + 0x02, 0x0b, 0x0b, 0x20, 0x01, 0x22, 0x03, 0x0d, 0x00, 0x41, 0x80, 0x0a, + 0x21, 0x00, 0x0c, 0x01, 0x0b, 0x41, 0x80, 0x0a, 0x21, 0x01, 0x03, 0x40, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x00, + 0x21, 0x01, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x01, 0x20, 0x03, 0x41, 0x7f, + 0x6a, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x28, 0x02, 0x14, + 0x1a, 0x20, 0x00, 0x0b, 0xdd, 0x02, 0x01, 0x03, 0x7f, 0x23, 0x00, 0x41, + 0xd0, 0x01, 0x6b, 0x22, 0x02, 0x24, 0x00, 0x20, 0x02, 0x20, 0x01, 0x36, + 0x02, 0xcc, 0x01, 0x20, 0x02, 0x41, 0xc0, 0x01, 0x6a, 0x42, 0x00, 0x37, + 0x03, 0x00, 0x20, 0x02, 0x41, 0xb8, 0x01, 0x6a, 0x42, 0x00, 0x37, 0x03, + 0x00, 0x20, 0x02, 0x41, 0xb0, 0x01, 0x6a, 0x42, 0x00, 0x37, 0x03, 0x00, + 0x20, 0x02, 0x42, 0x00, 0x37, 0x03, 0xa8, 0x01, 0x20, 0x02, 0x42, 0x00, + 0x37, 0x03, 0xa0, 0x01, 0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0xc8, 0x01, + 0x41, 0x00, 0x20, 0x00, 0x20, 0x02, 0x41, 0xc8, 0x01, 0x6a, 0x20, 0x02, + 0x41, 0xd0, 0x00, 0x6a, 0x20, 0x02, 0x41, 0xa0, 0x01, 0x6a, 0x10, 0x26, + 0x41, 0x00, 0x4e, 0x04, 0x40, 0x41, 0xb0, 0x28, 0x28, 0x02, 0x00, 0x21, + 0x03, 0x41, 0xec, 0x28, 0x28, 0x02, 0x00, 0x41, 0x00, 0x4c, 0x04, 0x40, + 0x41, 0xb0, 0x28, 0x20, 0x03, 0x41, 0x5f, 0x71, 0x36, 0x02, 0x00, 0x0b, + 0x02, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x41, 0xdc, 0x28, 0x28, 0x02, 0x00, + 0x45, 0x04, 0x40, 0x41, 0xdc, 0x28, 0x41, 0xd0, 0x00, 0x36, 0x02, 0x00, + 0x41, 0xc8, 0x28, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0xc0, 0x28, 0x42, + 0x00, 0x37, 0x03, 0x00, 0x41, 0xd8, 0x28, 0x28, 0x02, 0x00, 0x21, 0x04, + 0x41, 0xd8, 0x28, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x41, + 0xc0, 0x28, 0x28, 0x02, 0x00, 0x0d, 0x01, 0x0b, 0x41, 0x7f, 0x41, 0xb0, + 0x28, 0x10, 0x31, 0x0d, 0x01, 0x1a, 0x0b, 0x41, 0xb0, 0x28, 0x20, 0x00, + 0x20, 0x02, 0x41, 0xc8, 0x01, 0x6a, 0x20, 0x02, 0x41, 0xd0, 0x00, 0x6a, + 0x20, 0x02, 0x41, 0xa0, 0x01, 0x6a, 0x10, 0x26, 0x0b, 0x21, 0x01, 0x20, + 0x04, 0x04, 0x7f, 0x41, 0xb0, 0x28, 0x41, 0x00, 0x41, 0x00, 0x41, 0xd0, + 0x28, 0x28, 0x02, 0x00, 0x11, 0x00, 0x00, 0x1a, 0x41, 0xdc, 0x28, 0x41, + 0x00, 0x36, 0x02, 0x00, 0x41, 0xd8, 0x28, 0x20, 0x04, 0x36, 0x02, 0x00, + 0x41, 0xc8, 0x28, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0xc0, 0x28, 0x41, + 0x00, 0x36, 0x02, 0x00, 0x41, 0xc4, 0x28, 0x28, 0x02, 0x00, 0x21, 0x00, + 0x41, 0xc4, 0x28, 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0x00, 0x05, 0x20, + 0x01, 0x0b, 0x1a, 0x41, 0xb0, 0x28, 0x41, 0xb0, 0x28, 0x28, 0x02, 0x00, + 0x20, 0x03, 0x41, 0x20, 0x71, 0x72, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, + 0x41, 0xd0, 0x01, 0x6a, 0x24, 0x00, 0x0b, 0xc7, 0x45, 0x03, 0x1d, 0x7f, + 0x02, 0x7e, 0x02, 0x7c, 0x23, 0x00, 0x41, 0xf0, 0x06, 0x6b, 0x22, 0x09, + 0x24, 0x00, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, 0x41, 0x08, 0x72, 0x21, + 0x1e, 0x20, 0x09, 0x41, 0x37, 0x6a, 0x21, 0x1f, 0x41, 0xae, 0x7d, 0x20, + 0x09, 0x6b, 0x21, 0x20, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, 0x41, 0x09, + 0x72, 0x21, 0x1b, 0x20, 0x09, 0x41, 0x90, 0x05, 0x6a, 0x21, 0x21, 0x20, + 0x09, 0x41, 0xd0, 0x02, 0x6a, 0x21, 0x19, 0x20, 0x09, 0x41, 0x38, 0x6a, + 0x21, 0x15, 0x02, 0x40, 0x02, 0x40, 0x03, 0x40, 0x02, 0x40, 0x20, 0x01, + 0x21, 0x08, 0x20, 0x05, 0x41, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x13, + 0x6b, 0x4a, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x13, 0x6a, 0x21, 0x13, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x08, 0x2d, 0x00, 0x00, 0x22, 0x05, + 0x04, 0x40, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x05, 0x41, 0xff, + 0x01, 0x71, 0x22, 0x06, 0x04, 0x40, 0x20, 0x06, 0x41, 0x25, 0x47, 0x0d, + 0x02, 0x20, 0x01, 0x22, 0x06, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, 0x41, + 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x25, 0x47, 0x04, 0x40, 0x20, 0x05, + 0x21, 0x01, 0x0c, 0x03, 0x0b, 0x20, 0x06, 0x41, 0x01, 0x6a, 0x21, 0x06, + 0x20, 0x05, 0x2d, 0x00, 0x02, 0x20, 0x05, 0x41, 0x02, 0x6a, 0x22, 0x01, + 0x21, 0x05, 0x41, 0x25, 0x46, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20, + 0x01, 0x21, 0x06, 0x0b, 0x20, 0x06, 0x20, 0x08, 0x6b, 0x22, 0x05, 0x41, + 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x13, 0x6b, 0x22, 0x18, 0x4a, 0x0d, + 0x06, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x2d, 0x00, + 0x00, 0x41, 0x20, 0x71, 0x0d, 0x00, 0x20, 0x08, 0x20, 0x05, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x05, 0x0d, 0x07, 0x20, 0x01, 0x41, 0x01, + 0x6a, 0x21, 0x05, 0x02, 0x7f, 0x41, 0x7f, 0x20, 0x01, 0x2c, 0x00, 0x01, + 0x22, 0x0b, 0x41, 0x50, 0x6a, 0x22, 0x07, 0x41, 0x09, 0x4b, 0x0d, 0x00, + 0x1a, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x20, 0x05, 0x20, 0x01, 0x2d, 0x00, + 0x02, 0x41, 0x24, 0x46, 0x22, 0x06, 0x1b, 0x21, 0x05, 0x41, 0x01, 0x20, + 0x1a, 0x20, 0x06, 0x1b, 0x21, 0x1a, 0x20, 0x01, 0x41, 0x03, 0x41, 0x01, + 0x20, 0x06, 0x1b, 0x6a, 0x2c, 0x00, 0x00, 0x21, 0x0b, 0x20, 0x07, 0x41, + 0x7f, 0x20, 0x06, 0x1b, 0x0b, 0x21, 0x06, 0x41, 0x00, 0x21, 0x0c, 0x02, + 0x40, 0x20, 0x0b, 0x41, 0x60, 0x6a, 0x22, 0x01, 0x41, 0x1f, 0x4b, 0x0d, + 0x00, 0x41, 0x01, 0x20, 0x01, 0x74, 0x22, 0x01, 0x41, 0x89, 0xd1, 0x04, + 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x01, 0x6a, 0x21, 0x07, 0x03, + 0x40, 0x20, 0x01, 0x20, 0x0c, 0x72, 0x21, 0x0c, 0x20, 0x07, 0x22, 0x05, + 0x2c, 0x00, 0x00, 0x22, 0x0b, 0x41, 0x60, 0x6a, 0x22, 0x01, 0x41, 0x20, + 0x4f, 0x0d, 0x01, 0x20, 0x05, 0x41, 0x01, 0x6a, 0x21, 0x07, 0x41, 0x01, + 0x20, 0x01, 0x74, 0x22, 0x01, 0x41, 0x89, 0xd1, 0x04, 0x71, 0x0d, 0x00, + 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x0b, 0x41, 0x2a, 0x46, 0x04, 0x40, 0x02, + 0x7f, 0x02, 0x40, 0x20, 0x05, 0x2c, 0x00, 0x01, 0x41, 0x50, 0x6a, 0x22, + 0x01, 0x41, 0x09, 0x4b, 0x0d, 0x00, 0x20, 0x05, 0x2d, 0x00, 0x02, 0x41, + 0x24, 0x47, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x01, 0x41, 0x02, 0x74, 0x6a, + 0x41, 0x0a, 0x36, 0x02, 0x00, 0x20, 0x05, 0x41, 0x03, 0x6a, 0x21, 0x0a, + 0x41, 0x01, 0x21, 0x1a, 0x20, 0x05, 0x2c, 0x00, 0x01, 0x41, 0x03, 0x74, + 0x20, 0x03, 0x6a, 0x41, 0x80, 0x7d, 0x6a, 0x28, 0x02, 0x00, 0x0c, 0x01, + 0x0b, 0x20, 0x1a, 0x0d, 0x06, 0x20, 0x05, 0x41, 0x01, 0x6a, 0x21, 0x0a, + 0x20, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x21, 0x1a, 0x41, 0x00, 0x21, + 0x0e, 0x0c, 0x03, 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, + 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, 0x00, 0x41, 0x00, 0x21, 0x1a, 0x20, + 0x01, 0x28, 0x02, 0x00, 0x0b, 0x22, 0x0e, 0x41, 0x7f, 0x4a, 0x0d, 0x01, + 0x41, 0x00, 0x20, 0x0e, 0x6b, 0x21, 0x0e, 0x20, 0x0c, 0x41, 0x80, 0xc0, + 0x00, 0x72, 0x21, 0x0c, 0x0c, 0x01, 0x0b, 0x41, 0x00, 0x21, 0x0e, 0x20, + 0x0b, 0x41, 0x50, 0x6a, 0x22, 0x07, 0x41, 0x09, 0x4b, 0x04, 0x40, 0x20, + 0x05, 0x21, 0x0a, 0x0c, 0x01, 0x0b, 0x41, 0x00, 0x21, 0x01, 0x03, 0x40, + 0x41, 0x7f, 0x21, 0x0e, 0x20, 0x05, 0x2c, 0x00, 0x01, 0x20, 0x05, 0x41, + 0x01, 0x6a, 0x22, 0x0a, 0x21, 0x05, 0x20, 0x01, 0x41, 0xcc, 0x99, 0xb3, + 0xe6, 0x00, 0x4d, 0x04, 0x40, 0x41, 0x7f, 0x20, 0x01, 0x41, 0x0a, 0x6c, + 0x22, 0x01, 0x20, 0x07, 0x6a, 0x20, 0x07, 0x41, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x20, 0x01, 0x6b, 0x4a, 0x1b, 0x21, 0x0e, 0x0b, 0x20, 0x0e, 0x21, + 0x01, 0x41, 0x50, 0x6a, 0x22, 0x07, 0x41, 0x0a, 0x49, 0x0d, 0x00, 0x0b, + 0x20, 0x0e, 0x41, 0x00, 0x48, 0x0d, 0x07, 0x0b, 0x41, 0x00, 0x21, 0x05, + 0x41, 0x7f, 0x21, 0x0b, 0x02, 0x40, 0x20, 0x0a, 0x2d, 0x00, 0x00, 0x41, + 0x2e, 0x47, 0x04, 0x40, 0x20, 0x0a, 0x21, 0x01, 0x41, 0x00, 0x21, 0x0d, + 0x0c, 0x01, 0x0b, 0x20, 0x0a, 0x2c, 0x00, 0x01, 0x22, 0x07, 0x41, 0x2a, + 0x46, 0x04, 0x40, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x0a, 0x2c, 0x00, 0x02, + 0x41, 0x50, 0x6a, 0x22, 0x01, 0x41, 0x09, 0x4b, 0x0d, 0x00, 0x20, 0x0a, + 0x2d, 0x00, 0x03, 0x41, 0x24, 0x47, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x01, + 0x41, 0x02, 0x74, 0x6a, 0x41, 0x0a, 0x36, 0x02, 0x00, 0x20, 0x0a, 0x41, + 0x04, 0x6a, 0x21, 0x01, 0x20, 0x0a, 0x2c, 0x00, 0x02, 0x41, 0x03, 0x74, + 0x20, 0x03, 0x6a, 0x41, 0x80, 0x7d, 0x6a, 0x28, 0x02, 0x00, 0x0c, 0x01, + 0x0b, 0x20, 0x1a, 0x0d, 0x06, 0x20, 0x0a, 0x41, 0x02, 0x6a, 0x21, 0x01, + 0x41, 0x00, 0x20, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x02, 0x20, 0x02, + 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x04, 0x6a, 0x36, 0x02, 0x00, 0x20, + 0x07, 0x28, 0x02, 0x00, 0x0b, 0x22, 0x0b, 0x41, 0x7f, 0x73, 0x41, 0x1f, + 0x76, 0x21, 0x0d, 0x0c, 0x01, 0x0b, 0x20, 0x0a, 0x41, 0x01, 0x6a, 0x21, + 0x01, 0x20, 0x07, 0x41, 0x50, 0x6a, 0x22, 0x10, 0x41, 0x09, 0x4b, 0x04, + 0x40, 0x41, 0x01, 0x21, 0x0d, 0x41, 0x00, 0x21, 0x0b, 0x0c, 0x01, 0x0b, + 0x41, 0x00, 0x21, 0x0a, 0x20, 0x01, 0x21, 0x07, 0x03, 0x40, 0x41, 0x7f, + 0x21, 0x0b, 0x20, 0x0a, 0x41, 0xcc, 0x99, 0xb3, 0xe6, 0x00, 0x4d, 0x04, + 0x40, 0x41, 0x7f, 0x20, 0x0a, 0x41, 0x0a, 0x6c, 0x22, 0x01, 0x20, 0x10, + 0x6a, 0x20, 0x10, 0x41, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x01, 0x6b, + 0x4a, 0x1b, 0x21, 0x0b, 0x0b, 0x41, 0x01, 0x21, 0x0d, 0x20, 0x07, 0x2c, + 0x00, 0x01, 0x20, 0x07, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x21, 0x07, 0x20, + 0x0b, 0x21, 0x0a, 0x41, 0x50, 0x6a, 0x22, 0x10, 0x41, 0x0a, 0x49, 0x0d, + 0x00, 0x0b, 0x0b, 0x03, 0x40, 0x20, 0x05, 0x21, 0x07, 0x20, 0x01, 0x2c, + 0x00, 0x00, 0x41, 0xbf, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x39, 0x4b, 0x0d, + 0x04, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x07, 0x41, 0x3a, + 0x6c, 0x20, 0x05, 0x6a, 0x41, 0xc0, 0x16, 0x6a, 0x2d, 0x00, 0x00, 0x22, + 0x05, 0x41, 0x7f, 0x6a, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x0b, 0x20, 0x05, + 0x45, 0x0d, 0x03, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x05, 0x41, + 0x1b, 0x46, 0x04, 0x40, 0x20, 0x06, 0x41, 0x7f, 0x4c, 0x0d, 0x01, 0x0c, + 0x07, 0x0b, 0x20, 0x06, 0x41, 0x00, 0x48, 0x0d, 0x01, 0x20, 0x04, 0x20, + 0x06, 0x41, 0x02, 0x74, 0x6a, 0x20, 0x05, 0x36, 0x02, 0x00, 0x20, 0x09, + 0x20, 0x03, 0x20, 0x06, 0x41, 0x03, 0x74, 0x6a, 0x29, 0x03, 0x00, 0x37, + 0x03, 0x38, 0x0b, 0x41, 0x00, 0x21, 0x05, 0x20, 0x00, 0x45, 0x0d, 0x09, + 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x21, 0x13, + 0x0c, 0x0b, 0x0b, 0x20, 0x09, 0x41, 0x38, 0x6a, 0x20, 0x05, 0x20, 0x02, + 0x10, 0x27, 0x0b, 0x20, 0x0c, 0x41, 0xff, 0xff, 0x7b, 0x71, 0x22, 0x06, + 0x20, 0x0c, 0x20, 0x0c, 0x41, 0x80, 0xc0, 0x00, 0x71, 0x1b, 0x21, 0x0f, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x7f, 0x6a, 0x2c, + 0x00, 0x00, 0x22, 0x05, 0x41, 0x5f, 0x71, 0x20, 0x05, 0x20, 0x05, 0x41, + 0x0f, 0x71, 0x41, 0x03, 0x46, 0x1b, 0x20, 0x05, 0x20, 0x07, 0x1b, 0x22, + 0x11, 0x41, 0xbf, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x37, 0x4b, 0x0d, 0x00, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x7f, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x7f, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x05, + 0x41, 0x01, 0x6b, 0x0e, 0x37, 0x11, 0x0d, 0x11, 0x10, 0x10, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0c, 0x11, + 0x11, 0x11, 0x11, 0x03, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x10, 0x11, 0x08, 0x05, 0x10, 0x10, 0x10, 0x11, 0x05, 0x11, 0x11, 0x11, + 0x09, 0x01, 0x04, 0x02, 0x11, 0x11, 0x0a, 0x11, 0x00, 0x11, 0x11, 0x03, + 0x10, 0x0b, 0x41, 0x00, 0x21, 0x0a, 0x20, 0x09, 0x29, 0x03, 0x38, 0x21, + 0x22, 0x41, 0xa6, 0x16, 0x0c, 0x05, 0x0b, 0x41, 0x00, 0x21, 0x05, 0x20, + 0x07, 0x41, 0xff, 0x01, 0x71, 0x22, 0x06, 0x41, 0x07, 0x4b, 0x0d, 0x19, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x02, 0x40, 0x20, 0x06, 0x41, 0x01, 0x6b, 0x0e, 0x07, 0x01, 0x02, 0x03, + 0x04, 0x20, 0x05, 0x06, 0x00, 0x0b, 0x20, 0x09, 0x28, 0x02, 0x38, 0x20, + 0x13, 0x36, 0x02, 0x00, 0x0c, 0x1f, 0x0b, 0x20, 0x09, 0x28, 0x02, 0x38, + 0x20, 0x13, 0x36, 0x02, 0x00, 0x0c, 0x1e, 0x0b, 0x20, 0x09, 0x28, 0x02, + 0x38, 0x20, 0x13, 0xac, 0x37, 0x03, 0x00, 0x0c, 0x1d, 0x0b, 0x20, 0x09, + 0x28, 0x02, 0x38, 0x20, 0x13, 0x3b, 0x01, 0x00, 0x0c, 0x1c, 0x0b, 0x20, + 0x09, 0x28, 0x02, 0x38, 0x20, 0x13, 0x3a, 0x00, 0x00, 0x0c, 0x1b, 0x0b, + 0x20, 0x09, 0x28, 0x02, 0x38, 0x20, 0x13, 0x36, 0x02, 0x00, 0x0c, 0x1a, + 0x0b, 0x20, 0x09, 0x28, 0x02, 0x38, 0x20, 0x13, 0xac, 0x37, 0x03, 0x00, + 0x0c, 0x19, 0x0b, 0x20, 0x0b, 0x41, 0x08, 0x20, 0x0b, 0x41, 0x08, 0x4b, + 0x1b, 0x21, 0x0b, 0x20, 0x0f, 0x41, 0x08, 0x72, 0x21, 0x0f, 0x41, 0xf8, + 0x00, 0x21, 0x11, 0x0b, 0x41, 0x00, 0x21, 0x0a, 0x41, 0xa6, 0x16, 0x21, + 0x10, 0x20, 0x09, 0x29, 0x03, 0x38, 0x22, 0x22, 0x50, 0x04, 0x40, 0x20, + 0x15, 0x21, 0x08, 0x0c, 0x04, 0x0b, 0x20, 0x11, 0x41, 0x20, 0x71, 0x21, + 0x06, 0x20, 0x15, 0x21, 0x08, 0x03, 0x40, 0x20, 0x08, 0x41, 0x7f, 0x6a, + 0x22, 0x08, 0x20, 0x22, 0xa7, 0x41, 0x0f, 0x71, 0x41, 0xa0, 0x1b, 0x6a, + 0x2d, 0x00, 0x00, 0x20, 0x06, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x22, 0x42, + 0x04, 0x88, 0x22, 0x22, 0x42, 0x00, 0x52, 0x0d, 0x00, 0x0b, 0x20, 0x0f, + 0x41, 0x08, 0x71, 0x45, 0x0d, 0x03, 0x20, 0x09, 0x29, 0x03, 0x38, 0x50, + 0x0d, 0x03, 0x20, 0x11, 0x41, 0x04, 0x75, 0x41, 0xa6, 0x16, 0x6a, 0x21, + 0x10, 0x41, 0x02, 0x21, 0x0a, 0x0c, 0x03, 0x0b, 0x20, 0x15, 0x21, 0x08, + 0x20, 0x09, 0x29, 0x03, 0x38, 0x22, 0x22, 0x50, 0x45, 0x04, 0x40, 0x03, + 0x40, 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x22, 0x08, 0x20, 0x22, 0xa7, 0x41, + 0x07, 0x71, 0x41, 0x30, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x22, 0x42, 0x03, + 0x88, 0x22, 0x22, 0x42, 0x00, 0x52, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, + 0x21, 0x0a, 0x41, 0xa6, 0x16, 0x21, 0x10, 0x20, 0x0f, 0x41, 0x08, 0x71, + 0x45, 0x0d, 0x02, 0x20, 0x0b, 0x20, 0x15, 0x20, 0x08, 0x6b, 0x22, 0x06, + 0x41, 0x01, 0x6a, 0x20, 0x0b, 0x20, 0x06, 0x4a, 0x1b, 0x21, 0x0b, 0x0c, + 0x02, 0x0b, 0x20, 0x09, 0x29, 0x03, 0x38, 0x22, 0x22, 0x42, 0x7f, 0x57, + 0x04, 0x40, 0x20, 0x09, 0x42, 0x00, 0x20, 0x22, 0x7d, 0x22, 0x22, 0x37, + 0x03, 0x38, 0x41, 0x01, 0x21, 0x0a, 0x41, 0xa6, 0x16, 0x0c, 0x01, 0x0b, + 0x20, 0x0f, 0x41, 0x80, 0x10, 0x71, 0x04, 0x40, 0x41, 0x01, 0x21, 0x0a, + 0x41, 0xa7, 0x16, 0x0c, 0x01, 0x0b, 0x41, 0xa8, 0x16, 0x41, 0xa6, 0x16, + 0x20, 0x0f, 0x41, 0x01, 0x71, 0x22, 0x0a, 0x1b, 0x0b, 0x21, 0x10, 0x02, + 0x40, 0x20, 0x22, 0x42, 0x80, 0x80, 0x80, 0x80, 0x10, 0x54, 0x04, 0x40, + 0x20, 0x22, 0x21, 0x23, 0x20, 0x15, 0x21, 0x08, 0x0c, 0x01, 0x0b, 0x20, + 0x15, 0x21, 0x08, 0x03, 0x40, 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x22, 0x08, + 0x20, 0x22, 0x20, 0x22, 0x42, 0x0a, 0x80, 0x22, 0x23, 0x42, 0x0a, 0x7e, + 0x7d, 0xa7, 0x41, 0x30, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x22, 0x42, 0xff, + 0xff, 0xff, 0xff, 0x9f, 0x01, 0x56, 0x20, 0x23, 0x21, 0x22, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x23, 0xa7, 0x22, 0x05, 0x45, 0x0d, 0x00, 0x03, 0x40, + 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x22, 0x08, 0x20, 0x05, 0x20, 0x05, 0x41, + 0x0a, 0x6e, 0x22, 0x06, 0x41, 0x0a, 0x6c, 0x6b, 0x41, 0x30, 0x72, 0x3a, + 0x00, 0x00, 0x20, 0x05, 0x41, 0x09, 0x4b, 0x20, 0x06, 0x21, 0x05, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x0d, 0x41, 0x00, 0x20, 0x0b, 0x41, 0x00, 0x48, + 0x1b, 0x0d, 0x12, 0x20, 0x0f, 0x41, 0xff, 0xff, 0x7b, 0x71, 0x20, 0x0f, + 0x20, 0x0d, 0x1b, 0x21, 0x0f, 0x20, 0x09, 0x29, 0x03, 0x38, 0x21, 0x22, + 0x02, 0x40, 0x20, 0x0b, 0x0d, 0x00, 0x20, 0x22, 0x50, 0x45, 0x0d, 0x00, + 0x20, 0x15, 0x22, 0x08, 0x21, 0x05, 0x41, 0x00, 0x21, 0x0b, 0x0c, 0x12, + 0x0b, 0x20, 0x0b, 0x20, 0x22, 0x50, 0x20, 0x15, 0x20, 0x08, 0x6b, 0x6a, + 0x22, 0x06, 0x20, 0x0b, 0x20, 0x06, 0x4a, 0x1b, 0x21, 0x0b, 0x0c, 0x0a, + 0x0b, 0x20, 0x09, 0x20, 0x09, 0x29, 0x03, 0x38, 0x3c, 0x00, 0x37, 0x41, + 0x00, 0x21, 0x0a, 0x41, 0xa6, 0x16, 0x21, 0x10, 0x41, 0x01, 0x21, 0x0b, + 0x20, 0x1f, 0x21, 0x08, 0x20, 0x15, 0x21, 0x05, 0x20, 0x06, 0x21, 0x0f, + 0x0c, 0x10, 0x0b, 0x41, 0xe0, 0x1f, 0x28, 0x02, 0x00, 0x10, 0x24, 0x0c, + 0x01, 0x0b, 0x20, 0x09, 0x28, 0x02, 0x38, 0x22, 0x05, 0x41, 0xb0, 0x16, + 0x20, 0x05, 0x1b, 0x0b, 0x21, 0x08, 0x41, 0x00, 0x21, 0x0a, 0x20, 0x08, + 0x20, 0x08, 0x41, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x0b, 0x20, 0x0b, + 0x41, 0x00, 0x48, 0x1b, 0x22, 0x05, 0x10, 0x3c, 0x22, 0x07, 0x20, 0x08, + 0x6b, 0x20, 0x05, 0x20, 0x07, 0x1b, 0x22, 0x07, 0x6a, 0x21, 0x05, 0x41, + 0xa6, 0x16, 0x21, 0x10, 0x20, 0x0b, 0x41, 0x7f, 0x4c, 0x0d, 0x07, 0x20, + 0x06, 0x21, 0x0f, 0x20, 0x07, 0x21, 0x0b, 0x0c, 0x0d, 0x0b, 0x20, 0x09, + 0x28, 0x02, 0x38, 0x22, 0x08, 0x20, 0x0b, 0x0d, 0x01, 0x1a, 0x41, 0x00, + 0x21, 0x05, 0x0c, 0x02, 0x0b, 0x20, 0x09, 0x41, 0x00, 0x36, 0x02, 0x0c, + 0x20, 0x09, 0x20, 0x09, 0x29, 0x03, 0x38, 0x3e, 0x02, 0x08, 0x20, 0x09, + 0x20, 0x09, 0x41, 0x08, 0x6a, 0x36, 0x02, 0x38, 0x41, 0x7f, 0x21, 0x0b, + 0x20, 0x09, 0x41, 0x08, 0x6a, 0x0b, 0x21, 0x08, 0x41, 0x00, 0x21, 0x05, + 0x20, 0x08, 0x21, 0x06, 0x02, 0x40, 0x03, 0x40, 0x20, 0x06, 0x28, 0x02, + 0x00, 0x22, 0x07, 0x45, 0x0d, 0x01, 0x02, 0x40, 0x20, 0x09, 0x41, 0x04, + 0x6a, 0x20, 0x07, 0x10, 0x3d, 0x22, 0x07, 0x41, 0x00, 0x48, 0x22, 0x0a, + 0x0d, 0x00, 0x20, 0x07, 0x20, 0x0b, 0x20, 0x05, 0x6b, 0x4b, 0x0d, 0x00, + 0x20, 0x06, 0x41, 0x04, 0x6a, 0x21, 0x06, 0x20, 0x0b, 0x20, 0x05, 0x20, + 0x07, 0x6a, 0x22, 0x05, 0x4b, 0x0d, 0x01, 0x0c, 0x02, 0x0b, 0x0b, 0x20, + 0x0a, 0x0d, 0x0e, 0x0b, 0x20, 0x05, 0x41, 0x00, 0x48, 0x0d, 0x0b, 0x0b, + 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, 0x04, 0x71, 0x22, 0x0a, 0x0d, + 0x00, 0x20, 0x0e, 0x20, 0x05, 0x4c, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, 0x05, 0x6b, 0x22, 0x10, 0x41, 0x80, + 0x02, 0x20, 0x10, 0x41, 0x80, 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, + 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x0b, 0x41, 0x20, 0x71, 0x21, 0x06, + 0x02, 0x40, 0x20, 0x07, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, + 0x20, 0x10, 0x21, 0x07, 0x03, 0x40, 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, + 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x0b, 0x0b, 0x20, 0x0b, + 0x41, 0x20, 0x71, 0x22, 0x0c, 0x45, 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, + 0x7e, 0x6a, 0x22, 0x07, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, + 0x0c, 0x0d, 0x02, 0x20, 0x10, 0x41, 0xff, 0x01, 0x71, 0x21, 0x10, 0x0c, + 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, + 0x20, 0x10, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x05, + 0x45, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x06, 0x03, 0x40, 0x20, 0x08, 0x28, + 0x02, 0x00, 0x22, 0x07, 0x45, 0x0d, 0x01, 0x20, 0x09, 0x41, 0x04, 0x6a, + 0x20, 0x07, 0x10, 0x3d, 0x22, 0x07, 0x20, 0x06, 0x6a, 0x22, 0x06, 0x20, + 0x05, 0x4b, 0x0d, 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, + 0x45, 0x04, 0x40, 0x20, 0x09, 0x41, 0x04, 0x6a, 0x20, 0x07, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x08, 0x41, 0x04, 0x6a, 0x21, 0x08, 0x20, + 0x06, 0x20, 0x05, 0x49, 0x0d, 0x00, 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x0a, + 0x41, 0x80, 0xc0, 0x00, 0x47, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x05, 0x4c, + 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, + 0x05, 0x6b, 0x22, 0x0c, 0x41, 0x80, 0x02, 0x20, 0x0c, 0x41, 0x80, 0x02, + 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, + 0x08, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x07, 0x45, 0x04, + 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, 0x20, 0x0c, 0x21, 0x07, 0x03, 0x40, + 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, + 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, + 0x00, 0x21, 0x08, 0x0b, 0x20, 0x08, 0x41, 0x20, 0x71, 0x22, 0x0a, 0x45, + 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, 0x41, 0xff, + 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0a, 0x0d, 0x02, 0x20, 0x0c, 0x41, + 0xff, 0x01, 0x71, 0x21, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, + 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0c, 0x20, 0x00, 0x10, 0x33, + 0x1a, 0x0b, 0x20, 0x0e, 0x20, 0x05, 0x20, 0x0e, 0x20, 0x05, 0x4a, 0x1b, + 0x21, 0x05, 0x0c, 0x0b, 0x0b, 0x20, 0x0b, 0x41, 0x7f, 0x4c, 0x41, 0x00, + 0x20, 0x0d, 0x1b, 0x0d, 0x09, 0x20, 0x09, 0x2b, 0x03, 0x38, 0x21, 0x24, + 0x20, 0x09, 0x41, 0x00, 0x36, 0x02, 0xec, 0x02, 0x02, 0x7f, 0x20, 0x24, + 0xbd, 0x42, 0x7f, 0x57, 0x04, 0x40, 0x20, 0x24, 0x9a, 0x21, 0x24, 0x41, + 0x01, 0x21, 0x14, 0x41, 0xb0, 0x1b, 0x0c, 0x01, 0x0b, 0x20, 0x0f, 0x41, + 0x80, 0x10, 0x71, 0x04, 0x40, 0x41, 0x01, 0x21, 0x14, 0x41, 0xb3, 0x1b, + 0x0c, 0x01, 0x0b, 0x41, 0xb6, 0x1b, 0x41, 0xb1, 0x1b, 0x20, 0x0f, 0x41, + 0x01, 0x71, 0x22, 0x14, 0x1b, 0x0b, 0x21, 0x18, 0x02, 0x40, 0x20, 0x24, + 0x99, 0x22, 0x25, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, + 0x62, 0x20, 0x25, 0x20, 0x25, 0x61, 0x71, 0x45, 0x04, 0x40, 0x20, 0x14, + 0x41, 0x03, 0x6a, 0x21, 0x08, 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, + 0x00, 0x71, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x08, 0x4c, 0x0d, 0x00, 0x20, + 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, 0x08, 0x6b, 0x22, + 0x0c, 0x41, 0x80, 0x02, 0x20, 0x0c, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, + 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, + 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, + 0x45, 0x21, 0x05, 0x20, 0x0c, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, + 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, + 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, + 0x0b, 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, 0x0a, 0x45, 0x21, 0x05, 0x20, + 0x06, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, + 0x00, 0x0b, 0x20, 0x0a, 0x0d, 0x02, 0x20, 0x0c, 0x41, 0xff, 0x01, 0x71, + 0x21, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, + 0x41, 0x40, 0x6b, 0x20, 0x0c, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, + 0x00, 0x28, 0x02, 0x00, 0x22, 0x06, 0x41, 0x20, 0x71, 0x04, 0x7f, 0x20, + 0x06, 0x05, 0x20, 0x18, 0x20, 0x14, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, + 0x00, 0x28, 0x02, 0x00, 0x0b, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x41, + 0xcb, 0x1b, 0x41, 0xcf, 0x1b, 0x20, 0x11, 0x41, 0x20, 0x71, 0x41, 0x05, + 0x76, 0x22, 0x06, 0x1b, 0x41, 0xc3, 0x1b, 0x41, 0xc7, 0x1b, 0x20, 0x06, + 0x1b, 0x20, 0x24, 0x20, 0x24, 0x62, 0x1b, 0x41, 0x03, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, 0x04, 0x71, + 0x41, 0x80, 0xc0, 0x00, 0x47, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x08, 0x4c, + 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, + 0x08, 0x6b, 0x22, 0x0c, 0x41, 0x80, 0x02, 0x20, 0x0c, 0x41, 0x80, 0x02, + 0x49, 0x22, 0x05, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, + 0x07, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, + 0x40, 0x20, 0x06, 0x45, 0x21, 0x05, 0x20, 0x0c, 0x21, 0x06, 0x03, 0x40, + 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, + 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, + 0x00, 0x21, 0x07, 0x0b, 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, 0x0a, 0x45, + 0x21, 0x05, 0x20, 0x06, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, + 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0a, 0x0d, 0x02, 0x20, 0x0c, 0x41, + 0xff, 0x01, 0x71, 0x21, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, + 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0c, 0x20, 0x00, 0x10, 0x33, + 0x1a, 0x0b, 0x20, 0x0e, 0x20, 0x08, 0x20, 0x0e, 0x20, 0x08, 0x4a, 0x1b, + 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x20, 0x24, 0x20, 0x09, 0x41, 0xec, 0x02, + 0x6a, 0x10, 0x3f, 0x22, 0x24, 0x20, 0x24, 0xa0, 0x22, 0x24, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x04, 0x40, 0x20, 0x09, + 0x20, 0x09, 0x28, 0x02, 0xec, 0x02, 0x41, 0x7f, 0x6a, 0x36, 0x02, 0xec, + 0x02, 0x0b, 0x20, 0x11, 0x41, 0x20, 0x72, 0x22, 0x0c, 0x41, 0xe1, 0x00, + 0x46, 0x04, 0x40, 0x20, 0x18, 0x41, 0x09, 0x6a, 0x20, 0x18, 0x20, 0x11, + 0x41, 0x20, 0x71, 0x22, 0x0a, 0x1b, 0x21, 0x0c, 0x02, 0x40, 0x20, 0x0b, + 0x41, 0x0b, 0x4b, 0x0d, 0x00, 0x41, 0x0c, 0x20, 0x0b, 0x6b, 0x45, 0x0d, + 0x00, 0x20, 0x0b, 0x41, 0x74, 0x6a, 0x21, 0x05, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x40, 0x21, 0x25, 0x03, 0x40, 0x20, 0x25, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0xa2, 0x21, 0x25, 0x20, + 0x05, 0x41, 0x01, 0x6a, 0x22, 0x06, 0x20, 0x05, 0x4f, 0x20, 0x06, 0x21, + 0x05, 0x0d, 0x00, 0x0b, 0x20, 0x0c, 0x2d, 0x00, 0x00, 0x41, 0x2d, 0x46, + 0x04, 0x40, 0x20, 0x25, 0x20, 0x24, 0x9a, 0x20, 0x25, 0xa1, 0xa0, 0x9a, + 0x21, 0x24, 0x0c, 0x01, 0x0b, 0x20, 0x24, 0x20, 0x25, 0xa0, 0x20, 0x25, + 0xa1, 0x21, 0x24, 0x0b, 0x20, 0x19, 0x21, 0x07, 0x02, 0x40, 0x20, 0x09, + 0x28, 0x02, 0xec, 0x02, 0x22, 0x08, 0x20, 0x08, 0x41, 0x1f, 0x75, 0x22, + 0x06, 0x6a, 0x20, 0x06, 0x73, 0x22, 0x05, 0x04, 0x40, 0x41, 0x00, 0x21, + 0x06, 0x03, 0x40, 0x20, 0x06, 0x20, 0x09, 0x6a, 0x41, 0xcf, 0x02, 0x6a, + 0x20, 0x05, 0x20, 0x05, 0x41, 0x0a, 0x6e, 0x22, 0x07, 0x41, 0x0a, 0x6c, + 0x6b, 0x41, 0x30, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x06, 0x41, 0x7f, 0x6a, + 0x21, 0x06, 0x20, 0x05, 0x41, 0x09, 0x4b, 0x20, 0x07, 0x21, 0x05, 0x0d, + 0x00, 0x0b, 0x20, 0x06, 0x20, 0x09, 0x6a, 0x41, 0xd0, 0x02, 0x6a, 0x21, + 0x07, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x07, 0x41, 0x7f, 0x6a, 0x22, + 0x07, 0x41, 0x30, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x14, 0x41, 0x02, 0x72, + 0x21, 0x0d, 0x20, 0x07, 0x41, 0x7e, 0x6a, 0x22, 0x12, 0x20, 0x11, 0x41, + 0x0f, 0x6a, 0x3a, 0x00, 0x00, 0x20, 0x07, 0x41, 0x7f, 0x6a, 0x41, 0x2d, + 0x41, 0x2b, 0x20, 0x08, 0x41, 0x00, 0x48, 0x1b, 0x3a, 0x00, 0x00, 0x20, + 0x0f, 0x41, 0x08, 0x71, 0x21, 0x07, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, + 0x21, 0x06, 0x03, 0x40, 0x20, 0x06, 0x22, 0x05, 0x02, 0x7f, 0x20, 0x24, + 0x99, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x41, 0x63, 0x04, + 0x40, 0x20, 0x24, 0xaa, 0x0c, 0x01, 0x0b, 0x41, 0x80, 0x80, 0x80, 0x80, + 0x78, 0x0b, 0x22, 0x06, 0x41, 0xa0, 0x1b, 0x6a, 0x2d, 0x00, 0x00, 0x20, + 0x0a, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x24, 0x20, 0x06, 0xb7, 0xa1, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0xa2, 0x21, 0x24, 0x02, + 0x40, 0x20, 0x05, 0x41, 0x01, 0x6a, 0x22, 0x06, 0x20, 0x09, 0x41, 0xd0, + 0x02, 0x6a, 0x6b, 0x41, 0x01, 0x47, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x07, + 0x0d, 0x00, 0x20, 0x0b, 0x41, 0x00, 0x4a, 0x0d, 0x00, 0x20, 0x24, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x0d, 0x01, 0x0b, + 0x20, 0x05, 0x41, 0x2e, 0x3a, 0x00, 0x01, 0x20, 0x05, 0x41, 0x02, 0x6a, + 0x21, 0x06, 0x0b, 0x20, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x62, 0x0d, 0x00, 0x0b, 0x41, 0x7f, 0x21, 0x05, 0x41, 0xfd, + 0xff, 0xff, 0xff, 0x07, 0x20, 0x0d, 0x20, 0x19, 0x20, 0x12, 0x6b, 0x22, + 0x11, 0x6a, 0x22, 0x07, 0x6b, 0x20, 0x0b, 0x48, 0x0d, 0x01, 0x20, 0x07, + 0x20, 0x0b, 0x41, 0x02, 0x6a, 0x20, 0x06, 0x20, 0x09, 0x41, 0xd0, 0x02, + 0x6a, 0x6b, 0x22, 0x0a, 0x20, 0x06, 0x20, 0x20, 0x6a, 0x20, 0x0b, 0x48, + 0x1b, 0x20, 0x0a, 0x20, 0x0b, 0x1b, 0x22, 0x14, 0x6a, 0x21, 0x08, 0x02, + 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, 0x04, 0x71, 0x22, 0x0b, 0x0d, 0x00, + 0x20, 0x0e, 0x20, 0x08, 0x4c, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, + 0x41, 0x20, 0x20, 0x0e, 0x20, 0x08, 0x6b, 0x22, 0x0f, 0x41, 0x80, 0x02, + 0x20, 0x0f, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, 0x1b, 0x10, 0x3a, 0x20, + 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, + 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x05, 0x20, + 0x0f, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, + 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, + 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, 0x0b, 0x20, 0x07, 0x41, + 0x20, 0x71, 0x22, 0x10, 0x45, 0x21, 0x05, 0x20, 0x06, 0x41, 0x80, 0x7e, + 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x10, + 0x0d, 0x02, 0x20, 0x0f, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0f, 0x0c, 0x01, + 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, + 0x0f, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, + 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x0c, 0x20, 0x0d, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x0b, 0x41, 0x80, 0x80, 0x04, + 0x47, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x08, 0x4c, 0x0d, 0x00, 0x20, 0x09, + 0x41, 0x40, 0x6b, 0x41, 0x30, 0x20, 0x0e, 0x20, 0x08, 0x6b, 0x22, 0x10, + 0x41, 0x80, 0x02, 0x20, 0x10, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, 0x1b, + 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, 0x71, + 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, + 0x21, 0x05, 0x20, 0x10, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, + 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, + 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, 0x0b, + 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, 0x0c, 0x45, 0x21, 0x05, 0x20, 0x06, + 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, + 0x0b, 0x20, 0x0c, 0x0d, 0x02, 0x20, 0x10, 0x41, 0xff, 0x01, 0x71, 0x21, + 0x10, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x20, 0x10, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x00, + 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x09, 0x41, + 0xd0, 0x02, 0x6a, 0x20, 0x0a, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x02, + 0x40, 0x20, 0x14, 0x20, 0x0a, 0x6b, 0x22, 0x0c, 0x41, 0x01, 0x48, 0x0d, + 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x30, 0x20, 0x0c, 0x41, 0x80, + 0x02, 0x20, 0x0c, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, 0x1b, 0x10, 0x3a, + 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, 0x71, 0x21, 0x06, + 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x05, + 0x20, 0x0c, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, + 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, 0x0b, 0x20, 0x07, + 0x41, 0x20, 0x71, 0x22, 0x0a, 0x45, 0x21, 0x05, 0x20, 0x06, 0x41, 0x80, + 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, + 0x0a, 0x0d, 0x02, 0x20, 0x0c, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0c, 0x0c, + 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, + 0x20, 0x0c, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x00, 0x2d, 0x00, + 0x00, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x12, 0x20, 0x11, 0x20, + 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x0b, 0x41, 0x80, 0xc0, + 0x00, 0x47, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x08, 0x4c, 0x0d, 0x00, 0x20, + 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, 0x08, 0x6b, 0x22, + 0x0c, 0x41, 0x80, 0x02, 0x20, 0x0c, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, + 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, + 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, + 0x45, 0x21, 0x05, 0x20, 0x0c, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, + 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, + 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, + 0x0b, 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, 0x0a, 0x45, 0x21, 0x05, 0x20, + 0x06, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, + 0x00, 0x0b, 0x20, 0x0a, 0x0d, 0x02, 0x20, 0x0c, 0x41, 0xff, 0x01, 0x71, + 0x21, 0x0c, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, + 0x41, 0x40, 0x6b, 0x20, 0x0c, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, + 0x0e, 0x20, 0x08, 0x20, 0x0e, 0x20, 0x08, 0x4a, 0x1b, 0x21, 0x05, 0x0c, + 0x01, 0x0b, 0x20, 0x0b, 0x41, 0x00, 0x48, 0x21, 0x06, 0x02, 0x40, 0x20, + 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x04, + 0x40, 0x20, 0x09, 0x28, 0x02, 0xec, 0x02, 0x21, 0x08, 0x0c, 0x01, 0x0b, + 0x20, 0x09, 0x20, 0x09, 0x28, 0x02, 0xec, 0x02, 0x41, 0x64, 0x6a, 0x22, + 0x08, 0x36, 0x02, 0xec, 0x02, 0x20, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0x41, 0xa2, 0x21, 0x24, 0x0b, 0x41, 0x06, 0x20, 0x0b, + 0x20, 0x06, 0x1b, 0x21, 0x0d, 0x20, 0x09, 0x41, 0xf0, 0x02, 0x6a, 0x20, + 0x21, 0x20, 0x08, 0x41, 0x00, 0x48, 0x1b, 0x22, 0x12, 0x21, 0x07, 0x03, + 0x40, 0x20, 0x07, 0x02, 0x7f, 0x20, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x41, 0x63, 0x20, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x71, 0x04, 0x40, 0x20, 0x24, 0xab, 0x0c, + 0x01, 0x0b, 0x41, 0x00, 0x0b, 0x22, 0x06, 0x36, 0x02, 0x00, 0x20, 0x07, + 0x41, 0x04, 0x6a, 0x21, 0x07, 0x20, 0x24, 0x20, 0x06, 0xb8, 0xa1, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x65, 0xcd, 0xcd, 0x41, 0xa2, 0x22, 0x24, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x0d, 0x00, 0x0b, + 0x02, 0x40, 0x20, 0x08, 0x41, 0x01, 0x48, 0x04, 0x40, 0x20, 0x07, 0x21, + 0x05, 0x20, 0x12, 0x21, 0x06, 0x0c, 0x01, 0x0b, 0x20, 0x12, 0x21, 0x06, + 0x03, 0x40, 0x20, 0x08, 0x41, 0x1d, 0x20, 0x08, 0x41, 0x1d, 0x48, 0x1b, + 0x21, 0x08, 0x02, 0x40, 0x20, 0x07, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x20, + 0x06, 0x49, 0x0d, 0x00, 0x20, 0x08, 0xad, 0x21, 0x23, 0x42, 0x00, 0x21, + 0x22, 0x03, 0x40, 0x20, 0x05, 0x20, 0x22, 0x42, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x83, 0x20, 0x05, 0x35, 0x02, 0x00, 0x20, 0x23, 0x86, 0x7c, 0x22, + 0x22, 0x20, 0x22, 0x42, 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x80, 0x22, 0x22, + 0x42, 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x7e, 0x7d, 0x3e, 0x02, 0x00, 0x20, + 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x20, 0x06, 0x4f, 0x0d, 0x00, 0x0b, + 0x20, 0x22, 0xa7, 0x22, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x06, 0x41, 0x7c, + 0x6a, 0x22, 0x06, 0x20, 0x05, 0x36, 0x02, 0x00, 0x0b, 0x03, 0x40, 0x20, + 0x07, 0x22, 0x05, 0x20, 0x06, 0x4b, 0x04, 0x40, 0x20, 0x05, 0x41, 0x7c, + 0x6a, 0x22, 0x07, 0x28, 0x02, 0x00, 0x45, 0x0d, 0x01, 0x0b, 0x0b, 0x20, + 0x09, 0x20, 0x09, 0x28, 0x02, 0xec, 0x02, 0x20, 0x08, 0x6b, 0x22, 0x08, + 0x36, 0x02, 0xec, 0x02, 0x20, 0x05, 0x21, 0x07, 0x20, 0x08, 0x41, 0x00, + 0x4a, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x08, 0x41, 0x7f, 0x4c, 0x04, 0x40, + 0x20, 0x0d, 0x41, 0x19, 0x6a, 0x41, 0x09, 0x6e, 0x41, 0x01, 0x6a, 0x21, + 0x0b, 0x03, 0x40, 0x41, 0x00, 0x20, 0x08, 0x6b, 0x22, 0x07, 0x41, 0x09, + 0x20, 0x07, 0x41, 0x09, 0x48, 0x1b, 0x21, 0x0a, 0x02, 0x40, 0x20, 0x06, + 0x20, 0x05, 0x4f, 0x04, 0x40, 0x20, 0x06, 0x20, 0x06, 0x41, 0x04, 0x6a, + 0x20, 0x06, 0x28, 0x02, 0x00, 0x1b, 0x21, 0x06, 0x0c, 0x01, 0x0b, 0x41, + 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x20, 0x0a, 0x76, 0x21, 0x10, 0x41, 0x7f, + 0x20, 0x0a, 0x74, 0x41, 0x7f, 0x73, 0x21, 0x16, 0x41, 0x00, 0x21, 0x08, + 0x20, 0x06, 0x21, 0x07, 0x03, 0x40, 0x20, 0x07, 0x20, 0x08, 0x20, 0x07, + 0x28, 0x02, 0x00, 0x22, 0x17, 0x20, 0x0a, 0x76, 0x6a, 0x36, 0x02, 0x00, + 0x20, 0x16, 0x20, 0x17, 0x71, 0x20, 0x10, 0x6c, 0x21, 0x08, 0x20, 0x07, + 0x41, 0x04, 0x6a, 0x22, 0x07, 0x20, 0x05, 0x49, 0x0d, 0x00, 0x0b, 0x20, + 0x06, 0x20, 0x06, 0x41, 0x04, 0x6a, 0x20, 0x06, 0x28, 0x02, 0x00, 0x1b, + 0x21, 0x06, 0x20, 0x08, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x08, 0x36, + 0x02, 0x00, 0x20, 0x05, 0x41, 0x04, 0x6a, 0x21, 0x05, 0x0b, 0x20, 0x09, + 0x20, 0x09, 0x28, 0x02, 0xec, 0x02, 0x20, 0x0a, 0x6a, 0x22, 0x08, 0x36, + 0x02, 0xec, 0x02, 0x20, 0x12, 0x20, 0x06, 0x20, 0x0c, 0x41, 0xe6, 0x00, + 0x46, 0x1b, 0x22, 0x07, 0x20, 0x0b, 0x41, 0x02, 0x74, 0x6a, 0x20, 0x05, + 0x20, 0x05, 0x20, 0x07, 0x6b, 0x41, 0x02, 0x75, 0x20, 0x0b, 0x4a, 0x1b, + 0x21, 0x05, 0x20, 0x08, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x0b, 0x0b, 0x41, + 0x00, 0x21, 0x07, 0x02, 0x40, 0x20, 0x06, 0x20, 0x05, 0x4f, 0x0d, 0x00, + 0x20, 0x12, 0x20, 0x06, 0x6b, 0x41, 0x02, 0x75, 0x41, 0x09, 0x6c, 0x21, + 0x07, 0x20, 0x06, 0x28, 0x02, 0x00, 0x22, 0x0a, 0x41, 0x0a, 0x49, 0x0d, + 0x00, 0x41, 0x0a, 0x21, 0x08, 0x03, 0x40, 0x20, 0x07, 0x41, 0x01, 0x6a, + 0x21, 0x07, 0x20, 0x0a, 0x20, 0x08, 0x41, 0x0a, 0x6c, 0x22, 0x08, 0x4f, + 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x0d, 0x41, 0x00, 0x20, 0x07, 0x20, 0x0c, + 0x41, 0xe6, 0x00, 0x46, 0x1b, 0x22, 0x0a, 0x6b, 0x20, 0x0c, 0x41, 0xe7, + 0x00, 0x46, 0x22, 0x10, 0x20, 0x0d, 0x41, 0x00, 0x47, 0x71, 0x22, 0x0b, + 0x6b, 0x22, 0x08, 0x20, 0x05, 0x20, 0x12, 0x6b, 0x41, 0x02, 0x75, 0x41, + 0x09, 0x6c, 0x41, 0x77, 0x6a, 0x48, 0x04, 0x40, 0x20, 0x08, 0x41, 0x80, + 0xc8, 0x00, 0x6a, 0x22, 0x16, 0x41, 0x09, 0x6d, 0x22, 0x17, 0x41, 0x02, + 0x74, 0x20, 0x12, 0x6a, 0x22, 0x1d, 0x41, 0x84, 0x60, 0x6a, 0x21, 0x0c, + 0x41, 0x0a, 0x21, 0x08, 0x20, 0x16, 0x20, 0x17, 0x41, 0x09, 0x6c, 0x22, + 0x16, 0x6b, 0x41, 0x01, 0x6a, 0x41, 0x08, 0x4c, 0x04, 0x40, 0x20, 0x0a, + 0x20, 0x16, 0x6a, 0x20, 0x0b, 0x6a, 0x20, 0x0d, 0x6b, 0x41, 0x88, 0xb8, + 0x7f, 0x6a, 0x21, 0x0b, 0x03, 0x40, 0x20, 0x08, 0x41, 0x0a, 0x6c, 0x21, + 0x08, 0x20, 0x0b, 0x41, 0x7f, 0x6a, 0x22, 0x0b, 0x0d, 0x00, 0x0b, 0x0b, + 0x02, 0x40, 0x41, 0x00, 0x20, 0x05, 0x20, 0x0c, 0x41, 0x04, 0x6a, 0x22, + 0x16, 0x46, 0x20, 0x0c, 0x28, 0x02, 0x00, 0x22, 0x0b, 0x20, 0x0b, 0x20, + 0x08, 0x6e, 0x22, 0x17, 0x20, 0x08, 0x6c, 0x6b, 0x22, 0x0a, 0x1b, 0x0d, + 0x00, 0x02, 0x40, 0x20, 0x17, 0x41, 0x01, 0x71, 0x45, 0x04, 0x40, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x21, 0x24, 0x20, 0x0c, + 0x20, 0x06, 0x4d, 0x0d, 0x01, 0x20, 0x08, 0x41, 0x80, 0x94, 0xeb, 0xdc, + 0x03, 0x47, 0x0d, 0x01, 0x20, 0x0c, 0x41, 0x7c, 0x6a, 0x2d, 0x00, 0x00, + 0x41, 0x01, 0x71, 0x45, 0x0d, 0x01, 0x0b, 0x44, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x43, 0x21, 0x24, 0x0b, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x3f, 0x21, 0x25, 0x20, 0x0a, 0x20, 0x08, 0x41, 0x01, + 0x76, 0x22, 0x17, 0x4f, 0x04, 0x40, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0x3f, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x3f, + 0x20, 0x0a, 0x20, 0x17, 0x46, 0x1b, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0x3f, 0x20, 0x05, 0x20, 0x16, 0x46, 0x1b, 0x21, 0x25, 0x0b, + 0x02, 0x40, 0x20, 0x14, 0x45, 0x0d, 0x00, 0x20, 0x18, 0x2d, 0x00, 0x00, + 0x41, 0x2d, 0x47, 0x0d, 0x00, 0x20, 0x25, 0x9a, 0x21, 0x25, 0x20, 0x24, + 0x9a, 0x21, 0x24, 0x0b, 0x20, 0x0c, 0x20, 0x0b, 0x20, 0x0a, 0x6b, 0x22, + 0x0a, 0x36, 0x02, 0x00, 0x20, 0x24, 0x20, 0x25, 0xa0, 0x20, 0x24, 0x61, + 0x0d, 0x00, 0x20, 0x0c, 0x20, 0x08, 0x20, 0x0a, 0x6a, 0x22, 0x07, 0x36, + 0x02, 0x00, 0x20, 0x07, 0x41, 0x80, 0x94, 0xeb, 0xdc, 0x03, 0x4f, 0x04, + 0x40, 0x20, 0x1d, 0x41, 0x80, 0x60, 0x6a, 0x21, 0x07, 0x03, 0x40, 0x20, + 0x07, 0x41, 0x04, 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x07, 0x20, + 0x06, 0x49, 0x04, 0x40, 0x20, 0x06, 0x41, 0x7c, 0x6a, 0x22, 0x06, 0x41, + 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x07, 0x20, 0x07, 0x28, 0x02, 0x00, + 0x41, 0x01, 0x6a, 0x22, 0x08, 0x36, 0x02, 0x00, 0x20, 0x07, 0x41, 0x7c, + 0x6a, 0x21, 0x07, 0x20, 0x08, 0x41, 0xff, 0x93, 0xeb, 0xdc, 0x03, 0x4b, + 0x0d, 0x00, 0x0b, 0x20, 0x07, 0x41, 0x04, 0x6a, 0x21, 0x0c, 0x0b, 0x20, + 0x12, 0x20, 0x06, 0x6b, 0x41, 0x02, 0x75, 0x41, 0x09, 0x6c, 0x21, 0x07, + 0x20, 0x06, 0x28, 0x02, 0x00, 0x22, 0x0a, 0x41, 0x0a, 0x49, 0x0d, 0x00, + 0x41, 0x0a, 0x21, 0x08, 0x03, 0x40, 0x20, 0x07, 0x41, 0x01, 0x6a, 0x21, + 0x07, 0x20, 0x0a, 0x20, 0x08, 0x41, 0x0a, 0x6c, 0x22, 0x08, 0x4f, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x0c, 0x41, 0x04, 0x6a, 0x22, 0x08, 0x20, 0x05, + 0x20, 0x05, 0x20, 0x08, 0x4b, 0x1b, 0x21, 0x05, 0x0b, 0x02, 0x7f, 0x03, + 0x40, 0x41, 0x00, 0x20, 0x05, 0x22, 0x0b, 0x20, 0x06, 0x4d, 0x0d, 0x01, + 0x1a, 0x20, 0x0b, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x28, 0x02, 0x00, 0x45, + 0x0d, 0x00, 0x0b, 0x41, 0x01, 0x0b, 0x21, 0x16, 0x02, 0x40, 0x20, 0x10, + 0x45, 0x04, 0x40, 0x20, 0x0f, 0x41, 0x08, 0x71, 0x21, 0x10, 0x0c, 0x01, + 0x0b, 0x20, 0x07, 0x41, 0x7f, 0x73, 0x41, 0x7f, 0x20, 0x0d, 0x41, 0x01, + 0x20, 0x0d, 0x1b, 0x22, 0x05, 0x20, 0x07, 0x4a, 0x20, 0x07, 0x41, 0x7b, + 0x4a, 0x71, 0x22, 0x08, 0x1b, 0x20, 0x05, 0x6a, 0x21, 0x0d, 0x41, 0x7f, + 0x41, 0x7e, 0x20, 0x08, 0x1b, 0x20, 0x11, 0x6a, 0x21, 0x11, 0x20, 0x0f, + 0x41, 0x08, 0x71, 0x22, 0x10, 0x0d, 0x00, 0x41, 0x09, 0x21, 0x05, 0x02, + 0x40, 0x20, 0x16, 0x45, 0x0d, 0x00, 0x20, 0x0b, 0x41, 0x7c, 0x6a, 0x28, + 0x02, 0x00, 0x22, 0x0a, 0x45, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x05, 0x20, + 0x0a, 0x41, 0x0a, 0x70, 0x0d, 0x00, 0x41, 0x0a, 0x21, 0x08, 0x03, 0x40, + 0x20, 0x05, 0x41, 0x01, 0x6a, 0x21, 0x05, 0x20, 0x0a, 0x20, 0x08, 0x41, + 0x0a, 0x6c, 0x22, 0x08, 0x70, 0x45, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x0b, + 0x20, 0x12, 0x6b, 0x41, 0x02, 0x75, 0x41, 0x09, 0x6c, 0x41, 0x77, 0x6a, + 0x21, 0x08, 0x20, 0x11, 0x41, 0x20, 0x72, 0x41, 0xe6, 0x00, 0x46, 0x04, + 0x40, 0x41, 0x00, 0x21, 0x10, 0x20, 0x0d, 0x20, 0x08, 0x20, 0x05, 0x6b, + 0x22, 0x05, 0x41, 0x00, 0x20, 0x05, 0x41, 0x00, 0x4a, 0x1b, 0x22, 0x05, + 0x20, 0x0d, 0x20, 0x05, 0x48, 0x1b, 0x21, 0x0d, 0x0c, 0x01, 0x0b, 0x41, + 0x00, 0x21, 0x10, 0x20, 0x0d, 0x20, 0x07, 0x20, 0x08, 0x6a, 0x20, 0x05, + 0x6b, 0x22, 0x05, 0x41, 0x00, 0x20, 0x05, 0x41, 0x00, 0x4a, 0x1b, 0x22, + 0x05, 0x20, 0x0d, 0x20, 0x05, 0x48, 0x1b, 0x21, 0x0d, 0x0b, 0x41, 0x7f, + 0x21, 0x05, 0x20, 0x0d, 0x41, 0xfd, 0xff, 0xff, 0xff, 0x07, 0x41, 0xfe, + 0xff, 0xff, 0xff, 0x07, 0x20, 0x0d, 0x20, 0x10, 0x72, 0x22, 0x17, 0x1b, + 0x4a, 0x0d, 0x00, 0x20, 0x0d, 0x20, 0x17, 0x41, 0x00, 0x47, 0x6a, 0x41, + 0x01, 0x6a, 0x21, 0x0c, 0x02, 0x40, 0x20, 0x11, 0x41, 0x20, 0x72, 0x41, + 0xe6, 0x00, 0x47, 0x22, 0x1d, 0x45, 0x04, 0x40, 0x20, 0x07, 0x41, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x20, 0x0c, 0x6b, 0x4a, 0x0d, 0x02, 0x20, 0x07, + 0x41, 0x00, 0x20, 0x07, 0x41, 0x00, 0x4a, 0x1b, 0x21, 0x07, 0x0c, 0x01, + 0x0b, 0x20, 0x19, 0x21, 0x08, 0x20, 0x07, 0x20, 0x07, 0x41, 0x1f, 0x75, + 0x22, 0x05, 0x6a, 0x20, 0x05, 0x73, 0x22, 0x05, 0x04, 0x40, 0x03, 0x40, + 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x22, 0x08, 0x20, 0x05, 0x20, 0x05, 0x41, + 0x0a, 0x6e, 0x22, 0x0a, 0x41, 0x0a, 0x6c, 0x6b, 0x41, 0x30, 0x72, 0x3a, + 0x00, 0x00, 0x20, 0x05, 0x41, 0x09, 0x4b, 0x20, 0x0a, 0x21, 0x05, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x19, 0x20, 0x08, 0x6b, 0x41, 0x01, 0x4c, 0x04, + 0x40, 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, + 0x41, 0x30, 0x3a, 0x00, 0x00, 0x20, 0x19, 0x20, 0x05, 0x6b, 0x20, 0x05, + 0x41, 0x7f, 0x6a, 0x22, 0x0a, 0x21, 0x05, 0x41, 0x02, 0x48, 0x0d, 0x00, + 0x0b, 0x20, 0x0a, 0x41, 0x01, 0x6a, 0x21, 0x08, 0x0b, 0x20, 0x08, 0x41, + 0x7e, 0x6a, 0x22, 0x1c, 0x20, 0x11, 0x3a, 0x00, 0x00, 0x41, 0x7f, 0x21, + 0x05, 0x20, 0x08, 0x41, 0x7f, 0x6a, 0x41, 0x2d, 0x41, 0x2b, 0x20, 0x07, + 0x41, 0x00, 0x48, 0x1b, 0x3a, 0x00, 0x00, 0x20, 0x19, 0x20, 0x1c, 0x6b, + 0x22, 0x07, 0x41, 0xff, 0xff, 0xff, 0xff, 0x07, 0x20, 0x0c, 0x6b, 0x4a, + 0x0d, 0x01, 0x0b, 0x20, 0x07, 0x20, 0x0c, 0x6a, 0x22, 0x07, 0x20, 0x14, + 0x41, 0xff, 0xff, 0xff, 0xff, 0x07, 0x73, 0x4a, 0x0d, 0x00, 0x20, 0x07, + 0x20, 0x14, 0x6a, 0x21, 0x11, 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, + 0x04, 0x71, 0x22, 0x0f, 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x11, 0x4c, 0x0d, + 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, 0x11, + 0x6b, 0x22, 0x0a, 0x41, 0x80, 0x02, 0x20, 0x0a, 0x41, 0x80, 0x02, 0x49, + 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x08, + 0x41, 0x20, 0x71, 0x21, 0x05, 0x02, 0x40, 0x20, 0x07, 0x45, 0x04, 0x40, + 0x20, 0x05, 0x45, 0x21, 0x05, 0x20, 0x0a, 0x21, 0x07, 0x03, 0x40, 0x20, + 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, + 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x21, 0x08, 0x0b, 0x20, 0x08, 0x41, 0x20, 0x71, 0x22, 0x0c, 0x45, 0x21, + 0x05, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, 0x41, 0xff, 0x01, + 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0c, 0x0d, 0x02, 0x20, 0x0a, 0x41, 0xff, + 0x01, 0x71, 0x21, 0x0a, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x0d, 0x01, 0x0b, + 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0a, 0x20, 0x00, 0x10, 0x33, 0x1a, + 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, + 0x20, 0x18, 0x20, 0x14, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, + 0x20, 0x0f, 0x41, 0x80, 0x80, 0x04, 0x47, 0x0d, 0x00, 0x20, 0x0e, 0x20, + 0x11, 0x4c, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x30, 0x20, + 0x0e, 0x20, 0x11, 0x6b, 0x22, 0x0a, 0x41, 0x80, 0x02, 0x20, 0x0a, 0x41, + 0x80, 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, + 0x00, 0x22, 0x08, 0x41, 0x20, 0x71, 0x21, 0x05, 0x02, 0x40, 0x20, 0x07, + 0x45, 0x04, 0x40, 0x20, 0x05, 0x45, 0x21, 0x05, 0x20, 0x0a, 0x21, 0x07, + 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, + 0x28, 0x02, 0x00, 0x21, 0x08, 0x0b, 0x20, 0x08, 0x41, 0x20, 0x71, 0x22, + 0x0c, 0x45, 0x21, 0x05, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, + 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0c, 0x0d, 0x02, 0x20, + 0x0a, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0a, 0x0c, 0x01, 0x0b, 0x20, 0x05, + 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0a, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x1d, 0x45, 0x04, 0x40, 0x20, + 0x12, 0x20, 0x06, 0x20, 0x06, 0x20, 0x12, 0x4b, 0x1b, 0x22, 0x08, 0x21, + 0x0c, 0x03, 0x40, 0x02, 0x40, 0x20, 0x0c, 0x28, 0x02, 0x00, 0x22, 0x05, + 0x45, 0x04, 0x40, 0x41, 0x00, 0x21, 0x06, 0x0c, 0x01, 0x0b, 0x41, 0x00, + 0x21, 0x06, 0x03, 0x40, 0x20, 0x06, 0x20, 0x1e, 0x6a, 0x20, 0x05, 0x20, + 0x05, 0x41, 0x0a, 0x6e, 0x22, 0x07, 0x41, 0x0a, 0x6c, 0x6b, 0x41, 0x30, + 0x72, 0x3a, 0x00, 0x00, 0x20, 0x06, 0x41, 0x7f, 0x6a, 0x21, 0x06, 0x20, + 0x05, 0x41, 0x09, 0x4b, 0x20, 0x07, 0x21, 0x05, 0x0d, 0x00, 0x0b, 0x0b, + 0x20, 0x06, 0x20, 0x1b, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x08, 0x20, + 0x0c, 0x47, 0x04, 0x40, 0x20, 0x05, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, + 0x4d, 0x0d, 0x01, 0x03, 0x40, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x22, 0x05, + 0x41, 0x30, 0x3a, 0x00, 0x00, 0x20, 0x05, 0x20, 0x09, 0x41, 0xd0, 0x02, + 0x6a, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, 0x21, + 0x05, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x7f, + 0x6a, 0x22, 0x05, 0x41, 0x30, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x2d, + 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x05, 0x20, 0x1b, + 0x20, 0x05, 0x6b, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x0c, 0x41, + 0x04, 0x6a, 0x22, 0x0c, 0x20, 0x12, 0x4d, 0x0d, 0x00, 0x0b, 0x02, 0x40, + 0x20, 0x17, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, + 0x71, 0x0d, 0x00, 0x41, 0xd3, 0x1b, 0x41, 0x01, 0x20, 0x00, 0x10, 0x33, + 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x0d, 0x41, 0x01, 0x48, 0x0d, 0x00, 0x20, + 0x0c, 0x20, 0x0b, 0x4f, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x1b, 0x21, 0x05, + 0x02, 0x40, 0x20, 0x0c, 0x28, 0x02, 0x00, 0x22, 0x06, 0x04, 0x40, 0x03, + 0x40, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x20, 0x06, 0x20, 0x06, + 0x41, 0x0a, 0x6e, 0x22, 0x07, 0x41, 0x0a, 0x6c, 0x6b, 0x41, 0x30, 0x72, + 0x3a, 0x00, 0x00, 0x20, 0x06, 0x41, 0x09, 0x4b, 0x20, 0x07, 0x21, 0x06, + 0x0d, 0x00, 0x0b, 0x20, 0x05, 0x20, 0x09, 0x41, 0xd0, 0x02, 0x6a, 0x4d, + 0x0d, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x22, 0x05, + 0x41, 0x30, 0x3a, 0x00, 0x00, 0x20, 0x05, 0x20, 0x09, 0x41, 0xd0, 0x02, + 0x6a, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, + 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x05, 0x20, 0x0d, 0x41, 0x09, 0x20, + 0x0d, 0x41, 0x09, 0x48, 0x1b, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, + 0x0d, 0x41, 0x77, 0x6a, 0x22, 0x0d, 0x41, 0x01, 0x48, 0x0d, 0x01, 0x20, + 0x0c, 0x41, 0x04, 0x6a, 0x22, 0x0c, 0x20, 0x0b, 0x49, 0x0d, 0x00, 0x0b, + 0x0b, 0x20, 0x0d, 0x41, 0x01, 0x48, 0x0d, 0x01, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x41, 0x30, 0x20, 0x0d, 0x41, 0x80, 0x02, 0x20, 0x0d, 0x41, 0x80, + 0x02, 0x49, 0x22, 0x05, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x22, 0x07, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, + 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x05, 0x20, 0x0d, 0x21, 0x06, 0x03, + 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, + 0x02, 0x00, 0x21, 0x07, 0x0b, 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, 0x08, + 0x45, 0x21, 0x05, 0x20, 0x06, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, + 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x08, 0x0d, 0x03, 0x20, 0x0d, + 0x41, 0xff, 0x01, 0x71, 0x21, 0x0d, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, + 0x02, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0d, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x0d, 0x41, 0x7f, 0x4c, + 0x0d, 0x00, 0x20, 0x0b, 0x20, 0x06, 0x41, 0x04, 0x6a, 0x20, 0x16, 0x1b, + 0x21, 0x0a, 0x20, 0x06, 0x21, 0x0c, 0x03, 0x40, 0x20, 0x1b, 0x21, 0x08, + 0x02, 0x40, 0x20, 0x0c, 0x28, 0x02, 0x00, 0x22, 0x05, 0x04, 0x40, 0x41, + 0x00, 0x21, 0x07, 0x03, 0x40, 0x20, 0x07, 0x20, 0x09, 0x6a, 0x41, 0xd8, + 0x02, 0x6a, 0x20, 0x05, 0x20, 0x05, 0x41, 0x0a, 0x6e, 0x22, 0x08, 0x41, + 0x0a, 0x6c, 0x6b, 0x41, 0x30, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x07, 0x41, + 0x7f, 0x6a, 0x21, 0x07, 0x20, 0x05, 0x41, 0x09, 0x4b, 0x20, 0x08, 0x21, + 0x05, 0x0d, 0x00, 0x0b, 0x20, 0x07, 0x20, 0x09, 0x6a, 0x41, 0xd9, 0x02, + 0x6a, 0x21, 0x08, 0x20, 0x07, 0x0d, 0x01, 0x0b, 0x20, 0x08, 0x41, 0x7f, + 0x6a, 0x22, 0x08, 0x41, 0x30, 0x3a, 0x00, 0x00, 0x0b, 0x02, 0x40, 0x20, + 0x06, 0x20, 0x0c, 0x47, 0x04, 0x40, 0x20, 0x08, 0x20, 0x09, 0x41, 0xd0, + 0x02, 0x6a, 0x4d, 0x0d, 0x01, 0x03, 0x40, 0x20, 0x08, 0x41, 0x7f, 0x6a, + 0x22, 0x08, 0x41, 0x30, 0x3a, 0x00, 0x00, 0x20, 0x08, 0x20, 0x09, 0x41, + 0xd0, 0x02, 0x6a, 0x4b, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20, 0x00, + 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x08, 0x41, + 0x01, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x08, 0x41, 0x01, 0x6a, + 0x21, 0x08, 0x20, 0x10, 0x45, 0x41, 0x00, 0x20, 0x0d, 0x41, 0x01, 0x48, + 0x1b, 0x0d, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x0d, + 0x00, 0x41, 0xd3, 0x1b, 0x41, 0x01, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, + 0x20, 0x1b, 0x20, 0x08, 0x6b, 0x21, 0x05, 0x20, 0x00, 0x2d, 0x00, 0x00, + 0x41, 0x20, 0x71, 0x45, 0x04, 0x40, 0x20, 0x08, 0x20, 0x05, 0x20, 0x0d, + 0x20, 0x0d, 0x20, 0x05, 0x4a, 0x1b, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, + 0x20, 0x0c, 0x41, 0x04, 0x6a, 0x22, 0x0c, 0x20, 0x0a, 0x49, 0x41, 0x00, + 0x20, 0x0d, 0x20, 0x05, 0x6b, 0x22, 0x0d, 0x41, 0x7f, 0x4a, 0x1b, 0x0d, + 0x00, 0x0b, 0x20, 0x0d, 0x41, 0x01, 0x48, 0x0d, 0x00, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x41, 0x30, 0x20, 0x0d, 0x41, 0x80, 0x02, 0x20, 0x0d, 0x41, + 0x80, 0x02, 0x49, 0x22, 0x05, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, + 0x00, 0x22, 0x07, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x05, + 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x05, 0x20, 0x0d, 0x21, 0x06, + 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, + 0x28, 0x02, 0x00, 0x21, 0x07, 0x0b, 0x20, 0x07, 0x41, 0x20, 0x71, 0x22, + 0x08, 0x45, 0x21, 0x05, 0x20, 0x06, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x06, + 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x08, 0x0d, 0x02, 0x20, + 0x0d, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0d, 0x0c, 0x01, 0x0b, 0x20, 0x06, + 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0d, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, + 0x0d, 0x00, 0x20, 0x1c, 0x20, 0x19, 0x20, 0x1c, 0x6b, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0xc0, 0x00, 0x47, + 0x0d, 0x00, 0x20, 0x0e, 0x20, 0x11, 0x4c, 0x0d, 0x00, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x41, 0x20, 0x20, 0x0e, 0x20, 0x11, 0x6b, 0x22, 0x0b, 0x41, + 0x80, 0x02, 0x20, 0x0b, 0x41, 0x80, 0x02, 0x49, 0x22, 0x05, 0x1b, 0x10, + 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x20, 0x71, 0x21, + 0x06, 0x02, 0x40, 0x20, 0x05, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, + 0x05, 0x20, 0x0b, 0x21, 0x06, 0x03, 0x40, 0x20, 0x05, 0x41, 0x01, 0x71, + 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x07, 0x0b, 0x20, + 0x07, 0x41, 0x20, 0x71, 0x22, 0x08, 0x45, 0x21, 0x05, 0x20, 0x06, 0x41, + 0x80, 0x7e, 0x6a, 0x22, 0x06, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, + 0x20, 0x08, 0x0d, 0x02, 0x20, 0x0b, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0b, + 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x20, 0x0b, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x20, 0x0e, 0x20, + 0x11, 0x20, 0x0e, 0x20, 0x11, 0x4a, 0x1b, 0x21, 0x05, 0x0b, 0x20, 0x05, + 0x41, 0x00, 0x4e, 0x0d, 0x0a, 0x0c, 0x09, 0x0b, 0x41, 0x00, 0x21, 0x0a, + 0x41, 0xa6, 0x16, 0x21, 0x10, 0x0b, 0x20, 0x15, 0x21, 0x05, 0x0c, 0x06, + 0x0b, 0x20, 0x06, 0x21, 0x0f, 0x20, 0x07, 0x21, 0x0b, 0x20, 0x05, 0x2d, + 0x00, 0x00, 0x45, 0x0d, 0x05, 0x0c, 0x06, 0x0b, 0x20, 0x01, 0x2d, 0x00, + 0x01, 0x21, 0x05, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x00, + 0x0b, 0x00, 0x0b, 0x20, 0x00, 0x0d, 0x06, 0x20, 0x1a, 0x45, 0x04, 0x40, + 0x41, 0x00, 0x21, 0x13, 0x0c, 0x07, 0x0b, 0x02, 0x7f, 0x41, 0x01, 0x20, + 0x04, 0x28, 0x02, 0x04, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x02, 0x20, + 0x04, 0x28, 0x02, 0x08, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x10, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x03, 0x20, + 0x04, 0x28, 0x02, 0x0c, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x18, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x04, 0x20, + 0x04, 0x28, 0x02, 0x10, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x20, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x05, 0x20, + 0x04, 0x28, 0x02, 0x14, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x28, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x06, 0x20, + 0x04, 0x28, 0x02, 0x18, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x30, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x07, 0x20, + 0x04, 0x28, 0x02, 0x1c, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x38, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x08, 0x20, + 0x04, 0x28, 0x02, 0x20, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x1a, 0x20, 0x03, + 0x41, 0x40, 0x6b, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x20, 0x04, 0x28, + 0x02, 0x24, 0x22, 0x00, 0x0d, 0x02, 0x41, 0x09, 0x0b, 0x41, 0x02, 0x74, + 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x20, 0x04, 0x6a, 0x28, 0x02, 0x00, + 0x0d, 0x01, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x28, 0x47, + 0x0d, 0x00, 0x0b, 0x41, 0x01, 0x21, 0x13, 0x0c, 0x06, 0x0b, 0x41, 0xe0, + 0x1f, 0x41, 0x1c, 0x36, 0x02, 0x00, 0x0c, 0x04, 0x0b, 0x20, 0x03, 0x41, + 0xc8, 0x00, 0x6a, 0x20, 0x00, 0x20, 0x02, 0x10, 0x27, 0x41, 0x01, 0x21, + 0x13, 0x0c, 0x04, 0x0b, 0x20, 0x05, 0x20, 0x08, 0x6b, 0x22, 0x11, 0x20, + 0x0b, 0x20, 0x0b, 0x20, 0x11, 0x48, 0x1b, 0x22, 0x14, 0x41, 0xff, 0xff, + 0xff, 0xff, 0x07, 0x20, 0x0a, 0x6b, 0x4a, 0x0d, 0x00, 0x20, 0x0a, 0x20, + 0x14, 0x6a, 0x22, 0x12, 0x20, 0x0e, 0x20, 0x0e, 0x20, 0x12, 0x48, 0x1b, + 0x22, 0x05, 0x20, 0x18, 0x4a, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x0f, 0x41, + 0x80, 0xc0, 0x04, 0x71, 0x22, 0x0f, 0x0d, 0x00, 0x20, 0x12, 0x20, 0x0e, + 0x4e, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, 0x05, + 0x20, 0x12, 0x6b, 0x22, 0x0d, 0x41, 0x80, 0x02, 0x20, 0x0d, 0x41, 0x80, + 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x22, 0x0c, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x07, 0x45, + 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, 0x20, 0x0d, 0x21, 0x07, 0x03, + 0x40, 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, + 0x02, 0x00, 0x21, 0x0c, 0x0b, 0x20, 0x0c, 0x41, 0x20, 0x71, 0x22, 0x18, + 0x45, 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, 0x41, + 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x18, 0x0d, 0x02, 0x20, 0x0d, + 0x41, 0xff, 0x01, 0x71, 0x21, 0x0d, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, + 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0d, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, + 0x04, 0x40, 0x20, 0x10, 0x20, 0x0a, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, + 0x02, 0x40, 0x20, 0x0f, 0x41, 0x80, 0x80, 0x04, 0x47, 0x0d, 0x00, 0x20, + 0x12, 0x20, 0x0e, 0x4e, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, + 0x30, 0x20, 0x05, 0x20, 0x12, 0x6b, 0x22, 0x0a, 0x41, 0x80, 0x02, 0x20, + 0x0a, 0x41, 0x80, 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, + 0x28, 0x02, 0x00, 0x22, 0x0c, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, + 0x20, 0x07, 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, 0x20, 0x0a, + 0x21, 0x07, 0x03, 0x40, 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, + 0x09, 0x41, 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, + 0x20, 0x00, 0x28, 0x02, 0x00, 0x21, 0x0c, 0x0b, 0x20, 0x0c, 0x41, 0x20, + 0x71, 0x22, 0x0d, 0x45, 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, + 0x22, 0x07, 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0d, 0x0d, + 0x02, 0x20, 0x0a, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0a, 0x0c, 0x01, 0x0b, + 0x20, 0x06, 0x0d, 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0a, + 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, 0x02, 0x40, 0x20, 0x11, 0x20, 0x0b, + 0x4e, 0x0d, 0x00, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x30, 0x20, 0x14, + 0x20, 0x11, 0x6b, 0x22, 0x0a, 0x41, 0x80, 0x02, 0x20, 0x0a, 0x41, 0x80, + 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, 0x00, + 0x22, 0x0b, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x07, 0x45, + 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, 0x20, 0x0a, 0x21, 0x07, 0x03, + 0x40, 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, 0x40, + 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, 0x28, + 0x02, 0x00, 0x21, 0x0b, 0x0b, 0x20, 0x0b, 0x41, 0x20, 0x71, 0x22, 0x0c, + 0x45, 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, 0x41, + 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0c, 0x0d, 0x02, 0x20, 0x0a, + 0x41, 0xff, 0x01, 0x71, 0x21, 0x0a, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x0d, + 0x01, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0a, 0x20, 0x00, 0x10, + 0x33, 0x1a, 0x0b, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, 0x20, 0x71, 0x45, + 0x04, 0x40, 0x20, 0x08, 0x20, 0x11, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x0b, + 0x20, 0x0f, 0x41, 0x80, 0xc0, 0x00, 0x47, 0x0d, 0x01, 0x20, 0x12, 0x20, + 0x0e, 0x4e, 0x0d, 0x01, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x41, 0x20, 0x20, + 0x05, 0x20, 0x12, 0x6b, 0x22, 0x0b, 0x41, 0x80, 0x02, 0x20, 0x0b, 0x41, + 0x80, 0x02, 0x49, 0x22, 0x07, 0x1b, 0x10, 0x3a, 0x20, 0x00, 0x28, 0x02, + 0x00, 0x22, 0x08, 0x41, 0x20, 0x71, 0x21, 0x06, 0x02, 0x40, 0x20, 0x07, + 0x45, 0x04, 0x40, 0x20, 0x06, 0x45, 0x21, 0x06, 0x20, 0x0b, 0x21, 0x07, + 0x03, 0x40, 0x20, 0x06, 0x41, 0x01, 0x71, 0x04, 0x40, 0x20, 0x09, 0x41, + 0x40, 0x6b, 0x41, 0x80, 0x02, 0x20, 0x00, 0x10, 0x33, 0x1a, 0x20, 0x00, + 0x28, 0x02, 0x00, 0x21, 0x08, 0x0b, 0x20, 0x08, 0x41, 0x20, 0x71, 0x22, + 0x0a, 0x45, 0x21, 0x06, 0x20, 0x07, 0x41, 0x80, 0x7e, 0x6a, 0x22, 0x07, + 0x41, 0xff, 0x01, 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x0a, 0x0d, 0x03, 0x20, + 0x0b, 0x41, 0xff, 0x01, 0x71, 0x21, 0x0b, 0x0c, 0x01, 0x0b, 0x20, 0x06, + 0x0d, 0x02, 0x0b, 0x20, 0x09, 0x41, 0x40, 0x6b, 0x20, 0x0b, 0x20, 0x00, + 0x10, 0x33, 0x1a, 0x0c, 0x01, 0x0b, 0x0b, 0x41, 0xe0, 0x1f, 0x41, 0x3d, + 0x36, 0x02, 0x00, 0x0b, 0x41, 0x7f, 0x21, 0x13, 0x0b, 0x20, 0x09, 0x41, + 0xf0, 0x06, 0x6a, 0x24, 0x00, 0x20, 0x13, 0x0b, 0xa2, 0x02, 0x00, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x77, 0x6a, 0x22, 0x01, + 0x41, 0x11, 0x4d, 0x04, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6b, 0x0e, 0x11, + 0x07, 0x08, 0x09, 0x07, 0x08, 0x00, 0x01, 0x02, 0x03, 0x09, 0x08, 0x09, + 0x09, 0x07, 0x08, 0x09, 0x04, 0x05, 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, + 0x02, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, + 0x20, 0x01, 0x32, 0x01, 0x00, 0x37, 0x03, 0x00, 0x0f, 0x0b, 0x20, 0x02, + 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x33, 0x01, 0x00, 0x37, 0x03, 0x00, 0x0f, + 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x04, + 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x01, 0x30, 0x00, 0x00, 0x37, + 0x03, 0x00, 0x0f, 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, + 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x01, 0x31, + 0x00, 0x00, 0x37, 0x03, 0x00, 0x0f, 0x0b, 0x41, 0x90, 0x1a, 0x41, 0xa8, + 0x29, 0x10, 0x29, 0x1a, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, + 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, + 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x0f, 0x0b, 0x20, 0x02, + 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x04, 0x6a, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x34, 0x02, 0x00, 0x37, 0x03, 0x00, 0x0f, + 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x04, + 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x20, 0x01, 0x35, 0x02, 0x00, 0x37, + 0x03, 0x00, 0x0f, 0x0b, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x00, 0x41, + 0x07, 0x6a, 0x41, 0x78, 0x71, 0x22, 0x01, 0x41, 0x08, 0x6a, 0x36, 0x02, + 0x00, 0x20, 0x00, 0x20, 0x01, 0x29, 0x03, 0x00, 0x37, 0x03, 0x00, 0x0b, + 0x38, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x41, 0xf0, 0x28, 0x28, 0x02, 0x00, + 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x41, 0xc4, 0x28, 0x28, 0x02, 0x00, 0x22, + 0x00, 0x41, 0xc0, 0x28, 0x28, 0x02, 0x00, 0x46, 0x0d, 0x00, 0x41, 0xc4, + 0x28, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, + 0x0a, 0x3a, 0x00, 0x00, 0x0f, 0x0b, 0x10, 0x2a, 0x0b, 0x18, 0x01, 0x01, + 0x7f, 0x41, 0x7f, 0x41, 0x00, 0x20, 0x00, 0x10, 0x38, 0x22, 0x02, 0x20, + 0x00, 0x20, 0x02, 0x20, 0x01, 0x10, 0x34, 0x47, 0x1b, 0x0b, 0x84, 0x01, + 0x01, 0x02, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x00, + 0x20, 0x00, 0x41, 0x0a, 0x3a, 0x00, 0x0f, 0x02, 0x40, 0x02, 0x40, 0x41, + 0xc0, 0x28, 0x28, 0x02, 0x00, 0x22, 0x01, 0x04, 0x7f, 0x20, 0x01, 0x05, + 0x41, 0xb0, 0x28, 0x10, 0x31, 0x0d, 0x02, 0x41, 0xc0, 0x28, 0x28, 0x02, + 0x00, 0x0b, 0x41, 0xc4, 0x28, 0x28, 0x02, 0x00, 0x22, 0x01, 0x46, 0x0d, + 0x00, 0x41, 0xf0, 0x28, 0x28, 0x02, 0x00, 0x41, 0x0a, 0x46, 0x0d, 0x00, + 0x41, 0xc4, 0x28, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x00, 0x20, + 0x01, 0x41, 0x0a, 0x3a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x41, 0xb0, 0x28, + 0x20, 0x00, 0x41, 0x0f, 0x6a, 0x41, 0x01, 0x41, 0xd0, 0x28, 0x28, 0x02, + 0x00, 0x11, 0x00, 0x00, 0x41, 0x01, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x2d, + 0x00, 0x0f, 0x1a, 0x0b, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x0b, + 0x09, 0x00, 0x20, 0x00, 0x28, 0x02, 0x38, 0x10, 0x19, 0x0b, 0x48, 0x01, + 0x01, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x03, 0x24, 0x00, 0x02, + 0x7e, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x20, + 0x03, 0x41, 0x08, 0x6a, 0x10, 0x0d, 0x22, 0x00, 0x04, 0x40, 0x41, 0xe0, + 0x1f, 0x41, 0xc6, 0x00, 0x20, 0x00, 0x20, 0x00, 0x41, 0xcc, 0x00, 0x46, + 0x1b, 0x36, 0x02, 0x00, 0x42, 0x7f, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x29, + 0x03, 0x08, 0x0b, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x0b, 0x0d, + 0x00, 0x20, 0x00, 0x28, 0x02, 0x38, 0x20, 0x01, 0x20, 0x02, 0x10, 0x2c, + 0x0b, 0x4d, 0x01, 0x01, 0x7f, 0x23, 0x00, 0x41, 0x20, 0x6b, 0x22, 0x01, + 0x24, 0x00, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x08, + 0x6a, 0x10, 0x0a, 0x22, 0x00, 0x0d, 0x00, 0x41, 0x3b, 0x21, 0x00, 0x20, + 0x01, 0x2d, 0x00, 0x08, 0x41, 0x02, 0x47, 0x0d, 0x00, 0x20, 0x01, 0x2d, + 0x00, 0x10, 0x41, 0x24, 0x71, 0x0d, 0x00, 0x41, 0x01, 0x0c, 0x01, 0x0b, + 0x41, 0xe0, 0x1f, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0x00, 0x0b, 0x20, + 0x01, 0x41, 0x20, 0x6a, 0x24, 0x00, 0x0b, 0x2f, 0x00, 0x20, 0x00, 0x41, + 0x04, 0x36, 0x02, 0x20, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x41, + 0xc0, 0x00, 0x71, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x38, 0x10, 0x2e, + 0x0d, 0x00, 0x20, 0x00, 0x41, 0x7f, 0x36, 0x02, 0x40, 0x0b, 0x20, 0x00, + 0x20, 0x01, 0x20, 0x02, 0x10, 0x36, 0x0b, 0xca, 0x02, 0x01, 0x03, 0x7f, + 0x41, 0xec, 0x1f, 0x28, 0x02, 0x00, 0x22, 0x00, 0x04, 0x40, 0x03, 0x40, + 0x20, 0x00, 0x28, 0x02, 0x14, 0x20, 0x00, 0x28, 0x02, 0x18, 0x47, 0x04, + 0x40, 0x20, 0x00, 0x41, 0x00, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x20, + 0x11, 0x00, 0x00, 0x1a, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, 0x01, + 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, 0x02, 0x47, 0x04, 0x40, 0x20, 0x00, + 0x20, 0x01, 0x20, 0x02, 0x6b, 0xac, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, + 0x24, 0x11, 0x03, 0x00, 0x1a, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x34, 0x22, + 0x00, 0x0d, 0x00, 0x0b, 0x0b, 0x02, 0x40, 0x41, 0x98, 0x28, 0x28, 0x02, + 0x00, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x14, 0x20, + 0x00, 0x28, 0x02, 0x18, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, 0x00, 0x41, + 0x00, 0x20, 0x00, 0x28, 0x02, 0x20, 0x11, 0x00, 0x00, 0x1a, 0x0b, 0x20, + 0x00, 0x28, 0x02, 0x04, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, + 0x02, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x6b, 0xac, + 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x03, 0x00, 0x1a, 0x0b, + 0x02, 0x40, 0x41, 0xa0, 0x29, 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, 0x0d, + 0x00, 0x20, 0x00, 0x28, 0x02, 0x14, 0x20, 0x00, 0x28, 0x02, 0x18, 0x47, + 0x04, 0x40, 0x20, 0x00, 0x41, 0x00, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, + 0x20, 0x11, 0x00, 0x00, 0x1a, 0x0b, 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, + 0x01, 0x20, 0x00, 0x28, 0x02, 0x08, 0x22, 0x02, 0x46, 0x0d, 0x00, 0x20, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x6b, 0xac, 0x41, 0x00, 0x20, 0x00, 0x28, + 0x02, 0x24, 0x11, 0x03, 0x00, 0x1a, 0x0b, 0x02, 0x40, 0x41, 0x98, 0x2a, + 0x28, 0x02, 0x00, 0x22, 0x00, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, + 0x14, 0x20, 0x00, 0x28, 0x02, 0x18, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, + 0x00, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x20, 0x11, 0x00, 0x00, 0x1a, + 0x0b, 0x20, 0x00, 0x28, 0x02, 0x04, 0x22, 0x01, 0x20, 0x00, 0x28, 0x02, + 0x08, 0x22, 0x02, 0x46, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, + 0x6b, 0xac, 0x41, 0x00, 0x20, 0x00, 0x28, 0x02, 0x24, 0x11, 0x03, 0x00, + 0x1a, 0x0b, 0x0b, 0x59, 0x01, 0x01, 0x7f, 0x20, 0x00, 0x20, 0x00, 0x28, + 0x02, 0x3c, 0x22, 0x01, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x72, 0x36, 0x02, + 0x3c, 0x20, 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x08, 0x71, 0x04, + 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x20, 0x72, 0x36, 0x02, 0x00, 0x41, + 0x7f, 0x0f, 0x0b, 0x20, 0x00, 0x42, 0x00, 0x37, 0x02, 0x04, 0x20, 0x00, + 0x20, 0x00, 0x28, 0x02, 0x28, 0x22, 0x01, 0x36, 0x02, 0x18, 0x20, 0x00, + 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00, 0x28, + 0x02, 0x2c, 0x6a, 0x36, 0x02, 0x10, 0x41, 0x00, 0x0b, 0x47, 0x01, 0x01, + 0x7f, 0x41, 0x93, 0x09, 0x41, 0xb0, 0x28, 0x10, 0x29, 0x41, 0x00, 0x48, + 0x04, 0x40, 0x0f, 0x0b, 0x02, 0x40, 0x41, 0xf0, 0x28, 0x28, 0x02, 0x00, + 0x41, 0x0a, 0x46, 0x0d, 0x00, 0x41, 0xc4, 0x28, 0x28, 0x02, 0x00, 0x22, + 0x00, 0x41, 0xc0, 0x28, 0x28, 0x02, 0x00, 0x46, 0x0d, 0x00, 0x41, 0xc4, + 0x28, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x00, 0x41, + 0x0a, 0x3a, 0x00, 0x00, 0x0f, 0x0b, 0x10, 0x2a, 0x0b, 0xcf, 0x01, 0x01, + 0x06, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x28, 0x02, 0x10, 0x22, 0x03, 0x04, + 0x7f, 0x20, 0x03, 0x05, 0x20, 0x02, 0x10, 0x31, 0x0d, 0x01, 0x20, 0x02, + 0x28, 0x02, 0x10, 0x0b, 0x20, 0x02, 0x28, 0x02, 0x14, 0x22, 0x06, 0x6b, + 0x20, 0x01, 0x49, 0x04, 0x40, 0x20, 0x02, 0x20, 0x00, 0x20, 0x01, 0x20, + 0x02, 0x28, 0x02, 0x20, 0x11, 0x00, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20, + 0x02, 0x28, 0x02, 0x40, 0x41, 0x00, 0x48, 0x0d, 0x00, 0x20, 0x00, 0x21, + 0x04, 0x41, 0x00, 0x21, 0x03, 0x03, 0x40, 0x20, 0x01, 0x20, 0x03, 0x46, + 0x0d, 0x01, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x20, + 0x04, 0x6a, 0x20, 0x04, 0x41, 0x7f, 0x6a, 0x22, 0x08, 0x21, 0x04, 0x41, + 0x7f, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x0a, 0x47, 0x0d, 0x00, 0x0b, 0x20, + 0x02, 0x20, 0x00, 0x20, 0x01, 0x20, 0x03, 0x6b, 0x41, 0x01, 0x6a, 0x22, + 0x05, 0x20, 0x02, 0x28, 0x02, 0x20, 0x11, 0x00, 0x00, 0x22, 0x04, 0x20, + 0x05, 0x49, 0x0d, 0x01, 0x20, 0x01, 0x20, 0x08, 0x6a, 0x41, 0x01, 0x6a, + 0x21, 0x00, 0x20, 0x02, 0x28, 0x02, 0x14, 0x21, 0x06, 0x20, 0x03, 0x41, + 0x7f, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x06, 0x20, 0x00, 0x20, 0x01, 0x10, + 0x39, 0x1a, 0x20, 0x02, 0x20, 0x02, 0x28, 0x02, 0x14, 0x20, 0x01, 0x6a, + 0x36, 0x02, 0x14, 0x20, 0x01, 0x20, 0x05, 0x6a, 0x21, 0x04, 0x0b, 0x20, + 0x04, 0x0b, 0x17, 0x00, 0x20, 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, + 0x10, 0x33, 0x22, 0x00, 0x46, 0x04, 0x40, 0x20, 0x01, 0x0f, 0x0b, 0x20, + 0x00, 0x0b, 0x52, 0x01, 0x02, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, + 0x03, 0x24, 0x00, 0x41, 0x7f, 0x21, 0x04, 0x02, 0x40, 0x20, 0x02, 0x41, + 0x7f, 0x4c, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x41, 0x1c, 0x36, 0x02, 0x00, + 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x41, + 0x0c, 0x6a, 0x10, 0x0e, 0x22, 0x00, 0x04, 0x40, 0x41, 0xe0, 0x1f, 0x20, + 0x00, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x28, 0x02, 0x0c, + 0x21, 0x04, 0x0b, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x24, 0x00, 0x20, 0x04, + 0x0b, 0x96, 0x02, 0x01, 0x06, 0x7f, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, + 0x03, 0x24, 0x00, 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x0c, 0x20, 0x03, + 0x20, 0x01, 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, 0x00, 0x28, 0x02, 0x18, + 0x22, 0x01, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x00, 0x28, 0x02, 0x14, + 0x20, 0x01, 0x6b, 0x22, 0x01, 0x36, 0x02, 0x04, 0x41, 0x02, 0x21, 0x06, + 0x02, 0x7f, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x22, 0x07, 0x20, 0x00, 0x28, + 0x02, 0x38, 0x20, 0x03, 0x41, 0x02, 0x10, 0x35, 0x22, 0x04, 0x47, 0x04, + 0x40, 0x20, 0x03, 0x21, 0x01, 0x03, 0x40, 0x20, 0x04, 0x41, 0x7f, 0x4c, + 0x04, 0x40, 0x20, 0x00, 0x41, 0x00, 0x36, 0x02, 0x18, 0x20, 0x00, 0x42, + 0x00, 0x37, 0x03, 0x10, 0x20, 0x00, 0x20, 0x00, 0x28, 0x02, 0x00, 0x41, + 0x20, 0x72, 0x36, 0x02, 0x00, 0x41, 0x00, 0x20, 0x06, 0x41, 0x02, 0x46, + 0x0d, 0x03, 0x1a, 0x20, 0x02, 0x20, 0x01, 0x28, 0x02, 0x04, 0x6b, 0x0c, + 0x03, 0x0b, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x20, 0x01, 0x20, 0x04, 0x20, + 0x01, 0x28, 0x02, 0x04, 0x22, 0x08, 0x4b, 0x22, 0x05, 0x1b, 0x22, 0x01, + 0x20, 0x04, 0x20, 0x08, 0x41, 0x00, 0x20, 0x05, 0x1b, 0x6b, 0x22, 0x08, + 0x20, 0x01, 0x28, 0x02, 0x00, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, + 0x01, 0x28, 0x02, 0x04, 0x20, 0x08, 0x6b, 0x36, 0x02, 0x04, 0x20, 0x07, + 0x20, 0x04, 0x6b, 0x21, 0x07, 0x20, 0x00, 0x28, 0x02, 0x38, 0x20, 0x01, + 0x20, 0x06, 0x20, 0x05, 0x6b, 0x22, 0x06, 0x10, 0x35, 0x22, 0x05, 0x21, + 0x04, 0x20, 0x05, 0x20, 0x07, 0x47, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, + 0x20, 0x00, 0x28, 0x02, 0x28, 0x22, 0x01, 0x36, 0x02, 0x18, 0x20, 0x00, + 0x20, 0x01, 0x36, 0x02, 0x14, 0x20, 0x00, 0x20, 0x01, 0x20, 0x00, 0x28, + 0x02, 0x2c, 0x6a, 0x36, 0x02, 0x10, 0x20, 0x02, 0x0b, 0x20, 0x03, 0x41, + 0x10, 0x6a, 0x24, 0x00, 0x0b, 0x20, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x10, + 0x38, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x10, 0x14, 0x22, 0x02, 0x45, 0x04, + 0x40, 0x41, 0x00, 0x0f, 0x0b, 0x20, 0x02, 0x20, 0x00, 0x20, 0x01, 0x10, + 0x39, 0x0b, 0xa4, 0x01, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, + 0x00, 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x0f, 0x0b, 0x20, + 0x00, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x03, + 0x71, 0x45, 0x0d, 0x01, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, + 0x01, 0x6a, 0x22, 0x03, 0x21, 0x01, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, + 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, + 0x04, 0x6a, 0x22, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x7f, 0x73, + 0x20, 0x02, 0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, + 0x82, 0x84, 0x78, 0x71, 0x45, 0x0d, 0x00, 0x0b, 0x20, 0x02, 0x41, 0xff, + 0x01, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x20, 0x00, 0x6b, 0x0f, 0x0b, + 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x20, 0x01, 0x41, 0x01, 0x6a, + 0x22, 0x02, 0x21, 0x01, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20, 0x03, + 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x0b, 0x20, 0x02, 0x20, 0x00, 0x6b, 0x0b, + 0x92, 0x0b, 0x01, 0x08, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x45, + 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x00, + 0x21, 0x03, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, + 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, + 0x02, 0x41, 0x01, 0x46, 0x0d, 0x02, 0x20, 0x04, 0x21, 0x02, 0x20, 0x01, + 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x21, + 0x04, 0x20, 0x00, 0x21, 0x03, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, + 0x71, 0x22, 0x02, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x04, 0x41, 0x10, + 0x49, 0x04, 0x40, 0x20, 0x04, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x04, + 0x41, 0x70, 0x6a, 0x21, 0x02, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x28, + 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x01, + 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, + 0x08, 0x6a, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x01, 0x41, 0x0c, 0x6a, 0x28, + 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x03, + 0x20, 0x01, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x20, 0x04, 0x41, 0x70, 0x6a, + 0x22, 0x04, 0x41, 0x0f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, + 0x08, 0x71, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, 0x29, 0x02, 0x00, 0x37, + 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, + 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x71, 0x04, 0x40, + 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, + 0x0b, 0x20, 0x02, 0x41, 0x02, 0x71, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, + 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x20, + 0x01, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x01, 0x71, + 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x04, 0x41, 0x20, 0x49, + 0x0d, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x41, 0x02, 0x4b, + 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x01, + 0x6b, 0x0e, 0x02, 0x01, 0x02, 0x00, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, + 0x22, 0x05, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x02, + 0x3a, 0x00, 0x02, 0x20, 0x04, 0x41, 0x7d, 0x6a, 0x21, 0x08, 0x20, 0x03, + 0x41, 0x03, 0x6a, 0x21, 0x09, 0x20, 0x04, 0x41, 0x6c, 0x6a, 0x41, 0x70, + 0x71, 0x21, 0x0a, 0x41, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20, + 0x09, 0x6a, 0x22, 0x03, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x22, 0x06, 0x41, + 0x04, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x08, 0x74, 0x20, 0x05, + 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, + 0x20, 0x06, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x05, 0x41, 0x08, + 0x74, 0x20, 0x07, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x20, 0x06, 0x41, 0x0c, 0x6a, 0x28, 0x02, 0x00, 0x22, + 0x07, 0x41, 0x08, 0x74, 0x20, 0x05, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x06, 0x41, 0x10, 0x6a, 0x28, + 0x02, 0x00, 0x22, 0x05, 0x41, 0x08, 0x74, 0x20, 0x07, 0x41, 0x18, 0x76, + 0x72, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x21, 0x02, 0x20, + 0x08, 0x41, 0x70, 0x6a, 0x22, 0x08, 0x41, 0x10, 0x4b, 0x0d, 0x00, 0x0b, + 0x20, 0x02, 0x20, 0x09, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x20, 0x02, 0x6a, + 0x41, 0x03, 0x6a, 0x21, 0x01, 0x20, 0x04, 0x20, 0x0a, 0x6b, 0x41, 0x6d, + 0x6a, 0x21, 0x04, 0x0c, 0x02, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, + 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, + 0x01, 0x3a, 0x00, 0x01, 0x20, 0x04, 0x41, 0x7e, 0x6a, 0x21, 0x08, 0x20, + 0x03, 0x41, 0x02, 0x6a, 0x21, 0x09, 0x20, 0x04, 0x41, 0x6c, 0x6a, 0x41, + 0x70, 0x71, 0x21, 0x0a, 0x41, 0x00, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, + 0x20, 0x09, 0x6a, 0x22, 0x03, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x22, 0x06, + 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x10, 0x74, 0x20, + 0x05, 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, + 0x6a, 0x20, 0x06, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x05, 0x41, + 0x10, 0x74, 0x20, 0x07, 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, + 0x03, 0x41, 0x08, 0x6a, 0x20, 0x06, 0x41, 0x0c, 0x6a, 0x28, 0x02, 0x00, + 0x22, 0x07, 0x41, 0x10, 0x74, 0x20, 0x05, 0x41, 0x10, 0x76, 0x72, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x06, 0x41, 0x10, 0x6a, + 0x28, 0x02, 0x00, 0x22, 0x05, 0x41, 0x10, 0x74, 0x20, 0x07, 0x41, 0x10, + 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x21, 0x02, + 0x20, 0x08, 0x41, 0x70, 0x6a, 0x22, 0x08, 0x41, 0x11, 0x4b, 0x0d, 0x00, + 0x0b, 0x20, 0x02, 0x20, 0x09, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x20, 0x02, + 0x6a, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x20, 0x04, 0x20, 0x0a, 0x6b, 0x41, + 0x6e, 0x6a, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x28, + 0x02, 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x41, 0x7f, 0x6a, + 0x21, 0x08, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x09, 0x20, 0x04, 0x41, + 0x6c, 0x6a, 0x41, 0x70, 0x71, 0x21, 0x0a, 0x41, 0x00, 0x21, 0x02, 0x03, + 0x40, 0x20, 0x02, 0x20, 0x09, 0x6a, 0x22, 0x03, 0x20, 0x01, 0x20, 0x02, + 0x6a, 0x22, 0x06, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, + 0x18, 0x74, 0x20, 0x05, 0x41, 0x08, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, + 0x03, 0x41, 0x04, 0x6a, 0x20, 0x06, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, + 0x22, 0x05, 0x41, 0x18, 0x74, 0x20, 0x07, 0x41, 0x08, 0x76, 0x72, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, 0x06, 0x41, 0x0c, 0x6a, + 0x28, 0x02, 0x00, 0x22, 0x07, 0x41, 0x18, 0x74, 0x20, 0x05, 0x41, 0x08, + 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x06, + 0x41, 0x10, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x05, 0x41, 0x18, 0x74, 0x20, + 0x07, 0x41, 0x08, 0x76, 0x72, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x10, + 0x6a, 0x21, 0x02, 0x20, 0x08, 0x41, 0x70, 0x6a, 0x22, 0x08, 0x41, 0x12, + 0x4b, 0x0d, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x09, 0x6a, 0x21, 0x03, 0x20, + 0x01, 0x20, 0x02, 0x6a, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x04, 0x20, + 0x0a, 0x6b, 0x41, 0x6f, 0x6a, 0x21, 0x04, 0x0b, 0x20, 0x04, 0x41, 0x10, + 0x71, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, 0x00, + 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, + 0x03, 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x20, + 0x01, 0x2d, 0x00, 0x04, 0x3a, 0x00, 0x04, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x05, 0x3a, 0x00, 0x05, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x06, + 0x3a, 0x00, 0x06, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x07, 0x3a, 0x00, + 0x07, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x08, 0x3a, 0x00, 0x08, 0x20, + 0x03, 0x20, 0x01, 0x2d, 0x00, 0x09, 0x3a, 0x00, 0x09, 0x20, 0x03, 0x20, + 0x01, 0x2d, 0x00, 0x0a, 0x3a, 0x00, 0x0a, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x0b, 0x3a, 0x00, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x0c, + 0x3a, 0x00, 0x0c, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x0d, 0x3a, 0x00, + 0x0d, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x0e, 0x3a, 0x00, 0x0e, 0x20, + 0x03, 0x20, 0x01, 0x2d, 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x03, 0x41, + 0x10, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x0b, + 0x20, 0x04, 0x41, 0x08, 0x71, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x01, + 0x3a, 0x00, 0x01, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, + 0x02, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, + 0x03, 0x20, 0x01, 0x2d, 0x00, 0x04, 0x3a, 0x00, 0x04, 0x20, 0x03, 0x20, + 0x01, 0x2d, 0x00, 0x05, 0x3a, 0x00, 0x05, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x06, 0x3a, 0x00, 0x06, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x07, + 0x3a, 0x00, 0x07, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, + 0x41, 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x04, 0x41, 0x04, 0x71, 0x04, + 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, + 0x03, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x20, + 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x03, 0x20, 0x01, 0x2d, + 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, + 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x04, 0x41, 0x02, + 0x71, 0x04, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, + 0x03, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x21, + 0x01, 0x0b, 0x20, 0x04, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x03, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x0b, + 0xfa, 0x02, 0x02, 0x02, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x20, 0x02, 0x45, + 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x20, + 0x02, 0x6a, 0x22, 0x03, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, + 0x20, 0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, + 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x41, + 0x7d, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7e, 0x6a, + 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x07, 0x49, 0x0d, 0x00, + 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x41, 0x7c, 0x6a, + 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x09, 0x49, 0x0d, 0x00, + 0x20, 0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, 0x41, 0x03, 0x71, 0x22, 0x04, + 0x6a, 0x22, 0x03, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, + 0x84, 0x08, 0x6c, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x02, + 0x20, 0x04, 0x6b, 0x41, 0x7c, 0x71, 0x22, 0x02, 0x6a, 0x22, 0x01, 0x41, + 0x7c, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x09, 0x49, + 0x0d, 0x00, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, + 0x00, 0x36, 0x02, 0x04, 0x20, 0x01, 0x41, 0x78, 0x6a, 0x20, 0x00, 0x36, + 0x02, 0x00, 0x20, 0x01, 0x41, 0x74, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, + 0x20, 0x02, 0x41, 0x19, 0x49, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x00, 0x36, + 0x02, 0x18, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x14, 0x20, 0x03, 0x20, + 0x00, 0x36, 0x02, 0x10, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x0c, 0x20, + 0x01, 0x41, 0x70, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, + 0x6c, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x68, 0x6a, + 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x64, 0x6a, 0x20, 0x00, + 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x03, 0x41, 0x04, 0x71, 0x41, 0x18, + 0x72, 0x22, 0x01, 0x6b, 0x22, 0x02, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x20, + 0x00, 0xad, 0x22, 0x05, 0x42, 0x20, 0x86, 0x20, 0x05, 0x84, 0x21, 0x05, + 0x20, 0x01, 0x20, 0x03, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x20, + 0x05, 0x37, 0x03, 0x00, 0x20, 0x01, 0x41, 0x18, 0x6a, 0x20, 0x05, 0x37, + 0x03, 0x00, 0x20, 0x01, 0x41, 0x10, 0x6a, 0x20, 0x05, 0x37, 0x03, 0x00, + 0x20, 0x01, 0x41, 0x08, 0x6a, 0x20, 0x05, 0x37, 0x03, 0x00, 0x20, 0x01, + 0x41, 0x20, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x60, 0x6a, 0x22, 0x02, + 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x0b, 0x5a, 0x01, 0x03, 0x7f, + 0x41, 0x8f, 0x09, 0x2d, 0x00, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, + 0x2d, 0x00, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x20, 0x02, + 0x47, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x41, 0x90, + 0x09, 0x21, 0x03, 0x03, 0x40, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x21, 0x01, + 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, + 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, + 0x20, 0x01, 0x20, 0x02, 0x46, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, + 0x01, 0x6b, 0x0b, 0xd7, 0x01, 0x01, 0x02, 0x7f, 0x20, 0x01, 0x41, 0x00, + 0x47, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x45, + 0x04, 0x40, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x41, + 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x01, 0x0b, + 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x20, 0x01, + 0x21, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x01, 0x41, 0x01, 0x47, 0x21, 0x03, + 0x20, 0x01, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x20, 0x00, 0x41, 0x01, 0x6a, + 0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x46, 0x0d, 0x01, 0x20, 0x02, 0x21, + 0x01, 0x20, 0x00, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03, + 0x45, 0x0d, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x45, + 0x0d, 0x00, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, + 0x00, 0x28, 0x02, 0x00, 0x22, 0x01, 0x41, 0x7f, 0x73, 0x20, 0x01, 0x41, + 0xff, 0xfd, 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, + 0x71, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x00, 0x20, 0x02, + 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, + 0x20, 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, + 0x45, 0x04, 0x40, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, + 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, + 0x0b, 0x41, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x45, 0x04, 0x40, 0x41, + 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x10, 0x3e, 0x0b, 0x8c, 0x02, + 0x00, 0x20, 0x00, 0x04, 0x7f, 0x20, 0x01, 0x41, 0xff, 0x00, 0x4d, 0x04, + 0x40, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x41, 0x01, 0x0f, 0x0b, + 0x02, 0x40, 0x41, 0xf0, 0x1f, 0x28, 0x02, 0x00, 0x45, 0x04, 0x40, 0x20, + 0x01, 0x41, 0x80, 0x7f, 0x71, 0x41, 0x80, 0xbf, 0x03, 0x47, 0x0d, 0x01, + 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x41, 0x01, 0x0f, 0x0b, 0x20, + 0x01, 0x41, 0xff, 0x0f, 0x4d, 0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, + 0x3f, 0x71, 0x41, 0x80, 0x01, 0x72, 0x3a, 0x00, 0x01, 0x20, 0x00, 0x20, + 0x01, 0x41, 0x06, 0x76, 0x41, 0xc0, 0x01, 0x72, 0x3a, 0x00, 0x00, 0x41, + 0x02, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x80, 0xb0, 0x03, 0x4f, 0x41, 0x00, + 0x20, 0x01, 0x41, 0x80, 0x40, 0x71, 0x41, 0x80, 0xc0, 0x03, 0x47, 0x1b, + 0x45, 0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x3f, 0x71, 0x41, 0x80, + 0x01, 0x72, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0c, 0x76, + 0x41, 0xe0, 0x01, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x20, 0x01, 0x41, + 0x06, 0x76, 0x41, 0x3f, 0x71, 0x41, 0x80, 0x01, 0x72, 0x3a, 0x00, 0x01, + 0x41, 0x03, 0x0f, 0x0b, 0x20, 0x01, 0x41, 0x80, 0x80, 0x7c, 0x6a, 0x41, + 0xff, 0xff, 0x3f, 0x4d, 0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x41, 0x3f, + 0x71, 0x41, 0x80, 0x01, 0x72, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x20, 0x01, + 0x41, 0x12, 0x76, 0x41, 0xf0, 0x01, 0x72, 0x3a, 0x00, 0x00, 0x20, 0x00, + 0x20, 0x01, 0x41, 0x06, 0x76, 0x41, 0x3f, 0x71, 0x41, 0x80, 0x01, 0x72, + 0x3a, 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x41, 0x0c, 0x76, 0x41, 0x3f, + 0x71, 0x41, 0x80, 0x01, 0x72, 0x3a, 0x00, 0x01, 0x41, 0x04, 0x0f, 0x0b, + 0x0b, 0x41, 0xe0, 0x1f, 0x41, 0x19, 0x36, 0x02, 0x00, 0x41, 0x7f, 0x05, + 0x41, 0x01, 0x0b, 0x0b, 0x81, 0x01, 0x02, 0x01, 0x7f, 0x01, 0x7e, 0x20, + 0x00, 0xbd, 0x22, 0x03, 0x42, 0x34, 0x88, 0xa7, 0x41, 0xff, 0x0f, 0x71, + 0x22, 0x02, 0x41, 0xff, 0x0f, 0x47, 0x04, 0x7c, 0x20, 0x02, 0x45, 0x04, + 0x40, 0x20, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x04, 0x40, 0x20, 0x01, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00, + 0x0f, 0x0b, 0x20, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, + 0x43, 0xa2, 0x20, 0x01, 0x10, 0x3f, 0x20, 0x01, 0x20, 0x01, 0x28, 0x02, + 0x00, 0x41, 0x40, 0x6a, 0x36, 0x02, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x20, + 0x02, 0x41, 0x82, 0x78, 0x6a, 0x36, 0x02, 0x00, 0x20, 0x03, 0x42, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0x80, 0x7f, 0x83, 0x42, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf0, 0x3f, 0x84, 0xbf, 0x05, 0x20, + 0x00, 0x0b, 0x0b, 0x0b, 0xa0, 0x13, 0x1b, 0x00, 0x41, 0x80, 0x08, 0x0b, + 0xa5, 0x01, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, + 0x72, 0x20, 0x4f, 0x4b, 0x0a, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x0a, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, + 0x20, 0x25, 0x73, 0x21, 0x0a, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, + 0x00, 0x41, 0x72, 0x67, 0x73, 0x3a, 0x20, 0x00, 0x25, 0x73, 0x3b, 0x20, + 0x00, 0x25, 0x64, 0x20, 0x2b, 0x20, 0x25, 0x64, 0x20, 0x3d, 0x20, 0x25, + 0x64, 0x0a, 0x00, 0x4e, 0x6f, 0x77, 0x3a, 0x20, 0x25, 0x6c, 0x6c, 0x64, + 0x20, 0x73, 0x65, 0x63, 0x2c, 0x20, 0x25, 0x6c, 0x64, 0x20, 0x6e, 0x73, + 0x0a, 0x00, 0x66, 0x69, 0x62, 0x28, 0x25, 0x64, 0x29, 0x20, 0x3d, 0x20, + 0x00, 0x25, 0x64, 0x20, 0x5b, 0x25, 0x2e, 0x33, 0x66, 0x20, 0x6d, 0x73, + 0x5d, 0x0a, 0x00, 0x25, 0x30, 0x32, 0x78, 0x20, 0x00, 0x43, 0x61, 0x6e, + 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x25, 0x73, 0x0a, + 0x00, 0x63, 0x61, 0x74, 0x00, 0x3d, 0x3d, 0x3d, 0x20, 0x64, 0x6f, 0x6e, + 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x00, + 0x41, 0xb1, 0x09, 0x0b, 0x85, 0x0d, 0x19, 0x12, 0x44, 0x3b, 0x02, 0x3f, + 0x2c, 0x47, 0x14, 0x3d, 0x33, 0x30, 0x0a, 0x1b, 0x06, 0x46, 0x4b, 0x45, + 0x37, 0x0f, 0x49, 0x0e, 0x17, 0x03, 0x40, 0x1d, 0x3c, 0x2b, 0x36, 0x1f, + 0x4a, 0x2d, 0x1c, 0x01, 0x20, 0x25, 0x29, 0x21, 0x08, 0x0c, 0x15, 0x16, + 0x22, 0x2e, 0x10, 0x38, 0x3e, 0x0b, 0x34, 0x31, 0x18, 0x2f, 0x41, 0x09, + 0x39, 0x11, 0x23, 0x43, 0x32, 0x42, 0x3a, 0x05, 0x04, 0x26, 0x28, 0x27, + 0x0d, 0x2a, 0x1e, 0x35, 0x07, 0x1a, 0x48, 0x13, 0x24, 0x4c, 0xff, 0x00, + 0x00, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x00, 0x49, 0x6c, 0x6c, + 0x65, 0x67, 0x61, 0x6c, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x73, 0x65, + 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x00, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x4e, 0x6f, 0x74, + 0x20, 0x61, 0x20, 0x74, 0x74, 0x79, 0x00, 0x50, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, + 0x00, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, + 0x00, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x20, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x00, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x00, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x00, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x00, 0x4e, 0x6f, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x6c, 0x65, + 0x66, 0x74, 0x20, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x00, 0x4f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x00, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, + 0x62, 0x75, 0x73, 0x79, 0x00, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x65, 0x64, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, + 0x63, 0x61, 0x6c, 0x6c, 0x00, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x69, 0x6c, + 0x79, 0x20, 0x75, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x00, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x73, 0x65, + 0x65, 0x6b, 0x00, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x2d, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x00, 0x52, 0x65, 0x61, + 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x00, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x79, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x00, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, 0x62, 0x79, 0x20, 0x70, + 0x65, 0x65, 0x72, 0x00, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x64, 0x20, 0x6f, 0x75, 0x74, 0x00, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x00, 0x48, 0x6f, 0x73, 0x74, 0x20, + 0x69, 0x73, 0x20, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x69, + 0x6e, 0x20, 0x75, 0x73, 0x65, 0x00, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x6e, + 0x20, 0x70, 0x69, 0x70, 0x65, 0x00, 0x49, 0x2f, 0x4f, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x00, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x00, 0x4e, 0x6f, 0x20, 0x73, 0x75, 0x63, + 0x68, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, 0x4e, 0x6f, 0x74, + 0x20, 0x61, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, + 0x00, 0x49, 0x73, 0x20, 0x61, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x00, 0x54, 0x65, 0x78, 0x74, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x20, 0x62, 0x75, 0x73, 0x79, 0x00, 0x45, 0x78, 0x65, 0x63, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x00, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x6f, 0x20, + 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x53, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x69, + 0x63, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x6c, 0x6f, 0x6f, 0x70, 0x00, + 0x46, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x74, 0x6f, 0x6f, + 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x00, 0x54, 0x6f, 0x6f, 0x20, 0x6d, 0x61, + 0x6e, 0x79, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x00, + 0x4e, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x20, 0x61, 0x76, 0x61, 0x69, + 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x42, 0x61, 0x64, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x00, 0x4e, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x00, 0x42, 0x61, 0x64, 0x20, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x00, 0x46, 0x69, 0x6c, 0x65, 0x20, + 0x74, 0x6f, 0x6f, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x00, 0x54, 0x6f, + 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x79, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x73, + 0x00, 0x4e, 0x6f, 0x20, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x61, 0x76, + 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x20, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x6f, 0x63, + 0x6b, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x63, 0x63, 0x75, + 0x72, 0x00, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x6f, 0x74, 0x20, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x20, 0x64, 0x69, 0x65, 0x64, 0x00, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x65, 0x64, 0x00, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x00, 0x4e, 0x6f, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, + 0x64, 0x20, 0x74, 0x79, 0x70, 0x65, 0x00, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x64, 0x00, 0x4c, 0x69, 0x6e, 0x6b, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x20, 0x73, 0x65, 0x76, 0x65, 0x72, 0x65, 0x64, 0x00, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x00, 0x42, 0x61, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x00, 0x4e, 0x6f, 0x74, 0x20, 0x61, 0x20, 0x73, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x00, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x00, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x20, 0x6c, 0x61, 0x72, + 0x67, 0x65, 0x00, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, + 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x00, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x4e, 0x6f, 0x74, 0x20, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x00, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x6e, + 0x6f, 0x74, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x73, 0x20, + 0x64, 0x6f, 0x77, 0x6e, 0x00, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x20, 0x75, 0x6e, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, + 0x00, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x65, 0x73, 0x65, 0x74, 0x20, 0x62, 0x79, 0x20, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x00, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x00, + 0x4e, 0x6f, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x00, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x00, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, + 0x00, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x00, 0x53, + 0x74, 0x61, 0x6c, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x00, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x20, 0x65, + 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x00, 0x4d, 0x75, 0x6c, 0x74, + 0x69, 0x68, 0x6f, 0x70, 0x20, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, + 0x65, 0x64, 0x00, 0x43, 0x61, 0x70, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, + 0x69, 0x65, 0x6e, 0x74, 0x00, 0x4e, 0x6f, 0x20, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x2d, 0x2b, 0x20, 0x20, 0x20, 0x30, 0x58, 0x30, 0x78, + 0x00, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x00, 0x41, 0xc0, 0x16, 0x0b, + 0x18, 0x19, 0x00, 0x0a, 0x00, 0x19, 0x19, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x41, 0xe0, 0x16, 0x0b, 0x21, 0x19, 0x00, 0x11, 0x0a, 0x19, + 0x19, 0x19, 0x03, 0x0a, 0x07, 0x00, 0x01, 0x1b, 0x09, 0x0b, 0x18, 0x00, + 0x00, 0x09, 0x06, 0x0b, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x19, 0x00, 0x00, + 0x00, 0x19, 0x19, 0x19, 0x00, 0x41, 0x91, 0x17, 0x0b, 0x01, 0x0e, 0x00, + 0x41, 0x9a, 0x17, 0x0b, 0x18, 0x19, 0x00, 0x0a, 0x0d, 0x19, 0x19, 0x19, + 0x00, 0x0d, 0x00, 0x00, 0x02, 0x00, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x0e, 0x00, 0x00, 0x0e, 0x00, 0x41, 0xcb, 0x17, 0x0b, 0x01, 0x0c, + 0x00, 0x41, 0xd7, 0x17, 0x0b, 0x15, 0x13, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x0c, 0x00, 0x41, 0x85, 0x18, 0x0b, 0x01, 0x10, 0x00, 0x41, + 0x91, 0x18, 0x0b, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x10, 0x00, 0x41, 0xbf, 0x18, 0x0b, 0x01, 0x12, 0x00, 0x41, 0xcb, 0x18, + 0x0b, 0x1e, 0x11, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x1a, 0x1a, 0x00, 0x41, 0x82, 0x19, + 0x0b, 0x0e, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x1a, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x41, 0xb3, 0x19, 0x0b, 0x01, 0x14, 0x00, + 0x41, 0xbf, 0x19, 0x0b, 0x15, 0x17, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x14, 0x00, 0x41, 0xed, 0x19, 0x0b, 0x01, 0x16, 0x00, 0x41, 0xf9, + 0x19, 0x0b, 0x99, 0x01, 0x15, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x0a, 0x54, 0x6f, 0x20, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x69, 0x74, 0x2c, 0x20, 0x61, 0x64, + 0x64, 0x20, 0x2d, 0x6c, 0x63, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x73, + 0x63, 0x61, 0x6e, 0x2d, 0x6c, 0x6f, 0x6e, 0x67, 0x2d, 0x64, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, + 0x69, 0x6e, 0x6b, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, + 0x0a, 0x00, 0x41, 0xa0, 0x1b, 0x0b, 0x3a, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x2d, + 0x30, 0x58, 0x2b, 0x30, 0x58, 0x20, 0x30, 0x58, 0x2d, 0x30, 0x78, 0x2b, + 0x30, 0x78, 0x20, 0x30, 0x78, 0x00, 0x69, 0x6e, 0x66, 0x00, 0x49, 0x4e, + 0x46, 0x00, 0x6e, 0x61, 0x6e, 0x00, 0x4e, 0x41, 0x4e, 0x00, 0x2e, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x14, 0x00, 0x41, 0xb0, 0x28, 0x0b, 0x01, 0x05, + 0x00, 0x41, 0xbc, 0x28, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xd0, 0x28, 0x0b, + 0x0e, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x10, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x41, 0xe8, 0x28, 0x0b, 0x09, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x41, 0xa0, 0x29, 0x0b, 0x09, + 0x30, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x41, 0xb4, + 0x29, 0x0b, 0x01, 0x01, 0x00, 0x41, 0xc8, 0x29, 0x0b, 0x0a, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x24, 0x14, 0x00, 0x41, 0xe0, 0x29, + 0x0b, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x41, 0x98, 0x2a, 0x0b, 0x02, 0xa8, 0x14 +}; +unsigned int wasi_test_wasm_len = 27646; diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/sdkconfig.defaults b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/sdkconfig.defaults new file mode 100644 index 0000000..e5f6486 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf-wasi/sdkconfig.defaults @@ -0,0 +1,14 @@ +# Increased stack size +CONFIG_ESP_MAIN_TASK_STACK_SIZE=65536 + +# Disable task watchdog +CONFIG_ESP_TASK_WDT=n + +# Increase CPU frequency +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y + +# PSRAM support +CONFIG_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MALLOC=y + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.gitignore b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.gitignore new file mode 100644 index 0000000..d054d84 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.gitignore @@ -0,0 +1,3 @@ +build +sdkconfig +sdkconfig.old diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/Makefile b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/Makefile new file mode 100644 index 0000000..2f23716 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := wasm3 + +include $(IDF_PATH)/make/project.mk + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/component.mk b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/component.mk new file mode 100644 index 0000000..0b9d758 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/.old/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/CMakeLists.txt b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/CMakeLists.txt new file mode 100644 index 0000000..d88e541 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(wasm3) diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/README.md b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/README.md new file mode 100644 index 0000000..d340fd6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/README.md @@ -0,0 +1,24 @@ +## Build for ESP-IDF + +Download and install ESP-IDF v4.3-beta1 + +```sh +export IDF_PATH=/opt/esp32/esp-idf + +# Set tools path if needed: +#export IDF_TOOLS_PATH=/opt/esp32 + +source $IDF_PATH/export.sh + +idf.py menuconfig + +# Select target: +idf.py set-target esp32 +#idf.py set-target esp32s2 +#idf.py --preview set-target esp32c3 + +idf.py build + +idf.py -p /dev/ttyUSB0 flash monitor + +``` diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/CMakeLists.txt b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/CMakeLists.txt new file mode 100644 index 0000000..eaa975a --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/CMakeLists.txt @@ -0,0 +1,26 @@ +set(idf_ver "${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}") + +if (NOT CMAKE_BUILD_EARLY_EXPANSION) + idf_build_get_property(build_dir BUILD_DIR) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../../../source ${build_dir}/m3) +endif() + +set(APP_SOURCES "main.cpp") + +idf_component_register(SRCS ${APP_SOURCES} + INCLUDE_DIRS "" + LDFRAGMENTS linker.lf) + +if (idf_ver STREQUAL "4.0") + # IDF v4.0 links apps with -nostdlib, so need to explicitly list the dependencies. + + add_library(m3_deps INTERFACE) + target_link_libraries(m3_deps INTERFACE c m gcc) + target_link_libraries(${COMPONENT_TARGET} PRIVATE m3 m3_deps) +else() + # For IDF v4.1 and later, no tricks required. + + target_link_libraries(${COMPONENT_TARGET} PRIVATE m3) +endif() + +target_compile_options(m3 PUBLIC -DM3_IN_IRAM -DESP32 -O3 -freorder-blocks) diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/linker.lf b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/linker.lf new file mode 100644 index 0000000..077c98a --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/linker.lf @@ -0,0 +1,6 @@ +[mapping:wasm3] +archive: libm3.a +entries: + m3_core (noflash_text) + m3_exec (noflash_text) + m3_compile (noflash_text) diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/main.cpp b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/main.cpp new file mode 100644 index 0000000..43db66e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/main/main.cpp @@ -0,0 +1,70 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "esp_system.h" + +#include +#include +#include + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +static void run_wasm(void) +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + uint32_t fsize = fib32_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + result = m3_CallV(f, 24); + if (result) FATAL("m3_Call: %s", result); + + unsigned value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %u\n", value); +} + +extern "C" void app_main(void) +{ + printf("\nWasm3 v" M3_VERSION " on " CONFIG_IDF_TARGET ", build " __DATE__ " " __TIME__ "\n"); + + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC); + + sleep(3); + printf("Restarting...\n\n\n"); + esp_restart(); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-idf/sdkconfig.defaults b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/sdkconfig.defaults new file mode 100644 index 0000000..41dc237 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-idf/sdkconfig.defaults @@ -0,0 +1,8 @@ +# Increased stack size +CONFIG_ESP_MAIN_TASK_STACK_SIZE=32768 + +# Disable task watchdog +CONFIG_ESP_TASK_WDT=n + +# Increase CPU frequency +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/.gitignore b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/README.md b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/README.md new file mode 100644 index 0000000..6152d55 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/README.md @@ -0,0 +1,3 @@ +This is a placeholder for the wasm3 PIO library. + +At the moment it simply adds the source code as a symlink, and sets some build flags. diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/library.json b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/library.json new file mode 100644 index 0000000..f1b6cbe --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/library.json @@ -0,0 +1,5 @@ +{ + "build" : { + "flags": "-DESP32 -O3 -Wfatal-errors -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers" + } +} diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/src b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/src new file mode 120000 index 0000000..e3e41d7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/lib/wasm3/src @@ -0,0 +1 @@ +../../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/platformio.ini b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/platformio.ini new file mode 100644 index 0000000..42e4107 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = espidf + +monitor_speed = 115200 + +board_build.f_cpu = 240000000L diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/main.cpp b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/main.cpp new file mode 100644 index 0000000..43db66e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/main.cpp @@ -0,0 +1,70 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "esp_system.h" + +#include +#include +#include + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +static void run_wasm(void) +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + uint32_t fsize = fib32_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + result = m3_CallV(f, 24); + if (result) FATAL("m3_Call: %s", result); + + unsigned value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %u\n", value); +} + +extern "C" void app_main(void) +{ + printf("\nWasm3 v" M3_VERSION " on " CONFIG_IDF_TARGET ", build " __DATE__ " " __TIME__ "\n"); + + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC); + + sleep(3); + printf("Restarting...\n\n\n"); + esp_restart(); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig new file mode 100644 index 0000000..20625d8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig @@ -0,0 +1,962 @@ +# +# Automatically generated file; DO NOT EDIT. +# Espressif IoT Development Framework Configuration +# +CONFIG_IDF_TARGET="esp32" + +# +# SDK tool configuration +# +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +CONFIG_PYTHON="python" +CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +CONFIG_APP_EXCLUDE_PROJECT_VER_VAR= +CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR= + +# +# Bootloader config +# +CONFIG_LOG_BOOTLOADER_LEVEL_NONE= +CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= +CONFIG_LOG_BOOTLOADER_LEVEL_WARN= +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= +CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= +CONFIG_LOG_BOOTLOADER_LEVEL=3 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V= +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +CONFIG_BOOTLOADER_FACTORY_RESET= +CONFIG_BOOTLOADER_APP_TEST= +CONFIG_BOOTLOADER_WDT_ENABLE=y +CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +CONFIG_APP_ROLLBACK_ENABLE= + +# +# Security features +# +CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT= +CONFIG_SECURE_BOOT_ENABLED= +CONFIG_FLASH_ENCRYPTION_ENABLED= + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_PORT="COM19" +CONFIG_ESPTOOLPY_BAUD_115200B=y +CONFIG_ESPTOOLPY_BAUD_230400B= +CONFIG_ESPTOOLPY_BAUD_921600B= +CONFIG_ESPTOOLPY_BAUD_2MB= +CONFIG_ESPTOOLPY_BAUD_OTHER= +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_BAUD=115200 +CONFIG_ESPTOOLPY_COMPRESSED=y +CONFIG_FLASHMODE_QIO= +CONFIG_FLASHMODE_QOUT= +CONFIG_FLASHMODE_DIO=y +CONFIG_FLASHMODE_DOUT= +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M= +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHFREQ_26M= +CONFIG_ESPTOOLPY_FLASHFREQ_20M= +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +CONFIG_ESPTOOLPY_FLASHSIZE_1MB= +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB= +CONFIG_ESPTOOLPY_FLASHSIZE_8MB= +CONFIG_ESPTOOLPY_FLASHSIZE_16MB= +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +CONFIG_ESPTOOLPY_BEFORE_NORESET= +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +CONFIG_ESPTOOLPY_AFTER_NORESET= +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_MONITOR_BAUD_9600B= +CONFIG_MONITOR_BAUD_57600B= +CONFIG_MONITOR_BAUD_115200B=y +CONFIG_MONITOR_BAUD_230400B= +CONFIG_MONITOR_BAUD_921600B= +CONFIG_MONITOR_BAUD_2MB= +CONFIG_MONITOR_BAUD_OTHER= +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +CONFIG_PARTITION_TABLE_TWO_OTA= +CONFIG_PARTITION_TABLE_CUSTOM= +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y + +# +# Compiler options +# +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_OPTIMIZATION_LEVEL_RELEASE= +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= +CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= +CONFIG_CXX_EXCEPTIONS=y +CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 +CONFIG_STACK_CHECK_NONE=y +CONFIG_STACK_CHECK_NORM= +CONFIG_STACK_CHECK_STRONG= +CONFIG_STACK_CHECK_ALL= +CONFIG_STACK_CHECK= +CONFIG_WARN_WRITE_STRINGS= +CONFIG_DISABLE_GCC8_WARNINGS= + +# +# Component config +# + +# +# Application Level Tracing +# +CONFIG_ESP32_APPTRACE_DEST_TRAX= +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_ENABLE= +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_AWS_IOT_SDK=y +CONFIG_AWS_IOT_MQTT_HOST="" +CONFIG_AWS_IOT_MQTT_PORT=8883 +CONFIG_AWS_IOT_MQTT_TX_BUF_LEN=512 +CONFIG_AWS_IOT_MQTT_RX_BUF_LEN=512 +CONFIG_AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS=5 +CONFIG_AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL=1000 +CONFIG_AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL=128000 + +# +# Thing Shadow +# +CONFIG_AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER= +CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES=80 +CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS=10 +CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES=10 +CONFIG_AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED=120 +CONFIG_AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME=60 +CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME=20 + +# +# Bluetooth +# +CONFIG_BT_ENABLED=y + +# +# Bluetooth controller +# +CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= +CONFIG_BTDM_CONTROLLER_MODE_BTDM= +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=3 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0=y +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1= +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y +CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4= + +# +# MODEM SLEEP Options +# +CONFIG_BTDM_CONTROLLER_MODEM_SLEEP= +CONFIG_BLE_SCAN_DUPLICATE=y +CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR=y +CONFIG_SCAN_DUPLICATE_BY_ADV_DATA= +CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR= +CONFIG_SCAN_DUPLICATE_TYPE=0 +CONFIG_DUPLICATE_SCAN_CACHE_SIZE=50 +CONFIG_BLE_MESH_SCAN_DUPLICATE_EN= +CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED= +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED=y +CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM=100 +CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BLUEDROID_ENABLED=y +CONFIG_BLUEDROID_PINNED_TO_CORE_0=y +CONFIG_BLUEDROID_PINNED_TO_CORE_1= +CONFIG_BLUEDROID_PINNED_TO_CORE=0 +CONFIG_BTC_TASK_STACK_SIZE=32768 +CONFIG_BTU_TASK_STACK_SIZE=4096 +CONFIG_BLUEDROID_MEM_DEBUG= +CONFIG_CLASSIC_BT_ENABLED= +CONFIG_GATTS_ENABLE=y +CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL= +CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y +CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0 +CONFIG_GATTC_ENABLE=y +CONFIG_GATTC_CACHE_NVS_FLASH= +CONFIG_BLE_SMP_ENABLE=y +CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE= +CONFIG_BT_STACK_NO_LOG= + +# +# BT DEBUG LOG LEVEL +# +CONFIG_HCI_TRACE_LEVEL_NONE= +CONFIG_HCI_TRACE_LEVEL_ERROR= +CONFIG_HCI_TRACE_LEVEL_WARNING=y +CONFIG_HCI_TRACE_LEVEL_API= +CONFIG_HCI_TRACE_LEVEL_EVENT= +CONFIG_HCI_TRACE_LEVEL_DEBUG= +CONFIG_HCI_TRACE_LEVEL_VERBOSE= +CONFIG_HCI_INITIAL_TRACE_LEVEL=2 +CONFIG_BTM_TRACE_LEVEL_NONE= +CONFIG_BTM_TRACE_LEVEL_ERROR= +CONFIG_BTM_TRACE_LEVEL_WARNING=y +CONFIG_BTM_TRACE_LEVEL_API= +CONFIG_BTM_TRACE_LEVEL_EVENT= +CONFIG_BTM_TRACE_LEVEL_DEBUG= +CONFIG_BTM_TRACE_LEVEL_VERBOSE= +CONFIG_BTM_INITIAL_TRACE_LEVEL=2 +CONFIG_L2CAP_TRACE_LEVEL_NONE= +CONFIG_L2CAP_TRACE_LEVEL_ERROR= +CONFIG_L2CAP_TRACE_LEVEL_WARNING=y +CONFIG_L2CAP_TRACE_LEVEL_API= +CONFIG_L2CAP_TRACE_LEVEL_EVENT= +CONFIG_L2CAP_TRACE_LEVEL_DEBUG= +CONFIG_L2CAP_TRACE_LEVEL_VERBOSE= +CONFIG_L2CAP_INITIAL_TRACE_LEVEL=2 +CONFIG_RFCOMM_TRACE_LEVEL_NONE= +CONFIG_RFCOMM_TRACE_LEVEL_ERROR= +CONFIG_RFCOMM_TRACE_LEVEL_WARNING=y +CONFIG_RFCOMM_TRACE_LEVEL_API= +CONFIG_RFCOMM_TRACE_LEVEL_EVENT= +CONFIG_RFCOMM_TRACE_LEVEL_DEBUG= +CONFIG_RFCOMM_TRACE_LEVEL_VERBOSE= +CONFIG_RFCOMM_INITIAL_TRACE_LEVEL=2 +CONFIG_SDP_TRACE_LEVEL_NONE= +CONFIG_SDP_TRACE_LEVEL_ERROR= +CONFIG_SDP_TRACE_LEVEL_WARNING=y +CONFIG_SDP_TRACE_LEVEL_API= +CONFIG_SDP_TRACE_LEVEL_EVENT= +CONFIG_SDP_TRACE_LEVEL_DEBUG= +CONFIG_SDP_TRACE_LEVEL_VERBOSE= +CONFIG_SDP_INITIAL_TRACE_LEVEL=2 +CONFIG_GAP_TRACE_LEVEL_NONE= +CONFIG_GAP_TRACE_LEVEL_ERROR= +CONFIG_GAP_TRACE_LEVEL_WARNING=y +CONFIG_GAP_TRACE_LEVEL_API= +CONFIG_GAP_TRACE_LEVEL_EVENT= +CONFIG_GAP_TRACE_LEVEL_DEBUG= +CONFIG_GAP_TRACE_LEVEL_VERBOSE= +CONFIG_GAP_INITIAL_TRACE_LEVEL=2 +CONFIG_BNEP_TRACE_LEVEL_NONE= +CONFIG_BNEP_TRACE_LEVEL_ERROR= +CONFIG_BNEP_TRACE_LEVEL_WARNING=y +CONFIG_BNEP_TRACE_LEVEL_API= +CONFIG_BNEP_TRACE_LEVEL_EVENT= +CONFIG_BNEP_TRACE_LEVEL_DEBUG= +CONFIG_BNEP_TRACE_LEVEL_VERBOSE= +CONFIG_BNEP_INITIAL_TRACE_LEVEL=2 +CONFIG_PAN_TRACE_LEVEL_NONE= +CONFIG_PAN_TRACE_LEVEL_ERROR= +CONFIG_PAN_TRACE_LEVEL_WARNING=y +CONFIG_PAN_TRACE_LEVEL_API= +CONFIG_PAN_TRACE_LEVEL_EVENT= +CONFIG_PAN_TRACE_LEVEL_DEBUG= +CONFIG_PAN_TRACE_LEVEL_VERBOSE= +CONFIG_PAN_INITIAL_TRACE_LEVEL=2 +CONFIG_A2D_TRACE_LEVEL_NONE= +CONFIG_A2D_TRACE_LEVEL_ERROR= +CONFIG_A2D_TRACE_LEVEL_WARNING=y +CONFIG_A2D_TRACE_LEVEL_API= +CONFIG_A2D_TRACE_LEVEL_EVENT= +CONFIG_A2D_TRACE_LEVEL_DEBUG= +CONFIG_A2D_TRACE_LEVEL_VERBOSE= +CONFIG_A2D_INITIAL_TRACE_LEVEL=2 +CONFIG_AVDT_TRACE_LEVEL_NONE= +CONFIG_AVDT_TRACE_LEVEL_ERROR= +CONFIG_AVDT_TRACE_LEVEL_WARNING=y +CONFIG_AVDT_TRACE_LEVEL_API= +CONFIG_AVDT_TRACE_LEVEL_EVENT= +CONFIG_AVDT_TRACE_LEVEL_DEBUG= +CONFIG_AVDT_TRACE_LEVEL_VERBOSE= +CONFIG_AVDT_INITIAL_TRACE_LEVEL=2 +CONFIG_AVCT_TRACE_LEVEL_NONE= +CONFIG_AVCT_TRACE_LEVEL_ERROR= +CONFIG_AVCT_TRACE_LEVEL_WARNING=y +CONFIG_AVCT_TRACE_LEVEL_API= +CONFIG_AVCT_TRACE_LEVEL_EVENT= +CONFIG_AVCT_TRACE_LEVEL_DEBUG= +CONFIG_AVCT_TRACE_LEVEL_VERBOSE= +CONFIG_AVCT_INITIAL_TRACE_LEVEL=2 +CONFIG_AVRC_TRACE_LEVEL_NONE= +CONFIG_AVRC_TRACE_LEVEL_ERROR= +CONFIG_AVRC_TRACE_LEVEL_WARNING=y +CONFIG_AVRC_TRACE_LEVEL_API= +CONFIG_AVRC_TRACE_LEVEL_EVENT= +CONFIG_AVRC_TRACE_LEVEL_DEBUG= +CONFIG_AVRC_TRACE_LEVEL_VERBOSE= +CONFIG_AVRC_INITIAL_TRACE_LEVEL=2 +CONFIG_MCA_TRACE_LEVEL_NONE= +CONFIG_MCA_TRACE_LEVEL_ERROR= +CONFIG_MCA_TRACE_LEVEL_WARNING=y +CONFIG_MCA_TRACE_LEVEL_API= +CONFIG_MCA_TRACE_LEVEL_EVENT= +CONFIG_MCA_TRACE_LEVEL_DEBUG= +CONFIG_MCA_TRACE_LEVEL_VERBOSE= +CONFIG_MCA_INITIAL_TRACE_LEVEL=2 +CONFIG_HID_TRACE_LEVEL_NONE= +CONFIG_HID_TRACE_LEVEL_ERROR= +CONFIG_HID_TRACE_LEVEL_WARNING=y +CONFIG_HID_TRACE_LEVEL_API= +CONFIG_HID_TRACE_LEVEL_EVENT= +CONFIG_HID_TRACE_LEVEL_DEBUG= +CONFIG_HID_TRACE_LEVEL_VERBOSE= +CONFIG_HID_INITIAL_TRACE_LEVEL=2 +CONFIG_APPL_TRACE_LEVEL_NONE= +CONFIG_APPL_TRACE_LEVEL_ERROR= +CONFIG_APPL_TRACE_LEVEL_WARNING=y +CONFIG_APPL_TRACE_LEVEL_API= +CONFIG_APPL_TRACE_LEVEL_EVENT= +CONFIG_APPL_TRACE_LEVEL_DEBUG= +CONFIG_APPL_TRACE_LEVEL_VERBOSE= +CONFIG_APPL_INITIAL_TRACE_LEVEL=2 +CONFIG_GATT_TRACE_LEVEL_NONE= +CONFIG_GATT_TRACE_LEVEL_ERROR= +CONFIG_GATT_TRACE_LEVEL_WARNING=y +CONFIG_GATT_TRACE_LEVEL_API= +CONFIG_GATT_TRACE_LEVEL_EVENT= +CONFIG_GATT_TRACE_LEVEL_DEBUG= +CONFIG_GATT_TRACE_LEVEL_VERBOSE= +CONFIG_GATT_INITIAL_TRACE_LEVEL=2 +CONFIG_SMP_TRACE_LEVEL_NONE= +CONFIG_SMP_TRACE_LEVEL_ERROR= +CONFIG_SMP_TRACE_LEVEL_WARNING=y +CONFIG_SMP_TRACE_LEVEL_API= +CONFIG_SMP_TRACE_LEVEL_EVENT= +CONFIG_SMP_TRACE_LEVEL_DEBUG= +CONFIG_SMP_TRACE_LEVEL_VERBOSE= +CONFIG_SMP_INITIAL_TRACE_LEVEL=2 +CONFIG_BTIF_TRACE_LEVEL_NONE= +CONFIG_BTIF_TRACE_LEVEL_ERROR= +CONFIG_BTIF_TRACE_LEVEL_WARNING=y +CONFIG_BTIF_TRACE_LEVEL_API= +CONFIG_BTIF_TRACE_LEVEL_EVENT= +CONFIG_BTIF_TRACE_LEVEL_DEBUG= +CONFIG_BTIF_TRACE_LEVEL_VERBOSE= +CONFIG_BTIF_INITIAL_TRACE_LEVEL=2 +CONFIG_BTC_TRACE_LEVEL_NONE= +CONFIG_BTC_TRACE_LEVEL_ERROR= +CONFIG_BTC_TRACE_LEVEL_WARNING=y +CONFIG_BTC_TRACE_LEVEL_API= +CONFIG_BTC_TRACE_LEVEL_EVENT= +CONFIG_BTC_TRACE_LEVEL_DEBUG= +CONFIG_BTC_TRACE_LEVEL_VERBOSE= +CONFIG_BTC_INITIAL_TRACE_LEVEL=2 +CONFIG_OSI_TRACE_LEVEL_NONE= +CONFIG_OSI_TRACE_LEVEL_ERROR= +CONFIG_OSI_TRACE_LEVEL_WARNING=y +CONFIG_OSI_TRACE_LEVEL_API= +CONFIG_OSI_TRACE_LEVEL_EVENT= +CONFIG_OSI_TRACE_LEVEL_DEBUG= +CONFIG_OSI_TRACE_LEVEL_VERBOSE= +CONFIG_OSI_INITIAL_TRACE_LEVEL=2 +CONFIG_BLUFI_TRACE_LEVEL_NONE= +CONFIG_BLUFI_TRACE_LEVEL_ERROR= +CONFIG_BLUFI_TRACE_LEVEL_WARNING=y +CONFIG_BLUFI_TRACE_LEVEL_API= +CONFIG_BLUFI_TRACE_LEVEL_EVENT= +CONFIG_BLUFI_TRACE_LEVEL_DEBUG= +CONFIG_BLUFI_TRACE_LEVEL_VERBOSE= +CONFIG_BLUFI_INITIAL_TRACE_LEVEL=2 +CONFIG_BT_ACL_CONNECTIONS=4 +CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST= +CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY= +CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK= +CONFIG_SMP_ENABLE=y +CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY= +CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 +CONFIG_BT_RESERVE_DRAM=0xdb5c + +# +# Driver configurations +# + +# +# ADC configuration +# +CONFIG_ADC_FORCE_XPD_FSM= +CONFIG_ADC2_DISABLE_DAC=y + +# +# SPI configuration +# +CONFIG_SPI_MASTER_IN_IRAM= +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +CONFIG_SPI_SLAVE_IN_IRAM= +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y + +# +# eFuse Bit Manager +# +CONFIG_EFUSE_CUSTOM_TABLE= +CONFIG_EFUSE_VIRTUAL= +CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE= +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT= +CONFIG_EFUSE_MAX_BLK_LEN=192 + +# +# ESP32-specific +# +CONFIG_IDF_TARGET_ESP32=y +CONFIG_ESP32_REV_MIN_0= +CONFIG_ESP32_REV_MIN_1=y +CONFIG_ESP32_REV_MIN_2= +CONFIG_ESP32_REV_MIN_3= +CONFIG_ESP32_REV_MIN=1 +CONFIG_ESP32_DPORT_WORKAROUND=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_80= +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_240= +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_SPIRAM_SUPPORT= +CONFIG_MEMMAP_TRACEMEM= +CONFIG_MEMMAP_TRACEMEM_TWOBANKS= +CONFIG_ESP32_TRAX= +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= +CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= +CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +CONFIG_NEWLIB_NANO_FORMAT= +CONFIG_CONSOLE_UART_DEFAULT=y +CONFIG_CONSOLE_UART_CUSTOM= +CONFIG_CONSOLE_UART_NONE= +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ULP_COPROC_ENABLED= +CONFIG_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32_PANIC_PRINT_HALT= +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +CONFIG_ESP32_PANIC_SILENT_REBOOT= +CONFIG_ESP32_PANIC_GDBSTUB= +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP32_DEBUG_STUBS_ENABLE=y +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_TASK_WDT_PANIC= +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +CONFIG_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_BROWNOUT_DET_LVL_SEL_1= +CONFIG_BROWNOUT_DET_LVL_SEL_2= +CONFIG_BROWNOUT_DET_LVL_SEL_3= +CONFIG_BROWNOUT_DET_LVL_SEL_4= +CONFIG_BROWNOUT_DET_LVL_SEL_5= +CONFIG_BROWNOUT_DET_LVL_SEL_6= +CONFIG_BROWNOUT_DET_LVL_SEL_7= +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC= +CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= +CONFIG_ESP32_TIME_SYSCALL_USE_NONE= +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= +CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC= +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256= +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_XTAL_FREQ_40=y +CONFIG_ESP32_XTAL_FREQ_26= +CONFIG_ESP32_XTAL_FREQ_AUTO= +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_DISABLE_BASIC_ROM_CONSOLE= +CONFIG_ESP_TIMER_PROFILING= +CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y + +# +# Wi-Fi +# +CONFIG_SW_COEXIST_ENABLE=y +CONFIG_SW_COEXIST_PREFERENCE_WIFI= +CONFIG_SW_COEXIST_PREFERENCE_BT= +CONFIG_SW_COEXIST_PREFERENCE_BALANCE=y +CONFIG_SW_COEXIST_PREFERENCE_VALUE=2 +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_CSI_ENABLED= +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1= +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE= +CONFIG_ESP32_WIFI_IRAM_OPT=y + +# +# PHY +# +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 + +# +# Power Management +# +CONFIG_PM_ENABLE= + +# +# ADC-Calibration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y + +# +# Event Loop Library +# +CONFIG_EVENT_LOOP_PROFILING= + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +CONFIG_HTTPD_LOG_PURGE_DATA= + +# +# ESP HTTPS OTA +# +CONFIG_OTA_ALLOW_HTTP= + +# +# Core dump +# +CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= +CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_ESP32_ENABLE_COREDUMP= + +# +# Ethernet +# +CONFIG_DMA_RX_BUF_NUM=10 +CONFIG_DMA_TX_BUF_NUM=10 +CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= +CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 +CONFIG_EMAC_TASK_PRIORITY=20 +CONFIG_EMAC_TASK_STACK_SIZE=3072 + +# +# FAT Filesystem support +# +CONFIG_FATFS_CODEPAGE_DYNAMIC= +CONFIG_FATFS_CODEPAGE_437=y +CONFIG_FATFS_CODEPAGE_720= +CONFIG_FATFS_CODEPAGE_737= +CONFIG_FATFS_CODEPAGE_771= +CONFIG_FATFS_CODEPAGE_775= +CONFIG_FATFS_CODEPAGE_850= +CONFIG_FATFS_CODEPAGE_852= +CONFIG_FATFS_CODEPAGE_855= +CONFIG_FATFS_CODEPAGE_857= +CONFIG_FATFS_CODEPAGE_860= +CONFIG_FATFS_CODEPAGE_861= +CONFIG_FATFS_CODEPAGE_862= +CONFIG_FATFS_CODEPAGE_863= +CONFIG_FATFS_CODEPAGE_864= +CONFIG_FATFS_CODEPAGE_865= +CONFIG_FATFS_CODEPAGE_866= +CONFIG_FATFS_CODEPAGE_869= +CONFIG_FATFS_CODEPAGE_932= +CONFIG_FATFS_CODEPAGE_936= +CONFIG_FATFS_CODEPAGE_949= +CONFIG_FATFS_CODEPAGE_950= +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +CONFIG_FATFS_LFN_HEAP= +CONFIG_FATFS_LFN_STACK= +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y + +# +# Modbus configuration +# +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT= +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_MB_TIMER_PORT_ENABLED=y +CONFIG_MB_TIMER_GROUP=0 +CONFIG_MB_TIMER_INDEX=0 + +# +# FreeRTOS +# +CONFIG_FREERTOS_UNICORE= +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +CONFIG_FREERTOS_CORETIMER_1= +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL= +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= +CONFIG_FREERTOS_ASSERT_DISABLE= +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_LEGACY_HOOKS= +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_SUPPORT_STATIC_ALLOCATION= +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_USE_TRACE_FACILITY= +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= +CONFIG_FREERTOS_DEBUG_INTERNALS= +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE= + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +CONFIG_HEAP_POISONING_LIGHT= +CONFIG_HEAP_POISONING_COMPREHENSIVE= +CONFIG_HEAP_TRACING= + +# +# libsodium +# +CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE= +CONFIG_LOG_DEFAULT_LEVEL_ERROR= +CONFIG_LOG_DEFAULT_LEVEL_WARN= +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +CONFIG_LOG_DEFAULT_LEVEL_DEBUG= +CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_COLORS=y + +# +# LWIP +# +CONFIG_L2_TO_L3_COPY= +CONFIG_LWIP_IRAM_OPTIMIZATION= +CONFIG_LWIP_MAX_SOCKETS=10 +CONFIG_USE_ONLY_LWIP_SELECT= +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF= +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_IP_FRAG= +CONFIG_LWIP_IP_REASSEMBLY= +CONFIG_LWIP_STATS= +CONFIG_LWIP_ETHARP_TRUST_IP_MAC= +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +CONFIG_LWIP_DHCP_RESTORE_LAST_IP= + +# +# DHCP server +# +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_AUTOIP= +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=6 +CONFIG_TCP_MSS=1436 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES= +CONFIG_TCP_OVERSIZE_MSS=y +CONFIG_TCP_OVERSIZE_QUARTER_MSS= +CONFIG_TCP_OVERSIZE_DISABLE= + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=2048 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +CONFIG_TCPIP_TASK_AFFINITY_CPU0= +CONFIG_TCPIP_TASK_AFFINITY_CPU1= +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +CONFIG_PPP_SUPPORT= + +# +# ICMP +# +CONFIG_LWIP_MULTICAST_PING= +CONFIG_LWIP_BROADCAST_PING= + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= +CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= +CONFIG_MBEDTLS_DEBUG= +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI= +CONFIG_MBEDTLS_HARDWARE_SHA= +CONFIG_MBEDTLS_HAVE_TIME=y +CONFIG_MBEDTLS_HAVE_TIME_DATE= +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +CONFIG_MBEDTLS_TLS_SERVER_ONLY= +CONFIG_MBEDTLS_TLS_CLIENT_ONLY= +CONFIG_MBEDTLS_TLS_DISABLED= +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +CONFIG_MBEDTLS_PSK_MODES= +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_SSL3= +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS= +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +CONFIG_MBEDTLS_CAMELLIA_C= +CONFIG_MBEDTLS_DES_C= +CONFIG_MBEDTLS_RC4_DISABLED=y +CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= +CONFIG_MBEDTLS_RC4_ENABLED= +CONFIG_MBEDTLS_BLOWFISH_C= +CONFIG_MBEDTLS_XTEA_C= +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +CONFIG_MBEDTLS_RIPEMD160_C= + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +CONFIG_MQTT_USE_CUSTOM_CONFIG= +CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED= +CONFIG_MQTT_CUSTOM_OUTBOX= + +# +# NVS +# + +# +# OpenSSL +# +CONFIG_OPENSSL_DEBUG= +CONFIG_OPENSSL_ASSERT_DO_NOTHING=y +CONFIG_OPENSSL_ASSERT_EXIT= + +# +# PThreads +# +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0= +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1= +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" + +# +# SPI Flash driver +# +CONFIG_SPI_FLASH_VERIFY_WRITE= +CONFIG_SPI_FLASH_ENABLE_COUNTERS= +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +CONFIG_SPIFFS_CACHE_STATS= +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +CONFIG_SPIFFS_GC_STATS= +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +CONFIG_SPIFFS_DBG= +CONFIG_SPIFFS_API_DBG= +CONFIG_SPIFFS_GC_DBG= +CONFIG_SPIFFS_CACHE_DBG= +CONFIG_SPIFFS_CHECK_DBG= +CONFIG_SPIFFS_TEST_VISUALISATION= + +# +# TCP/IP Adapter +# +CONFIG_IP_LOST_TIMER_INTERVAL=120 +CONFIG_TCPIP_LWIP=y + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +CONFIG_UNITY_ENABLE_COLOR= +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +CONFIG_UNITY_ENABLE_FIXTURE= + +# +# Virtual file system +# +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y + +# +# Wear Levelling +# +CONFIG_WL_SECTOR_SIZE_512= +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 diff --git a/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig.h b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig.h new file mode 100644 index 0000000..4423559 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp32-pio/src/sdkconfig.h @@ -0,0 +1,371 @@ +/* + * + * Automatically generated file; DO NOT EDIT. + * Espressif IoT Development Framework Configuration + * + */ + +#define CONFIG_ENABLE_ARDUINO_DEPENDS 1 +#define CONFIG_AUTOSTART_ARDUINO 1 +#define CONFIG_ARDUINO_RUNNING_CORE 1 +#define CONFIG_ARDUINO_UDP_RUN_CORE1 1 +#define CONFIG_ARDUINO_EVENT_RUN_CORE1 1 +#define CONFIG_ARDUINO_EVENT_RUNNING_CORE 1 +#define CONFIG_ARDUINO_UDP_RUNNING_CORE 1 + +#define CONFIG_GATTC_ENABLE 1 +#define CONFIG_ESP32_PHY_MAX_TX_POWER 20 +#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0 +#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 +#define CONFIG_MQTT_TRANSPORT_SSL 1 +#define CONFIG_BLE_SMP_ENABLE 1 +#define CONFIG_FATFS_LFN_NONE 1 +#define CONFIG_SDP_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MB_SERIAL_TASK_PRIO 10 +#define CONFIG_MQTT_PROTOCOL_311 1 +#define CONFIG_TCP_RECVMBOX_SIZE 6 +#define CONFIG_FATFS_CODEPAGE_437 1 +#define CONFIG_BLE_SCAN_DUPLICATE 1 +#define CONFIG_AVDT_TRACE_LEVEL_WARNING 1 +#define CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS 10 +#define CONFIG_TCP_WND_DEFAULT 5744 +#define CONFIG_PARTITION_TABLE_OFFSET 0x8000 +#define CONFIG_SW_COEXIST_ENABLE 1 +#define CONFIG_SPIFFS_USE_MAGIC_LENGTH 1 +#define CONFIG_AVCT_INITIAL_TRACE_LEVEL 2 +#define CONFIG_IPC_TASK_STACK_SIZE 1024 +#define CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES 16 +#define CONFIG_FATFS_PER_FILE_CACHE 1 +#define CONFIG_ESPTOOLPY_FLASHFREQ "40m" +#define CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME 20 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_RSA 1 +#define CONFIG_UDP_RECVMBOX_SIZE 6 +#define CONFIG_SPI_FLASH_YIELD_DURING_ERASE 1 +#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0 +#define CONFIG_MBEDTLS_AES_C 1 +#define CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED 1 +#define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752 +#define CONFIG_MBEDTLS_GCM_C 1 +#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB" +#define CONFIG_HEAP_POISONING_DISABLED 1 +#define CONFIG_SPIFFS_CACHE_WR 1 +#define CONFIG_BROWNOUT_DET_LVL_SEL_0 1 +#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1 +#define CONFIG_SPIFFS_CACHE 1 +#define CONFIG_INT_WDT 1 +#define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN 3 +#define CONFIG_MBEDTLS_SSL_PROTO_TLS1 1 +#define CONFIG_ESP_GRATUITOUS_ARP 1 +#define CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES 80 +#define CONFIG_MBEDTLS_ECDSA_C 1 +#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1 +#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO 1 +#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1 +#define CONFIG_HTTPD_MAX_REQ_HDR_LEN 512 +#define CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE 0 +#define CONFIG_AWS_IOT_MQTT_PORT 8883 +#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 +#define CONFIG_MBEDTLS_ECDH_C 1 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE 1 +#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10 +#define CONFIG_AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL 128000 +#define CONFIG_MBEDTLS_SSL_ALPN 1 +#define CONFIG_BTM_TRACE_LEVEL_WARNING 1 +#define CONFIG_MBEDTLS_PEM_WRITE_C 1 +#define CONFIG_RFCOMM_TRACE_LEVEL_WARNING 1 +#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1 +#define CONFIG_BT_RESERVE_DRAM 0xdb5c +#define CONFIG_APP_COMPILE_TIME_DATE 1 +#define CONFIG_FATFS_FS_LOCK 0 +#define CONFIG_IP_LOST_TIMER_INTERVAL 120 +#define CONFIG_SPIFFS_META_LENGTH 4 +#define CONFIG_ESP32_PANIC_PRINT_REBOOT 1 +#define CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE 20 +#define CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED 1 +#define CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED 1 +#define CONFIG_AWS_IOT_MQTT_RX_BUF_LEN 512 +#define CONFIG_MB_SERIAL_BUF_SIZE 256 +#define CONFIG_CONSOLE_UART_BAUDRATE 115200 +#define CONFIG_LWIP_MAX_SOCKETS 10 +#define CONFIG_LWIP_NETIF_LOOPBACK 1 +#define CONFIG_MCA_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT "pthread" +#define CONFIG_EMAC_TASK_PRIORITY 20 +#define CONFIG_TIMER_TASK_STACK_DEPTH 2048 +#define CONFIG_TCP_MSS 1436 +#define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1 +#define CONFIG_BTIF_INITIAL_TRACE_LEVEL 2 +#define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF 3 +#define CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 1 +#define CONFIG_FATFS_CODEPAGE 437 +#define CONFIG_APPL_TRACE_LEVEL_WARNING 1 +#define CONFIG_BTC_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1 +#define CONFIG_ULP_COPROC_RESERVE_MEM 0 +#define CONFIG_LWIP_MAX_UDP_PCBS 16 +#define CONFIG_ESPTOOLPY_BAUD 115200 +#define CONFIG_INT_WDT_CHECK_CPU1 1 +#define CONFIG_AVRC_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ADC_CAL_LUT_ENABLE 1 +#define CONFIG_AWS_IOT_MQTT_TX_BUF_LEN 512 +#define CONFIG_FLASHMODE_DIO 1 +#define CONFIG_ESPTOOLPY_AFTER_RESET 1 +#define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED 1 +#define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8 +#define CONFIG_TOOLPREFIX "xtensa-esp32-elf-" +#define CONFIG_MBEDTLS_ECP_C 1 +#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1536 +#define CONFIG_MBEDTLS_RC4_DISABLED 1 +#define CONFIG_GAP_TRACE_LEVEL_WARNING 1 +#define CONFIG_CONSOLE_UART_NUM 0 +#define CONFIG_AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED 120 +#define CONFIG_ESP32_APPTRACE_LOCK_ENABLE 1 +#define CONFIG_PTHREAD_STACK_MIN 768 +#define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1 +#define CONFIG_ESPTOOLPY_BAUD_115200B 1 +#define CONFIG_TCP_OVERSIZE_MSS 1 +#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1 +#define CONFIG_CONSOLE_UART_DEFAULT 1 +#define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384 +#define CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS 4 +#define CONFIG_GATT_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1 +#define CONFIG_TIMER_TASK_STACK_SIZE 3584 +#define CONFIG_BTIF_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1 +#define CONFIG_HCI_INITIAL_TRACE_LEVEL 2 +#define CONFIG_AVDT_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1 +#define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1 +#define CONFIG_HTTPD_PURGE_BUF_LEN 32 +#define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR 1 +#define CONFIG_AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME 60 +#define CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER 1 +#define CONFIG_MB_SERIAL_TASK_STACK_SIZE 2048 +#define CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO 1 +#define CONFIG_LWIP_DHCPS_LEASE_UNIT 60 +#define CONFIG_EFUSE_MAX_BLK_LEN 192 +#define CONFIG_SPIFFS_USE_MAGIC 1 +#define CONFIG_TCPIP_TASK_STACK_SIZE 2048 +#define CONFIG_BLUFI_TRACE_LEVEL_WARNING 1 +#define CONFIG_BLUEDROID_PINNED_TO_CORE_0 1 +#define CONFIG_TASK_WDT 1 +#define CONFIG_RFCOMM_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MAIN_TASK_STACK_SIZE 32768 +#define CONFIG_SPIFFS_PAGE_CHECK 1 +#define CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 1 +#define CONFIG_LWIP_MAX_ACTIVE_TCP 16 +#define CONFIG_TASK_WDT_TIMEOUT_S 5 +#define CONFIG_INT_WDT_TIMEOUT_MS 300 +#define CONFIG_ESPTOOLPY_FLASHMODE "dio" +#define CONFIG_BTC_TASK_STACK_SIZE 3072 +#define CONFIG_BLUEDROID_ENABLED 1 +#define CONFIG_NEWLIB_STDIN_LINE_ENDING_CR 1 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA 1 +#define CONFIG_ESPTOOLPY_BEFORE "default_reset" +#define CONFIG_ADC2_DISABLE_DAC 1 +#define CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM 100 +#define CONFIG_ESP32_REV_MIN_1 1 +#define CONFIG_LOG_DEFAULT_LEVEL 3 +#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1 +#define CONFIG_TIMER_QUEUE_LENGTH 10 +#define CONFIG_ESP32_REV_MIN 1 +#define CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT 1 +#define CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE 0 +#define CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY 1 +#define CONFIG_MAKE_WARN_UNDEFINED_VARIABLES 1 +#define CONFIG_FATFS_TIMEOUT_MS 10000 +#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32 +#define CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS 1 +#define CONFIG_PAN_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MBEDTLS_CCM_C 1 +#define CONFIG_SPI_MASTER_ISR_IN_IRAM 1 +#define CONFIG_MCA_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20 +#define CONFIG_A2D_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024 +#define CONFIG_ESP32_WIFI_TX_BA_WIN 6 +#define CONFIG_ESP32_WIFI_NVS_ENABLED 1 +#define CONFIG_MDNS_MAX_SERVICES 10 +#define CONFIG_IDF_TARGET_ESP32 1 +#define CONFIG_EMAC_CHECK_LINK_PERIOD_MS 2000 +#define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1 +#define CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS 20 +#define CONFIG_LIBSODIUM_USE_MBEDTLS_SHA 1 +#define CONFIG_AWS_IOT_SDK 1 +#define CONFIG_DMA_RX_BUF_NUM 10 +#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1 +#define CONFIG_TCP_SYNMAXRTX 6 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1 +#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0 +#define CONFIG_PYTHON "python" +#define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1 +#define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1 +#define CONFIG_ESPTOOLPY_COMPRESSED 1 +#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv" +#define CONFIG_MB_CONTROLLER_STACK_SIZE 4096 +#define CONFIG_TCP_SND_BUF_DEFAULT 5744 +#define CONFIG_GARP_TMR_INTERVAL 60 +#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1 +#define CONFIG_BNEP_INITIAL_TRACE_LEVEL 2 +#define CONFIG_HCI_TRACE_LEVEL_WARNING 1 +#define CONFIG_TCP_MSL 60000 +#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1 +#define CONFIG_LWIP_SO_REUSE_RXTOALL 1 +#define CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT 20 +#define CONFIG_ESP32_WIFI_MGMT_SBUF_NUM 32 +#define CONFIG_PARTITION_TABLE_SINGLE_APP 1 +#define CONFIG_UNITY_ENABLE_FLOAT 1 +#define CONFIG_ESP32_WIFI_RX_BA_WIN 6 +#define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1 +#define CONFIG_SPIFFS_USE_MTIME 1 +#define CONFIG_BTC_TRACE_LEVEL_WARNING 1 +#define CONFIG_EMAC_TASK_STACK_SIZE 3072 +#define CONFIG_SMP_TRACE_LEVEL_WARNING 1 +#define CONFIG_MB_QUEUE_LENGTH 20 +#define CONFIG_SW_COEXIST_PREFERENCE_VALUE 2 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1 +#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1 +#define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1 +#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 2304 +#define CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V 1 +#define CONFIG_A2D_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000 +#define CONFIG_AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS 5 +#define CONFIG_BROWNOUT_DET_LVL 0 +#define CONFIG_MBEDTLS_PEM_PARSE_C 1 +#define CONFIG_SPIFFS_GC_MAX_RUNS 10 +#define CONFIG_ESP32_APPTRACE_DEST_NONE 1 +#define CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC 1 +#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1 +#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32 +#define CONFIG_HTTPD_MAX_URI_LEN 512 +#define CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED 1 +#define CONFIG_AVCT_TRACE_LEVEL_WARNING 1 +#define CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED 1 +#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 1 +#define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160 +#define CONFIG_MBEDTLS_HARDWARE_AES 1 +#define CONFIG_FREERTOS_HZ 100 +#define CONFIG_LOG_COLORS 1 +#define CONFIG_OSI_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1 +#define CONFIG_STACK_CHECK_NONE 1 +#define CONFIG_ADC_CAL_EFUSE_TP_ENABLE 1 +#define CONFIG_BNEP_TRACE_LEVEL_WARNING 1 +#define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1 +#define CONFIG_BROWNOUT_DET 1 +#define CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES 10 +#define CONFIG_ESP32_XTAL_FREQ 40 +#define CONFIG_OSI_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MONITOR_BAUD_115200B 1 +#define CONFIG_LOG_BOOTLOADER_LEVEL 3 +#define CONFIG_MBEDTLS_TLS_ENABLED 1 +#define CONFIG_LWIP_MAX_RAW_PCBS 16 +#define CONFIG_BTU_TASK_STACK_SIZE 4096 +#define CONFIG_SMP_ENABLE 1 +#define CONFIG_HID_TRACE_LEVEL_WARNING 1 +#define CONFIG_AVRC_TRACE_LEVEL_WARNING 1 +#define CONFIG_MBEDTLS_SSL_SESSION_TICKETS 1 +#define CONFIG_SPIFFS_MAX_PARTITIONS 3 +#define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1 +#define CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0 1 +#define CONFIG_MBEDTLS_SSL_RENEGOTIATION 1 +#define CONFIG_HID_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESPTOOLPY_BEFORE_RESET 1 +#define CONFIG_MB_EVENT_QUEUE_TIMEOUT 20 +#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 +#define CONFIG_SPIFFS_OBJ_NAME_LEN 32 +#define CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT 5 +#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF 0 +#define CONFIG_PARTITION_TABLE_MD5 1 +#define CONFIG_TCPIP_RECVMBOX_SIZE 32 +#define CONFIG_TCP_MAXRTX 12 +#define CONFIG_BTM_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESPTOOLPY_AFTER "hard_reset" +#define CONFIG_TCPIP_TASK_AFFINITY 0x7FFFFFFF +#define CONFIG_LWIP_SO_REUSE 1 +#define CONFIG_ESP32_XTAL_FREQ_40 1 +#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY 1 +#define CONFIG_DMA_TX_BUF_NUM 10 +#define CONFIG_LWIP_MAX_LISTENING_TCP 16 +#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1 +#define CONFIG_WL_SECTOR_SIZE 4096 +#define CONFIG_ESP32_DEBUG_OCDAWARE 1 +#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 +#define CONFIG_TIMER_TASK_PRIORITY 1 +#define CONFIG_MBEDTLS_TLS_CLIENT 1 +#define CONFIG_AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL 1000 +#define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI 1 +#define CONFIG_BT_ENABLED 1 +#define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY 1 +#define CONFIG_SDP_TRACE_LEVEL_WARNING 1 +#define CONFIG_SW_COEXIST_PREFERENCE_BALANCE 1 +#define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1 +#define CONFIG_MONITOR_BAUD 115200 +#define CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT -1 +#define CONFIG_ESP32_DEBUG_STUBS_ENABLE 1 +#define CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT 30 +#define CONFIG_TCPIP_LWIP 1 +#define CONFIG_REDUCE_PHY_TX_POWER 1 +#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000 +#define CONFIG_PAN_TRACE_LEVEL_WARNING 1 +#define CONFIG_FREERTOS_CORETIMER_0 1 +#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv" +#define CONFIG_MBEDTLS_HAVE_TIME 1 +#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1 +#define CONFIG_TCP_QUEUE_OOSEQ 1 +#define CONFIG_GATTS_ENABLE 1 +#define CONFIG_ADC_CAL_EFUSE_VREF_ENABLE 1 +#define CONFIG_MBEDTLS_TLS_SERVER 1 +#define CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT 1 +#define CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED 1 +#define CONFIG_FREERTOS_ISR_STACKSIZE 1536 +#define CONFIG_SUPPORT_TERMIOS 1 +#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1 +#define CONFIG_IDF_TARGET "esp32" +#define CONFIG_WL_SECTOR_SIZE_4096 1 +#define CONFIG_OPTIMIZATION_LEVEL_DEBUG 1 +#define CONFIG_GATT_INITIAL_TRACE_LEVEL 2 +#define CONFIG_FREERTOS_NO_AFFINITY 0x7FFFFFFF +#define CONFIG_AWS_IOT_MQTT_HOST "" +#define CONFIG_L2CAP_TRACE_LEVEL_WARNING 1 +#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1 +#define CONFIG_HTTPD_ERR_RESP_NO_DELAY 1 +#define CONFIG_MB_TIMER_INDEX 0 +#define CONFIG_SCAN_DUPLICATE_TYPE 0 +#define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1 +#define CONFIG_APPL_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1 +#define CONFIG_SPI_FLASH_ERASE_YIELD_TICKS 1 +#define CONFIG_SMP_INITIAL_TRACE_LEVEL 2 +#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA 1 +#define CONFIG_SPI_SLAVE_ISR_IN_IRAM 1 +#define CONFIG_L2CAP_INITIAL_TRACE_LEVEL 2 +#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32 +#define CONFIG_BT_ACL_CONNECTIONS 4 +#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1 +#define CONFIG_BOOTLOADER_WDT_ENABLE 1 +#define CONFIG_GAP_INITIAL_TRACE_LEVEL 2 +#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1 +#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8 +#define CONFIG_MB_TIMER_GROUP 0 +#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 +#define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1 +#define CONFIG_SPIFFS_PAGE_SIZE 256 +#define CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED 1 +#define CONFIG_ESP32_DPORT_WORKAROUND 1 +#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 1 +#define CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT 3072 +#define CONFIG_MB_TIMER_PORT_ENABLED 1 +#define CONFIG_DUPLICATE_SCAN_CACHE_SIZE 50 +#define CONFIG_MONITOR_BAUD_OTHER_VAL 115200 +#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1 +#define CONFIG_ESPTOOLPY_PORT "COM19" +#define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS 1 +#define CONFIG_UNITY_ENABLE_DOUBLE 1 +#define CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD 20 +#define CONFIG_BLUEDROID_PINNED_TO_CORE 0 +#define CONFIG_ESP32_WIFI_IRAM_OPT 1 +#define CONFIG_BLUFI_INITIAL_TRACE_LEVEL 2 diff --git a/wasm3-sys/wasm3/platforms/embedded/esp8266/.gitignore b/wasm3-sys/wasm3/platforms/embedded/esp8266/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp8266/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/wasm3-sys/wasm3/platforms/embedded/esp8266/lib/wasm3 b/wasm3-sys/wasm3/platforms/embedded/esp8266/lib/wasm3 new file mode 120000 index 0000000..17056a9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp8266/lib/wasm3 @@ -0,0 +1 @@ +../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/esp8266/platformio.ini b/wasm3-sys/wasm3/platforms/embedded/esp8266/platformio.ini new file mode 100644 index 0000000..5e1b0d8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp8266/platformio.ini @@ -0,0 +1,29 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp8266] +platform = espressif8266 +board = nodemcuv2 +framework = arduino +monitor_speed = 115200 +upload_speed = 460800 + +board_build.f_cpu = 160000000L + +src_filter = + +<*> + - + +src_build_flags = + -Dd_m3FixedHeap=8192 + -O3 -Wfatal-errors + -flto + #-fPIC -fverbose-asm -save-temps=obj + diff --git a/wasm3-sys/wasm3/platforms/embedded/esp8266/src/main.cpp b/wasm3-sys/wasm3/platforms/embedded/esp8266/src/main.cpp new file mode 100644 index 0000000..41d5417 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/esp8266/src/main.cpp @@ -0,0 +1,71 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "Arduino.h" + +#include +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + uint32_t fsize = fib32_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + result = m3_CallV(f, 24); + if (result) FATAL("m3_Call: %s", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %d\n", value); +} + +void setup() +{ + Serial.begin(115200); + delay(10); + + Serial.print("\nWasm3 v" M3_VERSION " on ESP8266, build " __DATE__ " " __TIME__ "\n"); + + u32 start = millis(); + run_wasm(); + u32 end = millis(); + + Serial.print(String("Elapsed: ") + (end - start) + " ms\n"); +} + +void loop() +{ + delay(100); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/.env b/wasm3-sys/wasm3/platforms/embedded/fomu/.env new file mode 100644 index 0000000..c4f2f8b --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/.env @@ -0,0 +1,17 @@ +fomu-reset () { + wishbone-tool 0xe0006000 0xac +} + +fomu-reload () { + fomu-reset + dfu-util -e +} + +fomu-load-dbg () { + dfu-util -e + wishbone-tool -s gdb +} + +fomu-gdb () { + riscv64-unknown-elf-gdb $1 -ex 'target remote localhost:1234' +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/.gitignore b/wasm3-sys/wasm3/platforms/embedded/fomu/.gitignore new file mode 100644 index 0000000..ba969de --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/.gitignore @@ -0,0 +1,5 @@ +.obj +wasm3.bin +wasm3.dfu +wasm3.elf +wasm3.ihex diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/Makefile b/wasm3-sys/wasm3/platforms/embedded/fomu/Makefile new file mode 100644 index 0000000..4619d6b --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/Makefile @@ -0,0 +1,121 @@ +GIT_VERSION := $(shell git describe --tags) + +# There is no 64-bit gcc on Raspberry Pi, so use the 32-bit version +ifneq (,$(wildcard /etc/rpi-issue)) +TRGT ?= riscv32-unknown-elf- +else +TRGT ?= riscv64-unknown-elf- +endif + +CC := $(TRGT)gcc +CXX := $(TRGT)g++ +OBJCOPY := $(TRGT)objcopy + +RM := rm -rf +COPY := cp -a +PATH_SEP := / + +ifeq ($(OS),Windows_NT) +COPY := copy +RM := del +PATH_SEP := \\ +endif + +BASE_DIR := . +LD_DIR := $(BASE_DIR)/ld +LDSCRIPT := $(BASE_DIR)/ld/linker.ld +ADD_CFLAGS := -I$(BASE_DIR)/include -I$(BASE_DIR)/src/wasm3/ -D__vexriscv__ \ + -DFOMU -Dd_m3FixedHeap=8192 + +ADD_LFLAGS := -lm +PACKAGE := wasm3 + +LTO := -flto -Wl,--allow-multiple-definition + +LDSCRIPTS := $(LDSCRIPT) $(LD_DIR)/output_format.ld $(LD_DIR)/regions.ld +SRC_DIR := $(BASE_DIR)/src +DBG_CFLAGS := -ggdb -g -DDEBUG -Wall +DBG_LFLAGS := -ggdb -g -Wall +CFLAGS := $(ADD_CFLAGS) \ + -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable \ + -Wno-missing-field-initializers \ + -ffunction-sections -fdata-sections -fno-common \ + -fomit-frame-pointer -Os $(LTO) \ + -march=rv32i -mabi=ilp32 \ + -DGIT_VERSION=u\"$(GIT_VERSION)\" -std=gnu11 +CXXFLAGS := $(CFLAGS) -std=c++11 -fno-rtti -fno-exceptions +LFLAGS := $(CFLAGS) $(ADD_LFLAGS) -L$(LD_DIR) \ + -nostartfiles $(LTO) \ + -Wl,--gc-sections \ + -Wl,--script=$(LDSCRIPT) \ + -Wl,--build-id=none + +OBJ_DIR := .obj + +CSOURCES := $(shell find -L $(SRC_DIR) -type f -name '*.c') +CPPSOURCES := $(shell find -L $(SRC_DIR) -type f -name '*.cpp') +ASOURCES := $(shell find -L $(SRC_DIR) -type f -name '*.S') +COBJS := $(addprefix $(OBJ_DIR)/,$(CSOURCES:.c=.o)) +CXXOBJS := $(addprefix $(OBJ_DIR)/,$(CPPSOURCES:.cpp=.o)) +AOBJS := $(addprefix $(OBJ_DIR)/,$(ASOURCES:.S=.o)) +OBJECTS := $(COBJS) $(CXXOBJS) $(AOBJS) +VPATH := $(SRC_DIR) + +QUIET := @ + +ALL := all +TARGET := $(PACKAGE).elf +CLEAN := clean + +$(ALL): $(TARGET) $(PACKAGE).bin $(PACKAGE).ihex $(PACKAGE).dfu + +#$(OBJECTS): | $(OBJ_DIR) + +$(TARGET): $(OBJECTS) $(LDSCRIPTS) + $(QUIET) echo " LD $@" + $(QUIET) $(CC) $(OBJECTS) $(LFLAGS) -o $@ + +$(PACKAGE).bin: $(TARGET) + $(QUIET) echo " OBJCOPY $@" + $(QUIET) $(OBJCOPY) -O binary $(TARGET) $@ + +$(PACKAGE).dfu: $(PACKAGE).bin + $(QUIET) echo " DFU $@" + $(QUIET) $(COPY) $(PACKAGE).bin $@ + $(QUIET) dfu-suffix -v 1209 -p 70b1 -a $@ + +$(PACKAGE).ihex: $(TARGET) + $(QUIET) echo " IHEX $(PACKAGE).ihex" + $(QUIET) $(OBJCOPY) -O ihex $(TARGET) $@ + +$(DEBUG): CFLAGS += $(DBG_CFLAGS) +$(DEBUG): LFLAGS += $(DBG_LFLAGS) +CFLAGS += $(DBG_CFLAGS) +LFLAGS += $(DBG_LFLAGS) +$(DEBUG): $(TARGET) + +$(OBJ_DIR): + $(QUIET) mkdir $(OBJ_DIR) + +$(COBJS) : $(OBJ_DIR)/%.o : %.c $(BASE_DIR)/Makefile + $(QUIET) mkdir -p $(@D) + $(QUIET) echo " CC $< $@" + $(QUIET) $(CC) -c $< $(CFLAGS) -o $@ -MMD + +$(OBJ_DIR)/%.o: %.cpp + $(QUIET) mkdir -p $(@D) + $(QUIET) echo " CXX $< $@" + $(QUIET) $(CXX) -c $< $(CXXFLAGS) -o $@ -MMD + +$(OBJ_DIR)/%.o: %.S + $(QUIET) mkdir -p $(@D) + $(QUIET) echo " AS $< $@" + $(QUIET) $(CC) -x assembler-with-cpp -c $< $(CFLAGS) -o $@ -MMD + +.PHONY: clean + +clean: + - $(RM) -rf $(OBJ_DIR) + - $(RM) $(TARGET) $(PACKAGE).bin $(PACKAGE).symbol $(PACKAGE).ihex $(PACKAGE).dfu + +-include $(OBJECTS:.o=.d) diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/README.md b/wasm3-sys/wasm3/platforms/embedded/fomu/README.md new file mode 100644 index 0000000..e919a41 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/README.md @@ -0,0 +1,36 @@ +## Build for Fomu + +```sh +export PATH=/opt/fomu-toolchain-linux_x86_64-v1.5.6/bin:$PATH +make +``` + +### Upload: + +```sh +dfu-util -D wasm3.dfu +``` + +## Hints + +```sh +# To reboot fomu: +wishbone-tool 0xe0006000 0xac + +# To run previously flashed program on Fomu: +dfu-util -e +``` + +## Debugging + +```sh +wishbone-tool -s gdb +``` +On second tab: +```sh +riscv64-unknown-elf-gdb wasm3.elf -ex 'target remote localhost:1234' + +b m3_CallWithArgs +print *(uint64_t*)env->stack + +``` diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/gdb_init b/wasm3-sys/wasm3/platforms/embedded/fomu/gdb_init new file mode 100644 index 0000000..e2287c9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/gdb_init @@ -0,0 +1,11 @@ +set history save on +set confirm off +set remotetimeout 240 +set print asm-demangle on + +target remote localhost:1234 + +# monitor reset halt +# load +# continue +# quit diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/console.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/console.h new file mode 100644 index 0000000..a1cf599 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/console.h @@ -0,0 +1,24 @@ +#ifndef __CONSOLE_H +#define __CONSOLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*console_write_hook)(char); +typedef char (*console_read_hook)(void); +typedef int (*console_read_nonblock_hook)(void); + +void console_set_write_hook(console_write_hook h); +void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn); + +char readchar(void); +int readchar_nonblock(void); + +void putsnonl(const char *s); + +#ifdef __cplusplus +} +#endif + +#endif /* __CONSOLE_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/crc.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/crc.h new file mode 100644 index 0000000..88c8d95 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/crc.h @@ -0,0 +1,15 @@ +#ifndef __CRC_H +#define __CRC_H + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned short crc16(const unsigned char *buffer, int len); +unsigned int crc32(const unsigned char *buffer, unsigned int len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/csr-defs.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/csr-defs.h new file mode 100644 index 0000000..d98e8df --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/csr-defs.h @@ -0,0 +1,11 @@ +#ifndef CSR_DEFS__H +#define CSR_DEFS__H + +#define CSR_MSTATUS_MIE 0x8 + +#define CSR_IRQ_MASK 0xBC0 +#define CSR_IRQ_PENDING 0xFC0 + +#define CSR_DCACHE_INFO 0xCC0 + +#endif /* CSR_DEFS__H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/csr.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/csr.h new file mode 100644 index 0000000..c18b102 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/csr.h @@ -0,0 +1,773 @@ +//-------------------------------------------------------------------------------- +// Auto-generated by Migen (ae42105) & LiteX (3a72688b) on 2019-08-23 13:21:26 +//-------------------------------------------------------------------------------- +#ifndef __GENERATED_CSR_H +#define __GENERATED_CSR_H +#include +#ifdef CSR_ACCESSORS_DEFINED +extern void csr_writeb(uint8_t value, unsigned long addr); +extern uint8_t csr_readb(unsigned long addr); +extern void csr_writew(uint16_t value, unsigned long addr); +extern uint16_t csr_readw(unsigned long addr); +extern void csr_writel(uint32_t value, unsigned long addr); +extern uint32_t csr_readl(unsigned long addr); +#else /* ! CSR_ACCESSORS_DEFINED */ +#include +#endif /* ! CSR_ACCESSORS_DEFINED */ + +/* ctrl */ +#define CSR_CTRL_BASE 0xe0000000L +#define CSR_CTRL_RESET_ADDR 0xe0000000L +#define CSR_CTRL_RESET_SIZE 1 +static inline unsigned char ctrl_reset_read(void) { + unsigned char r = csr_readl(0xe0000000L); + return r; +} +static inline void ctrl_reset_write(unsigned char value) { + csr_writel(value, 0xe0000000L); +} +#define CSR_CTRL_SCRATCH_ADDR 0xe0000004L +#define CSR_CTRL_SCRATCH_SIZE 4 +static inline unsigned int ctrl_scratch_read(void) { + unsigned int r = csr_readl(0xe0000004L); + r <<= 8; + r |= csr_readl(0xe0000008L); + r <<= 8; + r |= csr_readl(0xe000000cL); + r <<= 8; + r |= csr_readl(0xe0000010L); + return r; +} +static inline void ctrl_scratch_write(unsigned int value) { + csr_writel(value >> 24, 0xe0000004L); + csr_writel(value >> 16, 0xe0000008L); + csr_writel(value >> 8, 0xe000000cL); + csr_writel(value, 0xe0000010L); +} +#define CSR_CTRL_BUS_ERRORS_ADDR 0xe0000014L +#define CSR_CTRL_BUS_ERRORS_SIZE 4 +static inline unsigned int ctrl_bus_errors_read(void) { + unsigned int r = csr_readl(0xe0000014L); + r <<= 8; + r |= csr_readl(0xe0000018L); + r <<= 8; + r |= csr_readl(0xe000001cL); + r <<= 8; + r |= csr_readl(0xe0000020L); + return r; +} + +/* picorvspi */ +#define CSR_PICORVSPI_BASE 0xe0005000L +#define CSR_PICORVSPI_CFG1_ADDR 0xe0005000L +#define CSR_PICORVSPI_CFG1_SIZE 1 +static inline unsigned char picorvspi_cfg1_read(void) { + unsigned char r = csr_readl(0xe0005000L); + return r; +} +static inline void picorvspi_cfg1_write(unsigned char value) { + csr_writel(value, 0xe0005000L); +} +#define CSR_PICORVSPI_CFG2_ADDR 0xe0005004L +#define CSR_PICORVSPI_CFG2_SIZE 1 +static inline unsigned char picorvspi_cfg2_read(void) { + unsigned char r = csr_readl(0xe0005004L); + return r; +} +static inline void picorvspi_cfg2_write(unsigned char value) { + csr_writel(value, 0xe0005004L); +} +#define CSR_PICORVSPI_CFG3_ADDR 0xe0005008L +#define CSR_PICORVSPI_CFG3_SIZE 1 +static inline unsigned char picorvspi_cfg3_read(void) { + unsigned char r = csr_readl(0xe0005008L); + return r; +} +static inline void picorvspi_cfg3_write(unsigned char value) { + csr_writel(value, 0xe0005008L); +} +#define CSR_PICORVSPI_CFG4_ADDR 0xe000500cL +#define CSR_PICORVSPI_CFG4_SIZE 1 +static inline unsigned char picorvspi_cfg4_read(void) { + unsigned char r = csr_readl(0xe000500cL); + return r; +} +static inline void picorvspi_cfg4_write(unsigned char value) { + csr_writel(value, 0xe000500cL); +} +#define CSR_PICORVSPI_STAT1_ADDR 0xe0005010L +#define CSR_PICORVSPI_STAT1_SIZE 1 +static inline unsigned char picorvspi_stat1_read(void) { + unsigned char r = csr_readl(0xe0005010L); + return r; +} +#define CSR_PICORVSPI_STAT2_ADDR 0xe0005014L +#define CSR_PICORVSPI_STAT2_SIZE 1 +static inline unsigned char picorvspi_stat2_read(void) { + unsigned char r = csr_readl(0xe0005014L); + return r; +} +#define CSR_PICORVSPI_STAT3_ADDR 0xe0005018L +#define CSR_PICORVSPI_STAT3_SIZE 1 +static inline unsigned char picorvspi_stat3_read(void) { + unsigned char r = csr_readl(0xe0005018L); + return r; +} +#define CSR_PICORVSPI_STAT4_ADDR 0xe000501cL +#define CSR_PICORVSPI_STAT4_SIZE 1 +static inline unsigned char picorvspi_stat4_read(void) { + unsigned char r = csr_readl(0xe000501cL); + return r; +} + +/* reboot */ +#define CSR_REBOOT_BASE 0xe0006000L +#define CSR_REBOOT_CTRL_ADDR 0xe0006000L +#define CSR_REBOOT_CTRL_SIZE 1 +static inline unsigned char reboot_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006000L); + return r; +} +static inline void reboot_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006000L); +} +#define CSR_REBOOT_ADDR_ADDR 0xe0006004L +#define CSR_REBOOT_ADDR_SIZE 4 +static inline unsigned int reboot_addr_read(void) { + unsigned int r = csr_readl(0xe0006004L); + r <<= 8; + r |= csr_readl(0xe0006008L); + r <<= 8; + r |= csr_readl(0xe000600cL); + r <<= 8; + r |= csr_readl(0xe0006010L); + return r; +} +static inline void reboot_addr_write(unsigned int value) { + csr_writel(value >> 24, 0xe0006004L); + csr_writel(value >> 16, 0xe0006008L); + csr_writel(value >> 8, 0xe000600cL); + csr_writel(value, 0xe0006010L); +} + +/* rgb */ +#define CSR_RGB_BASE 0xe0006800L +#define CSR_RGB_DAT_ADDR 0xe0006800L +#define CSR_RGB_DAT_SIZE 1 +static inline unsigned char rgb_dat_read(void) { + unsigned char r = csr_readl(0xe0006800L); + return r; +} +static inline void rgb_dat_write(unsigned char value) { + csr_writel(value, 0xe0006800L); +} +#define CSR_RGB_ADDR_ADDR 0xe0006804L +#define CSR_RGB_ADDR_SIZE 1 +static inline unsigned char rgb_addr_read(void) { + unsigned char r = csr_readl(0xe0006804L); + return r; +} +static inline void rgb_addr_write(unsigned char value) { + csr_writel(value, 0xe0006804L); +} +#define CSR_RGB_CTRL_ADDR 0xe0006808L +#define CSR_RGB_CTRL_SIZE 1 +static inline unsigned char rgb_ctrl_read(void) { + unsigned char r = csr_readl(0xe0006808L); + return r; +} +static inline void rgb_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0006808L); +} +#define CSR_RGB_RAW_ADDR 0xe000680cL +#define CSR_RGB_RAW_SIZE 1 +static inline unsigned char rgb_raw_read(void) { + unsigned char r = csr_readl(0xe000680cL); + return r; +} +static inline void rgb_raw_write(unsigned char value) { + csr_writel(value, 0xe000680cL); +} + +/* timer0 */ +#define CSR_TIMER0_BASE 0xe0002800L +#define CSR_TIMER0_LOAD_ADDR 0xe0002800L +#define CSR_TIMER0_LOAD_SIZE 4 +static inline unsigned int timer0_load_read(void) { + unsigned int r = csr_readl(0xe0002800L); + r <<= 8; + r |= csr_readl(0xe0002804L); + r <<= 8; + r |= csr_readl(0xe0002808L); + r <<= 8; + r |= csr_readl(0xe000280cL); + return r; +} +static inline void timer0_load_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002800L); + csr_writel(value >> 16, 0xe0002804L); + csr_writel(value >> 8, 0xe0002808L); + csr_writel(value, 0xe000280cL); +} +#define CSR_TIMER0_RELOAD_ADDR 0xe0002810L +#define CSR_TIMER0_RELOAD_SIZE 4 +static inline unsigned int timer0_reload_read(void) { + unsigned int r = csr_readl(0xe0002810L); + r <<= 8; + r |= csr_readl(0xe0002814L); + r <<= 8; + r |= csr_readl(0xe0002818L); + r <<= 8; + r |= csr_readl(0xe000281cL); + return r; +} +static inline void timer0_reload_write(unsigned int value) { + csr_writel(value >> 24, 0xe0002810L); + csr_writel(value >> 16, 0xe0002814L); + csr_writel(value >> 8, 0xe0002818L); + csr_writel(value, 0xe000281cL); +} +#define CSR_TIMER0_EN_ADDR 0xe0002820L +#define CSR_TIMER0_EN_SIZE 1 +static inline unsigned char timer0_en_read(void) { + unsigned char r = csr_readl(0xe0002820L); + return r; +} +static inline void timer0_en_write(unsigned char value) { + csr_writel(value, 0xe0002820L); +} +#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002824L +#define CSR_TIMER0_UPDATE_VALUE_SIZE 1 +static inline unsigned char timer0_update_value_read(void) { + unsigned char r = csr_readl(0xe0002824L); + return r; +} +static inline void timer0_update_value_write(unsigned char value) { + csr_writel(value, 0xe0002824L); +} +#define CSR_TIMER0_VALUE_ADDR 0xe0002828L +#define CSR_TIMER0_VALUE_SIZE 4 +static inline unsigned int timer0_value_read(void) { + unsigned int r = csr_readl(0xe0002828L); + r <<= 8; + r |= csr_readl(0xe000282cL); + r <<= 8; + r |= csr_readl(0xe0002830L); + r <<= 8; + r |= csr_readl(0xe0002834L); + return r; +} +#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002838L +#define CSR_TIMER0_EV_STATUS_SIZE 1 +static inline unsigned char timer0_ev_status_read(void) { + unsigned char r = csr_readl(0xe0002838L); + return r; +} +static inline void timer0_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0002838L); +} +#define CSR_TIMER0_EV_PENDING_ADDR 0xe000283cL +#define CSR_TIMER0_EV_PENDING_SIZE 1 +static inline unsigned char timer0_ev_pending_read(void) { + unsigned char r = csr_readl(0xe000283cL); + return r; +} +static inline void timer0_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe000283cL); +} +#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002840L +#define CSR_TIMER0_EV_ENABLE_SIZE 1 +static inline unsigned char timer0_ev_enable_read(void) { + unsigned char r = csr_readl(0xe0002840L); + return r; +} +static inline void timer0_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe0002840L); +} + +/* touch */ +#define CSR_TOUCH_BASE 0xe0005800L +#define CSR_TOUCH_O_ADDR 0xe0005800L +#define CSR_TOUCH_O_SIZE 1 +static inline unsigned char touch_o_read(void) { + unsigned char r = csr_readl(0xe0005800L); + return r; +} +static inline void touch_o_write(unsigned char value) { + csr_writel(value, 0xe0005800L); +} +#define CSR_TOUCH_OE_ADDR 0xe0005804L +#define CSR_TOUCH_OE_SIZE 1 +static inline unsigned char touch_oe_read(void) { + unsigned char r = csr_readl(0xe0005804L); + return r; +} +static inline void touch_oe_write(unsigned char value) { + csr_writel(value, 0xe0005804L); +} +#define CSR_TOUCH_I_ADDR 0xe0005808L +#define CSR_TOUCH_I_SIZE 1 +static inline unsigned char touch_i_read(void) { + unsigned char r = csr_readl(0xe0005808L); + return r; +} + +/* usb */ +#define CSR_USB_BASE 0xe0004800L +#define CSR_USB_PULLUP_OUT_ADDR 0xe0004800L +#define CSR_USB_PULLUP_OUT_SIZE 1 +static inline unsigned char usb_pullup_out_read(void) { + unsigned char r = csr_readl(0xe0004800L); + return r; +} +static inline void usb_pullup_out_write(unsigned char value) { + csr_writel(value, 0xe0004800L); +} +#define CSR_USB_EP_0_OUT_EV_STATUS_ADDR 0xe0004804L +#define CSR_USB_EP_0_OUT_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004804L); + return r; +} +static inline void usb_ep_0_out_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004804L); +} +#define CSR_USB_EP_0_OUT_EV_PENDING_ADDR 0xe0004808L +#define CSR_USB_EP_0_OUT_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004808L); + return r; +} +static inline void usb_ep_0_out_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004808L); +} +#define CSR_USB_EP_0_OUT_EV_ENABLE_ADDR 0xe000480cL +#define CSR_USB_EP_0_OUT_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_0_out_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000480cL); + return r; +} +static inline void usb_ep_0_out_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000480cL); +} +#define CSR_USB_EP_0_OUT_LAST_TOK_ADDR 0xe0004810L +#define CSR_USB_EP_0_OUT_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_0_out_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004810L); + return r; +} +#define CSR_USB_EP_0_OUT_RESPOND_ADDR 0xe0004814L +#define CSR_USB_EP_0_OUT_RESPOND_SIZE 1 +static inline unsigned char usb_ep_0_out_respond_read(void) { + unsigned char r = csr_readl(0xe0004814L); + return r; +} +static inline void usb_ep_0_out_respond_write(unsigned char value) { + csr_writel(value, 0xe0004814L); +} +#define CSR_USB_EP_0_OUT_DTB_ADDR 0xe0004818L +#define CSR_USB_EP_0_OUT_DTB_SIZE 1 +static inline unsigned char usb_ep_0_out_dtb_read(void) { + unsigned char r = csr_readl(0xe0004818L); + return r; +} +static inline void usb_ep_0_out_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004818L); +} +#define CSR_USB_EP_0_OUT_OBUF_HEAD_ADDR 0xe000481cL +#define CSR_USB_EP_0_OUT_OBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_0_out_obuf_head_read(void) { + unsigned char r = csr_readl(0xe000481cL); + return r; +} +static inline void usb_ep_0_out_obuf_head_write(unsigned char value) { + csr_writel(value, 0xe000481cL); +} +#define CSR_USB_EP_0_OUT_OBUF_EMPTY_ADDR 0xe0004820L +#define CSR_USB_EP_0_OUT_OBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_0_out_obuf_empty_read(void) { + unsigned char r = csr_readl(0xe0004820L); + return r; +} +#define CSR_USB_EP_0_IN_EV_STATUS_ADDR 0xe0004824L +#define CSR_USB_EP_0_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004824L); + return r; +} +static inline void usb_ep_0_in_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004824L); +} +#define CSR_USB_EP_0_IN_EV_PENDING_ADDR 0xe0004828L +#define CSR_USB_EP_0_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004828L); + return r; +} +static inline void usb_ep_0_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004828L); +} +#define CSR_USB_EP_0_IN_EV_ENABLE_ADDR 0xe000482cL +#define CSR_USB_EP_0_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_0_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000482cL); + return r; +} +static inline void usb_ep_0_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000482cL); +} +#define CSR_USB_EP_0_IN_LAST_TOK_ADDR 0xe0004830L +#define CSR_USB_EP_0_IN_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_0_in_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004830L); + return r; +} +#define CSR_USB_EP_0_IN_RESPOND_ADDR 0xe0004834L +#define CSR_USB_EP_0_IN_RESPOND_SIZE 1 +static inline unsigned char usb_ep_0_in_respond_read(void) { + unsigned char r = csr_readl(0xe0004834L); + return r; +} +static inline void usb_ep_0_in_respond_write(unsigned char value) { + csr_writel(value, 0xe0004834L); +} +#define CSR_USB_EP_0_IN_DTB_ADDR 0xe0004838L +#define CSR_USB_EP_0_IN_DTB_SIZE 1 +static inline unsigned char usb_ep_0_in_dtb_read(void) { + unsigned char r = csr_readl(0xe0004838L); + return r; +} +static inline void usb_ep_0_in_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004838L); +} +#define CSR_USB_EP_0_IN_IBUF_HEAD_ADDR 0xe000483cL +#define CSR_USB_EP_0_IN_IBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_0_in_ibuf_head_read(void) { + unsigned char r = csr_readl(0xe000483cL); + return r; +} +static inline void usb_ep_0_in_ibuf_head_write(unsigned char value) { + csr_writel(value, 0xe000483cL); +} +#define CSR_USB_EP_0_IN_IBUF_EMPTY_ADDR 0xe0004840L +#define CSR_USB_EP_0_IN_IBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_0_in_ibuf_empty_read(void) { + unsigned char r = csr_readl(0xe0004840L); + return r; +} +#define CSR_USB_EP_1_IN_EV_STATUS_ADDR 0xe0004844L +#define CSR_USB_EP_1_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_1_in_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004844L); + return r; +} +static inline void usb_ep_1_in_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004844L); +} +#define CSR_USB_EP_1_IN_EV_PENDING_ADDR 0xe0004848L +#define CSR_USB_EP_1_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_1_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004848L); + return r; +} +static inline void usb_ep_1_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004848L); +} +#define CSR_USB_EP_1_IN_EV_ENABLE_ADDR 0xe000484cL +#define CSR_USB_EP_1_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_1_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000484cL); + return r; +} +static inline void usb_ep_1_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000484cL); +} +#define CSR_USB_EP_1_IN_LAST_TOK_ADDR 0xe0004850L +#define CSR_USB_EP_1_IN_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_1_in_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004850L); + return r; +} +#define CSR_USB_EP_1_IN_RESPOND_ADDR 0xe0004854L +#define CSR_USB_EP_1_IN_RESPOND_SIZE 1 +static inline unsigned char usb_ep_1_in_respond_read(void) { + unsigned char r = csr_readl(0xe0004854L); + return r; +} +static inline void usb_ep_1_in_respond_write(unsigned char value) { + csr_writel(value, 0xe0004854L); +} +#define CSR_USB_EP_1_IN_DTB_ADDR 0xe0004858L +#define CSR_USB_EP_1_IN_DTB_SIZE 1 +static inline unsigned char usb_ep_1_in_dtb_read(void) { + unsigned char r = csr_readl(0xe0004858L); + return r; +} +static inline void usb_ep_1_in_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004858L); +} +#define CSR_USB_EP_1_IN_IBUF_HEAD_ADDR 0xe000485cL +#define CSR_USB_EP_1_IN_IBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_1_in_ibuf_head_read(void) { + unsigned char r = csr_readl(0xe000485cL); + return r; +} +static inline void usb_ep_1_in_ibuf_head_write(unsigned char value) { + csr_writel(value, 0xe000485cL); +} +#define CSR_USB_EP_1_IN_IBUF_EMPTY_ADDR 0xe0004860L +#define CSR_USB_EP_1_IN_IBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_1_in_ibuf_empty_read(void) { + unsigned char r = csr_readl(0xe0004860L); + return r; +} +#define CSR_USB_EP_2_OUT_EV_STATUS_ADDR 0xe0004864L +#define CSR_USB_EP_2_OUT_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_2_out_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004864L); + return r; +} +static inline void usb_ep_2_out_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004864L); +} +#define CSR_USB_EP_2_OUT_EV_PENDING_ADDR 0xe0004868L +#define CSR_USB_EP_2_OUT_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_2_out_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004868L); + return r; +} +static inline void usb_ep_2_out_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004868L); +} +#define CSR_USB_EP_2_OUT_EV_ENABLE_ADDR 0xe000486cL +#define CSR_USB_EP_2_OUT_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_2_out_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000486cL); + return r; +} +static inline void usb_ep_2_out_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000486cL); +} +#define CSR_USB_EP_2_OUT_LAST_TOK_ADDR 0xe0004870L +#define CSR_USB_EP_2_OUT_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_2_out_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004870L); + return r; +} +#define CSR_USB_EP_2_OUT_RESPOND_ADDR 0xe0004874L +#define CSR_USB_EP_2_OUT_RESPOND_SIZE 1 +static inline unsigned char usb_ep_2_out_respond_read(void) { + unsigned char r = csr_readl(0xe0004874L); + return r; +} +static inline void usb_ep_2_out_respond_write(unsigned char value) { + csr_writel(value, 0xe0004874L); +} +#define CSR_USB_EP_2_OUT_DTB_ADDR 0xe0004878L +#define CSR_USB_EP_2_OUT_DTB_SIZE 1 +static inline unsigned char usb_ep_2_out_dtb_read(void) { + unsigned char r = csr_readl(0xe0004878L); + return r; +} +static inline void usb_ep_2_out_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004878L); +} +#define CSR_USB_EP_2_OUT_OBUF_HEAD_ADDR 0xe000487cL +#define CSR_USB_EP_2_OUT_OBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_2_out_obuf_head_read(void) { + unsigned char r = csr_readl(0xe000487cL); + return r; +} +static inline void usb_ep_2_out_obuf_head_write(unsigned char value) { + csr_writel(value, 0xe000487cL); +} +#define CSR_USB_EP_2_OUT_OBUF_EMPTY_ADDR 0xe0004880L +#define CSR_USB_EP_2_OUT_OBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_2_out_obuf_empty_read(void) { + unsigned char r = csr_readl(0xe0004880L); + return r; +} +#define CSR_USB_EP_2_IN_EV_STATUS_ADDR 0xe0004884L +#define CSR_USB_EP_2_IN_EV_STATUS_SIZE 1 +static inline unsigned char usb_ep_2_in_ev_status_read(void) { + unsigned char r = csr_readl(0xe0004884L); + return r; +} +static inline void usb_ep_2_in_ev_status_write(unsigned char value) { + csr_writel(value, 0xe0004884L); +} +#define CSR_USB_EP_2_IN_EV_PENDING_ADDR 0xe0004888L +#define CSR_USB_EP_2_IN_EV_PENDING_SIZE 1 +static inline unsigned char usb_ep_2_in_ev_pending_read(void) { + unsigned char r = csr_readl(0xe0004888L); + return r; +} +static inline void usb_ep_2_in_ev_pending_write(unsigned char value) { + csr_writel(value, 0xe0004888L); +} +#define CSR_USB_EP_2_IN_EV_ENABLE_ADDR 0xe000488cL +#define CSR_USB_EP_2_IN_EV_ENABLE_SIZE 1 +static inline unsigned char usb_ep_2_in_ev_enable_read(void) { + unsigned char r = csr_readl(0xe000488cL); + return r; +} +static inline void usb_ep_2_in_ev_enable_write(unsigned char value) { + csr_writel(value, 0xe000488cL); +} +#define CSR_USB_EP_2_IN_LAST_TOK_ADDR 0xe0004890L +#define CSR_USB_EP_2_IN_LAST_TOK_SIZE 1 +static inline unsigned char usb_ep_2_in_last_tok_read(void) { + unsigned char r = csr_readl(0xe0004890L); + return r; +} +#define CSR_USB_EP_2_IN_RESPOND_ADDR 0xe0004894L +#define CSR_USB_EP_2_IN_RESPOND_SIZE 1 +static inline unsigned char usb_ep_2_in_respond_read(void) { + unsigned char r = csr_readl(0xe0004894L); + return r; +} +static inline void usb_ep_2_in_respond_write(unsigned char value) { + csr_writel(value, 0xe0004894L); +} +#define CSR_USB_EP_2_IN_DTB_ADDR 0xe0004898L +#define CSR_USB_EP_2_IN_DTB_SIZE 1 +static inline unsigned char usb_ep_2_in_dtb_read(void) { + unsigned char r = csr_readl(0xe0004898L); + return r; +} +static inline void usb_ep_2_in_dtb_write(unsigned char value) { + csr_writel(value, 0xe0004898L); +} +#define CSR_USB_EP_2_IN_IBUF_HEAD_ADDR 0xe000489cL +#define CSR_USB_EP_2_IN_IBUF_HEAD_SIZE 1 +static inline unsigned char usb_ep_2_in_ibuf_head_read(void) { + unsigned char r = csr_readl(0xe000489cL); + return r; +} +static inline void usb_ep_2_in_ibuf_head_write(unsigned char value) { + csr_writel(value, 0xe000489cL); +} +#define CSR_USB_EP_2_IN_IBUF_EMPTY_ADDR 0xe00048a0L +#define CSR_USB_EP_2_IN_IBUF_EMPTY_SIZE 1 +static inline unsigned char usb_ep_2_in_ibuf_empty_read(void) { + unsigned char r = csr_readl(0xe00048a0L); + return r; +} +#define CSR_USB_ADDRESS_ADDR 0xe00048a4L +#define CSR_USB_ADDRESS_SIZE 1 +static inline unsigned char usb_address_read(void) { + unsigned char r = csr_readl(0xe00048a4L); + return r; +} +static inline void usb_address_write(unsigned char value) { + csr_writel(value, 0xe00048a4L); +} + +/* version */ +#define CSR_VERSION_BASE 0xe0007000L +#define CSR_VERSION_MAJOR_ADDR 0xe0007000L +#define CSR_VERSION_MAJOR_SIZE 1 +static inline unsigned char version_major_read(void) { + unsigned char r = csr_readl(0xe0007000L); + return r; +} +#define CSR_VERSION_MINOR_ADDR 0xe0007004L +#define CSR_VERSION_MINOR_SIZE 1 +static inline unsigned char version_minor_read(void) { + unsigned char r = csr_readl(0xe0007004L); + return r; +} +#define CSR_VERSION_REVISION_ADDR 0xe0007008L +#define CSR_VERSION_REVISION_SIZE 1 +static inline unsigned char version_revision_read(void) { + unsigned char r = csr_readl(0xe0007008L); + return r; +} +#define CSR_VERSION_GITREV_ADDR 0xe000700cL +#define CSR_VERSION_GITREV_SIZE 4 +static inline unsigned int version_gitrev_read(void) { + unsigned int r = csr_readl(0xe000700cL); + r <<= 8; + r |= csr_readl(0xe0007010L); + r <<= 8; + r |= csr_readl(0xe0007014L); + r <<= 8; + r |= csr_readl(0xe0007018L); + return r; +} +#define CSR_VERSION_GITEXTRA_ADDR 0xe000701cL +#define CSR_VERSION_GITEXTRA_SIZE 2 +static inline unsigned short int version_gitextra_read(void) { + unsigned short int r = csr_readl(0xe000701cL); + r <<= 8; + r |= csr_readl(0xe0007020L); + return r; +} +#define CSR_VERSION_DIRTY_ADDR 0xe0007024L +#define CSR_VERSION_DIRTY_SIZE 1 +static inline unsigned char version_dirty_read(void) { + unsigned char r = csr_readl(0xe0007024L); + return r; +} +#define CSR_VERSION_MODEL_ADDR 0xe0007028L +#define CSR_VERSION_MODEL_SIZE 1 +static inline unsigned char version_model_read(void) { + unsigned char r = csr_readl(0xe0007028L); + return r; +} + +/* constants */ +#define TIMER0_INTERRUPT 0 +static inline int timer0_interrupt_read(void) { + return 0; +} +#define USB_INTERRUPT 3 +static inline int usb_interrupt_read(void) { + return 3; +} +#define CSR_DATA_WIDTH 8 +static inline int csr_data_width_read(void) { + return 8; +} +#define SYSTEM_CLOCK_FREQUENCY 12000000 +static inline int system_clock_frequency_read(void) { + return 12000000; +} +#define CONFIG_BITSTREAM_SYNC_HEADER1 2123999870 +static inline int config_bitstream_sync_header1_read(void) { + return 2123999870; +} +#define CONFIG_BITSTREAM_SYNC_HEADER2 2125109630 +static inline int config_bitstream_sync_header2_read(void) { + return 2125109630; +} +#define CONFIG_CLOCK_FREQUENCY 12000000 +static inline int config_clock_frequency_read(void) { + return 12000000; +} +#define CONFIG_CPU_RESET_ADDR 0 +static inline int config_cpu_reset_addr_read(void) { + return 0; +} +#define CONFIG_CPU_TYPE "VEXRISCV" +static inline const char * config_cpu_type_read(void) { + return "VEXRISCV"; +} +#define CONFIG_CPU_VARIANT "VEXRISCV" +static inline const char * config_cpu_variant_read(void) { + return "VEXRISCV"; +} +#define CONFIG_CSR_DATA_WIDTH 8 +static inline int config_csr_data_width_read(void) { + return 8; +} +#define CONFIG_FOMU_REV "HACKER" +static inline const char * config_fomu_rev_read(void) { + return "HACKER"; +} +#define CONFIG_FOMU_REV_HACKER 1 +static inline int config_fomu_rev_hacker_read(void) { + return 1; +} + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/mem.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/mem.h new file mode 100644 index 0000000..6fe108e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/generated/mem.h @@ -0,0 +1,16 @@ +#ifndef __GENERATED_MEM_H +#define __GENERATED_MEM_H + +#define VEXRISCV_DEBUG_BASE 0xf00f0000 +#define VEXRISCV_DEBUG_SIZE 0x00000010 + +#define SRAM_BASE 0x10000000 +#define SRAM_SIZE 0x00020000 + +#define ROM_BASE 0x00000000 +#define ROM_SIZE 0x00002000 + +#define SPIFLASH_BASE 0x20000000 +#define SPIFLASH_SIZE 0x00200000 + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/common.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/common.h new file mode 100644 index 0000000..af668f7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/common.h @@ -0,0 +1,52 @@ +#ifndef __HW_COMMON_H +#define __HW_COMMON_H + +#include + +/* To overwrite CSR accessors, define extern, non-inlined versions + * of csr_read[bwl]() and csr_write[bwl](), and define + * CSR_ACCESSORS_DEFINED. + */ + +#ifndef CSR_ACCESSORS_DEFINED +#define CSR_ACCESSORS_DEFINED + +#ifdef __ASSEMBLER__ +#define MMPTR(x) x +#else /* ! __ASSEMBLER__ */ +#define MMPTR(x) (*((volatile unsigned int *)(x))) + +static inline void csr_writeb(uint8_t value, uint32_t addr) +{ + *((volatile uint8_t *)addr) = value; +} + +static inline uint8_t csr_readb(uint32_t addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline void csr_writew(uint16_t value, uint32_t addr) +{ + *((volatile uint16_t *)addr) = value; +} + +static inline uint16_t csr_readw(uint32_t addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline void csr_writel(uint32_t value, uint32_t addr) +{ + *((volatile uint32_t *)addr) = value; +} + +static inline uint32_t csr_readl(uint32_t addr) +{ + return *(volatile uint32_t *)addr; +} +#endif /* ! __ASSEMBLER__ */ + +#endif /* ! CSR_ACCESSORS_DEFINED */ + +#endif /* __HW_COMMON_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/flags.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/flags.h new file mode 100644 index 0000000..911a1b6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/hw/flags.h @@ -0,0 +1,40 @@ +#ifndef __HW_FLAGS_H +#define __HW_FLAGS_H + +#define UART_EV_TX 0x1 +#define UART_EV_RX 0x2 + +#define DFII_CONTROL_SEL 0x01 +#define DFII_CONTROL_CKE 0x02 +#define DFII_CONTROL_ODT 0x04 +#define DFII_CONTROL_RESET_N 0x08 + +#define DFII_COMMAND_CS 0x01 +#define DFII_COMMAND_WE 0x02 +#define DFII_COMMAND_CAS 0x04 +#define DFII_COMMAND_RAS 0x08 +#define DFII_COMMAND_WRDATA 0x10 +#define DFII_COMMAND_RDDATA 0x20 + +#define ETHMAC_EV_SRAM_WRITER 0x1 +#define ETHMAC_EV_SRAM_READER 0x1 + +#define CLKGEN_STATUS_BUSY 0x1 +#define CLKGEN_STATUS_PROGDONE 0x2 +#define CLKGEN_STATUS_LOCKED 0x4 + +#define DVISAMPLER_TOO_LATE 0x1 +#define DVISAMPLER_TOO_EARLY 0x2 + +#define DVISAMPLER_DELAY_MASTER_CAL 0x01 +#define DVISAMPLER_DELAY_MASTER_RST 0x02 +#define DVISAMPLER_DELAY_SLAVE_CAL 0x04 +#define DVISAMPLER_DELAY_SLAVE_RST 0x08 +#define DVISAMPLER_DELAY_INC 0x10 +#define DVISAMPLER_DELAY_DEC 0x20 + +#define DVISAMPLER_SLOT_EMPTY 0 +#define DVISAMPLER_SLOT_LOADED 1 +#define DVISAMPLER_SLOT_PENDING 2 + +#endif /* __HW_FLAGS_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/irq.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/irq.h new file mode 100644 index 0000000..19f00b1 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/irq.h @@ -0,0 +1,144 @@ +#ifndef __IRQ_H +#define __IRQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifdef __picorv32__ +// PicoRV32 has a very limited interrupt support, implemented via custom +// instructions. It also doesn't have a global interrupt enable/disable, so +// we have to emulate it via saving and restoring a mask and using 0/~1 as a +// hardware mask. +// Due to all this somewhat low-level mess, all of the glue is implemented in +// the RiscV crt0, and this header is kept as a thin wrapper. Since interrupts +// managed by this layer, do not call interrupt instructions directly, as the +// state will go out of sync with the hardware. + +// Read only. +extern unsigned int _irq_pending; +// Read only. +extern unsigned int _irq_mask; +// Read only. +extern unsigned int _irq_enabled; +extern void _irq_enable(void); +extern void _irq_disable(void); +extern void _irq_setmask(unsigned int); +#endif + +static inline unsigned int irq_getie(void) +{ +#if defined (__lm32__) + unsigned int ie; + __asm__ __volatile__("rcsr %0, IE" : "=r" (ie)); + return ie; +#elif defined (__or1k__) + return !!(mfspr(SPR_SR) & SPR_SR_IEE); +#elif defined (__picorv32__) + return _irq_enabled != 0; +#elif defined (__vexriscv__) + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +#elif defined (__minerva__) + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +#else +#error Unsupported architecture +#endif +} + +static inline void irq_setie(unsigned int ie) +{ +#if defined (__lm32__) + __asm__ __volatile__("wcsr IE, %0" : : "r" (ie)); +#elif defined (__or1k__) + if (ie & 0x1) + mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE); + else + mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE); +#elif defined (__picorv32__) + if (ie & 0x1) + _irq_enable(); + else + _irq_disable(); +#elif defined (__vexriscv__) + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +#elif defined (__minerva__) + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +#else +#error Unsupported architecture +#endif +} + +static inline unsigned int irq_getmask(void) +{ +#if defined (__lm32__) + unsigned int mask; + __asm__ __volatile__("rcsr %0, IM" : "=r" (mask)); + return mask; +#elif defined (__or1k__) + return mfspr(SPR_PICMR); +#elif defined (__picorv32__) + // PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how + // LiteX sees things. + return ~_irq_mask; +#elif defined (__vexriscv__) + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; +#elif defined (__minerva__) + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; +#else +#error Unsupported architecture +#endif +} + +static inline void irq_setmask(unsigned int mask) +{ +#if defined (__lm32__) + __asm__ __volatile__("wcsr IM, %0" : : "r" (mask)); +#elif defined (__or1k__) + mtspr(SPR_PICMR, mask); +#elif defined (__picorv32__) + // PicoRV32 interrupt mask bits are high-disabled. This is the inverse of how + // LiteX sees things. + _irq_setmask(~mask); +#elif defined (__vexriscv__) + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); +#elif defined (__minerva__) + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); +#else +#error Unsupported architecture +#endif +} + +static inline unsigned int irq_pending(void) +{ +#if defined (__lm32__) + unsigned int pending; + __asm__ __volatile__("rcsr %0, IP" : "=r" (pending)); + return pending; +#elif defined (__or1k__) + return mfspr(SPR_PICSR); +#elif defined (__picorv32__) + return _irq_pending; +#elif defined (__vexriscv__) + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; +#elif defined (__minerva__) + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; +#else +#error Unsupported architecture +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* __IRQ_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/printf.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/printf.h new file mode 100644 index 0000000..73a80a7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/printf.h @@ -0,0 +1,124 @@ +/* +File: printf.h + +Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +---------------------------------------------------------------------- + +This library is really just two files: 'printf.h' and 'printf.c'. + +They provide a simple and small (+200 loc) printf functionality to +be used in embedded systems. + +I've found them so useful in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and sprintf. + +The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the +long specifier is also +supported. Note that this will pull in some long math routines (pun intended!) +and thus make your executable noticeably longer. + +The memory footprint of course depends on the target cpu, compiler and +compiler options, but a rough guestimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your mileage may vary. By hacking the source code you can +get rid of some hundred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf you need to supply your own character output function, +something like : + +void putc ( void* p, char c) + { + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; + } + +Before you can call printf you need to initialize it to use your +character output function with something like: + +init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything really) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it +is safe to call it from interrupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf'. This makes it possible +to use them along with 'stdio.h' printf's in a single source file. +You just need to undef the names before you include the 'stdio.h'. +Note that these are not function like macros, so if you have variables +or struct members with these names, things will explode in your face. +Without variadic macros this is the best we can do to wrap these +fucnctions. If it is a problem just give up the macros and use the +functions directly or rename them. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +void init_printf(void* putp,void (*putf) (void*,char)); + +void tfp_printf(char *fmt, ...); +void tfp_sprintf(char* s,char *fmt, ...); + +void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); + +#define printf tfp_printf +#define sprintf tfp_sprintf + +#endif + + + diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/rgb.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/rgb.h new file mode 100644 index 0000000..5455429 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/rgb.h @@ -0,0 +1,29 @@ +#ifndef _RGB_H_ +#define _RGB_H_ + +void rgb_init(void); +void rgb_set(uint8_t r, uint8_t g, uint8_t b); + +// The amount of time to stay off or on +void rgb_on_time(uint8_t ms); +void rgb_off_time(uint8_t ms); + +// The amount of time to breathe in/out +void rgb_in_time(uint8_t ms); +void rgb_out_time(uint8_t ms); + +enum led_registers { + LEDDCR0 = 8, + LEDDBR = 9, + LEDDONR = 10, + LEDDOFR = 11, + LEDDBCRR = 5, + LEDDBCFR = 6, + LEDDPWRR = 1, + LEDDPWRG = 2, + LEDDPWRB = 3, +}; + +void rgb_write(uint8_t value, uint8_t addr); + +#endif /* _RGB_H_ */ \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/spi.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/spi.h new file mode 100644 index 0000000..190cec8 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/spi.h @@ -0,0 +1,93 @@ +#ifndef BB_SPI_H_ +#define BB_SPI_H_ + +#include + +enum spi_state { + SS_UNCONFIGURED = 0, + SS_SINGLE, + SS_DUAL_RX, + SS_DUAL_TX, + SS_QUAD_RX, + SS_QUAD_TX, + SS_HARDWARE, +}; + +enum spi_type { + ST_UNCONFIGURED, + ST_SINGLE, + ST_DUAL, + ST_QUAD, + ST_QPI, +}; + +enum spi_pin { + SP_MOSI, + SP_MISO, + SP_HOLD, + SP_WP, + SP_CS, + SP_CLK, + SP_D0, + SP_D1, + SP_D2, + SP_D3, +}; + +struct spi_id { + uint8_t manufacturer_id; // Result from 0x90 + uint8_t device_id; // Result from 0x90 + uint8_t _manufacturer_id; // Result from 0x9f + uint8_t memory_type; // Result from 0x9f + uint8_t memory_size; // Result from 0x9f + uint8_t signature; // Result from 0xab + uint8_t serial[4]; // Result from 0x4b + int bytes; // -1 if unknown + const char *manufacturer; + const char *model; + const char *capacity; +}; + +struct ff_spi; + +void spiPause(struct ff_spi *spi); +void spiBegin(struct ff_spi *spi); +void spiEnd(struct ff_spi *spi); + +//void spiSingleTx(struct ff_spi *spi, uint8_t out); +//uint8_t spiSingleRx(struct ff_spi *spi); +//void spiDualTx(struct ff_spi *spi, uint8_t out); +//void spiQuadTx(struct ff_spi *spi, uint8_t out); +void spiCommand(struct ff_spi *spi, uint8_t cmd); +//uint8_t spiDualRx(struct ff_spi *spi); +//uint8_t spiQuadRx(struct ff_spi *spi); +int spiTx(struct ff_spi *spi, uint8_t word); +uint8_t spiRx(struct ff_spi *spi); +uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr); +void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val); +void spiReadSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]); +void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]); +int spiSetType(struct ff_spi *spi, enum spi_type type); +int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count); +int spiIsBusy(struct ff_spi *spi); +int spiBeginErase32(struct ff_spi *spi, uint32_t erase_addr); +int spiBeginErase64(struct ff_spi *spi, uint32_t erase_addr); +int spiBeginWrite(struct ff_spi *spi, uint32_t addr, const void *data, unsigned int count); + +struct spi_id spiId(struct ff_spi *spi); +void spiOverrideSize(struct ff_spi *spi, uint32_t new_size); + +//int spi_wait_for_not_busy(struct ff_spi *spi); +int spiWrite(struct ff_spi *spi, uint32_t addr, const uint8_t *data, unsigned int count); +uint8_t spiReset(struct ff_spi *spi); +int spiInit(struct ff_spi *spi); + +void spiHold(struct ff_spi *spi); +void spiUnhold(struct ff_spi *spi); +void spiSwapTxRx(struct ff_spi *spi); + +struct ff_spi *spiAlloc(void); +void spiSetPin(struct ff_spi *spi, enum spi_pin pin, int val); +void spiFree(void); + +#endif /* BB_SPI_H_ */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/spiflash.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/spiflash.h new file mode 100644 index 0000000..a4ff495 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/spiflash.h @@ -0,0 +1,8 @@ +#ifndef __SPIFLASH_H +#define __SPIFLASH_H + +void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len); +void erase_flash_sector(unsigned int addr); +void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len); + +#endif /* __SPIFLASH_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/system.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/system.h new file mode 100644 index 0000000..ea3da85 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/system.h @@ -0,0 +1,67 @@ +#ifndef __SYSTEM_H +#define __SYSTEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +void flush_cpu_icache(void); +void flush_cpu_dcache(void); +void flush_l2_cache(void); + +#ifdef __or1k__ +#include +static inline unsigned long mfspr(unsigned long add) +{ + unsigned long ret; + + __asm__ __volatile__ ("l.mfspr %0,%1,0" : "=r" (ret) : "r" (add)); + + return ret; +} + +static inline void mtspr(unsigned long add, unsigned long val) +{ + __asm__ __volatile__ ("l.mtspr %0,%1,0" : : "r" (add), "r" (val)); +} +#endif + + +#if defined(__vexriscv__) || defined(__minerva__) +#include +#define csrr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define csrw(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define csrs(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) + +#define csrc(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) +#endif + +#ifdef __cplusplus +} +#endif + +#include + +__attribute__((noreturn)) void reboot(void); + +__attribute__((noreturn)) static inline void warmboot_to_image(uint8_t image_index) { + reboot_ctrl_write(0xac | (image_index & 3) << 0); + while (1); +} +#endif /* __SYSTEM_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/time.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/time.h new file mode 100644 index 0000000..cbbc688 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/time.h @@ -0,0 +1,16 @@ +#ifndef __TIME_H +#define __TIME_H + +#ifdef __cplusplus +extern "C" { +#endif + +void time_init(void); +int elapsed(int *last_event, int period); +void msleep(int ms); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIME_H */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-api.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-api.h new file mode 100644 index 0000000..a957f79 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-api.h @@ -0,0 +1,109 @@ +#ifndef TOBOOT_API_H_ +#define TOBOOT_API_H_ + +#include + +/// Store this configuration struct at offset 0x94 from the start +/// of your binary image. +/// You may set all RESERVED values to 0. as they will be calculated +/// when the program is written to flash. +struct toboot_configuration { + /// Set to 0x907070b2 to indicate a valid configuration header. + uint32_t magic; + + /// Reserved value. Used as a generational counter. Toboot will + /// overwrite this value with a monotonically-increasing counter + /// every time a new image is burned. This is used to determine + /// which image is the newest. + uint16_t reserved_gen; + + /// The starting page for your program in 1024-byte blocks. + /// Toboot itself sets this to 0. If this is nonzero, then it + /// must be located after the Toboot image. Toboot is currently + /// under 5 kilobytes, so make sure this value is at least 6. + uint8_t start; + + /// Configuration bitmask. See below for values. + uint8_t config; + + /// Set to 0x18349420 to prevent the user from entering Toboot manually. + /// Use this value with caution, as it can be used to lockout a Tomu. + uint32_t lock_entry; + + /// A bitmask of sectors to erase when updating the program. Each "1" + /// causes that sector to be erased, unless it's Toboot itself. Bit values + /// determine flash blocks 0-31. + uint32_t erase_mask_lo; + + /// A bitmask of sectors to erase when updating the program. Each "1" + /// causes that sector to e erased. Use these two values to e.g. force + /// private keys to be erased when updating. Bit values determine flash + /// blocks 32-63. + uint32_t erase_mask_hi; + + /// A hash of the entire header, minus this entry. Toboot calculates + /// this when it programs the first block. A Toboot configuration + /// header MUST have a valid hash in order to be considered valid. + uint32_t reserved_hash; +} __attribute__((packed)); + +/// Toboot V1.0 leaves IRQs enabled, mimicking the behavior of +/// AN0042. Toboot V2.0 makes this configurable by adding a +/// bit to the configuration area. +#define TOBOOT_CONFIG_FLAG_ENABLE_IRQ_MASK 0x01 +#define TOBOOT_CONFIG_FLAG_ENABLE_IRQ_SHIFT 0 +#define TOBOOT_CONFIG_FLAG_ENABLE_IRQ (1 << 0) +#define TOBOOT_CONFIG_FLAG_DISABLE_IRQ (0 << 0) + +/// When running a normal program, you won't want Toboot to run. +/// However, when developing new software it is handy to have +/// Toboot run at poweron, instead of jumping straight to your +/// program. Set this flag to enter your program whenever the +/// system has just powered on. +#define TOBOOT_CONFIG_FLAG_AUTORUN_MASK 0x02 +#define TOBOOT_CONFIG_FLAG_AUTORUN_SHIFT 1 +#define TOBOOT_CONFIG_FLAG_AUTORUN (1 << 1) +#define TOBOOT_CONFIG_FLAG_AUTORUN_DISABLED (0 << 1) + +/// When we create a fake header, this flag will be set. Otherwise, +/// leave the flag cleared. This field has no meaning in user +/// applications, and is only used internally. +#define TOBOOT_CONFIG_FAKE_MASK 0x04 +#define TOBOOT_CONFIG_FAKE_SHIFT 2 +#define TOBOOT_CONFIG_FAKE (1 << 2) + +/// Various magic values describing Toboot configuration headers. +#define TOBOOT_V1_MAGIC 0x6fb0 +#define TOBOOT_V1_MAGIC_MASK 0x0000ffff +#define TOBOOT_V2_MAGIC 0x907070b2 +#define TOBOOT_V2_MAGIC_MASK 0xffffffff + +/// This value is used to prevent manual entry into Toboot. +#define TOBOOT_LOCKOUT_MAGIC 0x18349420 + +/// The seed value for the hash of Toboot's configuration header +#define TOBOOT_HASH_SEED 0x037a5cf1 + +/// This is the runtime part that lives at the start of RAM. +/// Running programs can use this to force entry into Toboot +/// during the next reboot. +struct toboot_runtime { + /// Set this to 0x74624346 and reboot to enter bootloader, + /// even if LOCKOUT is enabled. + uint32_t magic; + + /// Set this to 0 when your program starts. + uint8_t boot_count; + + /// The bootloader should set this to 0x23 for Tomu. + uint8_t board_model; + + /// Unused. + uint16_t reserved; +}; + +/// Set runtime.magic to this value and reboot to force +/// entry into Toboot. +#define TOBOOT_FORCE_ENTRY_MAGIC 0x74624346 + +#endif /* TOBOOT_API_H_ */ \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-internal.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-internal.h new file mode 100644 index 0000000..9463766 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/toboot-internal.h @@ -0,0 +1,49 @@ +#ifndef TOBOOT_INTERNAL_H_ +#define TOBOOT_INTERNAL_H_ + +#include + +/// This describes the structure that allows the OS to communicate +/// with the bootloader. It keeps track of how many times we've +/// tried booting, as well as a magic value that tells us to enter +/// the bootloader instead of booting the app. +/// It also keeps track of the board model. +__attribute__((section(".boot_token"))) extern struct toboot_runtime boot_token; + +enum bootloader_reason +{ + NOT_ENTERING_BOOTLOADER = 0, + BOOT_TOKEN_PRESENT = 1, + BOOT_FAILED_TOO_MANY_TIMES = 2, + NO_PROGRAM_PRESENT = 3, + BUTTON_HELD_DOWN = 4, + COLD_BOOT_CONFIGURATION_FLAG = 5, +}; + +extern enum bootloader_reason bootloader_reason; + +/// Legacy Toboot V1 configuration values +#ifndef TOBOOT_V1_CFG_FLAGS +#define TOBOOT_V1_CFG_FLAGS 0 +#endif +#define TOBOOT_V1_CFG_MAGIC_MASK 0xffff +#define TOBOOT_V1_CFG_MAGIC 0x70b0 + +#ifndef TOBOOT_V1_APP_FLAGS +#define TOBOOT_V1_APP_FLAGS 0 +#endif + +#define TOBOOT_V1_APP_MAGIC_MASK 0xffff +#define TOBOOT_V1_APP_MAGIC 0x6fb0 +#define TOBOOT_V1_APP_PAGE_MASK 0x00ff0000 +#define TOBOOT_V1_APP_PAGE_SHIFT 16 + +uint32_t tb_first_free_address(void); +uint32_t tb_first_free_sector(void); +const struct toboot_configuration *tb_get_config(void); +uint32_t tb_config_hash(const struct toboot_configuration *cfg); +void tb_sign_config(struct toboot_configuration *cfg); +uint32_t tb_generation(const struct toboot_configuration *cfg); +int tb_valid_signature_at_page(uint32_t page); + +#endif /* TOBOOT_INTERNAL_H_ */ \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb-desc.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb-desc.h new file mode 100644 index 0000000..6ad6771 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb-desc.h @@ -0,0 +1,91 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * + * 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: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * 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. + */ + +#ifndef _usb_desc_h_ +#define _usb_desc_h_ + +#include +#include +#include + +struct usb_setup_request { + union { + struct { + uint8_t bmRequestType; + uint8_t bRequest; + }; + uint16_t wRequestAndType; + }; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}; + +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wString[]; +}; + +#define NUM_USB_BUFFERS 8 +#define VENDOR_ID 0x1209 // pid.codes +#define PRODUCT_ID 0x5bf0 // Assigned to Fomu project +#define DEVICE_VER 0x0101 // Bootloader version +#define MANUFACTURER_NAME u"Foosn" +#define MANUFACTURER_NAME_LEN sizeof(MANUFACTURER_NAME) +#define PRODUCT_NAME u"Fomu App " GIT_VERSION +#define PRODUCT_NAME_LEN sizeof(PRODUCT_NAME) + +// Microsoft Compatible ID Feature Descriptor +#define MSFT_VENDOR_CODE '~' // Arbitrary, but should be printable ASCII +#define MSFT_WCID_LEN 40 +extern const uint8_t usb_microsoft_wcid[MSFT_WCID_LEN]; + +typedef struct { + uint16_t wValue; + uint16_t length; + const uint8_t *addr; +} usb_descriptor_list_t; + +extern const usb_descriptor_list_t usb_descriptor_list[]; + +// WebUSB Landing page URL descriptor +#define WEBUSB_VENDOR_CODE 2 + +#ifndef LANDING_PAGE_URL +#define LANDING_PAGE_URL "dfu.tomu.im" +#endif + +#define LANDING_PAGE_DESCRIPTOR_SIZE (WEBUSB_DT_URL_DESCRIPTOR_SIZE \ + + sizeof(LANDING_PAGE_URL) - 1) + +extern const struct webusb_url_descriptor landing_url_descriptor; + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb.h new file mode 100644 index 0000000..60d57e4 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usb.h @@ -0,0 +1,40 @@ +#ifndef __USB_H +#define __USB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +struct usb_setup_request; + +void usb_isr(void); +void usb_init(void); +void usb_connect(void); +void usb_disconnect(void); + +int usb_irq_happened(void); +void usb_setup(const struct usb_setup_request *setup); +int usb_send(const void *data, int total_count); +void usb_ack_in(void); +void usb_ack_out(void); +void usb_err_in(void); +void usb_err_out(void); +int usb_recv(void *buffer, unsigned int buffer_len); +void usb_poll(void); +int usb_wait_for_send_done(void); +void usb_recv_done(void); +void usb_set_address(uint8_t new_address); + +void usb_putc(char c); +int usb_getc(void); +int usb_write(const char *buf, int count); +int usb_can_getc(void); +int usb_can_putc(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbcdc.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbcdc.h new file mode 100644 index 0000000..20b7836 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbcdc.h @@ -0,0 +1,162 @@ +/** @defgroup usb_cdc_defines USB CDC Type Definitions + +@brief Defined Constants and Types for the USB CDC Type Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __CDC_H +#define __CDC_H + +/* Definitions of Communications Device Class from + * "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2" + */ + +/* Table 2: Communications Device Class Code */ +#define USB_CLASS_CDC 0x02 + +/* Table 4: Class Subclass Code */ +#define USB_CDC_SUBCLASS_DLCM 0x01 +#define USB_CDC_SUBCLASS_ACM 0x02 +/* ... */ + +/* Table 5 Communications Interface Class Control Protocol Codes */ +#define USB_CDC_PROTOCOL_NONE 0x00 +#define USB_CDC_PROTOCOL_AT 0x01 +/* ... */ + +/* Table 6: Data Interface Class Code */ +#define USB_CLASS_DATA 0x0A + +/* Table 12: Type Values for the bDescriptorType Field */ +#define CS_INTERFACE 0x24 +#define CS_ENDPOINT 0x25 + +/* Table 13: bDescriptor SubType in Communications Class Functional + * Descriptors */ +#define USB_CDC_TYPE_HEADER 0x00 +#define USB_CDC_TYPE_CALL_MANAGEMENT 0x01 +#define USB_CDC_TYPE_ACM 0x02 +/* ... */ +#define USB_CDC_TYPE_UNION 0x06 +/* ... */ + +/* Table 15: Class-Specific Descriptor Header Format */ +struct usb_cdc_header_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint16_t bcdCDC; +} __attribute__((packed)); + +/* Table 16: Union Interface Functional Descriptor */ +struct usb_cdc_union_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bControlInterface; + uint8_t bSubordinateInterface0; + /* ... */ +} __attribute__((packed)); + + +/* Definitions for Abstract Control Model devices from: + * "Universal Serial Bus Communications Class Subclass Specification for + * PSTN Devices" + */ + +/* Table 3: Call Management Functional Descriptor */ +struct usb_cdc_call_management_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; + uint8_t bDataInterface; +} __attribute__((packed)); + +/* Table 4: Abstract Control Management Functional Descriptor */ +struct usb_cdc_acm_descriptor { + uint8_t bFunctionLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubtype; + uint8_t bmCapabilities; +} __attribute__((packed)); + +/* Table 13: Class-Specific Request Codes for PSTN subclasses */ +/* ... */ +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +/* ... */ +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +/* ... */ + +/* Table 17: Line Coding Structure */ +struct usb_cdc_line_coding { + uint32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} __attribute__((packed)); + +enum usb_cdc_line_coding_bCharFormat { + USB_CDC_1_STOP_BITS = 0, + USB_CDC_1_5_STOP_BITS = 1, + USB_CDC_2_STOP_BITS = 2, +}; + +enum usb_cdc_line_coding_bParityType { + USB_CDC_NO_PARITY = 0, + USB_CDC_ODD_PARITY = 1, + USB_CDC_EVEN_PARITY = 2, + USB_CDC_MARK_PARITY = 3, + USB_CDC_SPACE_PARITY = 4, +}; + +/* Table 30: Class-Specific Notification Codes for PSTN subclasses */ +/* ... */ +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +/* ... */ + +/* Notification Structure */ +struct usb_cdc_notification { + uint8_t bmRequestType; + uint8_t bNotification; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__((packed)); + +#endif + +/**@}*/ + diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbstd.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbstd.h new file mode 100644 index 0000000..3c61700 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/usbstd.h @@ -0,0 +1,277 @@ +/** @defgroup usb_type_defines USB Standard Structure Definitions + +@brief Defined Constants and Types for the USB Standard Structure +Definitions + +@ingroup USB_defines + +@version 1.0.0 + +@author @htmlonly © @endhtmlonly 2010 +Gareth McMullin + +@date 10 March 2013 + +A set of structure definitions for the USB control structures +defined in chapter 9 of the "Universal Serial Bus Specification Revision 2.0" +Available from the USB Implementers Forum - http://www.usb.org/ + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#ifndef __USBSTD_H +#define __USBSTD_H + +#include + +/* + * This file contains structure definitions for the USB control structures + * defined in chapter 9 of the "Universal Serial Bus Specification Revision 2.0" + * Available from the USB Implementers Forum - http://www.usb.org/ + */ + +/* USB Setup Data structure - Table 9-2 */ +struct usb_setup_data { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__((packed)); + +/* Class Definition */ +#define USB_CLASS_VENDOR 0xFF + +/* bmRequestType bit definitions */ +/* bit 7 : direction */ +#define USB_REQ_TYPE_DIRECTION 0x80 +#define USB_REQ_TYPE_IN 0x80 +/* bits 6..5 : type */ +#define USB_REQ_TYPE_TYPE 0x60 +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +/* bits 4..0 : recipient */ +#define USB_REQ_TYPE_RECIPIENT 0x1F +#define USB_REQ_TYPE_DEVICE 0x00 +#define USB_REQ_TYPE_INTERFACE 0x01 +#define USB_REQ_TYPE_ENDPOINT 0x02 +#define USB_REQ_TYPE_OTHER 0x03 + +/* USB Standard Request Codes - Table 9-4 */ +#define USB_REQ_GET_STATUS 0 +#define USB_REQ_CLEAR_FEATURE 1 +/* Reserved for future use: 2 */ +#define USB_REQ_SET_FEATURE 3 +/* Reserved for future use: 3 */ +#define USB_REQ_SET_ADDRESS 5 +#define USB_REQ_GET_DESCRIPTOR 6 +#define USB_REQ_SET_DESCRIPTOR 7 +#define USB_REQ_GET_CONFIGURATION 8 +#define USB_REQ_SET_CONFIGURATION 9 +#define USB_REQ_GET_INTERFACE 10 +#define USB_REQ_SET_INTERFACE 11 +#define USB_REQ_SET_SYNCH_FRAME 12 + +/* USB Descriptor Types - Table 9-5 */ +#define USB_DT_DEVICE 1 +#define USB_DT_CONFIGURATION 2 +#define USB_DT_STRING 3 +#define USB_DT_INTERFACE 4 +#define USB_DT_ENDPOINT 5 +#define USB_DT_DEVICE_QUALIFIER 6 +#define USB_DT_OTHER_SPEED_CONFIGURATION 7 +#define USB_DT_INTERFACE_POWER 8 +/* From ECNs */ +#define USB_DT_OTG 9 +#define USB_DT_DEBUG 10 +#define USB_DT_INTERFACE_ASSOCIATION 11 + +/* USB Standard Feature Selectors - Table 9-6 */ +#define USB_FEAT_ENDPOINT_HALT 0 +#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1 +#define USB_FEAT_TEST_MODE 2 + +/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */ +#define USB_DEV_STATUS_SELF_POWERED 0x01 +#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02 + +/* USB Standard Device Descriptor - Table 9-8 */ +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__((packed)); + +#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor) + +/* USB Device_Qualifier Descriptor - Table 9-9 + * Not used in this implementation. + */ +struct usb_device_qualifier_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} __attribute__((packed)); + +/* This is only defined as a top level named struct to improve c++ + * compatibility. You should never need to instance this struct + * in user code! */ +struct usb_interface { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +}; + +/* USB Standard Configuration Descriptor - Table 9-10 */ +struct usb_config_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; + + /* Descriptor ends here. The following are used internally: */ + const struct usb_interface interface[0]; +} __attribute__((packed)); +#define USB_DT_CONFIGURATION_SIZE 9 + +/* USB Configuration Descriptor bmAttributes bit definitions */ +#define USB_CONFIG_ATTR_DEFAULT 0x80 /** always required (USB2.0 table 9-10) */ +#define USB_CONFIG_ATTR_SELF_POWERED 0x40 +#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20 + +/* Other Speed Configuration is the same as Configuration Descriptor. + * - Table 9-11 + */ + +/* USB Standard Interface Descriptor - Table 9-12 */ +struct usb_interface_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; + + /* Descriptor ends here. The following are used internally: */ + const struct usb_endpoint_descriptor *endpoint; + const void *extra; + int extralen; +} __attribute__((packed)); +#define USB_DT_INTERFACE_SIZE 9 + +/* USB Standard Endpoint Descriptor - Table 9-13 */ +struct usb_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + + /* Descriptor ends here. The following are used internally: */ + const void *extra; + int extralen; +} __attribute__((packed)); +#define USB_DT_ENDPOINT_SIZE 7 + +/* USB bEndpointAddress helper macros */ +#define USB_ENDPOINT_ADDR_OUT(x) (x) +#define USB_ENDPOINT_ADDR_IN(x) (0x80 | (x)) + +/* USB Endpoint Descriptor bmAttributes bit definitions - Table 9-13 */ +/* bits 1..0 : transfer type */ +#define USB_ENDPOINT_ATTR_CONTROL 0x00 +#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01 +#define USB_ENDPOINT_ATTR_BULK 0x02 +#define USB_ENDPOINT_ATTR_INTERRUPT 0x03 +#define USB_ENDPOINT_ATTR_TYPE 0x03 +/* bits 3..2 : Sync type (only if ISOCHRONOUS) */ +#define USB_ENDPOINT_ATTR_NOSYNC 0x00 +#define USB_ENDPOINT_ATTR_ASYNC 0x04 +#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08 +#define USB_ENDPOINT_ATTR_SYNC 0x0C +#define USB_ENDPOINT_ATTR_SYNCTYPE 0x0C +/* bits 5..4 : usage type (only if ISOCHRONOUS) */ +#define USB_ENDPOINT_ATTR_DATA 0x00 +#define USB_ENDPOINT_ATTR_FEEDBACK 0x10 +#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20 +#define USB_ENDPOINT_ATTR_USAGETYPE 0x30 + +/* Table 9-15 specifies String Descriptor Zero. + * Table 9-16 specified UNICODE String Descriptor. + */ +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wData[]; +} __attribute__((packed)); + +/* From ECN: Interface Association Descriptors, Table 9-Z */ +struct usb_iface_assoc_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __attribute__((packed)); +#define USB_DT_INTERFACE_ASSOCIATION_SIZE \ + sizeof(struct usb_iface_assoc_descriptor) + +enum usb_language_id { + USB_LANGID_ENGLISH_US = 0x409, +}; +#endif + +/**@}*/ + diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/webusb-defs.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/webusb-defs.h new file mode 100644 index 0000000..fd699e9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/webusb-defs.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, Devan Lai + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice + * appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef WEBUSB_DEFS_H_INCLUDED +#define WEBUSB_DEFS_H_INCLUDED + +#include + +#define WEBUSB_REQ_GET_URL 0x02 + +#define WEBUSB_DT_URL 3 + +#define WEBUSB_URL_SCHEME_HTTP 0 +#define WEBUSB_URL_SCHEME_HTTPS 1 + +struct webusb_platform_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bReserved; + uint8_t platformCapabilityUUID[16]; + uint16_t bcdVersion; + uint8_t bVendorCode; + uint8_t iLandingPage; +} __attribute__((packed)); + +#define WEBUSB_PLATFORM_DESCRIPTOR_SIZE sizeof(struct webusb_platform_descriptor) + +#define WEBUSB_UUID {0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47,0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65} + +struct webusb_url_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bScheme; + char URL[]; +} __attribute__((packed)); + +#define WEBUSB_DT_URL_DESCRIPTOR_SIZE 3 + +#endif diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.c b/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.c new file mode 100644 index 0000000..6f85fc4 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.c @@ -0,0 +1,912 @@ +/* +* xxHash - Fast Hash algorithm +* Copyright (C) 2012-2016, Yann Collet +* +* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are +* met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above +* copyright notice, this list of conditions and the following disclaimer +* in the documentation and/or other materials provided with the +* distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +* You can contact the author at : +* - xxHash homepage: http://www.xxhash.com +* - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + + +/* ************************************* +* Tuning parameters +***************************************/ +/*!XXH_FORCE_MEMORY_ACCESS : + * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. + * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. + * The below switch allow to select different access method for improved performance. + * Method 0 (default) : use `memcpy()`. Safe and portable. + * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). + * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. + * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. + * It can generate buggy code on targets which do not support unaligned memory accesses. + * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) + * See http://stackoverflow.com/a/32095106/646947 for details. + * Prefer these methods in priority order (0 > 1 > 2) + */ +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) +# define XXH_FORCE_MEMORY_ACCESS 2 +# elif defined(__INTEL_COMPILER) || \ + (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7S__) )) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +/*!XXH_ACCEPT_NULL_INPUT_POINTER : + * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. + * When this macro is enabled, xxHash actively checks input for null pointer. + * It it is, result for null input pointers is the same as a null-length input. + */ +#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ +# define XXH_ACCEPT_NULL_INPUT_POINTER 0 +#endif + +/*!XXH_FORCE_NATIVE_FORMAT : + * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. + * Results are therefore identical for little-endian and big-endian CPU. + * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. + * Should endian-independence be of no importance for your application, you may set the #define below to 1, + * to improve speed for Big-endian CPU. + * This option has no impact on Little_Endian CPU. + */ +#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ +# define XXH_FORCE_NATIVE_FORMAT 0 +#endif + +/*!XXH_FORCE_ALIGN_CHECK : + * This is a minor performance trick, only useful with lots of very small keys. + * It means : check for aligned/unaligned input. + * The check costs one initial branch per hash; + * set it to 0 when the input is guaranteed to be aligned, + * or when alignment doesn't matter for performance. + */ +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + + +/* ************************************* +* Includes & Memory related functions +***************************************/ +/*! Modify the local functions below should you wish to use some other memory routines +* for malloc(), free() */ +#include +static void* XXH_malloc(size_t s) { return malloc(s); } +static void XXH_free (void* p) { free(p); } +/*! and for memcpy() */ +#include +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + + +/* ************************************* +* Compiler Specific Options +***************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# define FORCE_INLINE static __forceinline +#else +# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# ifdef __GNUC__ +# define FORCE_INLINE static inline __attribute__((always_inline)) +# else +# define FORCE_INLINE static inline +# endif +# else +# define FORCE_INLINE static +# endif /* __STDC_VERSION__ */ +#endif + + +/* ************************************* +* Basic Types +***************************************/ +#ifndef MEM_MODULE +# if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t BYTE; + typedef uint16_t U16; + typedef uint32_t U32; +# else + typedef unsigned char BYTE; + typedef unsigned short U16; + typedef unsigned int U32; +# endif +#endif + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; } __attribute__((packed)) unalign; +static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ +static U32 XXH_read32(const void* memPtr) +{ + U32 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ +#if defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) +# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) +#endif + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +#else +static U32 XXH_swap32 (U32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + + +/* ************************************* +* Architecture Macros +***************************************/ +typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; + +/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ +#ifndef XXH_CPU_LITTLE_ENDIAN + static const int g_one = 1; +# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) +#endif + + +/* *************************** +* Memory reads +*****************************/ +typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; + +FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); + else + return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); +} + +FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE32_align(ptr, endian, XXH_unaligned); +} + +static U32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} + + +/* ************************************* +* Macros +***************************************/ +#define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */ +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ******************************************************************* +* 32-bit hash functions +*********************************************************************/ +static const U32 PRIME32_1 = 2654435761U; +static const U32 PRIME32_2 = 2246822519U; +static const U32 PRIME32_3 = 3266489917U; +static const U32 PRIME32_4 = 668265263U; +static const U32 PRIME32_5 = 374761393U; + +static U32 XXH32_round(U32 seed, U32 input) +{ + seed += input * PRIME32_2; + seed = XXH_rotl32(seed, 13); + seed *= PRIME32_1; + return seed; +} + +FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U32 h32; +#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) + +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)16; + } +#endif + + if (len>=16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = seed + PRIME32_1 + PRIME32_2; + U32 v2 = seed + PRIME32_2; + U32 v3 = seed + 0; + U32 v4 = seed - PRIME32_1; + + do { + v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; + v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; + v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; + v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; + } while (p<=limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + PRIME32_5; + } + + h32 += (U32) len; + + while (p+4<=bEnd) { + h32 += XXH_get32bits(p) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, input, len); + return XXH32_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + + + +/*====== Hash streaming ======*/ + +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) +{ + XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME32_1 + PRIME32_2; + state.v2 = seed + PRIME32_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME32_1; + /* do not write into reserved, planned to be removed in a future version */ + memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); + return XXH_OK; +} + + +FORCE_INLINE +XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + state->total_len_32 += (unsigned)len; + state->large_len |= (len>=16) | (state->total_len_32>=16); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); + state->memsize += (unsigned)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const unsigned* p32 = state->mem32; + state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; + state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; + state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; + state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const BYTE* const limit = bEnd - 16; + U32 v1 = state->v1; + U32 v2 = state->v2; + U32 v3 = state->v3; + U32 v4 = state->v4; + + do { + v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; + v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; + v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; + v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH32_update_endian(state_in, input, len, XXH_bigEndian); +} + + + +FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem32; + const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; + U32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v1, 1) + + XXH_rotl32(state->v2, 7) + + XXH_rotl32(state->v3, 12) + + XXH_rotl32(state->v4, 18); + } else { + h32 = state->v3 /* == seed */ + PRIME32_5; + } + + h32 += state->total_len_32; + + while (p+4<=bEnd) { + h32 += XXH_readLE32(p, endian) * PRIME32_3; + h32 = XXH_rotl32(h32, 17) * PRIME32_4; + p+=4; + } + + while (p> 15; + h32 *= PRIME32_2; + h32 ^= h32 >> 13; + h32 *= PRIME32_3; + h32 ^= h32 >> 16; + + return h32; +} + + +XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH32_digest_endian(state_in, XXH_littleEndian); + else + return XXH32_digest_endian(state_in, XXH_bigEndian); +} + + +/*====== Canonical representation ======*/ + +/*! Default XXH result types are basic unsigned 32 and 64 bits. +* The canonical representation follows human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file or buffer, remaining comparable across different systems. +*/ + +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} + + +#ifndef XXH_NO_LONG_LONG + +/* ******************************************************************* +* 64-bit hash functions +*********************************************************************/ + +/*====== Memory access ======*/ + +#ifndef MEM_MODULE +# define MEM_MODULE +# if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint64_t U64; +# else + /* if compiler doesn't support unsigned long long, replace by another 64-bit type */ + typedef unsigned long long U64; +# endif +#endif + + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ +/* currently only defined for gcc and icc */ +typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; +static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; } + +#else + +/* portable and safe solution. Generally efficient. + * see : http://stackoverflow.com/a/32095106/646947 + */ + +static U64 XXH_read64(const void* memPtr) +{ + U64 val; + memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap64 _byteswap_uint64 +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap64 __builtin_bswap64 +#else +static U64 XXH_swap64 (U64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + +FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) +{ + if (align==XXH_unaligned) + return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); + else + return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); +} + +FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) +{ + return XXH_readLE64_align(ptr, endian, XXH_unaligned); +} + +static U64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} + + +/*====== xxh64 ======*/ + +static const U64 PRIME64_1 = 11400714785074694791ULL; +static const U64 PRIME64_2 = 14029467366897019727ULL; +static const U64 PRIME64_3 = 1609587929392839161ULL; +static const U64 PRIME64_4 = 9650029242287828579ULL; +static const U64 PRIME64_5 = 2870177450012600261ULL; + +static U64 XXH64_round(U64 acc, U64 input) +{ + acc += input * PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= PRIME64_1; + return acc; +} + +static U64 XXH64_mergeRound(U64 acc, U64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * PRIME64_1 + PRIME64_4; + return acc; +} + +FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* bEnd = p + len; + U64 h64; +#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) + +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + if (p==NULL) { + len=0; + bEnd=p=(const BYTE*)(size_t)32; + } +#endif + + if (len>=32) { + const BYTE* const limit = bEnd - 32; + U64 v1 = seed + PRIME64_1 + PRIME64_2; + U64 v2 = seed + PRIME64_2; + U64 v3 = seed + 0; + U64 v4 = seed - PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; + v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; + v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; + v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; + } while (p<=limit); + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + + } else { + h64 = seed + PRIME64_5; + } + + h64 += (U64) len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_get64bits(p)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + + +XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH64_state_t state; + XXH64_reset(&state, seed); + XXH64_update(&state, input, len); + return XXH64_digest(&state); +#else + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); + } } + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); + else + return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); +#endif +} + +/*====== Hash Streaming ======*/ + +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) +{ + return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); +} +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState) +{ + memcpy(dstState, srcState, sizeof(*dstState)); +} + +XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) +{ + XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ + memset(&state, 0, sizeof(state)); + state.v1 = seed + PRIME64_1 + PRIME64_2; + state.v2 = seed + PRIME64_2; + state.v3 = seed + 0; + state.v4 = seed - PRIME64_1; + /* do not write into reserved, planned to be removed in a future version */ + memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); + return XXH_OK; +} + +FORCE_INLINE +XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) +{ + const BYTE* p = (const BYTE*)input; + const BYTE* const bEnd = p + len; + + if (input==NULL) +#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) + return XXH_OK; +#else + return XXH_ERROR; +#endif + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); + state->memsize += (U32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); + state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); + state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); + state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); + p += 32-state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const BYTE* const limit = bEnd - 32; + U64 v1 = state->v1; + U64 v2 = state->v2; + U64 v3 = state->v3; + U64 v4 = state->v4; + + do { + v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; + v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; + v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; + v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; + } while (p<=limit); + + state->v1 = v1; + state->v2 = v2; + state->v3 = v3; + state->v4 = v4; + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + + return XXH_OK; +} + +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_update_endian(state_in, input, len, XXH_littleEndian); + else + return XXH64_update_endian(state_in, input, len, XXH_bigEndian); +} + +FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) +{ + const BYTE * p = (const BYTE*)state->mem64; + const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; + U64 h64; + + if (state->total_len >= 32) { + U64 const v1 = state->v1; + U64 const v2 = state->v2; + U64 const v3 = state->v3; + U64 const v4 = state->v4; + + h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); + h64 = XXH64_mergeRound(h64, v1); + h64 = XXH64_mergeRound(h64, v2); + h64 = XXH64_mergeRound(h64, v3); + h64 = XXH64_mergeRound(h64, v4); + } else { + h64 = state->v3 + PRIME64_5; + } + + h64 += (U64) state->total_len; + + while (p+8<=bEnd) { + U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; + p+=8; + } + + if (p+4<=bEnd) { + h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; + h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; + p+=4; + } + + while (p> 33; + h64 *= PRIME64_2; + h64 ^= h64 >> 29; + h64 *= PRIME64_3; + h64 ^= h64 >> 32; + + return h64; +} + +XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) +{ + XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; + + if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) + return XXH64_digest_endian(state_in, XXH_littleEndian); + else + return XXH64_digest_endian(state_in, XXH_bigEndian); +} + + +/*====== Canonical representation ======*/ + +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + memcpy(dst, &hash, sizeof(*dst)); +} + +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} + +#endif /* XXH_NO_LONG_LONG */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.h b/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.h new file mode 100644 index 0000000..4099da0 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/include/xxhash.h @@ -0,0 +1,294 @@ +/* + xxHash - Extremely Fast Hash algorithm + Header File + Copyright (C) 2012-2016, Yann Collet. + + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + You can contact the author at : + - xxHash source repository : https://github.com/Cyan4973/xxHash +*/ + +/* Notice extracted from xxHash homepage : + +xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +It also successfully passes all tests from the SMHasher suite. + +Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) + +Name Speed Q.Score Author +xxHash 5.4 GB/s 10 +CrapWow 3.2 GB/s 2 Andrew +MumurHash 3a 2.7 GB/s 10 Austin Appleby +SpookyHash 2.0 GB/s 10 Bob Jenkins +SBox 1.4 GB/s 9 Bret Mulvey +Lookup3 1.2 GB/s 9 Bob Jenkins +SuperFastHash 1.2 GB/s 1 Paul Hsieh +CityHash64 1.05 GB/s 10 Pike & Alakuijala +FNV 0.55 GB/s 5 Fowler, Noll, Vo +CRC32 0.43 GB/s 9 +MD5-32 0.33 GB/s 10 Ronald L. Rivest +SHA1-32 0.28 GB/s 10 + +Q.Score is a measure of quality of the hash function. +It depends on successfully passing SMHasher test set. +10 is a perfect score. + +A 64-bit version, named XXH64, is available since r35. +It offers much better speed, but for 64-bit applications only. +Name Speed on 64 bits Speed on 32 bits +XXH64 13.8 GB/s 1.9 GB/s +XXH32 6.8 GB/s 6.0 GB/s +*/ + +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* **************************** +* Definitions +******************************/ +#include /* size_t */ +typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; + + +/* **************************** +* API modifier +******************************/ +/** XXH_PRIVATE_API +* This is useful to include xxhash functions in `static` mode +* in order to inline them, and remove their symbol from the public list. +* Methodology : +* #define XXH_PRIVATE_API +* #include "xxhash.h" +* `xxhash.c` is automatically included. +* It's not useful to compile and link it as a separate module. +*/ +#ifdef XXH_PRIVATE_API +# ifndef XXH_STATIC_LINKING_ONLY +# define XXH_STATIC_LINKING_ONLY +# endif +# if defined(__GNUC__) +# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define XXH_PUBLIC_API static inline +# elif defined(_MSC_VER) +# define XXH_PUBLIC_API static __inline +# else + /* this version may generate warnings for unused static functions */ +# define XXH_PUBLIC_API static +# endif +#else +# define XXH_PUBLIC_API /* do nothing */ +#endif /* XXH_PRIVATE_API */ + +/*!XXH_NAMESPACE, aka Namespace Emulation : + +If you want to include _and expose_ xxHash functions from within your own library, +but also want to avoid symbol collisions with other libraries which may also include xxHash, + +you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library +with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). + +Note that no change is required within the calling program as long as it includes `xxhash.h` : +regular symbol name will be automatically translated by this header. +*/ +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) +# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) +# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) +# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +#endif + + +/* ************************************* +* Version +***************************************/ +#define XXH_VERSION_MAJOR 0 +#define XXH_VERSION_MINOR 6 +#define XXH_VERSION_RELEASE 4 +#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) +XXH_PUBLIC_API unsigned XXH_versionNumber (void); + + +/*-********************************************************************** +* 32-bit hash +************************************************************************/ +typedef unsigned int XXH32_hash_t; + +/*! XXH32() : + Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". + The memory between input & input+length must be valid (allocated and read-accessible). + "seed" can be used to alter the result predictably. + Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); + +/*====== Streaming ======*/ +typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); +XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); + +/* +These functions generate the xxHash of an input provided in multiple segments. +Note that, for small input, they are slower than single-call functions, due to state management. +For small input, prefer `XXH32()` and `XXH64()` . + +XXH state must first be allocated, using XXH*_createState() . + +Start a new hash by initializing state with a seed, using XXH*_reset(). + +Then, feed the hash state by calling XXH*_update() as many times as necessary. +Obviously, input must be allocated and read accessible. +The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. + +Finally, a hash value can be produced anytime, by using XXH*_digest(). +This function returns the nn-bits hash as an int or long long. + +It's still possible to continue inserting input into the hash state after a digest, +and generate some new hashes later on, by calling again XXH*_digest(). + +When done, free XXH state space if it was allocated dynamically. +*/ + +/*====== Canonical representation ======*/ + +typedef struct { unsigned char digest[4]; } XXH32_canonical_t; +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); + +/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. +* The canonical representation uses human-readable write convention, aka big-endian (large digits first). +* These functions allow transformation of hash result into and from its canonical format. +* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. +*/ + + +#ifndef XXH_NO_LONG_LONG +/*-********************************************************************** +* 64-bit hash +************************************************************************/ +typedef unsigned long long XXH64_hash_t; + +/*! XXH64() : + Calculate the 64-bit hash of sequence of length "len" stored at memory address "input". + "seed" can be used to alter the result predictably. + This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). +*/ +XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); + +/*====== Streaming ======*/ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); +XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); + +/*====== Canonical representation ======*/ +typedef struct { unsigned char digest[8]; } XXH64_canonical_t; +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); +#endif /* XXH_NO_LONG_LONG */ + + +#ifdef XXH_STATIC_LINKING_ONLY + +/* ================================================================================================ + This section contains declarations which are not guaranteed to remain stable. + They may change in future versions, becoming incompatible with a different version of the library. + These declarations should only be used with static linking. + Never use them in association with dynamic linking ! +=================================================================================================== */ + +/* These definitions are only meant to make possible + static allocation of XXH state, on stack or in a struct for example. + Never use members directly. */ + +struct XXH32_state_s { + unsigned total_len_32; + unsigned large_len; + unsigned v1; + unsigned v2; + unsigned v3; + unsigned v4; + unsigned mem32[4]; /* buffer defined as U32 for alignment */ + unsigned memsize; + unsigned reserved; /* never read nor write, will be removed in a future version */ +}; /* typedef'd to XXH32_state_t */ + +#ifndef XXH_NO_LONG_LONG /* remove 64-bit support */ +struct XXH64_state_s { + unsigned long long total_len; + unsigned long long v1; + unsigned long long v2; + unsigned long long v3; + unsigned long long v4; + unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ + unsigned memsize; + unsigned reserved[2]; /* never read nor write, will be removed in a future version */ +}; /* typedef'd to XXH64_state_t */ +#endif + +#ifdef XXH_PRIVATE_API +# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ +#endif + +#endif /* XXH_STATIC_LINKING_ONLY */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* XXHASH_H_5627135585666179 */ diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/ld/linker.ld b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/linker.ld new file mode 100644 index 0000000..a0fa473 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/linker.ld @@ -0,0 +1,56 @@ +INCLUDE output_format.ld +ENTRY(_start) + +__DYNAMIC = 0; + +INCLUDE regions.ld + +SECTIONS +{ + .text : + { + _ftext = .; + *(.text.start) + *(.text .stub .text.* .gnu.linkonce.t.*) + _etext = .; + } > rom + + .rodata : + { + . = ALIGN(4); + _frodata = .; + *(.rodata .rodata.* .gnu.linkonce.r.*) + *(.rodata1) + *(.srodata .srodata.*) + _erodata = .; + } > rom + + .data : AT (ADDR(.rodata) + SIZEOF (.rodata)) + { + . = ALIGN(4); + _fdata = .; + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + _gp = ALIGN(16); + *(.sdata .sdata.* .gnu.linkonce.s.* .sdata2 .sdata2.*) + *(.ramtext .ramtext.*) + _edata = ALIGN(16); /* Make sure _edata is >= _gp. */ + } > sram + + .bss : + { + . = ALIGN(4); + _fbss = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = .; + _end = .; + } > sram +} + +PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/ld/output_format.ld b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/output_format.ld new file mode 100644 index 0000000..5e76f5f --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/output_format.ld @@ -0,0 +1 @@ +OUTPUT_FORMAT("elf32-littleriscv") diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/ld/regions.ld b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/regions.ld new file mode 100644 index 0000000..72cb118 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/ld/regions.ld @@ -0,0 +1,4 @@ +MEMORY { + sram : ORIGIN = 0x10000000, LENGTH = 0x00020000 + rom : ORIGIN = 0x20040000, LENGTH = 0x100000 /* 1 MBit */ +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/crt0-vexriscv.S b/wasm3-sys/wasm3/platforms/embedded/fomu/src/crt0-vexriscv.S new file mode 100644 index 0000000..a02c3aa --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/crt0-vexriscv.S @@ -0,0 +1,83 @@ +.global main +.global isr + +.section .text.start +.global _start + +_start: + j crt_init + +.global trap_entry +.section .ramtext +trap_entry: + sw x1, - 1*4(sp) + sw x5, - 2*4(sp) + sw x6, - 3*4(sp) + sw x7, - 4*4(sp) + sw x10, - 5*4(sp) + sw x11, - 6*4(sp) + sw x12, - 7*4(sp) + sw x13, - 8*4(sp) + sw x14, - 9*4(sp) + sw x15, -10*4(sp) + sw x16, -11*4(sp) + sw x17, -12*4(sp) + sw x28, -13*4(sp) + sw x29, -14*4(sp) + sw x30, -15*4(sp) + sw x31, -16*4(sp) + addi sp,sp,-16*4 + call isr + lw x1 , 15*4(sp) + lw x5, 14*4(sp) + lw x6, 13*4(sp) + lw x7, 12*4(sp) + lw x10, 11*4(sp) + lw x11, 10*4(sp) + lw x12, 9*4(sp) + lw x13, 8*4(sp) + lw x14, 7*4(sp) + lw x15, 6*4(sp) + lw x16, 5*4(sp) + lw x17, 4*4(sp) + lw x28, 3*4(sp) + lw x29, 2*4(sp) + lw x30, 1*4(sp) + lw x31, 0*4(sp) + addi sp,sp,16*4 + mret + +.text +crt_init: + la sp, _fstack + 4 + la a0, trap_entry + csrw mtvec, a0 + +bss_init: + la a0, _fbss + la a1, _ebss +bss_loop: + beq a0,a1,bss_done + sw zero,0(a0) + add a0,a0,4 + j bss_loop +bss_done: + + /* Load DATA */ + la t0, _erodata + la t1, _fdata + la t2, _edata +3: + lw t3, 0(t0) + sw t3, 0(t1) + /* _edata is aligned to 16 bytes. Use word-xfers. */ + addi t0, t0, 4 + addi t1, t1, 4 + bltu t1, t2, 3b + + li a0, 0x880 //880 enable timer + external interrupt sources (until mstatus.MIE is set, they will never trigger an interrupt) + csrw mie,a0 + + call main +infinite_loop: + j infinite_loop diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/ltoa.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/ltoa.c new file mode 100644 index 0000000..f0bdcd6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/ltoa.c @@ -0,0 +1,58 @@ +/* +** LTOA.C +** +** Converts a long integer to a string. +** +** Copyright 1988-90 by Robert B. Stout dba MicroFirm +** +** Released to public domain, 1991 +** +** Parameters: 1 - number to be converted +** 2 - buffer in which to build the converted string +** 3 - number base to use for conversion +** +** Returns: A character pointer to the converted string if +** successful, a NULL pointer if the number base specified +** is out of range. +*/ + +#include +#include + +#define BUFSIZE (sizeof(long) * 8 + 1) + +char *ltoa(long N, char *str, int base) +{ + register int i = 2; + long uarg; + char *tail, *head = str, buf[BUFSIZE]; + + if (36 < base || 2 > base) + base = 10; /* can only use 0-9, A-Z */ + tail = &buf[BUFSIZE - 1]; /* last character position */ + *tail-- = '\0'; + + if (10 == base && N < 0L) + { + *head++ = '-'; + uarg = -N; + } + else uarg = N; + + if (uarg) + { + for (i = 1; uarg; ++i) + { + register ldiv_t r; + + r = ldiv(uarg, base); + *tail-- = (char)(r.rem + ((9L < r.rem) ? + ('A' - 10L) : '0')); + uarg = r.quot; + } + } + else *tail-- = '0'; + + memcpy(head, ++tail, i); + return str; +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/main.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/main.c new file mode 100644 index 0000000..77cea3e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/main.c @@ -0,0 +1,148 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ff_spi *spi; + +char *ltoa(long N, char *str, int base); + +void uart_write(const char *str, unsigned len) { + if (!usb_can_putc()) return; + + while (len) { + while (!usb_can_putc()) + usb_poll(); + int bytes_written = usb_write(str, len); + str += bytes_written; + len -= bytes_written; + } +} + +void uart_print(const char *str) { + uart_write(str, strlen(str)); +} + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(func, msg) { \ + uart_print("Fatal: " func ": "); \ + uart_print(msg); uart_print("\n"); \ + return false; } + +bool run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + size_t fsize = fib32_wasm_len; + + uart_print("Loading WebAssembly...\n"); + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment", "failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime", "failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction", result); + + uart_print("Running...\n"); + + result = m3_CallV (f, 24); + if (result) FATAL("m3_Call", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults", result); + + char buff[32]; + ltoa(value, buff, 10); + + uart_print("Result: "); + uart_print(buff); + uart_print("\n"); + + return true; +} + + +__attribute__((section(".ramtext"))) +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + + if (irqs & (1 << USB_INTERRUPT)) + usb_isr(); +} + +__attribute__((section(".ramtext"))) +static void init(void) +{ + irq_setmask(0); + irq_setie(1); + usb_init(); + time_init(); + rgb_init(); +} + +void m3Yield () +{ + usb_poll(); +} + +__attribute__((section(".ramtext"))) +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + init(); + + usb_connect(); + + for (int i = 0; i< 10000; i++) { + usb_poll(); + msleep(1); + } + + uart_print("\nWasm3 v" M3_VERSION " on Fomu (" M3_ARCH "), build " __DATE__ " " __TIME__ "\n"); + + rgb_set(0, 0, 255); + if (run_wasm()) { + rgb_set(0, 255, 0); + } else { + rgb_set(255, 0, 0); + } + + while (1) + { + usb_poll(); + } + return 0; +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/rgb.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/rgb.c new file mode 100644 index 0000000..7cc3d21 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/rgb.c @@ -0,0 +1,73 @@ +#include +#include +#include + +#define BREATHE_ENABLE (1 << 7) +#define BREATHE_EDGE_ON (0 << 6) +#define BREATHE_EDGE_BOTH (1 << 6) +#define BREATHE_MODE_MODULATE (1 << 5) +#define BREATHE_MODE_FIXED (0 << 5) + +// Breathe rate is in 128 ms increments +#define BREATHE_RATE_MS(x) ((((x)+1) / 128 & 7) << 0) + +// Blink on/off time is in 32 ms increments +#define BLINK_TIME_MS(x) (((x)) / 32) + +#define LEDDEN (1 << 7) +#define FR250 (1 << 6) +#define OUTPUL (1 << 5) +#define OUTSKEW (1 << 4) +#define QUICK_STOP (1 << 3) +#define PWM_MODE_LFSR (1 << 2) +#define PWM_MODE_LINEAR (0 << 2) + +void rgb_write(uint8_t value, uint8_t addr) { + rgb_addr_write(addr); + rgb_dat_write(value); +} + +void rgb_init(void) { + // Turn on the RGB block and current enable, as well as enabling led control + rgb_ctrl_write((1 << 0) | (1 << 1) | (1 << 2)); + + // Enable the LED driver, and set 250 Hz mode. + // Also set quick stop, which we'll use to switch patterns quickly. + rgb_write(LEDDEN | FR250 | QUICK_STOP, LEDDCR0); + + // Set clock register to 12 MHz / 64 kHz - 1 + rgb_write((12000000/64000)-1, LEDDBR); + + rgb_write(BLINK_TIME_MS(32), LEDDONR); // Amount of time to stay "on" + rgb_write(BLINK_TIME_MS(0), LEDDOFR); // Amount of time to stay "off" + + rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(128), LEDDBCRR); + rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(128), LEDDBCFR); +} + +void rgb_set(uint8_t r, uint8_t g, uint8_t b) { + // Note: the LEDD control registers have arbitrary names that + // do not match up with the LEDD pin outputs. Hence this strange + // mapping. + rgb_write(r, LEDDPWRR); // Blue + rgb_write(g, LEDDPWRG); // Red + rgb_write(b, LEDDPWRB); // Green +} + +// The amount of time to stay off or on +void rgb_on_time(uint8_t ms) { + rgb_write(BLINK_TIME_MS(ms), LEDDONR); // Amount of time to stay "on" +} + +void rgb_off_time(uint8_t ms) { + rgb_write(BLINK_TIME_MS(ms), LEDDOFR); // Amount of time to stay "off" +} + +// The amount of time to breathe in/out +void rgb_in_time(uint8_t ms) { + rgb_write(BREATHE_ENABLE| BREATHE_MODE_FIXED | BREATHE_RATE_MS(ms), LEDDBCRR); +} + +void rgb_out_time(uint8_t ms) { + rgb_write(BREATHE_ENABLE | BREATHE_MODE_FIXED | BREATHE_RATE_MS(ms), LEDDBCFR); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/time.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/time.c new file mode 100644 index 0000000..c7ab3f7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/time.c @@ -0,0 +1,43 @@ +#include +#include + +void time_init(void) +{ + int t; + + timer0_en_write(0); + t = 2*SYSTEM_CLOCK_FREQUENCY; + timer0_reload_write(t); + timer0_load_write(t); + timer0_en_write(1); +} + +int elapsed(int *last_event, int period) +{ + int t, dt; + + timer0_update_value_write(1); + t = timer0_reload_read() - timer0_value_read(); + if(period < 0) { + *last_event = t; + return 1; + } + dt = t - *last_event; + if(dt < 0) + dt += timer0_reload_read(); + if((dt > period) || (dt < 0)) { + *last_event = t; + return 1; + } else + return 0; +} + +void msleep(int ms) +{ + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(SYSTEM_CLOCK_FREQUENCY/1000*ms); + timer0_en_write(1); + timer0_update_value_write(1); + while(timer0_value_read()) timer0_update_value_write(1); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-desc.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-desc.c new file mode 100644 index 0000000..105cc29 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-desc.c @@ -0,0 +1,284 @@ +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * + * 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: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * 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 +#include +#include + +// USB Descriptors are binary data which the USB host reads to +// automatically detect a USB device's capabilities. The format +// and meaning of every field is documented in numerous USB +// standards. When working with USB descriptors, despite the +// complexity of the standards and poor writing quality in many +// of those documents, remember descriptors are nothing more +// than constant binary data that tells the USB host what the +// device can do. Computers will load drivers based on this data. +// Those drivers then communicate on the endpoints specified by +// the descriptors. + +// To configure a new combination of interfaces or make minor +// changes to existing configuration (eg, change the name or ID +// numbers), usually you would edit "usb_desc.h". This file +// is meant to be configured by the header, so generally it is +// only edited to add completely new USB interfaces or features. + +// ************************************************************** +// USB Device +// ************************************************************** + +#define LSB(n) ((n) & 255) +#define MSB(n) (((n) >> 8) & 255) + +#define USB_DT_BOS_SIZE 5 +#define USB_DT_BOS 0xf +#define USB_DT_DEVICE_CAPABILITY 0x10 +#define USB_DC_PLATFORM 5 + +struct usb_bos_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} __attribute__((packed)); + +// USB Device Descriptor. The USB host reads this first, to learn +// what type of device is connected. +static const uint8_t device_descriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x10, 0x02, // bcdUSB + USB_CLASS_CDC, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + 64, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + LSB(DEVICE_VER), MSB(DEVICE_VER), // bcdDevice + 1, // iManufacturer + 2, // iProduct + 0, // iSerialNumber + 1 // bNumConfigurations +}; + + +// ************************************************************** +// USB Configuration +// ************************************************************** + +// USB Configuration Descriptor. This huge descriptor tells all +// of the devices capbilities. +#define CONFIG_DESC_SIZE 67 +static const uint8_t config_descriptor[CONFIG_DESC_SIZE] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG_DESC_SIZE), // wTotalLength + MSB(CONFIG_DESC_SIZE), + 2, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0x80, // bmAttributes + 50, // bMaxPower + + // interface descriptor, CDC + USB_DT_INTERFACE_SIZE, // bLength + USB_DT_INTERFACE, // bDescriptorType + 0, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + USB_CLASS_CDC, // bInterfaceClass + USB_CDC_SUBCLASS_ACM, // bInterfaceSubClass + USB_CDC_PROTOCOL_AT, // bInterfaceProtocol + 0, // iInterface + + // Header Functional Descriptor + 0x05, // bLength: Endpoint Descriptor size + CS_INTERFACE, // bDescriptorType: CS_INTERFACE + USB_CDC_TYPE_HEADER, // bDescriptorSubtype: Header Func Desc + 0x10, // bcdCDC: spec release number + 0x01, + + // Call Management Functional Descriptor + 0x05, // bFunctionLength + CS_INTERFACE, // bDescriptorType: CS_INTERFACE + USB_CDC_TYPE_CALL_MANAGEMENT, // bDescriptorSubtype: Call Management Func Desc + 0, // bmCapabilities: D0+D1 + 1, // bDataInterface: 1 + + // ACM Functional Descriptor + 0x04, // bFunctionLength + CS_INTERFACE, // bDescriptorType: CS_INTERFACE + USB_CDC_TYPE_ACM, // bDescriptorSubtype: Abstract Control Management desc + 6, // bmCapabilities + + // Union Functional Descriptor + 0x05, // bFunctionLength + CS_INTERFACE, // bDescriptorType: CS_INTERFACE + USB_CDC_TYPE_UNION, // bDescriptorSubtype: Union func desc + 0, // bMasterInterface: Communication class interface + 1, // bSlaveInterface0: Data Class Interface + + // Endpoint descriptor + USB_DT_ENDPOINT_SIZE, // bLength + USB_DT_ENDPOINT, // bDescriptorType + 0x81, // bEndpointAddress + USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes + LSB(16), // wMaxPacketSize + MSB(16), // wMaxPacketSize + 255, // bInterval + + // interface descriptor, CDC + USB_DT_INTERFACE_SIZE, // bLength + USB_DT_INTERFACE, // bDescriptorType + 1, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + USB_CLASS_DATA, // bInterfaceClass + 0, // bInterfaceSubClass + 0, // bInterfaceProtocol + 0, // iInterface + + // Endpoint descriptor + USB_DT_ENDPOINT_SIZE, // bLength + USB_DT_ENDPOINT, // bDescriptorType + 0x82, // bEndpointAddress + USB_ENDPOINT_ATTR_BULK, // bmAttributes + LSB(64), // wMaxPacketSize + MSB(64), // wMaxPacketSize + 1, // bInterval + + // Endpoint descriptor + USB_DT_ENDPOINT_SIZE, // bLength + USB_DT_ENDPOINT, // bDescriptorType + 0x02, // bEndpointAddress + USB_ENDPOINT_ATTR_BULK, // bmAttributes + LSB(64), // wMaxPacketSize + MSB(64), // wMaxPacketSize + 1, // bInterval +}; + + +// ************************************************************** +// String Descriptors +// ************************************************************** + +// The descriptors above can provide human readable strings, +// referenced by index numbers. These descriptors are the +// actual string data + +static const struct usb_string_descriptor_struct string0 = { + 4, + 3, + {0x0409} +}; + +// Microsoft OS String Descriptor. See: https://github.com/pbatard/libwdi/wiki/WCID-Devices +static const struct usb_string_descriptor_struct usb_string_microsoft = { + 18, 3, + {'M','S','F','T','1','0','0', MSFT_VENDOR_CODE} +}; + +// Microsoft WCID +const uint8_t usb_microsoft_wcid[MSFT_WCID_LEN] = { + MSFT_WCID_LEN, 0, 0, 0, // Length + 0x00, 0x01, // Version + 0x04, 0x00, // Compatibility ID descriptor index + 0x01, // Number of sections + 0, 0, 0, 0, 0, 0, 0, // Reserved (7 bytes) + + 0, // Interface number + 0x01, // Reserved + 'W','I','N','U','S','B',0,0, // Compatible ID + 0,0,0,0,0,0,0,0, // Sub-compatible ID (unused) + 0,0,0,0,0,0, // Reserved +}; + +const struct webusb_url_descriptor landing_url_descriptor = { + .bLength = LANDING_PAGE_DESCRIPTOR_SIZE, + .bDescriptorType = WEBUSB_DT_URL, + .bScheme = WEBUSB_URL_SCHEME_HTTPS, + .URL = LANDING_PAGE_URL +}; + +struct full_bos { + struct usb_bos_descriptor bos; + struct webusb_platform_descriptor webusb; +}; + +static const struct full_bos full_bos = { + .bos = { + .bLength = USB_DT_BOS_SIZE, + .bDescriptorType = USB_DT_BOS, + .wTotalLength = USB_DT_BOS_SIZE + WEBUSB_PLATFORM_DESCRIPTOR_SIZE, + .bNumDeviceCaps = 1, + }, + .webusb = { + .bLength = WEBUSB_PLATFORM_DESCRIPTOR_SIZE, + .bDescriptorType = USB_DT_DEVICE_CAPABILITY, + .bDevCapabilityType = USB_DC_PLATFORM, + .bReserved = 0, + .platformCapabilityUUID = WEBUSB_UUID, + .bcdVersion = 0x0100, + .bVendorCode = WEBUSB_VENDOR_CODE, + .iLandingPage = 1, + }, +}; + +__attribute__((aligned(4))) +static const struct usb_string_descriptor_struct usb_string_manufacturer_name = { + 2 + MANUFACTURER_NAME_LEN, + 3, + MANUFACTURER_NAME +}; + +__attribute__((aligned(4))) +struct usb_string_descriptor_struct usb_string_product_name = { + 2 + PRODUCT_NAME_LEN, + 3, + PRODUCT_NAME +}; + +// ************************************************************** +// Descriptors List +// ************************************************************** + +// This table provides access to all the descriptor data above. + +__attribute__((section(".data"))) +const usb_descriptor_list_t usb_descriptor_list[] = { + {0x0100, sizeof(device_descriptor), device_descriptor}, + {0x0200, sizeof(config_descriptor), config_descriptor}, + {0x0300, 0, (const uint8_t *)&string0}, + {0x0301, 0, (const uint8_t *)&usb_string_manufacturer_name}, + {0x0302, 0, (const uint8_t *)&usb_string_product_name}, + {0x03EE, 0, (const uint8_t *)&usb_string_microsoft}, + {0x0F00, sizeof(full_bos), (const uint8_t *)&full_bos}, + {0, 0, NULL} +}; diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-dev.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-dev.c new file mode 100644 index 0000000..bf0739e --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-dev.c @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include + +static uint8_t reply_buffer[8]; +static uint8_t usb_configuration = 0; +// #define USB_MAX_PACKET_SIZE 64 +// static uint32_t rx_buffer[USB_MAX_PACKET_SIZE/4]; + +volatile uint8_t terminal_is_connected; + +__attribute__((section(".ramtext"))) +void usb_setup(const struct usb_setup_request *setup) { + const uint8_t *data = NULL; + uint32_t datalen = 0; + const usb_descriptor_list_t *list; + + switch (setup->wRequestAndType) + { + case 0x2021: // Set Line Coding + break; + case 0x2221: // Set control line state + terminal_is_connected = setup->wValue & 1; + break; + + case 0x0500: // SET_ADDRESS + usb_set_address(((uint8_t *)setup)[2]); + break; + + case 0x0b01: // SET_INTERFACE + //dfu_clrstatus(); + break; + + case 0x0900: // SET_CONFIGURATION + usb_configuration = setup->wValue; + break; + + case 0x0880: // GET_CONFIGURATION + reply_buffer[0] = usb_configuration; + datalen = 1; + data = reply_buffer; + break; + + case 0x0080: // GET_STATUS (device) + reply_buffer[0] = 0; + reply_buffer[1] = 0; + datalen = 2; + data = reply_buffer; + break; + + case 0x0082: // GET_STATUS (endpoint) + if (setup->wIndex > 0) + { + usb_err_in(); + return; + } + reply_buffer[0] = 0; + reply_buffer[1] = 0; + + // XXX handle endpoint stall here +// if (USB->DIEP0CTL & USB_DIEP_CTL_STALL) +// reply_buffer[0] = 1; + data = reply_buffer; + datalen = 2; + break; + + case 0x0102: // CLEAR_FEATURE (endpoint) + // if (setup->wIndex > 0 || setup->wValue != 0) + // { + // // TODO: do we need to handle IN vs OUT here? + // usb_err_in(); + // return; + // } + // XXX: Should we clear the stall bit? + // USB->DIEP0CTL &= ~USB_DIEP_CTL_STALL; + // TODO: do we need to clear the data toggle here? + break; + + case 0x0302: // SET_FEATURE (endpoint) + // if (setup->wIndex > 0 || setup->wValue != 0) + // { + // // TODO: do we need to handle IN vs OUT here? + // usb_err_in(); + // return; + // } + // XXX: Should we set the stall bit? + // USB->DIEP0CTL |= USB_DIEP_CTL_STALL; + // TODO: do we need to clear the data toggle here? + break; + + case 0x0680: // GET_DESCRIPTOR + case 0x0681: + for (list = usb_descriptor_list; 1; list++) + { + if (list->addr == NULL) + break; + if (setup->wValue == list->wValue) + { + data = list->addr; + if ((setup->wValue >> 8) == 3) + { + // for string descriptors, use the descriptor's + // length field, allowing runtime configured + // length. + datalen = *(list->addr); + } + else + { + datalen = list->length; + } + goto send; + } + } + usb_err_in(); + return; +#if 0 + case (MSFT_VENDOR_CODE << 8) | 0xC0: // Get Microsoft descriptor + case (MSFT_VENDOR_CODE << 8) | 0xC1: + if (setup->wIndex == 0x0004) + { + // Return WCID descriptor + data = usb_microsoft_wcid; + datalen = MSFT_WCID_LEN; + break; + } + usb_err(); + return; + + case (WEBUSB_VENDOR_CODE << 8) | 0xC0: // Get WebUSB descriptor + if (setup->wIndex == 0x0002) + { + if (setup->wValue == 0x0001) + { + // Return landing page URL descriptor + data = (uint8_t*)&landing_url_descriptor; + datalen = LANDING_PAGE_DESCRIPTOR_SIZE; + break; + } + } + // printf("%s:%d couldn't find webusb descriptor (%d / %d)\n", __FILE__, __LINE__, setup->wIndex, setup->wValue); + usb_err(); + return; +#endif + +#if 0 + case 0x0121: // DFU_DNLOAD + if (setup->wIndex > 0) + { + usb_err(); + return; + } + // Data comes in the OUT phase. But if it's a zero-length request, handle it now. + if (setup->wLength == 0) + { + if (!dfu_download(setup->wValue, 0, 0, 0, NULL)) + { + usb_err(); + return; + } + usb_ack_in(); + return; + } + + // ACK the setup packet + // usb_ack_out(); + + int bytes_remaining = setup->wLength; + int ep0_rx_offset = 0; + // Fill the buffer, or if there is enough space transfer the whole packet. + unsigned int blockLength = setup->wLength; + unsigned int blockNum = setup->wValue; + + while (bytes_remaining > 0) { + unsigned int i; + unsigned int len = blockLength; + if (len > sizeof(rx_buffer)) + len = sizeof(rx_buffer); + for (i = 0; i < sizeof(rx_buffer)/4; i++) + rx_buffer[i] = 0xffffffff; + + // Receive DATA packets (which are automatically ACKed) + len = usb_recv((void *)rx_buffer, len); + + // Append the data to the download buffer. + dfu_download(blockNum, blockLength, ep0_rx_offset, len, (void *)rx_buffer); + + bytes_remaining -= len; + ep0_rx_offset += len; + } + + // ACK the final IN packet. + usb_ack_in(); + + return; + + case 0x0021: // DFU_DETACH + // Send the "ACK" packet and wait for it + // to be received. + usb_ack_in(); + usb_wait_for_send_done(); + reboot(); + while (1) + ; + return; + + case 0x03a1: // DFU_GETSTATUS + if (setup->wIndex > 0) + { + usb_err(); + return; + } + if (dfu_getstatus(reply_buffer)) + { + data = reply_buffer; + datalen = 6; + break; + } + else + { + usb_err(); + return; + } + break; + + case 0x0421: // DFU_CLRSTATUS + if (setup->wIndex > 0) + { + usb_err(); + return; + } + if (dfu_clrstatus()) + { + break; + } + else + { + usb_err(); + return; + } + + case 0x05a1: // DFU_GETSTATE + if (setup->wIndex > 0) + { + usb_err(); + return; + } + reply_buffer[0] = dfu_getstate(); + data = reply_buffer; + datalen = 1; + break; + + case 0x0621: // DFU_ABORT + if (setup->wIndex > 0) + { + usb_err(); + return; + } + if (dfu_abort()) + { + break; + } + else + { + usb_err(); + return; + } +#endif + + default: + usb_err_in(); + return; + } + +send: + if (data && datalen) { + if (datalen > setup->wLength) + datalen = setup->wLength; + usb_send(data, datalen); + } + else + usb_ack_in(); + return; +} diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-epfifo.c b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-epfifo.c new file mode 100644 index 0000000..35dd83c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/usb-epfifo.c @@ -0,0 +1,369 @@ +#include +#include +#include +#include +#include + +#ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR + +static volatile uint8_t usb_rx_fifo[64]; +static volatile uint8_t usb_rx_fifo_rd; +static volatile uint8_t usb_rx_fifo_wr; + +static volatile int have_new_address; +static volatile uint8_t new_address; + +// Firmware versions < 1.9 didn't have usb_address_write() +static inline void usb_set_address_wrapper(uint8_t address) { + if (version_major_read() < 1) + return; + if (version_minor_read() < 9) + return; + usb_address_write(address); +} + +// Note that our PIDs are only bits 2 and 3 of the token, +// since all other bits are effectively redundant at this point. +enum USB_PID { + USB_PID_OUT = 0, + USB_PID_SOF = 1, + USB_PID_IN = 2, + USB_PID_SETUP = 3, +}; + +enum epfifo_response { + EPF_ACK = 0, + EPF_NAK = 1, + EPF_NONE = 2, + EPF_STALL = 3, +}; + +#define USB_EV_ERROR 1 +#define USB_EV_PACKET 2 + +void usb_disconnect(void) { + usb_ep_0_out_ev_enable_write(0); + usb_ep_0_in_ev_enable_write(0); + irq_setmask(irq_getmask() & ~(1 << USB_INTERRUPT)); + usb_pullup_out_write(0); + usb_set_address_wrapper(0); +} + +void usb_connect(void) { + + usb_set_address_wrapper(0); + usb_ep_0_out_ev_pending_write(usb_ep_0_out_ev_enable_read()); + usb_ep_0_in_ev_pending_write(usb_ep_0_in_ev_pending_read()); + usb_ep_0_out_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + usb_ep_0_in_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + + usb_ep_1_in_ev_pending_write(usb_ep_1_in_ev_enable_read()); + usb_ep_1_in_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + + usb_ep_2_out_ev_pending_write(usb_ep_2_out_ev_enable_read()); + usb_ep_2_in_ev_pending_write(usb_ep_2_in_ev_pending_read()); + usb_ep_2_out_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + usb_ep_2_in_ev_enable_write(USB_EV_PACKET | USB_EV_ERROR); + + // Accept incoming data by default. + usb_ep_0_out_respond_write(EPF_ACK); + usb_ep_2_out_respond_write(EPF_ACK); + + // Reject outgoing data, since we have none to give yet. + usb_ep_0_in_respond_write(EPF_NAK); + usb_ep_1_in_respond_write(EPF_NAK); + usb_ep_2_in_respond_write(EPF_NAK); + + usb_pullup_out_write(1); + + irq_setmask(irq_getmask() | (1 << USB_INTERRUPT)); +} + +void usb_init(void) { + usb_pullup_out_write(0); + return; +} + +#define EP0OUT_BUFFERS 4 +__attribute__((aligned(4))) +static uint8_t volatile usb_ep0out_buffer[EP0OUT_BUFFERS][256]; +static uint8_t volatile usb_ep0out_buffer_len[EP0OUT_BUFFERS]; +static uint8_t volatile usb_ep0out_last_tok[EP0OUT_BUFFERS]; +static volatile uint8_t usb_ep0out_wr_ptr; +static volatile uint8_t usb_ep0out_rd_ptr; +static const int max_byte_length = 64; + +static const uint8_t * volatile current_data; +static volatile int current_length; +static volatile int data_offset; +static volatile int data_to_send; +static int next_packet_is_empty; +static volatile uint8_t ep2_fifo_bytes; + +__attribute__((section(".ramtext"))) +static void process_tx(void) { + + // Don't allow requeueing -- only queue more data if we're + // currently set up to respond NAK. + if (usb_ep_0_in_respond_read() != EPF_NAK) { + return; + } + + // Prevent us from double-filling the buffer. + if (!usb_ep_0_in_ibuf_empty_read()) { + return; + } + + if (!current_data || !current_length) { + return; + } + + data_offset += data_to_send; + + data_to_send = current_length - data_offset; + + // Clamp the data to the maximum packet length + if (data_to_send > max_byte_length) { + data_to_send = max_byte_length; + next_packet_is_empty = 0; + } + else if (data_to_send == max_byte_length) { + next_packet_is_empty = 1; + } + else if (next_packet_is_empty) { + next_packet_is_empty = 0; + data_to_send = 0; + } + else if (current_data == NULL || data_to_send <= 0) { + next_packet_is_empty = 0; + current_data = NULL; + current_length = 0; + data_offset = 0; + data_to_send = 0; + return; + } + + int this_offset; + for (this_offset = data_offset; this_offset < (data_offset + data_to_send); this_offset++) { + usb_ep_0_in_ibuf_head_write(current_data[this_offset]); + } + usb_ep_0_in_respond_write(EPF_ACK); + return; +} + +int usb_send(const void *data, int total_count) { + + while ((current_length || current_data))// && usb_ep_0_in_respond_read() != EPF_NAK) + ; + current_data = (uint8_t *)data; + current_length = total_count; + data_offset = 0; + data_to_send = 0; + process_tx(); + + return 0; +} + +int usb_wait_for_send_done(void) { + while (current_data && current_length) + usb_poll(); + while ((usb_ep_0_in_dtb_read() & 1) == 1) + usb_poll(); + return 0; +} + +__attribute__((section(".ramtext"))) +void usb_isr(void) { + uint8_t ep_pending; + + ep_pending = usb_ep_0_out_ev_pending_read(); + + // We got an OUT or a SETUP packet. Copy it to usb_ep0out_buffer + // and clear the "pending" bit. + if (ep_pending) { + uint8_t last_tok = usb_ep_0_out_last_tok_read(); + + int byte_count = 0; + usb_ep0out_last_tok[usb_ep0out_wr_ptr] = last_tok; + volatile uint8_t * obuf = usb_ep0out_buffer[usb_ep0out_wr_ptr]; + while (!usb_ep_0_out_obuf_empty_read()) { + obuf[byte_count++] = usb_ep_0_out_obuf_head_read(); + usb_ep_0_out_obuf_head_write(0); + } + + if (last_tok == USB_PID_SETUP) { + usb_ep_0_in_dtb_write(1); + data_offset = 0; + current_length = 0; + current_data = NULL; + const struct usb_setup_request *request = (const struct usb_setup_request *)obuf; + usb_setup(request); + } + else { + usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count - 2 /* Strip off CRC16 */; + usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1); + } + usb_ep_0_out_ev_pending_write(ep_pending); + usb_ep_0_out_respond_write(EPF_ACK); + } + + ep_pending = usb_ep_0_in_ev_pending_read(); + // We just got an "IN" token. Send data if we have it. + if (ep_pending) { + usb_ep_0_in_respond_write(EPF_NAK); + usb_ep_0_in_ev_pending_write(ep_pending); + if (have_new_address) { + have_new_address = 0; + usb_set_address_wrapper(new_address); + } + process_tx(); + } + + ep_pending = usb_ep_1_in_ev_pending_read(); + if (ep_pending) { + usb_ep_1_in_respond_write(EPF_NAK); + usb_ep_1_in_ev_pending_write(ep_pending); + } + + ep_pending = usb_ep_2_in_ev_pending_read(); + if (ep_pending) { + usb_ep_2_in_respond_write(EPF_NAK); + usb_ep_2_in_ev_pending_write(ep_pending); + ep2_fifo_bytes = 0; + } + + ep_pending = usb_ep_2_out_ev_pending_read(); + if (ep_pending) { + while (!usb_ep_2_out_obuf_empty_read()) { + usb_rx_fifo[(usb_rx_fifo_wr++) & 0x3f] = usb_ep_2_out_obuf_head_read(); + usb_ep_2_out_obuf_head_write(0); + } + // Strip off the CRC16. + usb_rx_fifo_wr -= 2; + + usb_ep_2_out_ev_pending_write(ep_pending); + usb_ep_2_out_respond_write(EPF_NAK); + } + + return; +} + +__attribute__((section(".ramtext"))) +int usb_getc(void) { + if (usb_rx_fifo_rd == usb_rx_fifo_wr) { + usb_ep_2_out_respond_write(EPF_ACK); + return -1; + } + return usb_rx_fifo[(usb_rx_fifo_rd++) & 0x3f]; +} + +__attribute__((section(".ramtext"))) +void usb_putc(char c) { + usb_ep_2_in_ibuf_head_write(c); + ep2_fifo_bytes++; + usb_ep_2_in_respond_write(EPF_ACK); +} + +__attribute__((section(".ramtext"))) +int usb_write(const char *buf, int count) { + int to_write = 64; + int i; + if (to_write > count) + to_write = count; + for (i = 0; i < to_write; i++) + usb_ep_2_in_ibuf_head_write(buf[i]); + ep2_fifo_bytes += to_write; + usb_ep_2_in_respond_write(EPF_ACK); + + return to_write; +} + +extern volatile uint8_t terminal_is_connected; + +__attribute__((section(".ramtext"))) +int usb_can_getc(void) { + if (usb_rx_fifo_rd == usb_rx_fifo_wr) { + usb_ep_2_out_respond_write(EPF_ACK); + return 0; + } + return terminal_is_connected; +} + +__attribute__((section(".ramtext"))) +int usb_can_putc(void) { + return terminal_is_connected && usb_ep_2_in_ibuf_empty_read() && (usb_ep_2_in_respond_read() == EPF_NAK);// (ep2_fifo_bytes <= 60); +} + +__attribute__((section(".ramtext"))) +void usb_ack_in(void) { + // usb_ep_0_in_dtb_write(1); + while (usb_ep_0_in_respond_read() == EPF_ACK) + ; + usb_ep_0_in_respond_write(EPF_ACK); +} + +__attribute__((section(".ramtext"))) +void usb_ack_out(void) { + // usb_ep_0_out_dtb_write(1); + while (usb_ep_0_out_respond_read() == EPF_ACK) + ; + usb_ep_0_out_respond_write(EPF_ACK); +} + +__attribute__((section(".ramtext"))) +void usb_err_in(void) { + usb_ep_0_in_respond_write(EPF_STALL); +} + +__attribute__((section(".ramtext"))) +void usb_err_out(void) { + usb_ep_0_out_respond_write(EPF_STALL); +} + +__attribute__((section(".ramtext"))) +int usb_recv(void *buffer, unsigned int buffer_len) { + + // Set the OUT response to ACK, since we are in a position to receive data now. + usb_ep_0_out_respond_write(EPF_ACK); + while (1) { + if (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) { + if (usb_ep0out_last_tok[usb_ep0out_rd_ptr] == USB_PID_OUT) { + unsigned int ep0_buffer_len = usb_ep0out_buffer_len[usb_ep0out_rd_ptr]; + if (ep0_buffer_len < buffer_len) + buffer_len = ep0_buffer_len; + usb_ep0out_buffer_len[usb_ep0out_rd_ptr] = 0; + memcpy(buffer, (void *)&usb_ep0out_buffer[usb_ep0out_rd_ptr], buffer_len); + usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1); + return buffer_len; + } + usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1); + } + } + return 0; +} + +void usb_set_address(uint8_t new_address_) { + new_address = new_address_; + have_new_address = 1; +} + +__attribute__((section(".ramtext"))) +void usb_poll(void) { + // If some data was received, then process it. + while (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) { + const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]); + // unsigned int len = usb_ep0out_buffer_len[usb_ep0out_rd_ptr]; + uint8_t last_tok = usb_ep0out_last_tok[usb_ep0out_rd_ptr]; + + usb_ep0out_buffer_len[usb_ep0out_rd_ptr] = 0; + usb_ep0out_rd_ptr = (usb_ep0out_rd_ptr + 1) & (EP0OUT_BUFFERS-1); + + if (last_tok == USB_PID_SETUP) { + usb_setup(request); + } + } + + process_tx(); +} + +#endif /* CSR_USB_EP_0_OUT_EV_PENDING_ADDR */ \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/fomu/src/wasm3 b/wasm3-sys/wasm3/platforms/embedded/fomu/src/wasm3 new file mode 120000 index 0000000..17056a9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/fomu/src/wasm3 @@ -0,0 +1 @@ +../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/hifive1/.gitignore b/wasm3-sys/wasm3/platforms/embedded/hifive1/.gitignore new file mode 100644 index 0000000..03f4a3c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/hifive1/.gitignore @@ -0,0 +1 @@ +.pio diff --git a/wasm3-sys/wasm3/platforms/embedded/hifive1/README.md b/wasm3-sys/wasm3/platforms/embedded/hifive1/README.md new file mode 100644 index 0000000..f49dfbc --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/hifive1/README.md @@ -0,0 +1,19 @@ +## Build for HiFive1 + +### Debugging: + +On first console, run +```sh +JLinkGDBServer -singlerun -if JTAG -select USB -speed 1000 -jtagconf -1,-1 -device FE310 --port 2331 +``` + +On second console, run `riscv64-unknown-elf-gdb`: +```gdb +file ".pio/build/hifive1-revb/firmware.elf" +target extended-remote :2331 +b main +monitor halt +monitor reset +load +c +``` diff --git a/wasm3-sys/wasm3/platforms/embedded/hifive1/lib/wasm3 b/wasm3-sys/wasm3/platforms/embedded/hifive1/lib/wasm3 new file mode 120000 index 0000000..17056a9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/hifive1/lib/wasm3 @@ -0,0 +1 @@ +../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/hifive1/platformio.ini b/wasm3-sys/wasm3/platforms/embedded/hifive1/platformio.ini new file mode 100644 index 0000000..50b1d46 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/hifive1/platformio.ini @@ -0,0 +1,36 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +default_envs = hifive1-revb + +[env] +platform = sifive +framework = freedom-e-sdk +monitor_speed = 115200 + +board_build.f_cpu = 320000000L + +src_filter = + +<*> + - + +src_build_flags = + -Dd_m3FixedHeap=8192 + -Os -Wfatal-errors + -flto + +build_flags = -lm + +[env:hifive1] +board = hifive1 + +[env:hifive1-revb] +board = hifive1-revb diff --git a/wasm3-sys/wasm3/platforms/embedded/hifive1/src/main.c b/wasm3-sys/wasm3/platforms/embedded/hifive1/src/main.c new file mode 100644 index 0000000..3e489c3 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/hifive1/src/main.c @@ -0,0 +1,62 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + uint32_t fsize = fib32_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + result = m3_CallV (f, 24); + if (result) FATAL("m3_Call: %s", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %d\n", value); +} + +int main() { + printf("\n"); + printf("Wasm3 v" M3_VERSION " on HiFive1 (" M3_ARCH "), build " __DATE__ " " __TIME__ "\n"); + // TODO: fix clock (shows wrong time) + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + printf("Elapsed: %ld ms\n", (end - start)*1000 / CLOCKS_PER_SEC); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/.gitignore b/wasm3-sys/wasm3/platforms/embedded/particle/.gitignore new file mode 100644 index 0000000..a8a0dce --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/.gitignore @@ -0,0 +1 @@ +*.bin diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/README.md b/wasm3-sys/wasm3/platforms/embedded/particle/README.md new file mode 100644 index 0000000..bbb0420 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/README.md @@ -0,0 +1,18 @@ +## Build for Particle + +You need to install Particle CLI. + +Build for `photon`, `electron`, `pi`, `duo`, `p1`, `argon`, `boron`, `xenon`: +```sh +particle compile --followSymlinks photon +``` + +Upload to device: +``` +particle list +particle flash MyDevice1 ./firmware_*.bin + +# Or using USB: +particle flash --usb ./firmware_*.bin +``` + diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/library.properties b/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/library.properties new file mode 100644 index 0000000..a257fd2 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/library.properties @@ -0,0 +1,6 @@ +name=wasm3 +version=0.1.0 +license=MIT +author=Volodymyr Shymanskyy +sentence=WebAssembly interpreter for Particle devices +url=https://github.com/vshymanskyy/wasm3 diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/src b/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/src new file mode 120000 index 0000000..e3e41d7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/lib/wasm3/src @@ -0,0 +1 @@ +../../../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/project.properties b/wasm3-sys/wasm3/platforms/embedded/particle/project.properties new file mode 100644 index 0000000..e09fa29 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/project.properties @@ -0,0 +1 @@ +name=wasm3 diff --git a/wasm3-sys/wasm3/platforms/embedded/particle/src/main.ino b/wasm3-sys/wasm3/platforms/embedded/particle/src/main.ino new file mode 100644 index 0000000..227557c --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/particle/src/main.ino @@ -0,0 +1,80 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(func, msg) { \ + Serial.print("Fatal: " func ": "); \ + Serial.println(msg); return; } + +// Redefine puts +int puts(const char* s) { + Serial.println(s); +} + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + size_t fsize = fib32_wasm_len; + + Serial.println("Loading WebAssembly..."); + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment", "failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime", "failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction", result); + + Serial.println("Running..."); + + result = m3_CallV (f, 24); + if (result) FATAL("m3_Call: %s", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + Serial.print("Result: "); + Serial.println(value); +} + +void setup() +{ + Serial.begin(115200); + delay(10); + + Serial.println(); + Serial.println("Wasm3 v" M3_VERSION " on Particle, build " __DATE__ " " __TIME__); + + uint32_t start = millis(); + run_wasm(); + uint32_t end = millis(); + + Serial.print("Elapsed: "); + Serial.print(end - start); + Serial.println(" ms"); +} + +void loop() +{ + delay(100); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/.gitignore b/wasm3-sys/wasm3/platforms/embedded/wm_w600/.gitignore new file mode 100644 index 0000000..16ff3c7 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/.gitignore @@ -0,0 +1 @@ +.output diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/Makefile b/wasm3-sys/wasm3/platforms/embedded/wm_w600/Makefile new file mode 100644 index 0000000..645616f --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/Makefile @@ -0,0 +1,120 @@ +############################################################# +# Required variables for each makefile +# Discard this section from all parent makefiles +# Expected variables (with automatic defaults): +# CSRCS (all "C" files in the dir) +# SUBDIRS (all subdirs with a Makefile) +# GEN_LIBS - list of libs to be generated () +# GEN_IMAGES - list of object file images to be generated () +# GEN_BINS - list of binaries to be generated () +# COMPONENTS_xxx - a list of libs/objs in the form +# subdir/lib to be extracted and rolled up into +# a generated lib/image xxx.a () +# + +TOP_DIR:= $(WM_SDK) + +sinclude $(TOP_DIR)/tools/tool_chain.def + +USE_LIB=1 + +CSRCS = $(wildcard *.c) $(wildcard wasm3/*.c) + +#EXTRA_CCFLAGS += -u +ifndef PDIR +GEN_IMAGES= $(TARGET).out +GEN_BINS = $(TARGET).bin +SUBDIRS = \ + $(TOP_DIR)/platform/boot/$(COMPILE) + +ifeq ($(USE_LIB), 0) +SUBDIRS += \ + $(TOP_DIR)/platform/common \ + $(TOP_DIR)/platform/drivers \ + $(TOP_DIR)/platform/sys \ + $(TOP_DIR)/src/os \ + $(TOP_DIR)/src/app \ + $(TOP_DIR)/src/network +endif +endif + +COMPONENTS_$(TARGET) = \ + $(TOP_DIR)/platform/boot/$(COMPILE)/startup.o \ + $(TOP_DIR)/platform/boot/$(COMPILE)/misc.o \ + $(TOP_DIR)/platform/boot/$(COMPILE)/retarget.o + +ifeq ($(USE_LIB), 0) +COMPONENTS_$(TARGET) += \ + $(TOP_DIR)/platform/common/libcommon$(LIB_EXT) \ + $(TOP_DIR)/platform/drivers/libdrivers$(LIB_EXT) \ + $(TOP_DIR)/platform/sys/libsys$(LIB_EXT) \ + $(TOP_DIR)/src/os/libos$(LIB_EXT) \ + $(TOP_DIR)/src/network/libnetwork$(LIB_EXT) \ + $(TOP_DIR)/src/app/libapp$(LIB_EXT) +endif + +ifeq ($(USE_LIB), 1) +LINKLIB = \ + $(TOP_DIR)/lib/libcommon$(LIB_EXT) \ + $(TOP_DIR)/lib/libdrivers$(LIB_EXT) \ + $(TOP_DIR)/lib/libsys$(LIB_EXT) \ + $(TOP_DIR)/lib/libos$(LIB_EXT) \ + $(TOP_DIR)/lib/libnetwork$(LIB_EXT) \ + $(TOP_DIR)/lib/libapp$(LIB_EXT) +endif + +LINKLIB += \ + $(TOP_DIR)/lib/libairkiss_log$(LIB_EXT) \ + $(TOP_DIR)/lib/libwlan$(LIB_EXT) + +ifeq ($(COMPILE), gcc) +LINKFLAGS_$(TARGET) = \ + $(LINKLIB) \ + -T$(LD_FILE) \ + -Wl,-warn-common +else +LINKFLAGS_$(TARGET) = \ + --library_type=microlib \ + $(LINKLIB) \ + --strict --scatter $(LD_FILE) +endif + +############################################################# +# Configuration i.e. compile options etc. +# Target specific stuff (defines etc.) goes in here! +# Generally values applying to a tree are captured in the +# makefile at its root level - these are then overridden +# for a subtree within the makefile rooted therein +# + +CONFIGURATION_DEFINES += -DWM_W600 + +DEFINES += $(CONFIGURATION_DEFINES) -Os -flto -Wfatal-errors \ + -fomit-frame-pointer -fno-stack-check -fno-stack-protector \ + -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers +# -Dd_m3FixedHeap=8192 +# -fno-optimize-sibling-calls + +LINKFLAGS_$(TARGET) += -Os -flto + +LINKLIB += -lm + +############################################################# +# Recursion Magic - Don't touch this!! +# +# Each subtree potentially has an include directory +# corresponding to the common APIs applicable to modules +# rooted at that subtree. Accordingly, the INCLUDE PATH +# of a module can only contain the include directories up +# its parent path, and not its siblings +# +# Required for each makefile to inherit from the parent +# + +INCLUDES := $(INCLUDES) -I$(PDIR)include +INCLUDES += -I ./ -I ./wasm3/ + +sinclude $(TOP_DIR)/tools/rules.mk + +.PHONY: FORCE +FORCE: diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/README.md b/wasm3-sys/wasm3/platforms/embedded/wm_w600/README.md new file mode 100644 index 0000000..7e7983d --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/README.md @@ -0,0 +1,28 @@ +## Build for Winner Micro W600 + +You will need: + +- [W600 SDK from ThingsTurn](https://github.com/w600/sdk) + `git clone --depth=1 --branch=sdk_v3.2.0 https://github.com/w600/sdk.git /opt/w600-sdk` +- [gcc-arm-none-eabi-4_9-2015q3](https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update) +- [w600tool](https://github.com/vshymanskyy/w600tool) + +```sh +export PATH=/opt/gcc-arm-none-eabi-4_9-2015q3/bin:$PATH + +export PATH=/opt/w600tool:$PATH + +export WM_SDK=/opt/w600-sdk + +./build.sh +``` + +To upload: + +```sh +w600tool.py --upload .output/wasm3_gz.img +``` +or +```sh +w600tool.py --upload .output/wasm3.fls +``` diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/build.sh b/wasm3-sys/wasm3/platforms/embedded/wm_w600/build.sh new file mode 100755 index 0000000..dc28b5f --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/build.sh @@ -0,0 +1,10 @@ +#!/bin/sh +rm -rf .output + +mkdir -p .output/wasm3/obj/wasm3/ + +make COMPILE=gcc TARGET=wasm3 FLASH_SIZE=1M VERBOSE=YES + +cp $WM_SDK/bin/wasm3/* ./.output/ + +rm test.bin diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/main.c b/wasm3-sys/wasm3/platforms/embedded/wm_w600/main.c new file mode 100644 index 0000000..8777eb0 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/main.c @@ -0,0 +1,91 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include "wm_include.h" + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +unsigned int millis(void) +{ + return tls_os_get_time()*2; +} + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + uint32_t fsize = fib32_wasm_len; + + printf("Loading WebAssembly...\n"); + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + printf("Running...\n"); + + result = m3_CallV (f, 24); + if (result) FATAL("m3_Call: %s", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %ld\n", value); +} + + +#define USER_TASK_STK_SIZE 32768 +#define USER_TASK_PRIO 32 + +static u8 user_task_stk[USER_TASK_STK_SIZE]; + +void wasm3_task(void *data) +{ + printf("\nWasm3 v" M3_VERSION " on W600, build " __DATE__ " " __TIME__ "\n"); + + uint32_t start = millis(); + run_wasm(); + uint32_t end = millis(); + + printf("Elapsed: %ld ms\n", (end - start)); +} + +void pre_gpio_config(void) +{ + +} + +void UserMain(void) +{ + /* create task */ + tls_os_task_create(NULL, + "wasm3", + wasm3_task, + (void*) 0, + (void*) &user_task_stk, + USER_TASK_STK_SIZE, + USER_TASK_PRIO, + 0); +} diff --git a/wasm3-sys/wasm3/platforms/embedded/wm_w600/wasm3 b/wasm3-sys/wasm3/platforms/embedded/wm_w600/wasm3 new file mode 120000 index 0000000..03cc5a6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/embedded/wm_w600/wasm3 @@ -0,0 +1 @@ +../../../source \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/emscripten/README.md b/wasm3-sys/wasm3/platforms/emscripten/README.md new file mode 100644 index 0000000..d16d5bd --- /dev/null +++ b/wasm3-sys/wasm3/platforms/emscripten/README.md @@ -0,0 +1,35 @@ +## Build using Emscripten + +In root: + +```sh +source /opt/emsdk/emsdk_env.sh --build=Release +mkdir -p build +cd build +cmake -GNinja -DEMSCRIPTEN=1 .. +ninja +``` + +**Note:** + +To enable WebAssembly extensions: +```sh +cmake -GNinja -DEMSCRIPTEN=1 -DWASM_EXT=1 .. +``` + +You can convert the generated wasm to wat to see the effect: +```sh +wasm2wat --enable-tail-call --enable-bulk-memory wasm3.wasm > wasm3.wat +``` + +Running `tail-call` version will require Chrome with experimental flags: +```sh +emrun --no_browser --no_emrun_detect --port 8080 . +chrome --js-flags="--experimental-wasm-return-call --wasm-opt" --no-sandbox http://localhost:8080/wasm3.html +``` + +Or use Node.js: +```sh +node --experimental-wasm-return-call --wasm-opt ./wasm3.js +``` + diff --git a/wasm3-sys/wasm3/platforms/emscripten/main.c b/wasm3-sys/wasm3/platforms/emscripten/main.c new file mode 100644 index 0000000..da7633f --- /dev/null +++ b/wasm3-sys/wasm3/platforms/emscripten/main.c @@ -0,0 +1,65 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include + +#include "wasm3.h" + +#include "extra/fib32.wasm.h" + +#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } + +void run_wasm() +{ + M3Result result = m3Err_none; + + uint8_t* wasm = (uint8_t*)fib32_wasm; + size_t fsize = fib32_wasm_len; + + IM3Environment env = m3_NewEnvironment (); + if (!env) FATAL("m3_NewEnvironment failed"); + + IM3Runtime runtime = m3_NewRuntime (env, 64*1024, NULL); + if (!runtime) FATAL("m3_NewRuntime failed"); + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) FATAL("m3_ParseModule: %s", result); + + result = m3_LoadModule (runtime, module); + if (result) FATAL("m3_LoadModule: %s", result); + + IM3Function f; + result = m3_FindFunction (&f, runtime, "fib"); + if (result) FATAL("m3_FindFunction: %s", result); + + result = m3_CallV (f, 40); + + if (result) FATAL("Call: %s", result); + + uint32_t value = 0; + result = m3_GetResultsV (f, &value); + if (result) FATAL("m3_GetResults: %s", result); + + printf("Result: %d\n", value); +} + +int main (int i_argc, const char * i_argv []) +{ + printf("Wasm3 v" M3_VERSION " on WASM, build " __DATE__ " " __TIME__ "\n"); + + clock_t start = clock(); + run_wasm(); + clock_t end = clock(); + + uint32_t elapsed_time = (end - start)*1000 / CLOCKS_PER_SEC ; + printf("Elapsed: %d ms\n", elapsed_time); + + return 0; +} diff --git a/wasm3-sys/wasm3/platforms/emscripten_lib/main.c b/wasm3-sys/wasm3/platforms/emscripten_lib/main.c new file mode 100644 index 0000000..81a909a --- /dev/null +++ b/wasm3-sys/wasm3/platforms/emscripten_lib/main.c @@ -0,0 +1,57 @@ +// +// Wasm3 - high performance WebAssembly interpreter written in C. +// +// Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. +// All rights reserved. +// + +#include +#include +#include + +#include "wasm3.h" +#include "m3_env.h" + +IM3Environment env; + +EMSCRIPTEN_KEEPALIVE +void init() { + env = m3_NewEnvironment (); + if (!env) return; +} + +EMSCRIPTEN_KEEPALIVE +IM3Runtime new_runtime() { + return m3_NewRuntime (env, 64*1024, NULL); +} + +EMSCRIPTEN_KEEPALIVE +void free_runtime(IM3Runtime runtime) { + m3_FreeRuntime (runtime); +} + +EMSCRIPTEN_KEEPALIVE +void load(IM3Runtime runtime, uint8_t* wasm, size_t fsize) { + M3Result result = m3Err_none; + + IM3Module module; + result = m3_ParseModule (env, &module, wasm, fsize); + if (result) return; + + result = m3_LoadModule (runtime, module); + if (result) return; +} + +EMSCRIPTEN_KEEPALIVE +uint32_t call(IM3Runtime runtime, int argc, const char* argv[]) { + M3Result result = m3Err_none; + + IM3Function f; + result = m3_FindFunction (&f, runtime, argv[0]); + if (result) return -1; + + result = m3_CallArgv (f, argc-1, argv+1); + if (result) return -2; + + return *(uint64_t*)(runtime->stack); +} diff --git a/wasm3-sys/wasm3/platforms/emscripten_lib/run_native.js b/wasm3-sys/wasm3/platforms/emscripten_lib/run_native.js new file mode 100644 index 0000000..13c93d1 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/emscripten_lib/run_native.js @@ -0,0 +1,28 @@ +'use strict'; + +if (typeof(process) != 'undefined') { // Node.js environment? + var scriptArgs = process.argv.slice(2); + const fs = require('fs'); + var readFile = (fn) => new Uint8Array(fs.readFileSync(fn)); +} else { + var readFile = (fn) => read(fn, 'binary'); +} + +let instances = []; + +(async() => { + const wasm = scriptArgs[0]; + const func = scriptArgs[1]; + const args = scriptArgs.slice(2); + + const binary = readFile(wasm); + + for (let i=0; i<1000; i++) { // V8: 1028 max, SpiderMonkey: 32650 max + let instance = (await WebAssembly.instantiate(binary)).instance; + + instances[i] = instance; + + let result = instance.exports[func](...args); + //console.log(i, result); + } +})(); diff --git a/wasm3-sys/wasm3/platforms/emscripten_lib/run_wasm3.js b/wasm3-sys/wasm3/platforms/emscripten_lib/run_wasm3.js new file mode 100644 index 0000000..56a80b9 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/emscripten_lib/run_wasm3.js @@ -0,0 +1,129 @@ +'use strict'; + +/* + Node.js + ------- + node --v8-options | grep -A1 wasm + --print_wasm_code --code-comments + --wasm_interpret_all --trace_wasm_interpreter + + SpiderMonkey + ------------ + export PATH=/opt/jsshell/:$PATH + js --help | grep wasm + --wasm-compiler=baseline/ion/cranelift/baseline+ion/baseline+cranelift + --wasm-verbose + --ion-full-warmup-threshold=1 +*/ + +if (typeof(process) != 'undefined') { // Node.js environment? + var scriptArgs = process.argv.slice(2); + const fs = require('fs'); + var readFile = (fn) => new Uint8Array(fs.readFileSync(fn)); +} else { + var readFile = (fn) => read(fn, 'binary'); +} + + +// Encode string into Uint8Array (with '\0' terminator) +// Could use TextEncoder instead +function encode(str) { + const len = str.length; + const res = new Uint8Array(len + 1); + let pos = 0; + for (let i = 0; i < len; i++) { + const point = str.charCodeAt(i); + if (point <= 0x007f) { + res[pos++] = point; + } + } + return res.subarray(0, pos + 1); +} + +let instance; +let runtimes = {}; + +const imports = { + "env": { + "emscripten_notify_memory_growth": function() {}, + "emscripten_get_sbrk_ptr": function() {}, + }, + "wasi_snapshot_preview1": { + "fd_close": function() { return -1; }, + "fd_seek": function() { return -1; }, + "fd_write": function() { return -1; }, + "proc_exit": function() { } + } +} + +function load(buff) { + const runtime = instance.exports.new_runtime(); + const ptr = instance.exports.malloc(buff.length); + const mem = new Uint8Array(instance.exports.memory.buffer); + mem.set(buff, ptr); + instance.exports.load(runtime, ptr, buff.length); + runtimes[runtime] = { binary_ptr: ptr } + return runtime; +} + +function unload(runtime) { + if (!runtimes[runtime]) return; + instance.exports.free_runtime(runtime); + instance.exports.free(runtimes[runtime].binary_ptr); + runtimes[runtime] = undefined; +} + +function call(runtime, fname, args) { + // Convert names to buffers + args = [fname].concat(args).map(arg => encode(arg.toString())); + + const arglen = args.length; + let argbytes = arglen*4; + for (let arg of args) { + argbytes += arg.length; + } + + // Allocate the required memory + const buff = instance.exports.malloc(argbytes); + const mem = new Uint8Array(instance.exports.memory.buffer); + const ptrs = new Uint32Array(mem.buffer, buff, arglen); + + // Fill-in memory + let ptr = buff + ptrs.byteLength; + for (let i=0; i { + instance = (await WebAssembly.instantiate(readFile('wasm3.wasm'), imports)).instance; + instance.exports.init(); + + const wasm = scriptArgs[0]; + const func = scriptArgs[1]; + const args = scriptArgs.slice(2); + + const binary = readFile(wasm); + + for (let i=0; i<100000; i++) { + let module = load(binary); + + let result = call(module, func, args); + //console.log(i, result); + + unload(module); + } + + console.log(`Memory size: ${instance.exports.memory.buffer.byteLength/(1024*1024)} MB`); +})(); diff --git a/wasm3-sys/wasm3/platforms/ios/.gitignore b/wasm3-sys/wasm3/platforms/ios/.gitignore new file mode 100644 index 0000000..5073505 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/.gitignore @@ -0,0 +1,2 @@ +## User settings +xcuserdata/ diff --git a/wasm3-sys/wasm3/platforms/ios/README.md b/wasm3-sys/wasm3/platforms/ios/README.md new file mode 100644 index 0000000..4fd1a31 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/README.md @@ -0,0 +1,17 @@ +## Build for iOS + + + Wasm3 running on iPhone 8 + + + +Install Xcode, then open and build the project as usual. + +**Note:** Xcode runs apps in `Debug` mode by default. Select `Release` mode for significantly better performance. + +You can also build the project from command line: + +```sh +xcodebuild build -scheme wasm3 -project wasm3.xcodeproj -configuration Release -destination 'platform=iOS Simulator,name=iPhone 11,OS=13.3' +``` + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.pbxproj b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8306fd2 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.pbxproj @@ -0,0 +1,465 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + 3D1B3B1123C8E20D00142C16 /* m3_api_libc.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AF423C8E20C00142C16 /* m3_api_libc.c */; }; + 3D1B3B1223C8E20D00142C16 /* m3_api_meta_wasi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AF623C8E20C00142C16 /* m3_api_meta_wasi.c */; }; + 3D1B3B1323C8E20D00142C16 /* m3_api_wasi.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AF723C8E20C00142C16 /* m3_api_wasi.c */; }; + 3D1B3B1423C8E20D00142C16 /* m3_bind.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AF923C8E20C00142C16 /* m3_bind.c */; }; + 3D1B3B1523C8E20D00142C16 /* m3_code.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AFA23C8E20C00142C16 /* m3_code.c */; }; + 3D1B3B1623C8E20D00142C16 /* m3_compile.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3AFC23C8E20C00142C16 /* m3_compile.c */; }; + 3D1B3B1723C8E20D00142C16 /* m3_core.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0023C8E20C00142C16 /* m3_core.c */; }; + 3D1B3B1823C8E20D00142C16 /* m3_emit.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0223C8E20C00142C16 /* m3_emit.c */; }; + 3D1B3B1923C8E20D00142C16 /* m3_env.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0423C8E20C00142C16 /* m3_env.c */; }; + 3D1B3B1A23C8E20D00142C16 /* m3_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0723C8E20C00142C16 /* m3_exec.c */; }; + 3D1B3B1B23C8E20D00142C16 /* m3_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0A23C8E20C00142C16 /* m3_info.c */; }; + 3D1B3B1C23C8E20D00142C16 /* m3_module.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0D23C8E20C00142C16 /* m3_module.c */; }; + 3D1B3B1E23C8E20D00142C16 /* m3_parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1B3B0F23C8E20C00142C16 /* m3_parse.c */; }; + 3D1ED51023C8C8E70072E395 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1ED50F23C8C8E70072E395 /* AppDelegate.swift */; }; + 3D1ED51223C8C8E70072E395 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1ED51123C8C8E70072E395 /* ViewController.swift */; }; + 3D1ED51523C8C8E70072E395 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3D1ED51323C8C8E70072E395 /* Main.storyboard */; }; + 3D1ED51723C8C8E70072E395 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3D1ED51623C8C8E70072E395 /* Assets.xcassets */; }; + 3D1ED51A23C8C8E70072E395 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3D1ED51823C8C8E70072E395 /* LaunchScreen.storyboard */; }; + 3D1ED52423C8CB560072E395 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 3D1ED52223C8CB560072E395 /* main.c */; }; + 3D3C322E23C9319A00DB9F7E /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D3C322D23C9319A00DB9F7E /* icon.png */; }; + B5E985C8262018B700FBE0FC /* m3_function.c in Sources */ = {isa = PBXBuildFile; fileRef = B5E985C7262018B700FBE0FC /* m3_function.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 3D1B3AEE23C8E20C00142C16 /* fib32.wasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fib32.wasm.h; sourceTree = ""; }; + 3D1B3AEF23C8E20C00142C16 /* fib32_tail.wasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fib32_tail.wasm.h; sourceTree = ""; }; + 3D1B3AF023C8E20C00142C16 /* fib64.wasm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fib64.wasm.h; sourceTree = ""; }; + 3D1B3AF123C8E20C00142C16 /* wasi_core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wasi_core.h; sourceTree = ""; }; + 3D1B3AF423C8E20C00142C16 /* m3_api_libc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_api_libc.c; sourceTree = ""; }; + 3D1B3AF523C8E20C00142C16 /* m3_api_libc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_api_libc.h; sourceTree = ""; }; + 3D1B3AF623C8E20C00142C16 /* m3_api_meta_wasi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_api_meta_wasi.c; sourceTree = ""; }; + 3D1B3AF723C8E20C00142C16 /* m3_api_wasi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_api_wasi.c; sourceTree = ""; }; + 3D1B3AF823C8E20C00142C16 /* m3_api_wasi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_api_wasi.h; sourceTree = ""; }; + 3D1B3AF923C8E20C00142C16 /* m3_bind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_bind.c; sourceTree = ""; }; + 3D1B3AFA23C8E20C00142C16 /* m3_code.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_code.c; sourceTree = ""; }; + 3D1B3AFB23C8E20C00142C16 /* m3_code.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_code.h; sourceTree = ""; }; + 3D1B3AFC23C8E20C00142C16 /* m3_compile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_compile.c; sourceTree = ""; }; + 3D1B3AFD23C8E20C00142C16 /* m3_compile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_compile.h; sourceTree = ""; }; + 3D1B3AFE23C8E20C00142C16 /* m3_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_config.h; sourceTree = ""; }; + 3D1B3AFF23C8E20C00142C16 /* m3_config_platforms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_config_platforms.h; sourceTree = ""; }; + 3D1B3B0023C8E20C00142C16 /* m3_core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_core.c; sourceTree = ""; }; + 3D1B3B0123C8E20C00142C16 /* m3_core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_core.h; sourceTree = ""; }; + 3D1B3B0223C8E20C00142C16 /* m3_emit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_emit.c; sourceTree = ""; }; + 3D1B3B0323C8E20C00142C16 /* m3_emit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_emit.h; sourceTree = ""; }; + 3D1B3B0423C8E20C00142C16 /* m3_env.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_env.c; sourceTree = ""; }; + 3D1B3B0523C8E20C00142C16 /* m3_env.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_env.h; sourceTree = ""; }; + 3D1B3B0623C8E20C00142C16 /* m3_exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_exception.h; sourceTree = ""; }; + 3D1B3B0723C8E20C00142C16 /* m3_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_exec.c; sourceTree = ""; }; + 3D1B3B0823C8E20C00142C16 /* m3_exec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_exec.h; sourceTree = ""; }; + 3D1B3B0923C8E20C00142C16 /* m3_exec_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_exec_defs.h; sourceTree = ""; }; + 3D1B3B0A23C8E20C00142C16 /* m3_info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_info.c; sourceTree = ""; }; + 3D1B3B0B23C8E20C00142C16 /* m3_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_info.h; sourceTree = ""; }; + 3D1B3B0C23C8E20C00142C16 /* m3_math_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_math_utils.h; sourceTree = ""; }; + 3D1B3B0D23C8E20C00142C16 /* m3_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_module.c; sourceTree = ""; }; + 3D1B3B0F23C8E20C00142C16 /* m3_parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_parse.c; sourceTree = ""; }; + 3D1ED50C23C8C8E70072E395 /* wasm3.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = wasm3.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3D1ED50F23C8C8E70072E395 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 3D1ED51123C8C8E70072E395 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 3D1ED51423C8C8E70072E395 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 3D1ED51623C8C8E70072E395 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3D1ED51923C8C8E70072E395 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 3D1ED51B23C8C8E70072E395 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3D1ED52123C8CB550072E395 /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; }; + 3D1ED52223C8CB560072E395 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; + 3D3C322D23C9319A00DB9F7E /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 3D3EC19D23D558D5008FD665 /* wasm3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wasm3.h; sourceTree = ""; }; + B5E985C6262018B700FBE0FC /* m3_function.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = m3_function.h; sourceTree = ""; }; + B5E985C7262018B700FBE0FC /* m3_function.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = m3_function.c; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3D1ED50923C8C8E70072E395 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3D1B3AEC23C8E20C00142C16 /* source */ = { + isa = PBXGroup; + children = ( + B5E985C7262018B700FBE0FC /* m3_function.c */, + B5E985C6262018B700FBE0FC /* m3_function.h */, + 3D1B3AED23C8E20C00142C16 /* extra */, + 3D3EC19D23D558D5008FD665 /* wasm3.h */, + 3D1B3AF423C8E20C00142C16 /* m3_api_libc.c */, + 3D1B3AF523C8E20C00142C16 /* m3_api_libc.h */, + 3D1B3AF623C8E20C00142C16 /* m3_api_meta_wasi.c */, + 3D1B3AF723C8E20C00142C16 /* m3_api_wasi.c */, + 3D1B3AF823C8E20C00142C16 /* m3_api_wasi.h */, + 3D1B3AF923C8E20C00142C16 /* m3_bind.c */, + 3D1B3AFA23C8E20C00142C16 /* m3_code.c */, + 3D1B3AFB23C8E20C00142C16 /* m3_code.h */, + 3D1B3AFC23C8E20C00142C16 /* m3_compile.c */, + 3D1B3AFD23C8E20C00142C16 /* m3_compile.h */, + 3D1B3AFE23C8E20C00142C16 /* m3_config.h */, + 3D1B3AFF23C8E20C00142C16 /* m3_config_platforms.h */, + 3D1B3B0023C8E20C00142C16 /* m3_core.c */, + 3D1B3B0123C8E20C00142C16 /* m3_core.h */, + 3D1B3B0223C8E20C00142C16 /* m3_emit.c */, + 3D1B3B0323C8E20C00142C16 /* m3_emit.h */, + 3D1B3B0423C8E20C00142C16 /* m3_env.c */, + 3D1B3B0523C8E20C00142C16 /* m3_env.h */, + 3D1B3B0623C8E20C00142C16 /* m3_exception.h */, + 3D1B3B0723C8E20C00142C16 /* m3_exec.c */, + 3D1B3B0823C8E20C00142C16 /* m3_exec.h */, + 3D1B3B0923C8E20C00142C16 /* m3_exec_defs.h */, + 3D1B3B0A23C8E20C00142C16 /* m3_info.c */, + 3D1B3B0B23C8E20C00142C16 /* m3_info.h */, + 3D1B3B0C23C8E20C00142C16 /* m3_math_utils.h */, + 3D1B3B0D23C8E20C00142C16 /* m3_module.c */, + 3D1B3B0F23C8E20C00142C16 /* m3_parse.c */, + ); + name = source; + path = ../../source; + sourceTree = SOURCE_ROOT; + }; + 3D1B3AED23C8E20C00142C16 /* extra */ = { + isa = PBXGroup; + children = ( + 3D1B3AEE23C8E20C00142C16 /* fib32.wasm.h */, + 3D1B3AEF23C8E20C00142C16 /* fib32_tail.wasm.h */, + 3D1B3AF023C8E20C00142C16 /* fib64.wasm.h */, + 3D1B3AF123C8E20C00142C16 /* wasi_core.h */, + ); + path = extra; + sourceTree = ""; + }; + 3D1ED50323C8C8E70072E395 = { + isa = PBXGroup; + children = ( + 3D1ED50E23C8C8E70072E395 /* wasm3 */, + 3D1ED50D23C8C8E70072E395 /* Products */, + ); + sourceTree = ""; + }; + 3D1ED50D23C8C8E70072E395 /* Products */ = { + isa = PBXGroup; + children = ( + 3D1ED50C23C8C8E70072E395 /* wasm3.app */, + ); + name = Products; + sourceTree = ""; + }; + 3D1ED50E23C8C8E70072E395 /* wasm3 */ = { + isa = PBXGroup; + children = ( + 3D1B3AEC23C8E20C00142C16 /* source */, + 3D1ED50F23C8C8E70072E395 /* AppDelegate.swift */, + 3D1ED51123C8C8E70072E395 /* ViewController.swift */, + 3D1ED51323C8C8E70072E395 /* Main.storyboard */, + 3D1ED51623C8C8E70072E395 /* Assets.xcassets */, + 3D1ED51823C8C8E70072E395 /* LaunchScreen.storyboard */, + 3D1ED51B23C8C8E70072E395 /* Info.plist */, + 3D1ED52223C8CB560072E395 /* main.c */, + 3D3C322D23C9319A00DB9F7E /* icon.png */, + 3D1ED52123C8CB550072E395 /* Bridging-Header.h */, + ); + path = wasm3; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 3D1ED50B23C8C8E70072E395 /* wasm3 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3D1ED51E23C8C8E70072E395 /* Build configuration list for PBXNativeTarget "wasm3" */; + buildPhases = ( + 3D1ED50823C8C8E70072E395 /* Sources */, + 3D1ED50923C8C8E70072E395 /* Frameworks */, + 3D1ED50A23C8C8E70072E395 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = wasm3; + productName = wasm3; + productReference = 3D1ED50C23C8C8E70072E395 /* wasm3.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3D1ED50423C8C8E70072E395 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0900; + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = wasm3; + TargetAttributes = { + 3D1ED50B23C8C8E70072E395 = { + CreatedOnToolsVersion = 9.0.1; + LastSwiftMigration = 0900; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 3D1ED50723C8C8E70072E395 /* Build configuration list for PBXProject "wasm3" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 3D1ED50323C8C8E70072E395; + productRefGroup = 3D1ED50D23C8C8E70072E395 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3D1ED50B23C8C8E70072E395 /* wasm3 */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3D1ED50A23C8C8E70072E395 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D1ED51A23C8C8E70072E395 /* LaunchScreen.storyboard in Resources */, + 3D3C322E23C9319A00DB9F7E /* icon.png in Resources */, + 3D1ED51723C8C8E70072E395 /* Assets.xcassets in Resources */, + 3D1ED51523C8C8E70072E395 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3D1ED50823C8C8E70072E395 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D1B3B1323C8E20D00142C16 /* m3_api_wasi.c in Sources */, + 3D1B3B1123C8E20D00142C16 /* m3_api_libc.c in Sources */, + 3D1B3B1723C8E20D00142C16 /* m3_core.c in Sources */, + B5E985C8262018B700FBE0FC /* m3_function.c in Sources */, + 3D1ED51223C8C8E70072E395 /* ViewController.swift in Sources */, + 3D1B3B1A23C8E20D00142C16 /* m3_exec.c in Sources */, + 3D1B3B1223C8E20D00142C16 /* m3_api_meta_wasi.c in Sources */, + 3D1B3B1823C8E20D00142C16 /* m3_emit.c in Sources */, + 3D1B3B1523C8E20D00142C16 /* m3_code.c in Sources */, + 3D1B3B1423C8E20D00142C16 /* m3_bind.c in Sources */, + 3D1B3B1C23C8E20D00142C16 /* m3_module.c in Sources */, + 3D1B3B1B23C8E20D00142C16 /* m3_info.c in Sources */, + 3D1ED51023C8C8E70072E395 /* AppDelegate.swift in Sources */, + 3D1B3B1923C8E20D00142C16 /* m3_env.c in Sources */, + 3D1B3B1623C8E20D00142C16 /* m3_compile.c in Sources */, + 3D1ED52423C8CB560072E395 /* main.c in Sources */, + 3D1B3B1E23C8E20D00142C16 /* m3_parse.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 3D1ED51323C8C8E70072E395 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 3D1ED51423C8C8E70072E395 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 3D1ED51823C8C8E70072E395 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 3D1ED51923C8C8E70072E395 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 3D1ED51C23C8C8E70072E395 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = ""; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 3D1ED51D23C8C8E70072E395 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CFLAGS = "-fomit-frame-pointer"; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3D1ED51F23C8C8E70072E395 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = wasm3/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.wasm3; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "wasm3/Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3D1ED52023C8C8E70072E395 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = wasm3/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.wasm3; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "wasm3/Bridging-Header.h"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3D1ED50723C8C8E70072E395 /* Build configuration list for PBXProject "wasm3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3D1ED51C23C8C8E70072E395 /* Debug */, + 3D1ED51D23C8C8E70072E395 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3D1ED51E23C8C8E70072E395 /* Build configuration list for PBXNativeTarget "wasm3" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3D1ED51F23C8C8E70072E395 /* Debug */, + 3D1ED52023C8C8E70072E395 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 3D1ED50423C8C8E70072E395 /* Project object */; +} diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b90c664 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3 Release.xcscheme b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3 Release.xcscheme new file mode 100644 index 0000000..f65f4f6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3 Release.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3.xcscheme b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3.xcscheme new file mode 100644 index 0000000..d925f22 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3.xcodeproj/xcshareddata/xcschemes/wasm3.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3/AppDelegate.swift b/wasm3-sys/wasm3/platforms/ios/wasm3/AppDelegate.swift new file mode 100644 index 0000000..99e5823 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// wasm3 +// +// Created by Volodymyr Shymanskyy on 1/10/20. +// Copyright © 2020 wasm3. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3/Assets.xcassets/AppIcon.appiconset/Contents.json b/wasm3-sys/wasm3/platforms/ios/wasm3/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/wasm3-sys/wasm3/platforms/ios/wasm3/Base.lproj/LaunchScreen.storyboard b/wasm3-sys/wasm3/platforms/ios/wasm3/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..438943d --- /dev/null +++ b/wasm3-sys/wasm3/platforms/ios/wasm3/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + +
+ Wasm3 running on iPhone 8 +