LCOV - code coverage report
Current view: top level - src/wasm - wasm-external-refs.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 105 105 100.0 %
Date: 2019-01-20 Functions: 33 33 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/memcopy.h"
      14             : #include "src/utils.h"
      15             : #include "src/v8memory.h"
      16             : #include "src/wasm/wasm-external-refs.h"
      17             : 
      18             : namespace v8 {
      19             : namespace internal {
      20             : namespace wasm {
      21             : 
      22        1150 : void f32_trunc_wrapper(Address data) {
      23        1150 :   WriteUnalignedValue<float>(data, truncf(ReadUnalignedValue<float>(data)));
      24        1150 : }
      25             : 
      26        1150 : void f32_floor_wrapper(Address data) {
      27        1150 :   WriteUnalignedValue<float>(data, floorf(ReadUnalignedValue<float>(data)));
      28        1150 : }
      29             : 
      30        1150 : void f32_ceil_wrapper(Address data) {
      31        1150 :   WriteUnalignedValue<float>(data, ceilf(ReadUnalignedValue<float>(data)));
      32        1150 : }
      33             : 
      34        1150 : void f32_nearest_int_wrapper(Address data) {
      35        1150 :   WriteUnalignedValue<float>(data, nearbyintf(ReadUnalignedValue<float>(data)));
      36        1150 : }
      37             : 
      38         490 : void f64_trunc_wrapper(Address data) {
      39         490 :   WriteUnalignedValue<double>(data, trunc(ReadUnalignedValue<double>(data)));
      40         490 : }
      41             : 
      42         490 : void f64_floor_wrapper(Address data) {
      43         490 :   WriteUnalignedValue<double>(data, floor(ReadUnalignedValue<double>(data)));
      44         490 : }
      45             : 
      46         490 : void f64_ceil_wrapper(Address data) {
      47         490 :   WriteUnalignedValue<double>(data, ceil(ReadUnalignedValue<double>(data)));
      48         490 : }
      49             : 
      50         490 : void f64_nearest_int_wrapper(Address data) {
      51             :   WriteUnalignedValue<double>(data,
      52         490 :                               nearbyint(ReadUnalignedValue<double>(data)));
      53         490 : }
      54             : 
      55         810 : void int64_to_float32_wrapper(Address data) {
      56             :   int64_t input = ReadUnalignedValue<int64_t>(data);
      57         810 :   WriteUnalignedValue<float>(data, static_cast<float>(input));
      58         810 : }
      59             : 
      60        1190 : void uint64_to_float32_wrapper(Address data) {
      61             :   uint64_t input = ReadUnalignedValue<uint64_t>(data);
      62        1190 :   float result = static_cast<float>(input);
      63             : 
      64             : #if V8_CC_MSVC
      65             :   // With MSVC we use static_cast<float>(uint32_t) instead of
      66             :   // static_cast<float>(uint64_t) to achieve round-to-nearest-ties-even
      67             :   // semantics. The idea is to calculate
      68             :   // static_cast<float>(high_word) * 2^32 + static_cast<float>(low_word). To
      69             :   // achieve proper rounding in all cases we have to adjust the high_word
      70             :   // with a "rounding bit" sometimes. The rounding bit is stored in the LSB of
      71             :   // the high_word if the low_word may affect the rounding of the high_word.
      72             :   uint32_t low_word = static_cast<uint32_t>(input & 0xFFFFFFFF);
      73             :   uint32_t high_word = static_cast<uint32_t>(input >> 32);
      74             : 
      75             :   float shift = static_cast<float>(1ull << 32);
      76             :   // If the MSB of the high_word is set, then we make space for a rounding bit.
      77             :   if (high_word < 0x80000000) {
      78             :     high_word <<= 1;
      79             :     shift = static_cast<float>(1ull << 31);
      80             :   }
      81             : 
      82             :   if ((high_word & 0xFE000000) && low_word) {
      83             :     // Set the rounding bit.
      84             :     high_word |= 1;
      85             :   }
      86             : 
      87             :   result = static_cast<float>(high_word);
      88             :   result *= shift;
      89             :   result += static_cast<float>(low_word);
      90             : #endif
      91             : 
      92             :   WriteUnalignedValue<float>(data, result);
      93        1190 : }
      94             : 
      95         810 : void int64_to_float64_wrapper(Address data) {
      96             :   int64_t input = ReadUnalignedValue<int64_t>(data);
      97         810 :   WriteUnalignedValue<double>(data, static_cast<double>(input));
      98         810 : }
      99             : 
     100        1185 : void uint64_to_float64_wrapper(Address data) {
     101             :   uint64_t input = ReadUnalignedValue<uint64_t>(data);
     102        1185 :   double result = static_cast<double>(input);
     103             : 
     104             : #if V8_CC_MSVC
     105             :   // With MSVC we use static_cast<double>(uint32_t) instead of
     106             :   // static_cast<double>(uint64_t) to achieve round-to-nearest-ties-even
     107             :   // semantics. The idea is to calculate
     108             :   // static_cast<double>(high_word) * 2^32 + static_cast<double>(low_word).
     109             :   uint32_t low_word = static_cast<uint32_t>(input & 0xFFFFFFFF);
     110             :   uint32_t high_word = static_cast<uint32_t>(input >> 32);
     111             : 
     112             :   double shift = static_cast<double>(1ull << 32);
     113             : 
     114             :   result = static_cast<double>(high_word);
     115             :   result *= shift;
     116             :   result += static_cast<double>(low_word);
     117             : #endif
     118             : 
     119             :   WriteUnalignedValue<double>(data, result);
     120        1185 : }
     121             : 
     122        2300 : int32_t float32_to_int64_wrapper(Address data) {
     123             :   // We use "<" here to check the upper bound because of rounding problems: With
     124             :   // "<=" some inputs would be considered within int64 range which are actually
     125             :   // not within int64 range.
     126             :   float input = ReadUnalignedValue<float>(data);
     127        2300 :   if (input >= static_cast<float>(std::numeric_limits<int64_t>::min()) &&
     128             :       input < static_cast<float>(std::numeric_limits<int64_t>::max())) {
     129        1660 :     WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
     130        1660 :     return 1;
     131             :   }
     132             :   return 0;
     133             : }
     134             : 
     135        2300 : int32_t float32_to_uint64_wrapper(Address data) {
     136             :   float input = ReadUnalignedValue<float>(data);
     137             :   // We use "<" here to check the upper bound because of rounding problems: With
     138             :   // "<=" some inputs would be considered within uint64 range which are actually
     139             :   // not within uint64 range.
     140        2300 :   if (input > -1.0 &&
     141             :       input < static_cast<float>(std::numeric_limits<uint64_t>::max())) {
     142        1020 :     WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
     143        1020 :     return 1;
     144             :   }
     145             :   return 0;
     146             : }
     147             : 
     148        1394 : int32_t float64_to_int64_wrapper(Address data) {
     149             :   // We use "<" here to check the upper bound because of rounding problems: With
     150             :   // "<=" some inputs would be considered within int64 range which are actually
     151             :   // not within int64 range.
     152             :   double input = ReadUnalignedValue<double>(data);
     153        1394 :   if (input >= static_cast<double>(std::numeric_limits<int64_t>::min()) &&
     154             :       input < static_cast<double>(std::numeric_limits<int64_t>::max())) {
     155        1174 :     WriteUnalignedValue<int64_t>(data, static_cast<int64_t>(input));
     156        1174 :     return 1;
     157             :   }
     158             :   return 0;
     159             : }
     160             : 
     161         980 : int32_t float64_to_uint64_wrapper(Address data) {
     162             :   // We use "<" here to check the upper bound because of rounding problems: With
     163             :   // "<=" some inputs would be considered within uint64 range which are actually
     164             :   // not within uint64 range.
     165             :   double input = ReadUnalignedValue<double>(data);
     166         980 :   if (input > -1.0 &&
     167             :       input < static_cast<double>(std::numeric_limits<uint64_t>::max())) {
     168         580 :     WriteUnalignedValue<uint64_t>(data, static_cast<uint64_t>(input));
     169         580 :     return 1;
     170             :   }
     171             :   return 0;
     172             : }
     173             : 
     174       65610 : int32_t int64_div_wrapper(Address data) {
     175             :   int64_t dividend = ReadUnalignedValue<int64_t>(data);
     176       65610 :   int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
     177       65610 :   if (divisor == 0) {
     178             :     return 0;
     179             :   }
     180       63990 :   if (divisor == -1 && dividend == std::numeric_limits<int64_t>::min()) {
     181             :     return -1;
     182             :   }
     183       63990 :   WriteUnalignedValue<int64_t>(data, dividend / divisor);
     184       63990 :   return 1;
     185             : }
     186             : 
     187       65610 : int32_t int64_mod_wrapper(Address data) {
     188             :   int64_t dividend = ReadUnalignedValue<int64_t>(data);
     189       65610 :   int64_t divisor = ReadUnalignedValue<int64_t>(data + sizeof(dividend));
     190       65610 :   if (divisor == 0) {
     191             :     return 0;
     192             :   }
     193       63990 :   WriteUnalignedValue<int64_t>(data, dividend % divisor);
     194       63990 :   return 1;
     195             : }
     196             : 
     197       65610 : int32_t uint64_div_wrapper(Address data) {
     198             :   uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
     199       65610 :   uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
     200       65610 :   if (divisor == 0) {
     201             :     return 0;
     202             :   }
     203       63990 :   WriteUnalignedValue<uint64_t>(data, dividend / divisor);
     204       63990 :   return 1;
     205             : }
     206             : 
     207       65610 : int32_t uint64_mod_wrapper(Address data) {
     208             :   uint64_t dividend = ReadUnalignedValue<uint64_t>(data);
     209       65610 :   uint64_t divisor = ReadUnalignedValue<uint64_t>(data + sizeof(dividend));
     210       65610 :   if (divisor == 0) {
     211             :     return 0;
     212             :   }
     213       63990 :   WriteUnalignedValue<uint64_t>(data, dividend % divisor);
     214       63990 :   return 1;
     215             : }
     216             : 
     217         580 : uint32_t word32_ctz_wrapper(Address data) {
     218         580 :   return base::bits::CountTrailingZeros(ReadUnalignedValue<uint32_t>(data));
     219             : }
     220             : 
     221         810 : uint32_t word64_ctz_wrapper(Address data) {
     222         810 :   return base::bits::CountTrailingZeros(ReadUnalignedValue<uint64_t>(data));
     223             : }
     224             : 
     225         580 : uint32_t word32_popcnt_wrapper(Address data) {
     226         580 :   return base::bits::CountPopulation(ReadUnalignedValue<uint32_t>(data));
     227             : }
     228             : 
     229         810 : uint32_t word64_popcnt_wrapper(Address data) {
     230         810 :   return base::bits::CountPopulation(ReadUnalignedValue<uint64_t>(data));
     231             : }
     232             : 
     233       33649 : uint32_t word32_rol_wrapper(Address data) {
     234             :   uint32_t input = ReadUnalignedValue<uint32_t>(data);
     235       67298 :   uint32_t shift = ReadUnalignedValue<uint32_t>(data + sizeof(input)) & 31;
     236       33649 :   return (input << shift) | (input >> ((32 - shift) & 31));
     237             : }
     238             : 
     239       33640 : uint32_t word32_ror_wrapper(Address data) {
     240             :   uint32_t input = ReadUnalignedValue<uint32_t>(data);
     241       67280 :   uint32_t shift = ReadUnalignedValue<uint32_t>(data + sizeof(input)) & 31;
     242       33640 :   return (input >> shift) | (input << ((32 - shift) & 31));
     243             : }
     244             : 
     245       24049 : void float64_pow_wrapper(Address data) {
     246             :   double x = ReadUnalignedValue<double>(data);
     247       24049 :   double y = ReadUnalignedValue<double>(data + sizeof(x));
     248       24049 :   WriteUnalignedValue<double>(data, Pow(x, y));
     249       24049 : }
     250             : 
     251          99 : void memory_copy_wrapper(Address dst, Address src, uint32_t size) {
     252          99 :   MemMove(reinterpret_cast<void*>(dst), reinterpret_cast<void*>(src), size);
     253          99 : }
     254             : 
     255          54 : void memory_fill_wrapper(Address dst, uint32_t value, uint32_t size) {
     256          54 :   memset(reinterpret_cast<void*>(dst), value, size);
     257          54 : }
     258             : 
     259             : static WasmTrapCallbackForTesting wasm_trap_callback_for_testing = nullptr;
     260             : 
     261    11627460 : void set_trap_callback_for_testing(WasmTrapCallbackForTesting callback) {
     262    11627460 :   wasm_trap_callback_for_testing = callback;
     263    11627460 : }
     264             : 
     265       90390 : void call_trap_callback_for_testing() {
     266       90390 :   if (wasm_trap_callback_for_testing) {
     267       90390 :     wasm_trap_callback_for_testing();
     268             :   }
     269       90390 : }
     270             : 
     271             : }  // namespace wasm
     272             : }  // namespace internal
     273      183867 : }  // namespace v8

Generated by: LCOV version 1.10