diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ed6ca714..dde68f4d2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,147 +98,21 @@ jobs: runs-on: ${{ matrix.os }} + timeout-minutes: ${{ matrix.timeout-minutes }} + strategy: fail-fast: false matrix: include: - - name: 'NullVM on Linux/x86_64' - engine: 'null' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=gcc - - name: 'NullVM on Linux/x86_64 with ASan' - engine: 'null' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang-asan-strict --define=crypto=system - - name: 'NullVM on Linux/x86_64 with TSan' - engine: 'null' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang-tsan - - name: 'NullVM on Windows/x86_64' - engine: 'null' - os: windows-2019 - arch: x86_64 - action: test - targets: -//test/fuzz/... - - name: 'V8 on Linux/x86_64' - engine: 'v8' - repo: 'v8' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang --define=crypto=system - cache: true - - name: 'V8 on Linux/x86_64 with ASan' - engine: 'v8' - repo: 'v8' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang-asan - cache: true - - name: 'V8 on Linux/x86_64 with TSan' - engine: 'v8' - repo: 'v8' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang-tsan - cache: true - - name: 'V8 on Linux/aarch64' - engine: 'v8' - repo: 'v8' - os: ubuntu-20.04 - arch: aarch64 - action: test - targets: -//test/fuzz/... - flags: --config=zig-cc-linux-aarch64 --@v8//bazel/config:v8_target_cpu=arm64 - deps: qemu-user-static libc6-arm64-cross - cache: true - name: 'V8 on macOS/x86_64' engine: 'v8' repo: 'v8' os: macos-11 arch: x86_64 action: test + flags: --runs_per_test=50 cache: true - - name: 'WAMR on Linux/x86_64' - engine: 'wamr' - repo: 'com_github_bytecodealliance_wasm_micro_runtime' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang - - name: 'WAMR on macOS/x86_64' - engine: 'wamr' - repo: 'com_github_bytecodealliance_wasm_micro_runtime' - os: macos-11 - arch: x86_64 - action: test - - name: 'WasmEdge on Linux/x86_64' - engine: 'wasmedge' - repo: 'com_github_wasmedge_wasmedge' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang - - name: 'Wasmtime on Linux/x86_64' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang -c opt - - name: 'Wasmtime on Linux/x86_64 with ASan' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang-asan-strict --define=crypto=system - - name: 'Wasmtime on Linux/aarch64' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: ubuntu-20.04 - arch: aarch64 - action: build - flags: --config=zig-cc-linux-aarch64 - deps: qemu-user-static libc6-arm64-cross - - name: 'Wasmtime on Linux/s390x' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: ubuntu-20.04 - arch: s390x - action: test - flags: --config=clang --test_timeout=1800 - run_under: docker run --rm --env HOME=$HOME --env USER=$(id -un) --volume "$HOME:$HOME" --workdir $(pwd) --user $(id -u):$(id -g) --platform linux/s390x piotrsikora/build-tools:bazel-5.2.0-clang-14-gcc-12 - cache: true - - name: 'Wasmtime on macOS/x86_64' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: macos-11 - arch: x86_64 - action: test - - name: 'Wasmtime on Windows/x86_64' - engine: 'wasmtime' - repo: 'com_github_bytecodealliance_wasmtime' - os: windows-2019 - arch: x86_64 - action: test - targets: -//test/fuzz/... - - name: 'WAVM on Linux/x86_64' - engine: 'wavm' - repo: 'com_github_wavm_wavm' - os: ubuntu-20.04 - arch: x86_64 - action: test - flags: --config=clang - cache: true + timeout-minutes: 1440 steps: - uses: actions/checkout@v2 diff --git a/bazel/external/v8.patch b/bazel/external/v8.patch index 7748793d0..52af7b6ad 100644 --- a/bazel/external/v8.patch +++ b/bazel/external/v8.patch @@ -1,7 +1,5 @@ # 1. Disable pointer compression (limits the maximum number of WasmVMs). # 2. Don't expose Wasm C API (only Wasm C++ API). -# 3. Fix cross-compilation (https://crrev.com/c/3735165). -# 4. Fix build errors in SIMD IndexOf/includes (https://crrev.com/c/3749192). diff --git a/BUILD.bazel b/BUILD.bazel index 5fb10d3940..a19930d36e 100644 @@ -35,264 +33,3 @@ index ce3f569fd5..dc8a4c4f6a 100644 } // extern "C" + +#endif -diff --git a/src/execution/clobber-registers.cc b/src/execution/clobber-registers.cc -index 8f7fba765f..a7f5bf80cf 100644 ---- a/src/execution/clobber-registers.cc -+++ b/src/execution/clobber-registers.cc -@@ -5,19 +5,22 @@ - - #include "src/base/build_config.h" - --#if V8_HOST_ARCH_ARM -+// Check both {HOST_ARCH} and {TARGET_ARCH} to disable the functionality of this -+// file for cross-compilation. The reason is that the inline assembly code below -+// does not work for cross-compilation. -+#if V8_HOST_ARCH_ARM && V8_TARGET_ARCH_ARM - #include "src/codegen/arm/register-arm.h" --#elif V8_HOST_ARCH_ARM64 -+#elif V8_HOST_ARCH_ARM64 && V8_TARGET_ARCH_ARM64 - #include "src/codegen/arm64/register-arm64.h" --#elif V8_HOST_ARCH_IA32 -+#elif V8_HOST_ARCH_IA32 && V8_TARGET_ARCH_IA32 - #include "src/codegen/ia32/register-ia32.h" --#elif V8_HOST_ARCH_X64 -+#elif V8_HOST_ARCH_X64 && V8_TARGET_ARCH_X64 - #include "src/codegen/x64/register-x64.h" --#elif V8_HOST_ARCH_LOONG64 -+#elif V8_HOST_ARCH_LOONG64 && V8_TARGET_ARCH_LOONG64 - #include "src/codegen/loong64/register-loong64.h" --#elif V8_HOST_ARCH_MIPS -+#elif V8_HOST_ARCH_MIPS && V8_TARGET_ARCH_MIPS - #include "src/codegen/mips/register-mips.h" --#elif V8_HOST_ARCH_MIPS64 -+#elif V8_HOST_ARCH_MIPS64 && V8_TARGET_ARCH_MIPS64 - #include "src/codegen/mips64/register-mips64.h" - #endif - -@@ -26,14 +29,15 @@ namespace internal { - - #if V8_CC_MSVC - // msvc only support inline assembly on x86 --#if V8_HOST_ARCH_IA32 -+#if V8_HOST_ARCH_IA32 && V8_TARGET_ARCH_IA32 - #define CLOBBER_REGISTER(R) __asm xorps R, R - - #endif - - #else // !V8_CC_MSVC - --#if V8_HOST_ARCH_X64 || V8_HOST_ARCH_IA32 -+#if (V8_HOST_ARCH_X64 && V8_TARGET_ARCH_X64) || \ -+ (V8_HOST_ARCH_IA32 && V8_TARGET_ARCH_IA32) - #define CLOBBER_REGISTER(R) \ - __asm__ volatile( \ - "xorps " \ -@@ -42,20 +46,19 @@ namespace internal { - "%%" #R :: \ - :); - --#elif V8_HOST_ARCH_ARM64 -+#elif V8_HOST_ARCH_ARM64 && V8_TARGET_ARCH_ARM64 - #define CLOBBER_REGISTER(R) __asm__ volatile("fmov " #R ",xzr" :::); - --#elif V8_HOST_ARCH_LOONG64 -+#elif V8_HOST_ARCH_LOONG64 && V8_TARGET_ARCH_LOONG64 - #define CLOBBER_REGISTER(R) __asm__ volatile("movgr2fr.d $" #R ",$zero" :::); - --#elif V8_HOST_ARCH_MIPS -+#elif V8_HOST_ARCH_MIPS && V8_TARGET_ARCH_MIPS - #define CLOBBER_USE_REGISTER(R) __asm__ volatile("mtc1 $zero,$" #R :::); - --#elif V8_HOST_ARCH_MIPS64 -+#elif V8_HOST_ARCH_MIPS64 && V8_TARGET_ARCH_MIPS64 - #define CLOBBER_USE_REGISTER(R) __asm__ volatile("dmtc1 $zero,$" #R :::); - --#endif // V8_HOST_ARCH_X64 || V8_HOST_ARCH_IA32 || V8_HOST_ARCH_ARM64 || -- // V8_HOST_ARCH_LOONG64 || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64 -+#endif // V8_HOST_ARCH_XXX && V8_TARGET_ARCH_XXX - - #endif // V8_CC_MSVC - -diff --git a/src/objects/simd.cc b/src/objects/simd.cc -index 0a73b9c686..be6b72d157 100644 ---- a/src/objects/simd.cc -+++ b/src/objects/simd.cc -@@ -354,8 +354,13 @@ Address ArrayIndexOfIncludes(Address array_start, uintptr_t array_len, - if (reinterpret_cast(array) % sizeof(double) != 0) { - // Slow scalar search for unaligned double array. - for (; from_index < array_len; from_index++) { -- if (fixed_array.get_representation(static_cast(from_index)) == -- *reinterpret_cast(&search_num)) { -+ if (fixed_array.is_the_hole(static_cast(from_index))) { -+ // |search_num| cannot be NaN, so there is no need to check against -+ // holes. -+ continue; -+ } -+ if (fixed_array.get_scalar(static_cast(from_index)) == -+ search_num) { - return from_index; - } - } -diff --git a/src/objects/simd.cc b/src/objects/simd.cc -index d3cedfe330..0a73b9c686 100644 ---- a/src/objects/simd.cc -+++ b/src/objects/simd.cc -@@ -95,24 +95,21 @@ inline int extract_first_nonzero_index(T v) { - } - - template <> --inline int extract_first_nonzero_index(int32x4_t v) { -- int32x4_t mask = {4, 3, 2, 1}; -+inline int extract_first_nonzero_index(uint32x4_t v) { -+ uint32x4_t mask = {4, 3, 2, 1}; - mask = vandq_u32(mask, v); - return 4 - vmaxvq_u32(mask); - } - - template <> --inline int extract_first_nonzero_index(int64x2_t v) { -- int32x4_t mask = {2, 0, 1, 0}; // Could also be {2,2,1,1} or {0,2,0,1} -- mask = vandq_u32(mask, vreinterpretq_s32_s64(v)); -+inline int extract_first_nonzero_index(uint64x2_t v) { -+ uint32x4_t mask = {2, 0, 1, 0}; // Could also be {2,2,1,1} or {0,2,0,1} -+ mask = vandq_u32(mask, vreinterpretq_u32_u64(v)); - return 2 - vmaxvq_u32(mask); - } - --template <> --inline int extract_first_nonzero_index(float64x2_t v) { -- int32x4_t mask = {2, 0, 1, 0}; // Could also be {2,2,1,1} or {0,2,0,1} -- mask = vandq_u32(mask, vreinterpretq_s32_f64(v)); -- return 2 - vmaxvq_u32(mask); -+inline int32_t reinterpret_vmaxvq_u64(uint64x2_t v) { -+ return vmaxvq_u32(vreinterpretq_u32_u64(v)); - } - #endif - -@@ -204,14 +201,14 @@ inline uintptr_t fast_search_noavx(T* array, uintptr_t array_len, - } - #elif defined(NEON64) - if constexpr (std::is_same::value) { -- VECTORIZED_LOOP_Neon(int32x4_t, int32x4_t, vdupq_n_u32, vceqq_u32, -+ VECTORIZED_LOOP_Neon(uint32x4_t, uint32x4_t, vdupq_n_u32, vceqq_u32, - vmaxvq_u32) - } else if constexpr (std::is_same::value) { -- VECTORIZED_LOOP_Neon(int64x2_t, int64x2_t, vdupq_n_u64, vceqq_u64, -- vmaxvq_u32) -+ VECTORIZED_LOOP_Neon(uint64x2_t, uint64x2_t, vdupq_n_u64, vceqq_u64, -+ reinterpret_vmaxvq_u64) - } else if constexpr (std::is_same::value) { -- VECTORIZED_LOOP_Neon(float64x2_t, float64x2_t, vdupq_n_f64, vceqq_f64, -- vmaxvq_f64) -+ VECTORIZED_LOOP_Neon(float64x2_t, uint64x2_t, vdupq_n_f64, vceqq_f64, -+ reinterpret_vmaxvq_u64) - } - #else - UNREACHABLE(); -diff --git a/src/objects/simd.cc b/src/objects/simd.cc -index be6b72d157..a71968fd10 100644 ---- a/src/objects/simd.cc -+++ b/src/objects/simd.cc -@@ -148,9 +148,14 @@ inline int32_t reinterpret_vmaxvq_u64(uint64x2_t v) { - template - inline uintptr_t fast_search_noavx(T* array, uintptr_t array_len, - uintptr_t index, T search_element) { -- static_assert(std::is_same::value || -- std::is_same::value || -- std::is_same::value); -+ static constexpr bool is_uint32 = -+ sizeof(T) == sizeof(uint32_t) && std::is_integral::value; -+ static constexpr bool is_uint64 = -+ sizeof(T) == sizeof(uint64_t) && std::is_integral::value; -+ static constexpr bool is_double = -+ sizeof(T) == sizeof(double) && std::is_floating_point::value; -+ -+ static_assert(is_uint32 || is_uint64 || is_double); - - #if !(defined(__SSE3__) || defined(NEON64)) - // No SIMD available. -@@ -178,14 +183,14 @@ inline uintptr_t fast_search_noavx(T* array, uintptr_t array_len, - - // Inserting one of the vectorized loop - #ifdef __SSE3__ -- if constexpr (std::is_same::value) { -+ if constexpr (is_uint32) { - #define MOVEMASK(x) _mm_movemask_ps(_mm_castsi128_ps(x)) - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) - VECTORIZED_LOOP_x86(__m128i, __m128i, _mm_set1_epi32, _mm_cmpeq_epi32, - MOVEMASK, EXTRACT) - #undef MOVEMASK - #undef EXTRACT -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_uint64) { - #define SET1(x) _mm_castsi128_ps(_mm_set1_epi64x(x)) - #define CMP(a, b) _mm_cmpeq_pd(_mm_castps_pd(a), _mm_castps_pd(b)) - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) -@@ -193,20 +198,20 @@ inline uintptr_t fast_search_noavx(T* array, uintptr_t array_len, - #undef SET1 - #undef CMP - #undef EXTRACT -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_double) { - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) - VECTORIZED_LOOP_x86(__m128d, __m128d, _mm_set1_pd, _mm_cmpeq_pd, - _mm_movemask_pd, EXTRACT) - #undef EXTRACT - } - #elif defined(NEON64) -- if constexpr (std::is_same::value) { -+ if constexpr (is_uint32) { - VECTORIZED_LOOP_Neon(uint32x4_t, uint32x4_t, vdupq_n_u32, vceqq_u32, - vmaxvq_u32) -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_uint64) { - VECTORIZED_LOOP_Neon(uint64x2_t, uint64x2_t, vdupq_n_u64, vceqq_u64, - reinterpret_vmaxvq_u64) -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_double) { - VECTORIZED_LOOP_Neon(float64x2_t, uint64x2_t, vdupq_n_f64, vceqq_f64, - reinterpret_vmaxvq_u64) - } -@@ -240,9 +245,14 @@ template - TARGET_AVX2 inline uintptr_t fast_search_avx(T* array, uintptr_t array_len, - uintptr_t index, - T search_element) { -- static_assert(std::is_same::value || -- std::is_same::value || -- std::is_same::value); -+ static constexpr bool is_uint32 = -+ sizeof(T) == sizeof(uint32_t) && std::is_integral::value; -+ static constexpr bool is_uint64 = -+ sizeof(T) == sizeof(uint64_t) && std::is_integral::value; -+ static constexpr bool is_double = -+ sizeof(T) == sizeof(double) && std::is_floating_point::value; -+ -+ static_assert(is_uint32 || is_uint64 || is_double); - - const int target_align = 32; - // Scalar loop to reach desired alignment -@@ -256,21 +266,21 @@ TARGET_AVX2 inline uintptr_t fast_search_avx(T* array, uintptr_t array_len, - } - - // Generating vectorized loop -- if constexpr (std::is_same::value) { -+ if constexpr (is_uint32) { - #define MOVEMASK(x) _mm256_movemask_ps(_mm256_castsi256_ps(x)) - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) - VECTORIZED_LOOP_x86(__m256i, __m256i, _mm256_set1_epi32, _mm256_cmpeq_epi32, - MOVEMASK, EXTRACT) - #undef MOVEMASK - #undef EXTRACT -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_uint64) { - #define MOVEMASK(x) _mm256_movemask_pd(_mm256_castsi256_pd(x)) - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) - VECTORIZED_LOOP_x86(__m256i, __m256i, _mm256_set1_epi64x, - _mm256_cmpeq_epi64, MOVEMASK, EXTRACT) - #undef MOVEMASK - #undef EXTRACT -- } else if constexpr (std::is_same::value) { -+ } else if constexpr (is_double) { - #define CMP(a, b) _mm256_cmp_pd(a, b, _CMP_EQ_OQ) - #define EXTRACT(x) base::bits::CountTrailingZeros32(x) - VECTORIZED_LOOP_x86(__m256d, __m256d, _mm256_set1_pd, CMP, diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 87ca15ee8..5726866c6 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -126,10 +126,10 @@ def proxy_wasm_cpp_host_repositories(): maybe( git_repository, name = "v8", - # 10.4.132.18 - commit = "ce33dd2c08521fbe7f616bcd5941f2f388338030", + # 10.7.193.13 + commit = "6c8b357a84847a479cd329478522feefc1c3195a", remote = "https://chromium.googlesource.com/v8/v8", - shallow_since = "1657561920 +0000", + shallow_since = "1664374400 +0000", patches = ["@proxy_wasm_cpp_host//bazel/external:v8.patch"], patch_args = ["-p1"], ) @@ -143,9 +143,9 @@ def proxy_wasm_cpp_host_repositories(): new_git_repository, name = "com_googlesource_chromium_base_trace_event_common", build_file = "@v8//:bazel/BUILD.trace_event_common", - commit = "d115b033c4e53666b535cbd1985ffe60badad082", + commit = "521ac34ebd795939c7e16b37d9d3ddb40e8ed556", remote = "https://chromium.googlesource.com/chromium/src/base/trace_event/common.git", - shallow_since = "1642576054 -0800", + shallow_since = "1662508800 -0800", ) native.bind( @@ -153,25 +153,6 @@ def proxy_wasm_cpp_host_repositories(): actual = "@com_googlesource_chromium_base_trace_event_common//:trace_event_common", ) - maybe( - new_git_repository, - name = "com_googlesource_chromium_zlib", - build_file = "@v8//:bazel/BUILD.zlib", - commit = "64bbf988543996eb8df9a86877b32917187eba8f", - remote = "https://chromium.googlesource.com/chromium/src/third_party/zlib.git", - shallow_since = "1653988038 -0700", - ) - - native.bind( - name = "zlib", - actual = "@com_googlesource_chromium_zlib//:zlib", - ) - - native.bind( - name = "zlib_compression_utils", - actual = "@com_googlesource_chromium_zlib//:zlib_compression_utils", - ) - # WAMR with dependencies. maybe( diff --git a/include/proxy-wasm/null_vm.h b/include/proxy-wasm/null_vm.h index 3a38fd990..a0a3798ff 100644 --- a/include/proxy-wasm/null_vm.h +++ b/include/proxy-wasm/null_vm.h @@ -61,6 +61,7 @@ struct NullVm : public WasmVm { #undef _REGISTER_CALLBACK void terminate() override {} + bool usesWasmByteOrder() override { return false; } std::string plugin_name_; std::unique_ptr plugin_; diff --git a/include/proxy-wasm/wasm_vm.h b/include/proxy-wasm/wasm_vm.h index 879e200d1..acf0ccf3b 100644 --- a/include/proxy-wasm/wasm_vm.h +++ b/include/proxy-wasm/wasm_vm.h @@ -303,6 +303,12 @@ class WasmVm { */ virtual void terminate() = 0; + /** + * Byte order flag (host or wasm). + * @return 'false' for a null VM and 'true' for a wasm VM. + */ + virtual bool usesWasmByteOrder() = 0; + bool isFailed() { return failed_ != FailState::Ok; } void fail(FailState fail_state, std::string_view message) { integration()->error(message); diff --git a/include/proxy-wasm/word.h b/include/proxy-wasm/word.h index 559471eb8..90ea932df 100644 --- a/include/proxy-wasm/word.h +++ b/include/proxy-wasm/word.h @@ -24,11 +24,11 @@ namespace proxy_wasm { // 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) +#define htowasm(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? __builtin_bswap32(x) : (x)) +#define wasmtoh(x, vm_uses_wasm_byte_order) ((vm_uses_wasm_byte_order) ? __builtin_bswap32(x) : (x)) #else -#define htowasm(x) (x) -#define wasmtoh(x) (x) +#define htowasm(x, vm_uses_wasm_byte_order) (x) +#define wasmtoh(x, vm_uses_wasm_byte_order) (x) #endif // Represents a Wasm-native word-sized datum. On 32-bit VMs, the high bits are always zero. diff --git a/src/exports.cc b/src/exports.cc index b06c40437..0290dcf0f 100644 --- a/src/exports.cc +++ b/src/exports.cc @@ -693,8 +693,9 @@ Word writevImpl(Word fd, Word iovs, Word iovs_len, Word *nwritten_ptr) { } const auto *iovec = reinterpret_cast(memslice.value().data()); if (iovec[1] != 0U /* buf_len */) { - memslice = context->wasmVm()->getMemory(wasmtoh(iovec[0]) /* buf */, - wasmtoh(iovec[1]) /* buf_len */); + const auto buf = wasmtoh(iovec[0], context->wasmVm()->usesWasmByteOrder()); + const auto buf_len = wasmtoh(iovec[1], context->wasmVm()->usesWasmByteOrder()); + memslice = context->wasmVm()->getMemory(buf, buf_len); if (!memslice) { return 21; // __WASI_EFAULT } diff --git a/src/pairs_util.cc b/src/pairs_util.cc index d49259216..d21135788 100644 --- a/src/pairs_util.cc +++ b/src/pairs_util.cc @@ -19,6 +19,7 @@ #include #include +#include "include/proxy-wasm/exports.h" #include "include/proxy-wasm/limits.h" #include "include/proxy-wasm/word.h" @@ -45,7 +46,10 @@ bool PairsUtil::marshalPairs(const Pairs &pairs, char *buffer, size_t size) { const char *end = buffer + size; // Write number of pairs. - uint32_t num_pairs = htowasm(pairs.size()); + uint32_t num_pairs = + htowasm(pairs.size(), contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); if (pos + sizeof(uint32_t) > end) { return false; } @@ -54,7 +58,10 @@ bool PairsUtil::marshalPairs(const Pairs &pairs, char *buffer, size_t size) { for (const auto &p : pairs) { // Write name length. - uint32_t name_len = htowasm(p.first.size()); + uint32_t name_len = + htowasm(p.first.size(), contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); if (pos + sizeof(uint32_t) > end) { return false; } @@ -62,7 +69,10 @@ bool PairsUtil::marshalPairs(const Pairs &pairs, char *buffer, size_t size) { pos += sizeof(uint32_t); // Write value length. - uint32_t value_len = htowasm(p.second.size()); + uint32_t value_len = + htowasm(p.second.size(), contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); if (pos + sizeof(uint32_t) > end) { return false; } @@ -103,7 +113,10 @@ Pairs PairsUtil::toPairs(std::string_view buffer) { if (pos + sizeof(uint32_t) > end) { return {}; } - uint32_t num_pairs = wasmtoh(*reinterpret_cast(pos)); + uint32_t num_pairs = wasmtoh(*reinterpret_cast(pos), + contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); pos += sizeof(uint32_t); // Check if we're not going to exceed the limit. @@ -122,14 +135,20 @@ Pairs PairsUtil::toPairs(std::string_view buffer) { if (pos + sizeof(uint32_t) > end) { return {}; } - s.first = wasmtoh(*reinterpret_cast(pos)); + s.first = wasmtoh(*reinterpret_cast(pos), + contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); pos += sizeof(uint32_t); // Read value length. if (pos + sizeof(uint32_t) > end) { return {}; } - s.second = wasmtoh(*reinterpret_cast(pos)); + s.second = wasmtoh(*reinterpret_cast(pos), + contextOrEffectiveContext() != nullptr + ? contextOrEffectiveContext()->wasmVm()->usesWasmByteOrder() + : false); pos += sizeof(uint32_t); } diff --git a/src/signature_util.cc b/src/signature_util.cc index a8f29363b..46b9d3333 100644 --- a/src/signature_util.cc +++ b/src/signature_util.cc @@ -86,7 +86,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 = wasmtoh(alg_id); + alg_id = wasmtoh(alg_id, true); 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 2d8660bcc..61779c1d5 100644 --- a/src/v8/v8.cc +++ b/src/v8/v8.cc @@ -30,14 +30,10 @@ #include "include/v8-version.h" #include "include/v8.h" +#include "src/flags/flags.h" #include "src/wasm/c-api.h" #include "wasm-api/wasm.hh" -namespace v8::internal { -extern bool FLAG_liftoff; -extern unsigned int FLAG_wasm_max_mem_pages; -} // namespace v8::internal - namespace proxy_wasm { namespace v8 { @@ -46,8 +42,8 @@ wasm::Engine *engine() { static wasm::own engine; std::call_once(init, []() { - ::v8::internal::FLAG_liftoff = false; - ::v8::internal::FLAG_wasm_max_mem_pages = + ::v8::internal::v8_flags.liftoff = false; + ::v8::internal::v8_flags.wasm_max_mem_pages = PROXY_WASM_HOST_MAX_WASM_MEMORY_SIZE_BYTES / PROXY_WASM_HOST_WASM_MEMORY_PAGE_SIZE_BYTES; ::v8::V8::EnableWebAssemblyTrapHandler(true); engine = wasm::Engine::make(); @@ -105,6 +101,7 @@ class V8 : public WasmVm { #undef _GET_MODULE_FUNCTION void terminate() override; + bool usesWasmByteOrder() override { return true; } private: wasm::own trap(std::string message); @@ -503,7 +500,7 @@ bool V8::getWord(uint64_t pointer, Word *word) { } uint32_t word32; ::memcpy(&word32, memory_->data() + pointer, size); - word->u64_ = wasmtoh(word32); + word->u64_ = wasmtoh(word32, true); return true; } @@ -516,7 +513,7 @@ bool V8::setWord(uint64_t pointer, Word word) { if (pointer + size > memory_->data_size()) { return false; } - uint32_t word32 = htowasm(word.u32()); + uint32_t word32 = htowasm(word.u32(), true); ::memcpy(memory_->data() + pointer, &word32, size); return true; } diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc index e193358cc..2ca6863be 100644 --- a/src/wamr/wamr.cc +++ b/src/wamr/wamr.cc @@ -87,6 +87,7 @@ class Wamr : public WasmVm { #undef _GET_MODULE_FUNCTION void terminate() override {} + bool usesWasmByteOrder() override { return true; } private: template @@ -368,7 +369,7 @@ bool Wamr::getWord(uint64_t pointer, Word *word) { uint32_t word32; ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); - word->u64_ = wasmtoh(word32); + word->u64_ = wasmtoh(word32, true); return true; } @@ -377,7 +378,7 @@ bool Wamr::setWord(uint64_t pointer, Word word) { if (pointer + size > wasm_memory_data_size(memory_.get())) { return false; } - uint32_t word32 = htowasm(word.u32()); + uint32_t word32 = htowasm(word.u32(), true); ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); return true; } diff --git a/src/wasmedge/wasmedge.cc b/src/wasmedge/wasmedge.cc index f22d588ac..89813096f 100644 --- a/src/wasmedge/wasmedge.cc +++ b/src/wasmedge/wasmedge.cc @@ -281,6 +281,7 @@ class WasmEdge : public WasmVm { std::function *function); void terminate() override {} + bool usesWasmByteOrder() override { return true; } WasmEdgeLoaderPtr loader_; WasmEdgeValidatorPtr validator_; diff --git a/src/wasmtime/wasmtime.cc b/src/wasmtime/wasmtime.cc index 040dea072..2cfc21888 100644 --- a/src/wasmtime/wasmtime.cc +++ b/src/wasmtime/wasmtime.cc @@ -98,6 +98,7 @@ class Wasmtime : public WasmVm { std::function *function); void terminate() override {} + bool usesWasmByteOrder() override { return true; } WasmStorePtr store_; WasmModulePtr module_; @@ -394,7 +395,7 @@ bool Wasmtime::getWord(uint64_t pointer, Word *word) { uint32_t word32; ::memcpy(&word32, wasm_memory_data(memory_.get()) + pointer, size); - word->u64_ = wasmtoh(word32); + word->u64_ = wasmtoh(word32, true); return true; } @@ -403,7 +404,7 @@ bool Wasmtime::setWord(uint64_t pointer, Word word) { if (pointer + size > wasm_memory_data_size(memory_.get())) { return false; } - uint32_t word32 = htowasm(word.u32()); + uint32_t word32 = htowasm(word.u32(), true); ::memcpy(wasm_memory_data(memory_.get()) + pointer, &word32, size); return true; } diff --git a/src/wavm/wavm.cc b/src/wavm/wavm.cc index 1041b7fa7..670eb7c41 100644 --- a/src/wavm/wavm.cc +++ b/src/wavm/wavm.cc @@ -230,6 +230,7 @@ struct Wavm : public WasmVm { #undef _REGISTER_CALLBACK void terminate() override {} + bool usesWasmByteOrder() override { return true; } IR::Module ir_module_; WAVM::Runtime::ModuleRef module_ = nullptr; @@ -389,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_ = wasmtoh(data32); + data->u64_ = wasmtoh(data32, true); return true; } bool Wavm::setWord(uint64_t pointer, Word data) { - uint32_t data32 = htowasm(data.u32()); + uint32_t data32 = htowasm(data.u32(), true); return setMemory(pointer, sizeof(uint32_t), &data32); } diff --git a/test/BUILD b/test/BUILD index 42748b92d..aa99c0f35 100644 --- a/test/BUILD +++ b/test/BUILD @@ -52,6 +52,7 @@ cc_test( cc_test( name = "runtime_test", + timeout = "long", srcs = ["runtime_test.cc"], data = [ "//test/test_data:callback.wasm", @@ -152,6 +153,7 @@ cc_test( cc_test( name = "wasm_vm_test", + timeout = "long", srcs = ["wasm_vm_test.cc"], data = [ "//test/test_data:abi_export.wasm", @@ -165,6 +167,17 @@ cc_test( ], ) +cc_test( + name = "pairs_util_test", + srcs = ["pairs_util_test.cc"], + linkstatic = 1, + deps = [ + "//:lib", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "utility_lib", testonly = True, diff --git a/test/null_vm_test.cc b/test/null_vm_test.cc index 774c685d3..5bb862f96 100644 --- a/test/null_vm_test.cc +++ b/test/null_vm_test.cc @@ -73,4 +73,10 @@ TEST_F(BaseVmTest, NullVmStartup) { EXPECT_NE(test_null_vm_plugin, nullptr); } +TEST_F(BaseVmTest, ByteOrder) { + auto wasm_vm = createNullVm(); + EXPECT_TRUE(wasm_vm->load("test_null_vm_plugin", {}, {})); + EXPECT_FALSE(wasm_vm->usesWasmByteOrder()); +} + } // namespace proxy_wasm diff --git a/test/pairs_util_test.cc b/test/pairs_util_test.cc new file mode 100644 index 000000000..3f9fcd965 --- /dev/null +++ b/test/pairs_util_test.cc @@ -0,0 +1,33 @@ +// Copyright 2022 Google LLC +// +// 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. + +#include "include/proxy-wasm/pairs_util.h" +#include "gtest/gtest.h" + +namespace proxy_wasm { + +TEST(PairsUtilTest, EncodeDecode) { + proxy_wasm::Pairs pairs1; + std::string data1("some_data"); + auto size_str = std::to_string(data1.size()); + pairs1.push_back({data1, size_str}); + std::vector buffer(PairsUtil::pairsSize(pairs1)); + EXPECT_TRUE(PairsUtil::marshalPairs(pairs1, buffer.data(), buffer.size())); + auto pairs2 = PairsUtil::toPairs(std::string_view(buffer.data(), buffer.size())); + EXPECT_EQ(pairs2.size(), pairs1.size()); + EXPECT_EQ(pairs2[0].first, pairs1[0].first); + EXPECT_EQ(pairs2[0].second, pairs1[0].second); +} + +} // namespace proxy_wasm diff --git a/test/wasm_vm_test.cc b/test/wasm_vm_test.cc index 642ea636f..a9caac935 100644 --- a/test/wasm_vm_test.cc +++ b/test/wasm_vm_test.cc @@ -53,7 +53,8 @@ TEST_P(TestVm, Memory) { ASSERT_TRUE(vm_->getWord(0x2000, &word)); ASSERT_EQ(100, word.u64_); - uint32_t data[2] = {htowasm(static_cast(-1)), htowasm(200)}; + uint32_t data[2] = {htowasm(static_cast(-1), vm_->usesWasmByteOrder()), + htowasm(200, vm_->usesWasmByteOrder())}; 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_));