LCOV - code coverage report
Current view: top level - src/wasm - wasm-external-refs.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 81 81 100.0 %
Date: 2017-10-20 Functions: 29 29 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/trap-handler/trap-handler.h"
      14             : #include "src/utils.h"
      15             : #include "src/wasm/wasm-external-refs.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace wasm {
      20             : 
      21          12 : void f32_trunc_wrapper(float* param) { *param = truncf(*param); }
      22             : 
      23          12 : void f32_floor_wrapper(float* param) { *param = floorf(*param); }
      24             : 
      25          12 : void f32_ceil_wrapper(float* param) { *param = ceilf(*param); }
      26             : 
      27          12 : void f32_nearest_int_wrapper(float* param) { *param = nearbyintf(*param); }
      28             : 
      29          12 : void f64_trunc_wrapper(double* param) {
      30          12 :   WriteDoubleValue(param, trunc(ReadDoubleValue(param)));
      31          12 : }
      32             : 
      33          12 : void f64_floor_wrapper(double* param) {
      34          12 :   WriteDoubleValue(param, floor(ReadDoubleValue(param)));
      35          12 : }
      36             : 
      37          12 : void f64_ceil_wrapper(double* param) {
      38          12 :   WriteDoubleValue(param, ceil(ReadDoubleValue(param)));
      39          12 : }
      40             : 
      41          12 : void f64_nearest_int_wrapper(double* param) {
      42          12 :   WriteDoubleValue(param, nearbyint(ReadDoubleValue(param)));
      43          12 : }
      44             : 
      45         498 : void int64_to_float32_wrapper(int64_t* input, float* output) {
      46         498 :   *output = static_cast<float>(ReadUnalignedValue<int64_t>(input));
      47         498 : }
      48             : 
      49         468 : void uint64_to_float32_wrapper(uint64_t* input, float* output) {
      50             : #if V8_CC_MSVC
      51             :   // With MSVC we use static_cast<float>(uint32_t) instead of
      52             :   // static_cast<float>(uint64_t) to achieve round-to-nearest-ties-even
      53             :   // semantics. The idea is to calculate
      54             :   // static_cast<float>(high_word) * 2^32 + static_cast<float>(low_word). To
      55             :   // achieve proper rounding in all cases we have to adjust the high_word
      56             :   // with a "rounding bit" sometimes. The rounding bit is stored in the LSB of
      57             :   // the high_word if the low_word may affect the rounding of the high_word.
      58             :   uint32_t low_word = static_cast<uint32_t>(*input & 0xffffffff);
      59             :   uint32_t high_word = static_cast<uint32_t>(*input >> 32);
      60             : 
      61             :   float shift = static_cast<float>(1ull << 32);
      62             :   // If the MSB of the high_word is set, then we make space for a rounding bit.
      63             :   if (high_word < 0x80000000) {
      64             :     high_word <<= 1;
      65             :     shift = static_cast<float>(1ull << 31);
      66             :   }
      67             : 
      68             :   if ((high_word & 0xfe000000) && low_word) {
      69             :     // Set the rounding bit.
      70             :     high_word |= 1;
      71             :   }
      72             : 
      73             :   float result = static_cast<float>(high_word);
      74             :   result *= shift;
      75             :   result += static_cast<float>(low_word);
      76             :   *output = result;
      77             : 
      78             : #else
      79         468 :   *output = static_cast<float>(ReadUnalignedValue<uint64_t>(input));
      80             : #endif
      81         468 : }
      82             : 
      83       23060 : void int64_to_float64_wrapper(int64_t* input, double* output) {
      84             :   WriteDoubleValue(output,
      85       23060 :                    static_cast<double>(ReadUnalignedValue<int64_t>(input)));
      86       23060 : }
      87             : 
      88         462 : void uint64_to_float64_wrapper(uint64_t* input, double* output) {
      89             : #if V8_CC_MSVC
      90             :   // With MSVC we use static_cast<double>(uint32_t) instead of
      91             :   // static_cast<double>(uint64_t) to achieve round-to-nearest-ties-even
      92             :   // semantics. The idea is to calculate
      93             :   // static_cast<double>(high_word) * 2^32 + static_cast<double>(low_word).
      94             :   uint32_t low_word = static_cast<uint32_t>(*input & 0xffffffff);
      95             :   uint32_t high_word = static_cast<uint32_t>(*input >> 32);
      96             : 
      97             :   double shift = static_cast<double>(1ull << 32);
      98             : 
      99             :   double result = static_cast<double>(high_word);
     100             :   result *= shift;
     101             :   result += static_cast<double>(low_word);
     102             :   *output = result;
     103             : 
     104             : #else
     105             :   WriteDoubleValue(output,
     106         462 :                    static_cast<double>(ReadUnalignedValue<uint64_t>(input)));
     107             : #endif
     108         462 : }
     109             : 
     110        1392 : int32_t float32_to_int64_wrapper(float* input, int64_t* output) {
     111             :   // We use "<" here to check the upper bound because of rounding problems: With
     112             :   // "<=" some inputs would be considered within int64 range which are actually
     113             :   // not within int64 range.
     114        1392 :   if (*input >= static_cast<float>(std::numeric_limits<int64_t>::min()) &&
     115             :       *input < static_cast<float>(std::numeric_limits<int64_t>::max())) {
     116        1008 :     WriteUnalignedValue<int64_t>(output, static_cast<int64_t>(*input));
     117        1008 :     return 1;
     118             :   }
     119             :   return 0;
     120             : }
     121             : 
     122        1392 : int32_t float32_to_uint64_wrapper(float* input, uint64_t* output) {
     123             :   // We use "<" here to check the upper bound because of rounding problems: With
     124             :   // "<=" some inputs would be considered within uint64 range which are actually
     125             :   // not within uint64 range.
     126        1392 :   if (*input > -1.0 &&
     127             :       *input < static_cast<float>(std::numeric_limits<uint64_t>::max())) {
     128         624 :     WriteUnalignedValue<uint64_t>(output, static_cast<uint64_t>(*input));
     129         624 :     return 1;
     130             :   }
     131             :   return 0;
     132             : }
     133             : 
     134        1096 : int32_t float64_to_int64_wrapper(double* input, int64_t* output) {
     135             :   // We use "<" here to check the upper bound because of rounding problems: With
     136             :   // "<=" some inputs would be considered within int64 range which are actually
     137             :   // not within int64 range.
     138             :   double input_val = ReadDoubleValue(input);
     139        1096 :   if (input_val >= static_cast<double>(std::numeric_limits<int64_t>::min()) &&
     140             :       input_val < static_cast<double>(std::numeric_limits<int64_t>::max())) {
     141         964 :     WriteUnalignedValue<int64_t>(output, static_cast<int64_t>(input_val));
     142         964 :     return 1;
     143             :   }
     144             :   return 0;
     145             : }
     146             : 
     147         600 : int32_t float64_to_uint64_wrapper(double* input, uint64_t* output) {
     148             :   // We use "<" here to check the upper bound because of rounding problems: With
     149             :   // "<=" some inputs would be considered within uint64 range which are actually
     150             :   // not within uint64 range.
     151             :   double input_val = ReadDoubleValue(input);
     152         600 :   if (input_val > -1.0 &&
     153             :       input_val < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
     154         360 :     WriteUnalignedValue<uint64_t>(output, static_cast<uint64_t>(input_val));
     155         360 :     return 1;
     156             :   }
     157             :   return 0;
     158             : }
     159             : 
     160          12 : int32_t int64_div_wrapper(int64_t* dst, int64_t* src) {
     161             :   int64_t src_val = ReadUnalignedValue<int64_t>(src);
     162             :   int64_t dst_val = ReadUnalignedValue<int64_t>(dst);
     163          12 :   if (src_val == 0) {
     164             :     return 0;
     165             :   }
     166          12 :   if (src_val == -1 && dst_val == std::numeric_limits<int64_t>::min()) {
     167             :     return -1;
     168             :   }
     169          12 :   WriteUnalignedValue<int64_t>(dst, dst_val / src_val);
     170          12 :   return 1;
     171             : }
     172             : 
     173          12 : int32_t int64_mod_wrapper(int64_t* dst, int64_t* src) {
     174             :   int64_t src_val = ReadUnalignedValue<int64_t>(src);
     175             :   int64_t dst_val = ReadUnalignedValue<int64_t>(dst);
     176          12 :   if (src_val == 0) {
     177             :     return 0;
     178             :   }
     179          12 :   WriteUnalignedValue<int64_t>(dst, dst_val % src_val);
     180          12 :   return 1;
     181             : }
     182             : 
     183          12 : int32_t uint64_div_wrapper(uint64_t* dst, uint64_t* src) {
     184             :   uint64_t src_val = ReadUnalignedValue<uint64_t>(src);
     185             :   uint64_t dst_val = ReadUnalignedValue<uint64_t>(dst);
     186          12 :   if (src_val == 0) {
     187             :     return 0;
     188             :   }
     189          12 :   WriteUnalignedValue<uint64_t>(dst, dst_val / src_val);
     190          12 :   return 1;
     191             : }
     192             : 
     193          12 : int32_t uint64_mod_wrapper(uint64_t* dst, uint64_t* src) {
     194             :   uint64_t src_val = ReadUnalignedValue<uint64_t>(src);
     195             :   uint64_t dst_val = ReadUnalignedValue<uint64_t>(dst);
     196          12 :   if (src_val == 0) {
     197             :     return 0;
     198             :   }
     199          12 :   WriteUnalignedValue<uint64_t>(dst, dst_val % src_val);
     200          12 :   return 1;
     201             : }
     202             : 
     203          12 : uint32_t word32_ctz_wrapper(uint32_t* input) {
     204          24 :   return static_cast<uint32_t>(base::bits::CountTrailingZeros32(*input));
     205             : }
     206             : 
     207          12 : uint32_t word64_ctz_wrapper(uint64_t* input) {
     208             :   return static_cast<uint32_t>(
     209          12 :       base::bits::CountTrailingZeros64(ReadUnalignedValue<uint64_t>(input)));
     210             : }
     211             : 
     212          72 : uint32_t word32_popcnt_wrapper(uint32_t* input) {
     213         144 :   return static_cast<uint32_t>(base::bits::CountPopulation(*input));
     214             : }
     215             : 
     216          72 : uint32_t word64_popcnt_wrapper(uint64_t* input) {
     217             :   return static_cast<uint32_t>(
     218          72 :       base::bits::CountPopulation(ReadUnalignedValue<uint64_t>(input)));
     219             : }
     220             : 
     221          55 : void float64_pow_wrapper(double* param0, double* param1) {
     222             :   double x = ReadDoubleValue(param0);
     223             :   double y = ReadDoubleValue(param1);
     224          55 :   WriteDoubleValue(param0, Pow(x, y));
     225          55 : }
     226             : 
     227    11134070 : void set_thread_in_wasm_flag() { trap_handler::SetThreadInWasm(); }
     228             : 
     229    11126208 : void clear_thread_in_wasm_flag() { trap_handler::ClearThreadInWasm(); }
     230             : 
     231             : static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr;
     232             : 
     233     3526351 : void set_trap_callback_for_testing(WasmTrapCallbackForTesting callback) {
     234     3526351 :   wasm_trap_callback_for_testing = callback;
     235     3526351 : }
     236             : 
     237       10869 : void call_trap_callback_for_testing() {
     238       10869 :   if (wasm_trap_callback_for_testing) {
     239       10869 :     wasm_trap_callback_for_testing();
     240             :   }
     241       10869 : }
     242             : 
     243             : }  // namespace wasm
     244             : }  // namespace internal
     245             : }  // namespace v8

Generated by: LCOV version 1.10