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