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