13ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Copyright 2014 The Chromium Authors. All rights reserved. 23ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Use of this source code is governed by a BSD-style license that can be 33ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// found in the LICENSE file. 43ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 53ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Slightly adapted for inclusion in V8. 63ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Copyright 2014 the V8 project authors. All rights reserved. 73ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 83ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#ifndef V8_BASE_SAFE_CONVERSIONS_IMPL_H_ 93ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#define V8_BASE_SAFE_CONVERSIONS_IMPL_H_ 103ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 113ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#include <limits> 123ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 13d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org#include "src/base/logging.h" 143ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#include "src/base/macros.h" 153ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 163ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgnamespace v8 { 173ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgnamespace base { 183ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgnamespace internal { 193ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 203ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// The std library doesn't provide a binary max_exponent for integers, however 213ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// we can compute one by adding one to the number of non-sign bits. This allows 223ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// for accurate range comparisons between floating point and integer types. 233ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename NumericType> 243ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct MaxExponent { 253ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static const int value = std::numeric_limits<NumericType>::is_iec559 263ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? std::numeric_limits<NumericType>::max_exponent 273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : (sizeof(NumericType) * 8 + 1 - 283ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org std::numeric_limits<NumericType>::is_signed); 293ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 303ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 313ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgenum IntegerRepresentation { 323ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 333ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED 343ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 353ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 363ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// A range for a given nunmeric Src type is contained for a given numeric Dst 373ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and 383ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true. 393ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// We implement this as template specializations rather than simple static 403ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// comparisons to ensure type correctness in our comparisons. 413ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgenum NumericRangeRepresentation { 423ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_NOT_CONTAINED, 433ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_CONTAINED 443ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 453ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 463ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Helper templates to statically determine if our destination type can contain 473ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// maximum and minimum values represented by the source type. 483ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 493ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate < 503ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org typename Dst, 513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org typename Src, 523ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed 533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? INTEGER_REPRESENTATION_SIGNED 543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : INTEGER_REPRESENTATION_UNSIGNED, 553ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation SrcSign = 563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org std::numeric_limits<Src>::is_signed 573ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? INTEGER_REPRESENTATION_SIGNED 583ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : INTEGER_REPRESENTATION_UNSIGNED > 593ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct StaticDstRangeRelationToSrcRange; 603ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 613ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Same sign: Dst is guaranteed to contain Src only if its range is equal or 623ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// larger. 633ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src, IntegerRepresentation Sign> 643ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign> { 653ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static const NumericRangeRepresentation value = 663ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org MaxExponent<Dst>::value >= MaxExponent<Src>::value 673ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? NUMERIC_RANGE_CONTAINED 683ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : NUMERIC_RANGE_NOT_CONTAINED; 693ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 703ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 713ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Unsigned to signed: Dst is guaranteed to contain source only if its range is 723ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// larger. 733ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 743ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct StaticDstRangeRelationToSrcRange<Dst, 753ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 763ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED, 773ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED> { 783ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static const NumericRangeRepresentation value = 793ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org MaxExponent<Dst>::value > MaxExponent<Src>::value 803ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? NUMERIC_RANGE_CONTAINED 813ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : NUMERIC_RANGE_NOT_CONTAINED; 823ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 833ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 843ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Signed to unsigned: Dst cannot be statically determined to contain Src. 853ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 863ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct StaticDstRangeRelationToSrcRange<Dst, 873ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 883ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 893ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED> { 903ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; 913ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 923ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 933ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgenum RangeConstraint { 943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org RANGE_VALID = 0x0, // Value can be represented by the destination type. 953ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org RANGE_UNDERFLOW = 0x1, // Value would overflow. 963ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org RANGE_OVERFLOW = 0x2, // Value would underflow. 973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). 983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Helper function for coercing an int back to a RangeContraint. 1013ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orginline RangeConstraint GetRangeConstraint(int integer_range_constraint) { 102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(integer_range_constraint >= RANGE_VALID && 103d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org integer_range_constraint <= RANGE_INVALID); 1043ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return static_cast<RangeConstraint>(integer_range_constraint); 1053ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} 1063ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1073ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// This function creates a RangeConstraint from an upper and lower bound 1083ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// check by taking advantage of the fact that only NaN can be out of range in 1093ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// both directions at once. 1103ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orginline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, 1113ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org bool is_in_lower_bound) { 1123ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) | 1133ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org (is_in_lower_bound ? 0 : RANGE_UNDERFLOW)); 1143ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} 1153ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1163ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate < 1173ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org typename Dst, 1183ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org typename Src, 1193ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed 1203ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? INTEGER_REPRESENTATION_SIGNED 1213ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : INTEGER_REPRESENTATION_UNSIGNED, 1223ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed 1233ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? INTEGER_REPRESENTATION_SIGNED 1243ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : INTEGER_REPRESENTATION_UNSIGNED, 1253ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NumericRangeRepresentation DstRange = 1263ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org StaticDstRangeRelationToSrcRange<Dst, Src>::value > 1273ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl; 1283ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1293ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// The following templates are for ranges that must be verified at runtime. We 1303ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// split it into checks based on signedness to avoid confusing casts and 1313ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// compiler warnings on signed an unsigned comparisons. 1323ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1333ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Dst range is statically determined to contain Src: Nothing to check. 1343ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, 1353ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org typename Src, 1363ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation DstSign, 1373ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org IntegerRepresentation SrcSign> 1383ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl<Dst, 1393ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 1403ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org DstSign, 1413ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org SrcSign, 1423ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_CONTAINED> { 1433ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static RangeConstraint Check(Src value) { return RANGE_VALID; } 1443ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 1453ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1463ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Signed to signed narrowing: Both the upper and lower boundaries may be 1473ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// exceeded. 1483ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 1493ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl<Dst, 1503ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 1513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED, 1523ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED, 1533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_NOT_CONTAINED> { 1543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static RangeConstraint Check(Src value) { 1553ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return std::numeric_limits<Dst>::is_iec559 1563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), 1573ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org value >= -std::numeric_limits<Dst>::max()) 1583ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), 1593ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org value >= std::numeric_limits<Dst>::min()); 1603ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org } 1613ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 1623ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1633ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. 1643ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 1653ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl<Dst, 1663ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 1673ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 1683ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 1693ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_NOT_CONTAINED> { 1703ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static RangeConstraint Check(Src value) { 1713ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), true); 1723ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org } 1733ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 1743ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1753ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Unsigned to signed: The upper boundary may be exceeded. 1763ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 1773ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl<Dst, 1783ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 1793ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED, 1803ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 1813ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_NOT_CONTAINED> { 1823ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static RangeConstraint Check(Src value) { 1833ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return sizeof(Dst) > sizeof(Src) 1843ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? RANGE_VALID 1853ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : GetRangeConstraint( 1863ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org value <= static_cast<Src>(std::numeric_limits<Dst>::max()), 1873ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org true); 1883ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org } 1893ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 1903ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 1913ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, 1923ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org// and any negative value exceeds the lower boundary. 1933ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 1943ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgstruct DstRangeRelationToSrcRangeImpl<Dst, 1953ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Src, 1963ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_UNSIGNED, 1973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org INTEGER_REPRESENTATION_SIGNED, 1983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org NUMERIC_RANGE_NOT_CONTAINED> { 1993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org static RangeConstraint Check(Src value) { 2003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) 2013ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ? GetRangeConstraint(true, value >= static_cast<Src>(0)) 2023ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org : GetRangeConstraint( 2033ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org value <= static_cast<Src>(std::numeric_limits<Dst>::max()), 2043ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org value >= static_cast<Src>(0)); 2053ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org } 2063ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org}; 2073ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 2083ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orgtemplate <typename Dst, typename Src> 2093ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.orginline RangeConstraint DstRangeRelationToSrcRange(Src value) { 2103ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org // Both source and destination must be numeric. 2113ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org STATIC_ASSERT(std::numeric_limits<Src>::is_specialized); 2123ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org STATIC_ASSERT(std::numeric_limits<Dst>::is_specialized); 2133ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); 2143ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} 2153ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 2163ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} // namespace internal 2173ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} // namespace base 2183ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org} // namespace v8 2193ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org 2203ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org#endif // V8_BASE_SAFE_CONVERSIONS_IMPL_H_ 221