11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include <math.h>
61cb0ef41Sopenharmony_ci#include <stdint.h>
71cb0ef41Sopenharmony_ci#include <stdlib.h>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include <limits>
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "include/v8config.h"
121cb0ef41Sopenharmony_ci#include "src/base/bits.h"
131cb0ef41Sopenharmony_ci#include "src/base/ieee754.h"
141cb0ef41Sopenharmony_ci#include "src/base/safe_conversions.h"
151cb0ef41Sopenharmony_ci#include "src/common/assert-scope.h"
161cb0ef41Sopenharmony_ci#include "src/utils/memcopy.h"
171cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects-inl.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
201cb0ef41Sopenharmony_ci    defined(THREAD_SANITIZER) || defined(LEAK_SANITIZER) ||    \
211cb0ef41Sopenharmony_ci    defined(UNDEFINED_SANITIZER)
221cb0ef41Sopenharmony_ci#define V8_WITH_SANITIZER
231cb0ef41Sopenharmony_ci#endif
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN) && defined(V8_WITH_SANITIZER)
261cb0ef41Sopenharmony_ci// With ASAN on Windows we have to reset the thread-in-wasm flag. Exceptions
271cb0ef41Sopenharmony_ci// caused by ASAN let the thread-in-wasm flag get out of sync. Even marking
281cb0ef41Sopenharmony_ci// functions with DISABLE_ASAN is not sufficient when the compiler produces
291cb0ef41Sopenharmony_ci// calls to memset. Therefore we add test-specific code for ASAN on
301cb0ef41Sopenharmony_ci// Windows.
311cb0ef41Sopenharmony_ci#define RESET_THREAD_IN_WASM_FLAG_FOR_ASAN_ON_WINDOWS
321cb0ef41Sopenharmony_ci#include "src/trap-handler/trap-handler.h"
331cb0ef41Sopenharmony_ci#endif
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci#include "src/base/memory.h"
361cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
371cb0ef41Sopenharmony_ci#include "src/wasm/wasm-external-refs.h"
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_cinamespace v8 {
401cb0ef41Sopenharmony_cinamespace internal {
411cb0ef41Sopenharmony_cinamespace wasm {
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciusing base::ReadUnalignedValue;
441cb0ef41Sopenharmony_ciusing base::WriteUnalignedValue;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_civoid f32_trunc_wrapper(Address data) {
471cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, truncf(ReadUnalignedValue<float>(data)));
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_civoid f32_floor_wrapper(Address data) {
511cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, floorf(ReadUnalignedValue<float>(data)));
521cb0ef41Sopenharmony_ci}
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_civoid f32_ceil_wrapper(Address data) {
551cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, ceilf(ReadUnalignedValue<float>(data)));
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_civoid f32_nearest_int_wrapper(Address data) {
591cb0ef41Sopenharmony_ci  float input = ReadUnalignedValue<float>(data);
601cb0ef41Sopenharmony_ci  float value = nearbyintf(input);
611cb0ef41Sopenharmony_ci#if V8_OS_AIX
621cb0ef41Sopenharmony_ci  value = FpOpWorkaround<float>(input, value);
631cb0ef41Sopenharmony_ci#endif
641cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, value);
651cb0ef41Sopenharmony_ci}
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_civoid f64_trunc_wrapper(Address data) {
681cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, trunc(ReadUnalignedValue<double>(data)));
691cb0ef41Sopenharmony_ci}
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_civoid f64_floor_wrapper(Address data) {
721cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, floor(ReadUnalignedValue<double>(data)));
731cb0ef41Sopenharmony_ci}
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_civoid f64_ceil_wrapper(Address data) {
761cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, ceil(ReadUnalignedValue<double>(data)));
771cb0ef41Sopenharmony_ci}
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_civoid f64_nearest_int_wrapper(Address data) {
801cb0ef41Sopenharmony_ci  double input = ReadUnalignedValue<double>(data);
811cb0ef41Sopenharmony_ci  double value = nearbyint(input);
821cb0ef41Sopenharmony_ci#if V8_OS_AIX
831cb0ef41Sopenharmony_ci  value = FpOpWorkaround<double>(input, value);
841cb0ef41Sopenharmony_ci#endif
851cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, value);
861cb0ef41Sopenharmony_ci}
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_civoid int64_to_float32_wrapper(Address data) {
891cb0ef41Sopenharmony_ci  int64_t input = ReadUnalignedValue<int64_t>(data);
901cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, static_cast<float>(input));
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_civoid uint64_to_float32_wrapper(Address data) {
941cb0ef41Sopenharmony_ci  uint64_t input = ReadUnalignedValue<uint64_t>(data);
951cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN)
961cb0ef41Sopenharmony_ci  // On Windows, the FP stack registers calculate with less precision, which
971cb0ef41Sopenharmony_ci  // leads to a uint64_t to float32 conversion which does not satisfy the
981cb0ef41Sopenharmony_ci  // WebAssembly specification. Therefore we do a different approach here:
991cb0ef41Sopenharmony_ci  //
1001cb0ef41Sopenharmony_ci  // / leading 0 \/  24 float data bits  \/  for rounding \/ trailing 0 \
1011cb0ef41Sopenharmony_ci  // 00000000000001XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX100000000000000
1021cb0ef41Sopenharmony_ci  //
1031cb0ef41Sopenharmony_ci  // Float32 can only represent 24 data bit (1 implicit 1 bit + 23 mantissa
1041cb0ef41Sopenharmony_ci  // bits). Starting from the most significant 1 bit, we can therefore extract
1051cb0ef41Sopenharmony_ci  // 24 bits and do the conversion only on them. The other bits can affect the
1061cb0ef41Sopenharmony_ci  // result only through rounding. Rounding works as follows:
1071cb0ef41Sopenharmony_ci  // * If the most significant rounding bit is not set, then round down.
1081cb0ef41Sopenharmony_ci  // * If the most significant rounding bit is set, and at least one of the
1091cb0ef41Sopenharmony_ci  //   other rounding bits is set, then round up.
1101cb0ef41Sopenharmony_ci  // * If the most significant rounding bit is set, but all other rounding bits
1111cb0ef41Sopenharmony_ci  //   are not set, then round to even.
1121cb0ef41Sopenharmony_ci  // We can aggregate 'all other rounding bits' in the second-most significant
1131cb0ef41Sopenharmony_ci  // rounding bit.
1141cb0ef41Sopenharmony_ci  // The resulting algorithm is therefore as follows:
1151cb0ef41Sopenharmony_ci  // * Check if the distance between the most significant bit (MSB) and the
1161cb0ef41Sopenharmony_ci  //   least significant bit (LSB) is greater than 25 bits. If the distance is
1171cb0ef41Sopenharmony_ci  //   less or equal to 25 bits, the uint64 to float32 conversion is anyways
1181cb0ef41Sopenharmony_ci  //   exact, and we just use the C++ conversion.
1191cb0ef41Sopenharmony_ci  // * Find the most significant bit (MSB).
1201cb0ef41Sopenharmony_ci  // * Starting from the MSB, extract 25 bits (24 data bits + the first rounding
1211cb0ef41Sopenharmony_ci  //   bit).
1221cb0ef41Sopenharmony_ci  // * The remaining rounding bits are guaranteed to contain at least one 1 bit,
1231cb0ef41Sopenharmony_ci  //   due to the check we did above.
1241cb0ef41Sopenharmony_ci  // * Store the 25 bits + 1 aggregated bit in an uint32_t.
1251cb0ef41Sopenharmony_ci  // * Convert this uint32_t to float. The conversion does the correct rounding
1261cb0ef41Sopenharmony_ci  //   now.
1271cb0ef41Sopenharmony_ci  // * Shift the result back to the original magnitude.
1281cb0ef41Sopenharmony_ci  uint32_t leading_zeros = base::bits::CountLeadingZeros(input);
1291cb0ef41Sopenharmony_ci  uint32_t trailing_zeros = base::bits::CountTrailingZeros(input);
1301cb0ef41Sopenharmony_ci  constexpr uint32_t num_extracted_bits = 25;
1311cb0ef41Sopenharmony_ci  // Check if there are any rounding bits we have to aggregate.
1321cb0ef41Sopenharmony_ci  if (leading_zeros + trailing_zeros + num_extracted_bits < 64) {
1331cb0ef41Sopenharmony_ci    // Shift to extract the data bits.
1341cb0ef41Sopenharmony_ci    uint32_t num_aggregation_bits = 64 - num_extracted_bits - leading_zeros;
1351cb0ef41Sopenharmony_ci    // We extract the bits we want to convert. Note that we convert one bit more
1361cb0ef41Sopenharmony_ci    // than necessary. This bit is a placeholder where we will store the
1371cb0ef41Sopenharmony_ci    // aggregation bit.
1381cb0ef41Sopenharmony_ci    int32_t extracted_bits =
1391cb0ef41Sopenharmony_ci        static_cast<int32_t>(input >> (num_aggregation_bits - 1));
1401cb0ef41Sopenharmony_ci    // Set the aggregation bit. We don't have to clear the slot first, because
1411cb0ef41Sopenharmony_ci    // the bit there is also part of the aggregation.
1421cb0ef41Sopenharmony_ci    extracted_bits |= 1;
1431cb0ef41Sopenharmony_ci    float result = static_cast<float>(extracted_bits);
1441cb0ef41Sopenharmony_ci    // We have to shift the result back. The shift amount is
1451cb0ef41Sopenharmony_ci    // (num_aggregation_bits - 1), which is the shift amount we did originally,
1461cb0ef41Sopenharmony_ci    // and (-2), which is for the two additional bits we kept originally for
1471cb0ef41Sopenharmony_ci    // rounding.
1481cb0ef41Sopenharmony_ci    int32_t shift_back = static_cast<int32_t>(num_aggregation_bits) - 1 - 2;
1491cb0ef41Sopenharmony_ci    // Calculate the multiplier to shift the extracted bits back to the original
1501cb0ef41Sopenharmony_ci    // magnitude. This multiplier is a power of two, so in the float32 bit
1511cb0ef41Sopenharmony_ci    // representation we just have to construct the correct exponent and put it
1521cb0ef41Sopenharmony_ci    // at the correct bit offset. The exponent consists of 8 bits, starting at
1531cb0ef41Sopenharmony_ci    // the second MSB (a.k.a '<< 23'). The encoded exponent itself is
1541cb0ef41Sopenharmony_ci    // ('actual exponent' - 127).
1551cb0ef41Sopenharmony_ci    int32_t multiplier_bits = ((shift_back - 127) & 0xff) << 23;
1561cb0ef41Sopenharmony_ci    result *= bit_cast<float>(multiplier_bits);
1571cb0ef41Sopenharmony_ci    WriteUnalignedValue<float>(data, result);
1581cb0ef41Sopenharmony_ci    return;
1591cb0ef41Sopenharmony_ci  }
1601cb0ef41Sopenharmony_ci#endif  // defined(V8_OS_WIN)
1611cb0ef41Sopenharmony_ci  WriteUnalignedValue<float>(data, static_cast<float>(input));
1621cb0ef41Sopenharmony_ci}
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_civoid int64_to_float64_wrapper(Address data) {
1651cb0ef41Sopenharmony_ci  int64_t input = ReadUnalignedValue<int64_t>(data);
1661cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, static_cast<double>(input));
1671cb0ef41Sopenharmony_ci}
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_civoid uint64_to_float64_wrapper(Address data) {
1701cb0ef41Sopenharmony_ci  uint64_t input = ReadUnalignedValue<uint64_t>(data);
1711cb0ef41Sopenharmony_ci  double result = static_cast<double>(input);
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci#if V8_CC_MSVC
1741cb0ef41Sopenharmony_ci  // With MSVC we use static_cast<double>(uint32_t) instead of
1751cb0ef41Sopenharmony_ci  // static_cast<double>(uint64_t) to achieve round-to-nearest-ties-even
1761cb0ef41Sopenharmony_ci  // semantics. The idea is to calculate
1771cb0ef41Sopenharmony_ci  // static_cast<double>(high_word) * 2^32 + static_cast<double>(low_word).
1781cb0ef41Sopenharmony_ci  uint32_t low_word = static_cast<uint32_t>(input & 0xFFFFFFFF);
1791cb0ef41Sopenharmony_ci  uint32_t high_word = static_cast<uint32_t>(input >> 32);
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  double shift = static_cast<double>(1ull << 32);
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  result = static_cast<double>(high_word);
1841cb0ef41Sopenharmony_ci  result *= shift;
1851cb0ef41Sopenharmony_ci  result += static_cast<double>(low_word);
1861cb0ef41Sopenharmony_ci#endif
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, result);
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciint32_t float32_to_int64_wrapper(Address data) {
1921cb0ef41Sopenharmony_ci  float input = ReadUnalignedValue<float>(data);
1931cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<int64_t>(input)) {
1941cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
1951cb0ef41Sopenharmony_ci    return 1;
1961cb0ef41Sopenharmony_ci  }
1971cb0ef41Sopenharmony_ci  return 0;
1981cb0ef41Sopenharmony_ci}
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ciint32_t float32_to_uint64_wrapper(Address data) {
2011cb0ef41Sopenharmony_ci  float input = ReadUnalignedValue<float>(data);
2021cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<uint64_t>(input)) {
2031cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
2041cb0ef41Sopenharmony_ci    return 1;
2051cb0ef41Sopenharmony_ci  }
2061cb0ef41Sopenharmony_ci  return 0;
2071cb0ef41Sopenharmony_ci}
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ciint32_t float64_to_int64_wrapper(Address data) {
2101cb0ef41Sopenharmony_ci  double input = ReadUnalignedValue<double>(data);
2111cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<int64_t>(input)) {
2121cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
2131cb0ef41Sopenharmony_ci    return 1;
2141cb0ef41Sopenharmony_ci  }
2151cb0ef41Sopenharmony_ci  return 0;
2161cb0ef41Sopenharmony_ci}
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ciint32_t float64_to_uint64_wrapper(Address data) {
2191cb0ef41Sopenharmony_ci  double input = ReadUnalignedValue<double>(data);
2201cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<uint64_t>(input)) {
2211cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
2221cb0ef41Sopenharmony_ci    return 1;
2231cb0ef41Sopenharmony_ci  }
2241cb0ef41Sopenharmony_ci  return 0;
2251cb0ef41Sopenharmony_ci}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_civoid float32_to_int64_sat_wrapper(Address data) {
2281cb0ef41Sopenharmony_ci  float input = ReadUnalignedValue<float>(data);
2291cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<int64_t>(input)) {
2301cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
2311cb0ef41Sopenharmony_ci    return;
2321cb0ef41Sopenharmony_ci  }
2331cb0ef41Sopenharmony_ci  if (std::isnan(input)) {
2341cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, 0);
2351cb0ef41Sopenharmony_ci    return;
2361cb0ef41Sopenharmony_ci  }
2371cb0ef41Sopenharmony_ci  if (input < 0.0) {
2381cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, std::numeric_limits<int64_t>::min());
2391cb0ef41Sopenharmony_ci    return;
2401cb0ef41Sopenharmony_ci  }
2411cb0ef41Sopenharmony_ci  WriteUnalignedValue<int64_t>(data, std::numeric_limits<int64_t>::max());
2421cb0ef41Sopenharmony_ci}
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_civoid float32_to_uint64_sat_wrapper(Address data) {
2451cb0ef41Sopenharmony_ci  float input = ReadUnalignedValue<float>(data);
2461cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<uint64_t>(input)) {
2471cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
2481cb0ef41Sopenharmony_ci    return;
2491cb0ef41Sopenharmony_ci  }
2501cb0ef41Sopenharmony_ci  if (input >= static_cast<float>(std::numeric_limits<uint64_t>::max())) {
2511cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, std::numeric_limits<uint64_t>::max());
2521cb0ef41Sopenharmony_ci    return;
2531cb0ef41Sopenharmony_ci  }
2541cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, 0);
2551cb0ef41Sopenharmony_ci}
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_civoid float64_to_int64_sat_wrapper(Address data) {
2581cb0ef41Sopenharmony_ci  double input = ReadUnalignedValue<double>(data);
2591cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<int64_t>(input)) {
2601cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
2611cb0ef41Sopenharmony_ci    return;
2621cb0ef41Sopenharmony_ci  }
2631cb0ef41Sopenharmony_ci  if (std::isnan(input)) {
2641cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, 0);
2651cb0ef41Sopenharmony_ci    return;
2661cb0ef41Sopenharmony_ci  }
2671cb0ef41Sopenharmony_ci  if (input < 0.0) {
2681cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, std::numeric_limits<int64_t>::min());
2691cb0ef41Sopenharmony_ci    return;
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci  WriteUnalignedValue<int64_t>(data, std::numeric_limits<int64_t>::max());
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_civoid float64_to_uint64_sat_wrapper(Address data) {
2751cb0ef41Sopenharmony_ci  double input = ReadUnalignedValue<double>(data);
2761cb0ef41Sopenharmony_ci  if (base::IsValueInRangeForNumericType<uint64_t>(input)) {
2771cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
2781cb0ef41Sopenharmony_ci    return;
2791cb0ef41Sopenharmony_ci  }
2801cb0ef41Sopenharmony_ci  if (input >= static_cast<double>(std::numeric_limits<uint64_t>::max())) {
2811cb0ef41Sopenharmony_ci    WriteUnalignedValue<uint64_t>(data, std::numeric_limits<uint64_t>::max());
2821cb0ef41Sopenharmony_ci    return;
2831cb0ef41Sopenharmony_ci  }
2841cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, 0);
2851cb0ef41Sopenharmony_ci}
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ciint32_t int64_div_wrapper(Address data) {
2881cb0ef41Sopenharmony_ci  int64_t dividend = ReadUnalignedValue<int64_t>(data);
2891cb0ef41Sopenharmony_ci  int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
2901cb0ef41Sopenharmony_ci  if (divisor == 0) {
2911cb0ef41Sopenharmony_ci    return 0;
2921cb0ef41Sopenharmony_ci  }
2931cb0ef41Sopenharmony_ci  if (divisor == -1 && dividend == std::numeric_limits<int64_t>::min()) {
2941cb0ef41Sopenharmony_ci    return -1;
2951cb0ef41Sopenharmony_ci  }
2961cb0ef41Sopenharmony_ci  WriteUnalignedValue<int64_t>(data, dividend / divisor);
2971cb0ef41Sopenharmony_ci  return 1;
2981cb0ef41Sopenharmony_ci}
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ciint32_t int64_mod_wrapper(Address data) {
3011cb0ef41Sopenharmony_ci  int64_t dividend = ReadUnalignedValue<int64_t>(data);
3021cb0ef41Sopenharmony_ci  int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
3031cb0ef41Sopenharmony_ci  if (divisor == 0) {
3041cb0ef41Sopenharmony_ci    return 0;
3051cb0ef41Sopenharmony_ci  }
3061cb0ef41Sopenharmony_ci  if (divisor == -1 && dividend == std::numeric_limits<int64_t>::min()) {
3071cb0ef41Sopenharmony_ci    WriteUnalignedValue<int64_t>(data, 0);
3081cb0ef41Sopenharmony_ci    return 1;
3091cb0ef41Sopenharmony_ci  }
3101cb0ef41Sopenharmony_ci  WriteUnalignedValue<int64_t>(data, dividend % divisor);
3111cb0ef41Sopenharmony_ci  return 1;
3121cb0ef41Sopenharmony_ci}
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ciint32_t uint64_div_wrapper(Address data) {
3151cb0ef41Sopenharmony_ci  uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
3161cb0ef41Sopenharmony_ci  uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
3171cb0ef41Sopenharmony_ci  if (divisor == 0) {
3181cb0ef41Sopenharmony_ci    return 0;
3191cb0ef41Sopenharmony_ci  }
3201cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, dividend / divisor);
3211cb0ef41Sopenharmony_ci  return 1;
3221cb0ef41Sopenharmony_ci}
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ciint32_t uint64_mod_wrapper(Address data) {
3251cb0ef41Sopenharmony_ci  uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
3261cb0ef41Sopenharmony_ci  uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
3271cb0ef41Sopenharmony_ci  if (divisor == 0) {
3281cb0ef41Sopenharmony_ci    return 0;
3291cb0ef41Sopenharmony_ci  }
3301cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, dividend % divisor);
3311cb0ef41Sopenharmony_ci  return 1;
3321cb0ef41Sopenharmony_ci}
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ciuint32_t word32_ctz_wrapper(Address data) {
3351cb0ef41Sopenharmony_ci  return base::bits::CountTrailingZeros(ReadUnalignedValue<uint32_t>(data));
3361cb0ef41Sopenharmony_ci}
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ciuint32_t word64_ctz_wrapper(Address data) {
3391cb0ef41Sopenharmony_ci  return base::bits::CountTrailingZeros(ReadUnalignedValue<uint64_t>(data));
3401cb0ef41Sopenharmony_ci}
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ciuint32_t word32_popcnt_wrapper(Address data) {
3431cb0ef41Sopenharmony_ci  return base::bits::CountPopulation(ReadUnalignedValue<uint32_t>(data));
3441cb0ef41Sopenharmony_ci}
3451cb0ef41Sopenharmony_ci
3461cb0ef41Sopenharmony_ciuint32_t word64_popcnt_wrapper(Address data) {
3471cb0ef41Sopenharmony_ci  return base::bits::CountPopulation(ReadUnalignedValue<uint64_t>(data));
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ciuint32_t word32_rol_wrapper(Address data) {
3511cb0ef41Sopenharmony_ci  uint32_t input = ReadUnalignedValue<uint32_t>(data);
3521cb0ef41Sopenharmony_ci  uint32_t shift = ReadUnalignedValue<uint32_t>(data + sizeof(input)) & 31;
3531cb0ef41Sopenharmony_ci  return (input << shift) | (input >> ((32 - shift) & 31));
3541cb0ef41Sopenharmony_ci}
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ciuint32_t word32_ror_wrapper(Address data) {
3571cb0ef41Sopenharmony_ci  uint32_t input = ReadUnalignedValue<uint32_t>(data);
3581cb0ef41Sopenharmony_ci  uint32_t shift = ReadUnalignedValue<uint32_t>(data + sizeof(input)) & 31;
3591cb0ef41Sopenharmony_ci  return (input >> shift) | (input << ((32 - shift) & 31));
3601cb0ef41Sopenharmony_ci}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_civoid word64_rol_wrapper(Address data) {
3631cb0ef41Sopenharmony_ci  uint64_t input = ReadUnalignedValue<uint64_t>(data);
3641cb0ef41Sopenharmony_ci  uint64_t shift = ReadUnalignedValue<uint64_t>(data + sizeof(input)) & 63;
3651cb0ef41Sopenharmony_ci  uint64_t result = (input << shift) | (input >> ((64 - shift) & 63));
3661cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, result);
3671cb0ef41Sopenharmony_ci}
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_civoid word64_ror_wrapper(Address data) {
3701cb0ef41Sopenharmony_ci  uint64_t input = ReadUnalignedValue<uint64_t>(data);
3711cb0ef41Sopenharmony_ci  uint64_t shift = ReadUnalignedValue<uint64_t>(data + sizeof(input)) & 63;
3721cb0ef41Sopenharmony_ci  uint64_t result = (input >> shift) | (input << ((64 - shift) & 63));
3731cb0ef41Sopenharmony_ci  WriteUnalignedValue<uint64_t>(data, result);
3741cb0ef41Sopenharmony_ci}
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_civoid float64_pow_wrapper(Address data) {
3771cb0ef41Sopenharmony_ci  double x = ReadUnalignedValue<double>(data);
3781cb0ef41Sopenharmony_ci  double y = ReadUnalignedValue<double>(data + sizeof(x));
3791cb0ef41Sopenharmony_ci  WriteUnalignedValue<double>(data, base::ieee754::pow(x, y));
3801cb0ef41Sopenharmony_ci}
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_citemplate <typename T, T (*float_round_op)(T)>
3831cb0ef41Sopenharmony_civoid simd_float_round_wrapper(Address data) {
3841cb0ef41Sopenharmony_ci  constexpr int n = kSimd128Size / sizeof(T);
3851cb0ef41Sopenharmony_ci  for (int i = 0; i < n; i++) {
3861cb0ef41Sopenharmony_ci    T input = ReadUnalignedValue<T>(data + (i * sizeof(T)));
3871cb0ef41Sopenharmony_ci    T value = float_round_op(input);
3881cb0ef41Sopenharmony_ci#if V8_OS_AIX
3891cb0ef41Sopenharmony_ci    value = FpOpWorkaround<T>(input, value);
3901cb0ef41Sopenharmony_ci#endif
3911cb0ef41Sopenharmony_ci    WriteUnalignedValue<T>(data + (i * sizeof(T)), value);
3921cb0ef41Sopenharmony_ci  }
3931cb0ef41Sopenharmony_ci}
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_civoid f64x2_ceil_wrapper(Address data) {
3961cb0ef41Sopenharmony_ci  simd_float_round_wrapper<double, &ceil>(data);
3971cb0ef41Sopenharmony_ci}
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_civoid f64x2_floor_wrapper(Address data) {
4001cb0ef41Sopenharmony_ci  simd_float_round_wrapper<double, &floor>(data);
4011cb0ef41Sopenharmony_ci}
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_civoid f64x2_trunc_wrapper(Address data) {
4041cb0ef41Sopenharmony_ci  simd_float_round_wrapper<double, &trunc>(data);
4051cb0ef41Sopenharmony_ci}
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_civoid f64x2_nearest_int_wrapper(Address data) {
4081cb0ef41Sopenharmony_ci  simd_float_round_wrapper<double, &nearbyint>(data);
4091cb0ef41Sopenharmony_ci}
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_civoid f32x4_ceil_wrapper(Address data) {
4121cb0ef41Sopenharmony_ci  simd_float_round_wrapper<float, &ceilf>(data);
4131cb0ef41Sopenharmony_ci}
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_civoid f32x4_floor_wrapper(Address data) {
4161cb0ef41Sopenharmony_ci  simd_float_round_wrapper<float, &floorf>(data);
4171cb0ef41Sopenharmony_ci}
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_civoid f32x4_trunc_wrapper(Address data) {
4201cb0ef41Sopenharmony_ci  simd_float_round_wrapper<float, &truncf>(data);
4211cb0ef41Sopenharmony_ci}
4221cb0ef41Sopenharmony_ci
4231cb0ef41Sopenharmony_civoid f32x4_nearest_int_wrapper(Address data) {
4241cb0ef41Sopenharmony_ci  simd_float_round_wrapper<float, &nearbyintf>(data);
4251cb0ef41Sopenharmony_ci}
4261cb0ef41Sopenharmony_ci
4271cb0ef41Sopenharmony_cinamespace {
4281cb0ef41Sopenharmony_ciclass V8_NODISCARD ThreadNotInWasmScope {
4291cb0ef41Sopenharmony_ci// Asan on Windows triggers exceptions to allocate shadow memory lazily. When
4301cb0ef41Sopenharmony_ci// this function is called from WebAssembly, these exceptions would be handled
4311cb0ef41Sopenharmony_ci// by the trap handler before they get handled by Asan, and thereby confuse the
4321cb0ef41Sopenharmony_ci// thread-in-wasm flag. Therefore we disable ASAN for this function.
4331cb0ef41Sopenharmony_ci// Alternatively we could reset the thread-in-wasm flag before calling this
4341cb0ef41Sopenharmony_ci// function. However, as this is only a problem with Asan on Windows, we did not
4351cb0ef41Sopenharmony_ci// consider it worth the overhead.
4361cb0ef41Sopenharmony_ci#if defined(RESET_THREAD_IN_WASM_FLAG_FOR_ASAN_ON_WINDOWS)
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci public:
4391cb0ef41Sopenharmony_ci  ThreadNotInWasmScope() : thread_was_in_wasm_(trap_handler::IsThreadInWasm()) {
4401cb0ef41Sopenharmony_ci    if (thread_was_in_wasm_) {
4411cb0ef41Sopenharmony_ci      trap_handler::ClearThreadInWasm();
4421cb0ef41Sopenharmony_ci    }
4431cb0ef41Sopenharmony_ci  }
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ci  ~ThreadNotInWasmScope() {
4461cb0ef41Sopenharmony_ci    if (thread_was_in_wasm_) {
4471cb0ef41Sopenharmony_ci      trap_handler::SetThreadInWasm();
4481cb0ef41Sopenharmony_ci    }
4491cb0ef41Sopenharmony_ci  }
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci private:
4521cb0ef41Sopenharmony_ci  bool thread_was_in_wasm_;
4531cb0ef41Sopenharmony_ci#else
4541cb0ef41Sopenharmony_ci
4551cb0ef41Sopenharmony_ci public:
4561cb0ef41Sopenharmony_ci  ThreadNotInWasmScope() {
4571cb0ef41Sopenharmony_ci    // This is needed to avoid compilation errors (unused variable).
4581cb0ef41Sopenharmony_ci    USE(this);
4591cb0ef41Sopenharmony_ci  }
4601cb0ef41Sopenharmony_ci#endif
4611cb0ef41Sopenharmony_ci};
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ciinline byte* EffectiveAddress(WasmInstanceObject instance, uintptr_t index) {
4641cb0ef41Sopenharmony_ci  return instance.memory_start() + index;
4651cb0ef41Sopenharmony_ci}
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_citemplate <typename V>
4681cb0ef41Sopenharmony_ciV ReadAndIncrementOffset(Address data, size_t* offset) {
4691cb0ef41Sopenharmony_ci  V result = ReadUnalignedValue<V>(data + *offset);
4701cb0ef41Sopenharmony_ci  *offset += sizeof(V);
4711cb0ef41Sopenharmony_ci  return result;
4721cb0ef41Sopenharmony_ci}
4731cb0ef41Sopenharmony_ci
4741cb0ef41Sopenharmony_ciconstexpr int32_t kSuccess = 1;
4751cb0ef41Sopenharmony_ciconstexpr int32_t kOutOfBounds = 0;
4761cb0ef41Sopenharmony_ci}  // namespace
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ciint32_t memory_init_wrapper(Address data) {
4791cb0ef41Sopenharmony_ci  ThreadNotInWasmScope thread_not_in_wasm_scope;
4801cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
4811cb0ef41Sopenharmony_ci  size_t offset = 0;
4821cb0ef41Sopenharmony_ci  Object raw_instance = ReadAndIncrementOffset<Object>(data, &offset);
4831cb0ef41Sopenharmony_ci  WasmInstanceObject instance = WasmInstanceObject::cast(raw_instance);
4841cb0ef41Sopenharmony_ci  uintptr_t dst = ReadAndIncrementOffset<uintptr_t>(data, &offset);
4851cb0ef41Sopenharmony_ci  uint32_t src = ReadAndIncrementOffset<uint32_t>(data, &offset);
4861cb0ef41Sopenharmony_ci  uint32_t seg_index = ReadAndIncrementOffset<uint32_t>(data, &offset);
4871cb0ef41Sopenharmony_ci  uint32_t size = ReadAndIncrementOffset<uint32_t>(data, &offset);
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  uint64_t mem_size = instance.memory_size();
4901cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint64_t>(dst, size, mem_size)) return kOutOfBounds;
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_ci  uint32_t seg_size = instance.data_segment_sizes()[seg_index];
4931cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint32_t>(src, size, seg_size)) return kOutOfBounds;
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci  byte* seg_start =
4961cb0ef41Sopenharmony_ci      reinterpret_cast<byte*>(instance.data_segment_starts()[seg_index]);
4971cb0ef41Sopenharmony_ci  std::memcpy(EffectiveAddress(instance, dst), seg_start + src, size);
4981cb0ef41Sopenharmony_ci  return kSuccess;
4991cb0ef41Sopenharmony_ci}
5001cb0ef41Sopenharmony_ci
5011cb0ef41Sopenharmony_ciint32_t memory_copy_wrapper(Address data) {
5021cb0ef41Sopenharmony_ci  ThreadNotInWasmScope thread_not_in_wasm_scope;
5031cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
5041cb0ef41Sopenharmony_ci  size_t offset = 0;
5051cb0ef41Sopenharmony_ci  Object raw_instance = ReadAndIncrementOffset<Object>(data, &offset);
5061cb0ef41Sopenharmony_ci  WasmInstanceObject instance = WasmInstanceObject::cast(raw_instance);
5071cb0ef41Sopenharmony_ci  uintptr_t dst = ReadAndIncrementOffset<uintptr_t>(data, &offset);
5081cb0ef41Sopenharmony_ci  uintptr_t src = ReadAndIncrementOffset<uintptr_t>(data, &offset);
5091cb0ef41Sopenharmony_ci  uintptr_t size = ReadAndIncrementOffset<uintptr_t>(data, &offset);
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_ci  uint64_t mem_size = instance.memory_size();
5121cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint64_t>(dst, size, mem_size)) return kOutOfBounds;
5131cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint64_t>(src, size, mem_size)) return kOutOfBounds;
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci  // Use std::memmove, because the ranges can overlap.
5161cb0ef41Sopenharmony_ci  std::memmove(EffectiveAddress(instance, dst), EffectiveAddress(instance, src),
5171cb0ef41Sopenharmony_ci               size);
5181cb0ef41Sopenharmony_ci  return kSuccess;
5191cb0ef41Sopenharmony_ci}
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ciint32_t memory_fill_wrapper(Address data) {
5221cb0ef41Sopenharmony_ci  ThreadNotInWasmScope thread_not_in_wasm_scope;
5231cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci  size_t offset = 0;
5261cb0ef41Sopenharmony_ci  Object raw_instance = ReadAndIncrementOffset<Object>(data, &offset);
5271cb0ef41Sopenharmony_ci  WasmInstanceObject instance = WasmInstanceObject::cast(raw_instance);
5281cb0ef41Sopenharmony_ci  uintptr_t dst = ReadAndIncrementOffset<uintptr_t>(data, &offset);
5291cb0ef41Sopenharmony_ci  uint8_t value =
5301cb0ef41Sopenharmony_ci      static_cast<uint8_t>(ReadAndIncrementOffset<uint32_t>(data, &offset));
5311cb0ef41Sopenharmony_ci  uintptr_t size = ReadAndIncrementOffset<uintptr_t>(data, &offset);
5321cb0ef41Sopenharmony_ci
5331cb0ef41Sopenharmony_ci  uint64_t mem_size = instance.memory_size();
5341cb0ef41Sopenharmony_ci  if (!base::IsInBounds<uint64_t>(dst, size, mem_size)) return kOutOfBounds;
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ci  std::memset(EffectiveAddress(instance, dst), value, size);
5371cb0ef41Sopenharmony_ci  return kSuccess;
5381cb0ef41Sopenharmony_ci}
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_cinamespace {
5411cb0ef41Sopenharmony_ciinline void* ArrayElementAddress(WasmArray array, uint32_t index,
5421cb0ef41Sopenharmony_ci                                 int element_size_bytes) {
5431cb0ef41Sopenharmony_ci  return reinterpret_cast<void*>(array.ptr() + WasmArray::kHeaderSize -
5441cb0ef41Sopenharmony_ci                                 kHeapObjectTag + index * element_size_bytes);
5451cb0ef41Sopenharmony_ci}
5461cb0ef41Sopenharmony_ci}  // namespace
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_civoid array_copy_wrapper(Address raw_instance, Address raw_dst_array,
5491cb0ef41Sopenharmony_ci                        uint32_t dst_index, Address raw_src_array,
5501cb0ef41Sopenharmony_ci                        uint32_t src_index, uint32_t length) {
5511cb0ef41Sopenharmony_ci  DCHECK_GT(length, 0);
5521cb0ef41Sopenharmony_ci  ThreadNotInWasmScope thread_not_in_wasm_scope;
5531cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
5541cb0ef41Sopenharmony_ci  WasmArray dst_array = WasmArray::cast(Object(raw_dst_array));
5551cb0ef41Sopenharmony_ci  WasmArray src_array = WasmArray::cast(Object(raw_src_array));
5561cb0ef41Sopenharmony_ci
5571cb0ef41Sopenharmony_ci  bool overlapping_ranges =
5581cb0ef41Sopenharmony_ci      dst_array.ptr() == src_array.ptr() &&
5591cb0ef41Sopenharmony_ci      (dst_index < src_index ? dst_index + length > src_index
5601cb0ef41Sopenharmony_ci                             : src_index + length > dst_index);
5611cb0ef41Sopenharmony_ci  wasm::ValueType element_type = src_array.type()->element_type();
5621cb0ef41Sopenharmony_ci  if (element_type.is_reference()) {
5631cb0ef41Sopenharmony_ci    WasmInstanceObject instance =
5641cb0ef41Sopenharmony_ci        WasmInstanceObject::cast(Object(raw_instance));
5651cb0ef41Sopenharmony_ci    Isolate* isolate = Isolate::FromRootAddress(instance.isolate_root());
5661cb0ef41Sopenharmony_ci    ObjectSlot dst_slot = dst_array.ElementSlot(dst_index);
5671cb0ef41Sopenharmony_ci    ObjectSlot src_slot = src_array.ElementSlot(src_index);
5681cb0ef41Sopenharmony_ci    if (overlapping_ranges) {
5691cb0ef41Sopenharmony_ci      isolate->heap()->MoveRange(dst_array, dst_slot, src_slot, length,
5701cb0ef41Sopenharmony_ci                                 UPDATE_WRITE_BARRIER);
5711cb0ef41Sopenharmony_ci    } else {
5721cb0ef41Sopenharmony_ci      isolate->heap()->CopyRange(dst_array, dst_slot, src_slot, length,
5731cb0ef41Sopenharmony_ci                                 UPDATE_WRITE_BARRIER);
5741cb0ef41Sopenharmony_ci    }
5751cb0ef41Sopenharmony_ci  } else {
5761cb0ef41Sopenharmony_ci    int element_size_bytes = element_type.value_kind_size();
5771cb0ef41Sopenharmony_ci    void* dst = ArrayElementAddress(dst_array, dst_index, element_size_bytes);
5781cb0ef41Sopenharmony_ci    void* src = ArrayElementAddress(src_array, src_index, element_size_bytes);
5791cb0ef41Sopenharmony_ci    size_t copy_size = length * element_size_bytes;
5801cb0ef41Sopenharmony_ci    if (overlapping_ranges) {
5811cb0ef41Sopenharmony_ci      MemMove(dst, src, copy_size);
5821cb0ef41Sopenharmony_ci    } else {
5831cb0ef41Sopenharmony_ci      MemCopy(dst, src, copy_size);
5841cb0ef41Sopenharmony_ci    }
5851cb0ef41Sopenharmony_ci  }
5861cb0ef41Sopenharmony_ci}
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_cistatic WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr;
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_civoid set_trap_callback_for_testing(WasmTrapCallbackForTesting callback) {
5911cb0ef41Sopenharmony_ci  wasm_trap_callback_for_testing = callback;
5921cb0ef41Sopenharmony_ci}
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_civoid call_trap_callback_for_testing() {
5951cb0ef41Sopenharmony_ci  if (wasm_trap_callback_for_testing) {
5961cb0ef41Sopenharmony_ci    wasm_trap_callback_for_testing();
5971cb0ef41Sopenharmony_ci  }
5981cb0ef41Sopenharmony_ci}
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci}  // namespace wasm
6011cb0ef41Sopenharmony_ci}  // namespace internal
6021cb0ef41Sopenharmony_ci}  // namespace v8
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci#undef V8_WITH_SANITIZER
6051cb0ef41Sopenharmony_ci#undef RESET_THREAD_IN_WASM_FLAG_FOR_ASAN_ON_WINDOWS
606