// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_INTL_SUPPORT #error Internationalization is expected to be enabled. #endif // V8_INTL_SUPPORT #include "src/objects/js-segment-iterator.h" #include #include #include #include "src/execution/isolate.h" #include "src/heap/factory.h" #include "src/objects/intl-objects.h" #include "src/objects/js-segment-iterator-inl.h" #include "src/objects/js-segments.h" #include "src/objects/managed.h" #include "src/objects/objects-inl.h" #include "unicode/brkiter.h" namespace v8 { namespace internal { Handle JSSegmentIterator::GranularityAsString(Isolate* isolate) const { return JSSegmenter::GetGranularityString(isolate, granularity()); } // ecma402 #sec-createsegmentiterator MaybeHandle JSSegmentIterator::Create( Isolate* isolate, icu::BreakIterator* break_iterator, JSSegmenter::Granularity granularity) { // Clone a copy for both the ownership and not sharing with containing and // other calls to the iterator because icu::BreakIterator keep the iteration // position internally and cannot be shared across multiple calls to // JSSegmentIterator::Create and JSSegments::Containing. break_iterator = break_iterator->clone(); DCHECK_NOT_NULL(break_iterator); Handle map = Handle( isolate->native_context()->intl_segment_iterator_map(), isolate); // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0. break_iterator->first(); Handle> managed_break_iterator = Managed::FromRawPtr(isolate, 0, break_iterator); icu::UnicodeString* string = new icu::UnicodeString(); break_iterator->getText().getText(*string); Handle> unicode_string = Managed::FromRawPtr(isolate, 0, string); break_iterator->setText(*string); // Now all properties are ready, so we can allocate the result object. Handle result = isolate->factory()->NewJSObjectFromMap(map); DisallowHeapAllocation no_gc; Handle segment_iterator = Handle::cast(result); segment_iterator->set_flags(0); segment_iterator->set_granularity(granularity); segment_iterator->set_icu_break_iterator(*managed_break_iterator); segment_iterator->set_unicode_string(*unicode_string); return segment_iterator; } // ecma402 #sec-%segmentiteratorprototype%.next MaybeHandle JSSegmentIterator::Next( Isolate* isolate, Handle segment_iterator) { Factory* factory = isolate->factory(); icu::BreakIterator* icu_break_iterator = segment_iterator->icu_break_iterator().raw(); // 5. Let startIndex be iterator.[[IteratedStringNextSegmentCodeUnitIndex]]. int32_t start_index = icu_break_iterator->current(); // 6. Let endIndex be ! FindBoundary(segmenter, string, startIndex, after). int32_t end_index = icu_break_iterator->next(); // 7. If endIndex is not finite, then if (end_index == icu::BreakIterator::DONE) { // a. Return ! CreateIterResultObject(undefined, true). return factory->NewJSIteratorResult(isolate->factory()->undefined_value(), true); } // 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex. // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, // startIndex, endIndex). icu::UnicodeString string; icu_break_iterator->getText().getText(string); Handle segment_data; ASSIGN_RETURN_ON_EXCEPTION( isolate, segment_data, JSSegments::CreateSegmentDataObject( isolate, segment_iterator->granularity(), icu_break_iterator, string, start_index, end_index), JSReceiver); // 10. Return ! CreateIterResultObject(segmentData, false). return factory->NewJSIteratorResult(segment_data, false); } } // namespace internal } // namespace v8