⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 conversions.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// Copyright 2006-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include <stdarg.h>#include "v8.h"#include "conversions-inl.h"#include "factory.h"#include "scanner.h"namespace v8 { namespace internal {int HexValue(uc32 c) {  if ('0' <= c && c <= '9')    return c - '0';  if ('a' <= c && c <= 'f')    return c - 'a' + 10;  if ('A' <= c && c <= 'F')    return c - 'A' + 10;  return -1;}// Provide a common interface to getting a character at a certain// index from a char* or a String object.static inline int GetChar(const char* str, int index) {  ASSERT(index >= 0 && index < static_cast<int>(strlen(str)));  return str[index];}static inline int GetChar(String* str, int index) {  return str->Get(index);}static inline int GetLength(const char* str) {  return strlen(str);}static inline int GetLength(String* str) {  return str->length();}static inline const char* GetCString(const char* str, int index) {  return str + index;}static inline const char* GetCString(String* str, int index) {  char* result = NewArray<char>(str->length() + 1);  for (int i = index; i < str->length(); i++) {    if (str->Get(i) <= 127) {      result[i - index] = static_cast<char>(str->Get(i));    } else {      result[i - index] = 127;  // Force number parsing to fail.    }  }  result[str->length() - index] = '\0';  return result;}static inline void ReleaseCString(const char* original, const char* str) {}static inline void ReleaseCString(String* original, const char* str) {  DeleteArray(const_cast<char *>(str));}static inline bool IsSpace(const char* str, int index) {  ASSERT(index >= 0 && index < static_cast<int>(strlen(str)));  return Scanner::kIsWhiteSpace.get(str[index]);}static inline bool IsSpace(String* str, int index) {  return Scanner::kIsWhiteSpace.get(str->Get(index));}static inline bool SubStringEquals(const char* str,                                   int index,                                   const char* other) {  return strncmp(str + index, other, strlen(other)) != 0;}static inline bool SubStringEquals(String* str, int index, const char* other) {  HandleScope scope;  int len = strlen(other);  int end = index + len < str->length() ? index + len : str->length();  Handle<String> slice =      Factory::NewStringSlice(Handle<String>(str), index, end);  return slice->IsEqualTo(Vector<const char>(other, len));}// Check if a string should be parsed as an octal number.  The string// can be either a char* or a String*.template<class S>static bool ShouldParseOctal(S* s, int i) {  int index = i;  int len = GetLength(s);  if (index < len && GetChar(s, index) != '0') return false;  // If the first real character (following '0') is not an octal  // digit, bail out early. This also takes care of numbers of the  // forms 0.xxx and 0exxx by not allowing the first 0 to be  // interpreted as an octal.  index++;  if (index < len) {    int d = GetChar(s, index) - '0';    if (d < 0 || d > 7) return false;  } else {    return false;  }  // Traverse all digits (including the first). If there is an octal  // prefix which is not a part of a longer decimal prefix, we return  // true. Otherwise, false is returned.  while (index < len) {    int d = GetChar(s, index++) - '0';    if (d == 8 || d == 9) return false;    if (d <  0 || d >  7) return true;  }  return true;}extern "C" double gay_strtod(const char* s00, const char** se);// Parse an int from a string starting a given index and in a given// radix.  The string can be either a char* or a String*.template <class S>static int InternalStringToInt(S* s, int i, int radix, double* value) {  int len = GetLength(s);  // Setup limits for computing the value.  ASSERT(2 <= radix && radix <= 36);  int lim_0 = '0' + (radix < 10 ? radix : 10);  int lim_a = 'a' + (radix - 10);  int lim_A = 'A' + (radix - 10);  // NOTE: The code for computing the value may seem a bit complex at  // first glance. It is structured to use 32-bit multiply-and-add  // loops as long as possible to avoid loosing precision.  double v = 0.0;  int j;  for (j = i; j < len;) {    // Parse the longest part of the string starting at index j    // possible while keeping the multiplier, and thus the part    // itself, within 32 bits.    uint32_t part = 0, multiplier = 1;    int k;    for (k = j; k < len; k++) {      int c = GetChar(s, k);      if (c >= '0' && c < lim_0) {        c = c - '0';      } else if (c >= 'a' && c < lim_a) {        c = c - 'a' + 10;      } else if (c >= 'A' && c < lim_A) {        c = c - 'A' + 10;      } else {        break;      }      // Update the value of the part as long as the multiplier fits      // in 32 bits. When we can't guarantee that the next iteration      // will not overflow the multiplier, we stop parsing the part      // by leaving the loop.      static const uint32_t kMaximumMultiplier = 0xffffffffU / 36;      uint32_t m = multiplier * radix;      if (m > kMaximumMultiplier) break;      part = part * radix + c;      multiplier = m;      ASSERT(multiplier > part);    }    // Compute the number of part digits. If no digits were parsed;    // we're done parsing the entire string.    int digits = k - j;    if (digits == 0) break;    // Update the value and skip the part in the string.    ASSERT(multiplier ==           pow(static_cast<double>(radix), static_cast<double>(digits)));    v = v * multiplier + part;    j = k;  }  // If the resulting value is larger than 2^53 the value does not fit  // in the mantissa of the double and there is a loss of precision.  // When the value is larger than 2^53 the rounding depends on the  // code generation.  If the code generator spills the double value  // it uses 64 bits and if it does not it uses 80 bits.  //  // If there is a potential for overflow we resort to strtod for  // radix 10 numbers to get higher precision.  For numbers in another  // radix we live with the loss of precision.  static const double kPreciseConversionLimit = 9007199254740992.0;  if (radix == 10 && v > kPreciseConversionLimit) {    const char* cstr = GetCString(s, i);    const char* end;    v = gay_strtod(cstr, &end);    ReleaseCString(s, cstr);  }  *value = v;  return j;}int StringToInt(String* str, int index, int radix, double* value) {  return InternalStringToInt(str, index, radix, value);}int StringToInt(const char* str, int index, int radix, double* value) {  return InternalStringToInt(const_cast<char*>(str), index, radix, value);}static const double JUNK_STRING_VALUE = OS::nan_value();// Convert a string to a double value.  The string can be either a// char* or a String*.template<class S>static double InternalStringToDouble(S* str,                                     int flags,                                     double empty_string_val) {  double result = 0.0;  int index = 0;  int len = GetLength(str);  // Skip leading spaces.  while ((index < len) && IsSpace(str, index)) index++;  // Is the string empty?  if (index >= len) return empty_string_val;  // Get the first character.  uint16_t first = GetChar(str, index);  // Numbers can only start with '-', '+', '.', 'I' (Infinity), or a digit.  if (first != '-' && first != '+' && first != '.' && first != 'I' &&      (first > '9' || first < '0')) {    return JUNK_STRING_VALUE;  }  // Compute sign of result based on first character.  int sign = 1;  if (first == '-') {    sign = -1;    index++;    // String only containing a '-' are junk chars.    if (index == len) return JUNK_STRING_VALUE;  }  // do we have a hex number?  // (since the string is 0-terminated, it's ok to look one char beyond the end)  if ((flags & ALLOW_HEX) != 0 &&      (index + 1) < len &&      GetChar(str, index) == '0' &&      (GetChar(str, index + 1) == 'x' || GetChar(str, index + 1) == 'X')) {    index += 2;    index = StringToInt(str, index, 16, &result);  } else if ((flags & ALLOW_OCTALS) != 0 && ShouldParseOctal(str, index)) {    // NOTE: We optimistically try to parse the number as an octal (if    // we're allowed to), even though this is not as dictated by    // ECMA-262. The reason for doing this is compatibility with IE and    // Firefox.    index = StringToInt(str, index, 8, &result);  } else {    const char* cstr = GetCString(str, index);    const char* end;    // Optimistically parse the number and then, if that fails,    // check if it might have been {+,-,}Infinity.    result = gay_strtod(cstr, &end);    ReleaseCString(str, cstr);    if (result != 0.0 || end != cstr) {      // It appears that strtod worked      index += end - cstr;    } else {      // Check for {+,-,}Infinity      bool is_negative = (GetChar(str, index) == '-');      if (GetChar(str, index) == '+' || GetChar(str, index) == '-')        index++;      if (!SubStringEquals(str, index, "Infinity"))        return JUNK_STRING_VALUE;      result = is_negative ? -INFINITY : INFINITY;      index += 8;    }  }  if ((flags & ALLOW_TRAILING_JUNK) == 0) {    // skip trailing spaces    while ((index < len) && IsSpace(str, index)) index++;    // string ending with junk?    if (index < len) return JUNK_STRING_VALUE;  }  return sign * result;}double StringToDouble(String* str, int flags, double empty_string_val) {  return InternalStringToDouble(str, flags, empty_string_val);}double StringToDouble(const char* str, int flags, double empty_string_val) {  return InternalStringToDouble(str, flags, empty_string_val);}extern "C" char* dtoa(double d, int mode, int ndigits,                      int* decpt, int* sign, char** rve);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -