diff --git a/.bazelrc b/.bazelrc index e363d6f90..f8c0c4240 100644 --- a/.bazelrc +++ b/.bazelrc @@ -35,7 +35,7 @@ build:linux --linkopt=-ldl build:macos --cxxopt=-std=c++17 -# TODO(mathetake): Windows build is not verified yet. -# build:windows --cxxopt="/std:c++17" +build:windows --enable_runfiles +build:windows --cxxopt="/std:c++17" # See https://bytecodealliance.github.io/wasmtime/c-api/ # build:windows --linkopt="ws2_32.lib advapi32.lib userenv.lib ntdll.lib shell32.lib ole32.lib" diff --git a/.github/workflows/cpp.yml b/.github/workflows/cpp.yml index 7bc959623..449bde919 100644 --- a/.github/workflows/cpp.yml +++ b/.github/workflows/cpp.yml @@ -123,6 +123,11 @@ jobs: arch: x86_64 action: test flags: --config=gcc + - name: 'NullVM on Windows/x86_64' + engine: 'null' + os: windows-2019 + arch: x86_64 + action: test - name: 'V8 on Linux/x86_64' engine: 'v8' repo: 'v8' @@ -233,11 +238,12 @@ jobs: path: test/test_data/ - name: Mangle build rules to use existing test data - run: > - sed 's/\.wasm//g' test/BUILD > test/BUILD.tmp && mv test/BUILD.tmp test/BUILD; - echo "package(default_visibility = [\"//visibility:public\"])" > test/test_data/BUILD; - for i in $(cd test/test_data && ls -1 *.wasm | sed 's/\.wasm$//g'); - do echo "filegroup(name = \"$i\", srcs = [\"$i.wasm\"])" >> test/test_data/BUILD; + shell: bash + run: | + sed 's/\.wasm//g' test/BUILD > test/BUILD.tmp && mv test/BUILD.tmp test/BUILD + echo "package(default_visibility = [\"//visibility:public\"])" > test/test_data/BUILD + for i in $(cd test/test_data && ls -1 *.wasm | sed 's/\.wasm$//g'); do \ + echo "filegroup(name = \"$i\", srcs = [\"$i.wasm\"])" >> test/test_data/BUILD; \ done - name: Bazel build/test diff --git a/include/proxy-wasm/exports.h b/include/proxy-wasm/exports.h index 7fe8a4c57..8d823fedb 100644 --- a/include/proxy-wasm/exports.h +++ b/include/proxy-wasm/exports.h @@ -74,12 +74,12 @@ template size_t pairsSize(const Pairs &result) { template void marshalPairs(const Pairs &result, char *buffer) { char *b = buffer; - *reinterpret_cast(b) = htole32(result.size()); + *reinterpret_cast(b) = htowasm(result.size()); b += sizeof(uint32_t); for (auto &p : result) { - *reinterpret_cast(b) = htole32(p.first.size()); + *reinterpret_cast(b) = htowasm(p.first.size()); b += sizeof(uint32_t); - *reinterpret_cast(b) = htole32(p.second.size()); + *reinterpret_cast(b) = htowasm(p.second.size()); b += sizeof(uint32_t); } for (auto &p : result) { diff --git a/include/proxy-wasm/word.h b/include/proxy-wasm/word.h index 549968342..559471eb8 100644 --- a/include/proxy-wasm/word.h +++ b/include/proxy-wasm/word.h @@ -17,15 +17,20 @@ #include -#ifdef __APPLE__ -#define htole32(x) (x) -#define le32toh(x) (x) -#endif - namespace proxy_wasm { #include "proxy_wasm_common.h" +// Use byteswap functions only when compiling for big-endian platforms. +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define htowasm(x) __builtin_bswap32(x) +#define wasmtoh(x) __builtin_bswap32(x) +#else +#define htowasm(x) (x) +#define wasmtoh(x) (x) +#endif + // Represents a Wasm-native word-sized datum. On 32-bit VMs, the high bits are always zero. // The Wasm/VM API treats all bits as significant. struct Word { diff --git a/src/exports.cc b/src/exports.cc index 3e4f2622f..a63e09159 100644 --- a/src/exports.cc +++ b/src/exports.cc @@ -64,16 +64,16 @@ Pairs toPairs(std::string_view buffer) { if (buffer.size() < sizeof(uint32_t)) { return {}; } - auto size = le32toh(*reinterpret_cast(b)); + auto size = wasmtoh(*reinterpret_cast(b)); b += sizeof(uint32_t); if (sizeof(uint32_t) + size * 2 * sizeof(uint32_t) > buffer.size()) { return {}; } result.resize(size); for (uint32_t i = 0; i < size; i++) { - result[i].first = std::string_view(nullptr, le32toh(*reinterpret_cast(b))); + result[i].first = std::string_view(nullptr, wasmtoh(*reinterpret_cast(b))); b += sizeof(uint32_t); - result[i].second = std::string_view(nullptr, le32toh(*reinterpret_cast(b))); + result[i].second = std::string_view(nullptr, wasmtoh(*reinterpret_cast(b))); b += sizeof(uint32_t); } for (auto &p : result) { @@ -712,8 +712,8 @@ Word writevImpl(Word fd, Word iovs, Word iovs_len, Word *nwritten_ptr) { } const uint32_t *iovec = reinterpret_cast(memslice.value().data()); if (iovec[1] /* buf_len */) { - memslice = context->wasmVm()->getMemory(le32toh(iovec[0]) /* buf */, - le32toh(iovec[1]) /* buf_len */); + memslice = context->wasmVm()->getMemory(wasmtoh(iovec[0]) /* buf */, + wasmtoh(iovec[1]) /* buf_len */); if (!memslice) { return 21; // __WASI_EFAULT } diff --git a/src/signature_util.cc b/src/signature_util.cc index 9163c4661..2e63ebeb0 100644 --- a/src/signature_util.cc +++ b/src/signature_util.cc @@ -85,7 +85,7 @@ bool SignatureUtil::verifySignature(std::string_view bytecode, std::string &mess uint32_t alg_id; std::memcpy(&alg_id, payload.data(), sizeof(uint32_t)); - alg_id = le32toh(alg_id); + alg_id = wasmtoh(alg_id); if (alg_id != 2) { message = "Signature has a wrong alg_id (want: 2, is: " + std::to_string(alg_id) + ")"; diff --git a/src/v8/v8.cc b/src/v8/v8.cc index c2b6ff669..9a0f19559 100644 --- a/src/v8/v8.cc +++ b/src/v8/v8.cc @@ -475,7 +475,7 @@ bool V8::getWord(uint64_t pointer, Word *word) { } uint32_t word32; ::memcpy(&word32, memory_->data() + pointer, size); - word->u64_ = le32toh(word32); + word->u64_ = wasmtoh(word32); return true; } @@ -484,7 +484,7 @@ bool V8::setWord(uint64_t pointer, Word word) { if (pointer + size > memory_->data_size()) { return false; } - uint32_t word32 = htole32(word.u32()); + uint32_t word32 = htowasm(word.u32()); ::memcpy(memory_->data() + pointer, &word32, size); return true; } diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index 494c3f29c..ae5cfc2f8 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -365,7 +365,7 @@ bool Wamr::getWord(uint64_t pointer, Word *word) { uint32_t word32; ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); - word->u64_ = le32toh(word32); + word->u64_ = wasmtoh(word32); return true; } @@ -374,7 +374,7 @@ bool Wamr::setWord(uint64_t pointer, Word word) { if (pointer + size > wasm_memory_data_size(memory_.get())) { return false; } - uint32_t word32 = htole32(word.u32()); + uint32_t word32 = htowasm(word.u32()); ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); return true; } diff --git a/src/wasmtime/wasmtime.cc b/src/wasmtime/wasmtime.cc index b8bba1e1e..b3f5dc25c 100644 --- a/src/wasmtime/wasmtime.cc +++ b/src/wasmtime/wasmtime.cc @@ -392,7 +392,7 @@ bool Wasmtime::getWord(uint64_t pointer, Word *word) { uint32_t word32; ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); - word->u64_ = le32toh(word32); + word->u64_ = wasmtoh(word32); return true; } @@ -401,7 +401,7 @@ bool Wasmtime::setWord(uint64_t pointer, Word word) { if (pointer + size > wasm_memory_data_size(memory_.get())) { return false; } - uint32_t word32 = htole32(word.u32()); + uint32_t word32 = htowasm(word.u32()); ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); return true; } diff --git a/src/wavm/wavm.cc b/src/wavm/wavm.cc index 5704b7b83..6d3357de6 100644 --- a/src/wavm/wavm.cc +++ b/src/wavm/wavm.cc @@ -390,12 +390,12 @@ bool Wavm::getWord(uint64_t pointer, Word *data) { auto p = reinterpret_cast(memory_base_ + pointer); uint32_t data32; memcpy(&data32, p, sizeof(uint32_t)); - data->u64_ = le32toh(data32); + data->u64_ = wasmtoh(data32); return true; } bool Wavm::setWord(uint64_t pointer, Word data) { - uint32_t data32 = htole32(data.u32()); + uint32_t data32 = htowasm(data.u32()); return setMemory(pointer, sizeof(uint32_t), &data32); } diff --git a/test/runtime_test.cc b/test/runtime_test.cc index 7db6f0873..79e672164 100644 --- a/test/runtime_test.cc +++ b/test/runtime_test.cc @@ -57,7 +57,7 @@ TEST_P(TestVM, Memory) { ASSERT_TRUE(vm_->getWord(0x2000, &word)); ASSERT_EQ(100, word.u64_); - uint32_t data[2] = {htole32(static_cast(-1)), htole32(200)}; + uint32_t data[2] = {htowasm(static_cast(-1)), htowasm(200)}; ASSERT_TRUE(vm_->setMemory(0x200, sizeof(int32_t) * 2, static_cast(data))); ASSERT_TRUE(vm_->getWord(0x200, &word)); ASSERT_EQ(-1, static_cast(word.u64_));