LCOV - code coverage report
Current view: top level - src/wasm - wasm-external-refs.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 79 79 100.0 %
Date: 2017-04-26 Functions: 27 27 100.0 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <math.h>
       6             : #include <stdint.h>
       7             : #include <stdlib.h>
       8             : #include <limits>
       9             : 
      10             : #include "include/v8config.h"
      11             : 
      12             : #include "src/base/bits.h"
      13             : #include "src/utils.h"
      14             : #include "src/wasm/wasm-external-refs.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace wasm {
      19             : 
      20          14 : void f32_trunc_wrapper(float* param) { *param = truncf(*param); }
      21             : 
      22          14 : void f32_floor_wrapper(float* param) { *param = floorf(*param); }
      23             : 
      24          14 : void f32_ceil_wrapper(float* param) { *param = ceilf(*param); }
      25             : 
      26          14 : void f32_nearest_int_wrapper(float* param) { *param = nearbyintf(*param); }
      27             : 
      28          14 : void f64_trunc_wrapper(double* param) {
      29          14 :   WriteDoubleValue(param, trunc(ReadDoubleValue(param)));
      30          14 : }
      31             : 
      32          14 : void f64_floor_wrapper(double* param) {
      33          14 :   WriteDoubleValue(param, floor(ReadDoubleValue(param)));
      34          14 : }
      35             : 
      36          14 : void f64_ceil_wrapper(double* param) {
      37          14 :   WriteDoubleValue(param, ceil(ReadDoubleValue(param)));
      38          14 : }
      39             : 
      40          14 : void f64_nearest_int_wrapper(double* param) {
      41          14 :   WriteDoubleValue(param, nearbyint(ReadDoubleValue(param)));
      42          14 : }
      43             : 
      44         553 : void int64_to_float32_wrapper(int64_t* input, float* output) {
      45         553 :   *output = static_cast<float>(*input);
      46         553 : }
      47             : 
      48         546 : void uint64_to_float32_wrapper(uint64_t* input, float* output) {
      49             : #if V8_CC_MSVC
      50             :   // With MSVC we use static_cast<float>(uint32_t) instead of
      51             :   // static_cast<float>(uint64_t) to achieve round-to-nearest-ties-even
      52             :   // semantics. The idea is to calculate
      53             :   // static_cast<float>(high_word) * 2^32 + static_cast<float>(low_word). To
      54             :   // achieve proper rounding in all cases we have to adjust the high_word
      55             :   // with a "rounding bit" sometimes. The rounding bit is stored in the LSB of
      56             :   // the high_word if the low_word may affect the rounding of the high_word.
      57             :   uint32_t low_word = static_cast<uint32_t>(*input & 0xffffffff);
      58             :   uint32_t high_word = static_cast<uint32_t>(*input >> 32);
      59             : 
      60             :   float shift = static_cast<float>(1ull << 32);
      61             :   // If the MSB of the high_word is set, then we make space for a rounding bit.
      62             :   if (high_word < 0x80000000) {
      63             :     high_word <<= 1;
      64             :     shift = static_cast<float>(1ull << 31);
      65             :   }
      66             : 
      67             :   if ((high_word & 0xfe000000) && low_word) {
      68             :     // Set the rounding bit.
      69             :     high_word |= 1;
      70             :   }
      71             : 
      72             :   float result = static_cast<float>(high_word);
      73             :   result *= shift;
      74             :   result += static_cast<float>(low_word);
      75             :   *output = result;
      76             : 
      77             : #else
      78         546 :   *output = static_cast<float>(*input);
      79             : #endif
      80         546 : }
      81             : 
      82       23690 : void int64_to_float64_wrapper(int64_t* input, double* output) {
      83       23690 :   *output = static_cast<double>(*input);
      84       23690 : }
      85             : 
      86         539 : void uint64_to_float64_wrapper(uint64_t* input, double* output) {
      87             : #if V8_CC_MSVC
      88             :   // With MSVC we use static_cast<double>(uint32_t) instead of
      89             :   // static_cast<double>(uint64_t) to achieve round-to-nearest-ties-even
      90             :   // semantics. The idea is to calculate
      91             :   // static_cast<double>(high_word) * 2^32 + static_cast<double>(low_word).
      92             :   uint32_t low_word = static_cast<uint32_t>(*input & 0xffffffff);
      93             :   uint32_t high_word = static_cast<uint32_t>(*input >> 32);
      94             : 
      95             :   double shift = static_cast<double>(1ull << 32);
      96             : 
      97             :   double result = static_cast<double>(high_word);
      98             :   result *= shift;
      99             :   result += static_cast<double>(low_word);
     100             :   *output = result;
     101             : 
     102             : #else
     103         539 :   *output = static_cast<double>(*input);
     104             : #endif
     105         539 : }
     106             : 
     107        1624 : int32_t float32_to_int64_wrapper(float* input, int64_t* output) {
     108             :   // We use "<" here to check the upper bound because of rounding problems: With
     109             :   // "<=" some inputs would be considered within int64 range which are actually
     110             :   // not within int64 range.
     111        1624 :   if (*input >= static_cast<float>(std::numeric_limits<int64_t>::min()) &&
     112             :       *input < static_cast<float>(std::numeric_limits<int64_t>::max())) {
     113        1176 :     *output = static_cast<int64_t>(*input);
     114        1176 :     return 1;
     115             :   }
     116             :   return 0;
     117             : }
     118             : 
     119        1624 : int32_t float32_to_uint64_wrapper(float* input, uint64_t* output) {
     120             :   // We use "<" here to check the upper bound because of rounding problems: With
     121             :   // "<=" some inputs would be considered within uint64 range which are actually
     122             :   // not within uint64 range.
     123        1624 :   if (*input > -1.0 &&
     124             :       *input < static_cast<float>(std::numeric_limits<uint64_t>::max())) {
     125         728 :     *output = static_cast<uint64_t>(*input);
     126         728 :     return 1;
     127             :   }
     128             :   return 0;
     129             : }
     130             : 
     131        1254 : int32_t float64_to_int64_wrapper(double* input, int64_t* output) {
     132             :   // We use "<" here to check the upper bound because of rounding problems: With
     133             :   // "<=" some inputs would be considered within int64 range which are actually
     134             :   // not within int64 range.
     135        1254 :   if (*input >= static_cast<double>(std::numeric_limits<int64_t>::min()) &&
     136             :       *input < static_cast<double>(std::numeric_limits<int64_t>::max())) {
     137        1100 :     *output = static_cast<int64_t>(*input);
     138        1100 :     return 1;
     139             :   }
     140             :   return 0;
     141             : }
     142             : 
     143         700 : int32_t float64_to_uint64_wrapper(double* input, uint64_t* output) {
     144             :   // We use "<" here to check the upper bound because of rounding problems: With
     145             :   // "<=" some inputs would be considered within uint64 range which are actually
     146             :   // not within uint64 range.
     147         700 :   if (*input > -1.0 &&
     148             :       *input < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
     149         420 :     *output = static_cast<uint64_t>(*input);
     150         420 :     return 1;
     151             :   }
     152             :   return 0;
     153             : }
     154             : 
     155          14 : int32_t int64_div_wrapper(int64_t* dst, int64_t* src) {
     156          14 :   if (*src == 0) {
     157             :     return 0;
     158             :   }
     159          14 :   if (*src == -1 && *dst == std::numeric_limits<int64_t>::min()) {
     160             :     return -1;
     161             :   }
     162          14 :   *dst /= *src;
     163          14 :   return 1;
     164             : }
     165             : 
     166          14 : int32_t int64_mod_wrapper(int64_t* dst, int64_t* src) {
     167          14 :   if (*src == 0) {
     168             :     return 0;
     169             :   }
     170          14 :   *dst %= *src;
     171          14 :   return 1;
     172             : }
     173             : 
     174          14 : int32_t uint64_div_wrapper(uint64_t* dst, uint64_t* src) {
     175          14 :   if (*src == 0) {
     176             :     return 0;
     177             :   }
     178          14 :   *dst /= *src;
     179          14 :   return 1;
     180             : }
     181             : 
     182          14 : int32_t uint64_mod_wrapper(uint64_t* dst, uint64_t* src) {
     183          14 :   if (*src == 0) {
     184             :     return 0;
     185             :   }
     186          14 :   *dst %= *src;
     187          14 :   return 1;
     188             : }
     189             : 
     190          14 : uint32_t word32_ctz_wrapper(uint32_t* input) {
     191          28 :   return static_cast<uint32_t>(base::bits::CountTrailingZeros32(*input));
     192             : }
     193             : 
     194          14 : uint32_t word64_ctz_wrapper(uint64_t* input) {
     195          28 :   return static_cast<uint32_t>(base::bits::CountTrailingZeros64(*input));
     196             : }
     197             : 
     198          84 : uint32_t word32_popcnt_wrapper(uint32_t* input) {
     199         168 :   return static_cast<uint32_t>(base::bits::CountPopulation(*input));
     200             : }
     201             : 
     202          84 : uint32_t word64_popcnt_wrapper(uint64_t* input) {
     203         168 :   return static_cast<uint32_t>(base::bits::CountPopulation(*input));
     204             : }
     205             : 
     206          74 : void float64_pow_wrapper(double* param0, double* param1) {
     207             :   double x = ReadDoubleValue(param0);
     208             :   double y = ReadDoubleValue(param1);
     209          74 :   WriteDoubleValue(param0, Pow(x, y));
     210          74 : }
     211             : 
     212             : static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr;
     213             : 
     214     2936972 : void set_trap_callback_for_testing(WasmTrapCallbackForTesting callback) {
     215     2936972 :   wasm_trap_callback_for_testing = callback;
     216     2936972 : }
     217             : 
     218       12572 : void call_trap_callback_for_testing() {
     219       12572 :   if (wasm_trap_callback_for_testing) {
     220       12572 :     wasm_trap_callback_for_testing();
     221             :   }
     222       12572 : }
     223             : 
     224             : }  // namespace wasm
     225             : }  // namespace internal
     226             : }  // namespace v8

Generated by: LCOV version 1.10