11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_INTL_SUPPORT 61cb0ef41Sopenharmony_ci#error Internationalization is expected to be enabled. 71cb0ef41Sopenharmony_ci#endif // V8_INTL_SUPPORT 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ci#include "src/objects/js-segment-iterator.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include <map> 121cb0ef41Sopenharmony_ci#include <memory> 131cb0ef41Sopenharmony_ci#include <string> 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 161cb0ef41Sopenharmony_ci#include "src/heap/factory.h" 171cb0ef41Sopenharmony_ci#include "src/objects/intl-objects.h" 181cb0ef41Sopenharmony_ci#include "src/objects/js-segment-iterator-inl.h" 191cb0ef41Sopenharmony_ci#include "src/objects/js-segments.h" 201cb0ef41Sopenharmony_ci#include "src/objects/managed-inl.h" 211cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h" 221cb0ef41Sopenharmony_ci#include "unicode/brkiter.h" 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cinamespace v8 { 251cb0ef41Sopenharmony_cinamespace internal { 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciHandle<String> JSSegmentIterator::GranularityAsString(Isolate* isolate) const { 281cb0ef41Sopenharmony_ci return JSSegmenter::GetGranularityString(isolate, granularity()); 291cb0ef41Sopenharmony_ci} 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci// ecma402 #sec-createsegmentiterator 321cb0ef41Sopenharmony_ciMaybeHandle<JSSegmentIterator> JSSegmentIterator::Create( 331cb0ef41Sopenharmony_ci Isolate* isolate, icu::BreakIterator* break_iterator, 341cb0ef41Sopenharmony_ci JSSegmenter::Granularity granularity) { 351cb0ef41Sopenharmony_ci // Clone a copy for both the ownership and not sharing with containing and 361cb0ef41Sopenharmony_ci // other calls to the iterator because icu::BreakIterator keep the iteration 371cb0ef41Sopenharmony_ci // position internally and cannot be shared across multiple calls to 381cb0ef41Sopenharmony_ci // JSSegmentIterator::Create and JSSegments::Containing. 391cb0ef41Sopenharmony_ci break_iterator = break_iterator->clone(); 401cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(break_iterator); 411cb0ef41Sopenharmony_ci Handle<Map> map = Handle<Map>( 421cb0ef41Sopenharmony_ci isolate->native_context()->intl_segment_iterator_map(), isolate); 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0. 451cb0ef41Sopenharmony_ci break_iterator->first(); 461cb0ef41Sopenharmony_ci Handle<Managed<icu::BreakIterator>> managed_break_iterator = 471cb0ef41Sopenharmony_ci Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator); 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci icu::UnicodeString* string = new icu::UnicodeString(); 501cb0ef41Sopenharmony_ci break_iterator->getText().getText(*string); 511cb0ef41Sopenharmony_ci Handle<Managed<icu::UnicodeString>> unicode_string = 521cb0ef41Sopenharmony_ci Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, string); 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci break_iterator->setText(*string); 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci // Now all properties are ready, so we can allocate the result object. 571cb0ef41Sopenharmony_ci Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map); 581cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 591cb0ef41Sopenharmony_ci Handle<JSSegmentIterator> segment_iterator = 601cb0ef41Sopenharmony_ci Handle<JSSegmentIterator>::cast(result); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci segment_iterator->set_flags(0); 631cb0ef41Sopenharmony_ci segment_iterator->set_granularity(granularity); 641cb0ef41Sopenharmony_ci segment_iterator->set_icu_break_iterator(*managed_break_iterator); 651cb0ef41Sopenharmony_ci segment_iterator->set_unicode_string(*unicode_string); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci return segment_iterator; 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci// ecma402 #sec-%segmentiteratorprototype%.next 711cb0ef41Sopenharmony_ciMaybeHandle<JSReceiver> JSSegmentIterator::Next( 721cb0ef41Sopenharmony_ci Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) { 731cb0ef41Sopenharmony_ci Factory* factory = isolate->factory(); 741cb0ef41Sopenharmony_ci icu::BreakIterator* icu_break_iterator = 751cb0ef41Sopenharmony_ci segment_iterator->icu_break_iterator().raw(); 761cb0ef41Sopenharmony_ci // 5. Let startIndex be iterator.[[IteratedStringNextSegmentCodeUnitIndex]]. 771cb0ef41Sopenharmony_ci int32_t start_index = icu_break_iterator->current(); 781cb0ef41Sopenharmony_ci // 6. Let endIndex be ! FindBoundary(segmenter, string, startIndex, after). 791cb0ef41Sopenharmony_ci int32_t end_index = icu_break_iterator->next(); 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci // 7. If endIndex is not finite, then 821cb0ef41Sopenharmony_ci if (end_index == icu::BreakIterator::DONE) { 831cb0ef41Sopenharmony_ci // a. Return ! CreateIterResultObject(undefined, true). 841cb0ef41Sopenharmony_ci return factory->NewJSIteratorResult(isolate->factory()->undefined_value(), 851cb0ef41Sopenharmony_ci true); 861cb0ef41Sopenharmony_ci } 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ci // 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex. 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string, 911cb0ef41Sopenharmony_ci // startIndex, endIndex). 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci icu::UnicodeString string; 941cb0ef41Sopenharmony_ci icu_break_iterator->getText().getText(string); 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci Handle<Object> segment_data; 971cb0ef41Sopenharmony_ci ASSIGN_RETURN_ON_EXCEPTION( 981cb0ef41Sopenharmony_ci isolate, segment_data, 991cb0ef41Sopenharmony_ci JSSegments::CreateSegmentDataObject( 1001cb0ef41Sopenharmony_ci isolate, segment_iterator->granularity(), icu_break_iterator, string, 1011cb0ef41Sopenharmony_ci start_index, end_index), 1021cb0ef41Sopenharmony_ci JSReceiver); 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci // 10. Return ! CreateIterResultObject(segmentData, false). 1051cb0ef41Sopenharmony_ci return factory->NewJSIteratorResult(segment_data, false); 1061cb0ef41Sopenharmony_ci} 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci} // namespace internal 1091cb0ef41Sopenharmony_ci} // namespace v8 110