13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 23fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Redistribution and use in source and binary forms, with or without 33fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// modification, are permitted provided that the following conditions are 43fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// met: 53fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 63fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// * Redistributions of source code must retain the above copyright 73fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// notice, this list of conditions and the following disclaimer. 83fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// * Redistributions in binary form must reproduce the above 93fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// copyright notice, this list of conditions and the following 103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// disclaimer in the documentation and/or other materials provided 113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// with the distribution. 123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// * Neither the name of Google Inc. nor the names of its 133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// contributors may be used to endorse or promote products derived 143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// from this software without specific prior written permission. 153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// 163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <stdarg.h> 293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include <limits.h> 303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "v8.h" 323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "conversions-inl.h" 343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "v8conversions.h" 353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "dtoa.h" 363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "factory.h" 373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "strtod.h" 383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochnamespace v8 { 403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochnamespace internal { 413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochnamespace { 433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// C++-style iterator adaptor for StringInputBuffer 453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// (unlike C++ iterators the end-marker has different type). 463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochclass StringInputBufferIterator { 473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch public: 483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch class EndMarker {}; 493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch explicit StringInputBufferIterator(StringInputBuffer* buffer); 513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int operator*() const; 533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch void operator++(); 543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool operator==(EndMarker const&) const { return end_; } 553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool operator!=(EndMarker const& m) const { return !end_; } 563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch private: 583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBuffer* const buffer_; 593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int current_; 603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bool end_; 613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}; 623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 643fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochStringInputBufferIterator::StringInputBufferIterator( 653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBuffer* buffer) : buffer_(buffer) { 663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ++(*this); 673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint StringInputBufferIterator::operator*() const { 703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return current_; 713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid StringInputBufferIterator::operator++() { 753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch end_ = !buffer_->has_more(); 763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!end_) { 773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch current_ = buffer_->GetNext(); 783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} // End anonymous namespace. 813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdouble StringToDouble(UnicodeCache* unicode_cache, 843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch String* str, int flags, double empty_string_val) { 853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringShape shape(str); 863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (shape.IsSequentialAscii()) { 873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* begin = SeqAsciiString::cast(str)->GetChars(); 883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* end = begin + str->length(); 893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToDouble(unicode_cache, begin, end, flags, 903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch empty_string_val); 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (shape.IsSequentialTwoByte()) { 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); 933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const uc16* end = begin + str->length(); 943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToDouble(unicode_cache, begin, end, flags, 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch empty_string_val); 963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBuffer buffer(str); 983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToDouble(unicode_cache, 993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBufferIterator(&buffer), 1003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBufferIterator::EndMarker(), 1013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch flags, 1023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch empty_string_val); 1033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochdouble StringToInt(UnicodeCache* unicode_cache, 1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch String* str, 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int radix) { 1103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringShape shape(str); 1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (shape.IsSequentialAscii()) { 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* begin = SeqAsciiString::cast(str)->GetChars(); 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const char* end = begin + str->length(); 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToInt(unicode_cache, begin, end, radix); 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else if (shape.IsSequentialTwoByte()) { 1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const uc16* begin = SeqTwoByteString::cast(str)->GetChars(); 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const uc16* end = begin + str->length(); 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToInt(unicode_cache, begin, end, radix); 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 1203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBuffer buffer(str); 1213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return InternalStringToInt(unicode_cache, 1223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBufferIterator(&buffer), 1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StringInputBufferIterator::EndMarker(), 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch radix); 1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} } // namespace v8::internal 129