1/* 2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "builtins_segmenter.h" 17 18#include "ecmascript/intl/locale_helper.h" 19#include "ecmascript/js_segments.h" 20 21namespace panda::ecmascript::builtins { 22// 18.1.1 Intl.Segmenter ( [ locales [ , options ] ] ) 23JSTaggedValue BuiltinsSegmenter::SegmenterConstructor(EcmaRuntimeCallInfo *argv) 24{ 25 JSThread *thread = argv->GetThread(); 26 BUILTINS_API_TRACE(thread, Segmenter, Constructor); 27 [[maybe_unused]] EcmaHandleScope scope(thread); 28 EcmaVM *ecmaVm = thread->GetEcmaVM(); 29 ObjectFactory *factory = ecmaVm->GetFactory(); 30 31 // 1. If NewTarget is undefined, throw a TypeError exception. 32 JSHandle<JSTaggedValue> newTarget = GetNewTarget(argv); 33 if (newTarget->IsUndefined()) { 34 THROW_TYPE_ERROR_AND_RETURN(thread, "newTarget is undefined", JSTaggedValue::Exception()); 35 } 36 37 // 2. Let internalSlotsList be « [[InitializedSegmenter]], [[Locale]], [[SegmenterGranularity]] ». 38 // 3. Let segmenter be ? OrdinaryCreateFromConstructor(NewTarget, "%Segmenter.prototype%", internalSlotsList). 39 JSHandle<JSTaggedValue> constructor = GetConstructor(argv); 40 JSHandle<JSObject> newObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), newTarget); 41 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 42 JSHandle<JSSegmenter> segmenter = JSHandle<JSSegmenter>::Cast(newObject); 43 44 // 3. Perform ? InitializeSegmenter(segmenter, locales, options). 45 JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 46 JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 47 JSSegmenter::InitializeSegmenter(thread, segmenter, locales, options); 48 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 49 return segmenter.GetTaggedValue(); 50} 51 52// 18.2.2 Intl.Segmenter.supportedLocalesOf ( locales [ , options ] ) 53JSTaggedValue BuiltinsSegmenter::SupportedLocalesOf(EcmaRuntimeCallInfo *argv) 54{ 55 JSThread *thread = argv->GetThread(); 56 BUILTINS_API_TRACE(thread, Segmenter, SupportedLocalesOf); 57 [[maybe_unused]] EcmaHandleScope scope(thread); 58 59 // 1. Let availableLocales be %Segmenter%.[[AvailableLocales]]. 60 JSHandle<TaggedArray> availableLocales = JSSegmenter::GetAvailableLocales(thread); 61 62 // 2. Let requestedLocales be ? CanonicalizeLocaleList(locales). 63 JSHandle<JSTaggedValue> locales = GetCallArg(argv, 0); 64 JSHandle<TaggedArray> requestedLocales = intl::LocaleHelper::CanonicalizeLocaleList(thread, locales); 65 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 66 67 // 3. Return ? SupportedLocales(availableLocales, requestedLocales, options). 68 JSHandle<JSTaggedValue> options = GetCallArg(argv, 1); 69 JSHandle<JSArray> result = JSLocale::SupportedLocales(thread, availableLocales, requestedLocales, options); 70 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 71 return result.GetTaggedValue(); 72} 73 74// 18.3.3 Intl.Segmenter.prototype.segment ( string ) 75JSTaggedValue BuiltinsSegmenter::Segment(EcmaRuntimeCallInfo *argv) 76{ 77 JSThread *thread = argv->GetThread(); 78 BUILTINS_API_TRACE(thread, Segmenter, Segment); 79 [[maybe_unused]] EcmaHandleScope scope(thread); 80 81 // 1. Let segmenter be the this value. 82 JSHandle<JSTaggedValue> thisValue = GetThis(argv); 83 84 // 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]). 85 if (!thisValue->IsJSSegmenter()) { 86 THROW_TYPE_ERROR_AND_RETURN(thread, "this is not segmenter object", JSTaggedValue::Exception()); 87 } 88 89 // 3. Let string be ? ToString(string). 90 JSHandle<JSTaggedValue> stringValue = GetCallArg(argv, 0); 91 JSHandle<EcmaString> string = JSTaggedValue::ToString(thread, stringValue); 92 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 93 // 4. Return ! CreateSegmentsObject(segmenter, string). 94 JSHandle<JSSegments> segments = 95 JSSegments::CreateSegmentsObject(thread, JSHandle<JSSegmenter>::Cast(thisValue), string); 96 return segments.GetTaggedValue(); 97} 98 99// 18.3.4 Intl.Segmenter.prototype.resolvedOptions ( ) 100JSTaggedValue BuiltinsSegmenter::ResolvedOptions(EcmaRuntimeCallInfo *argv) 101{ 102 JSThread *thread = argv->GetThread(); 103 BUILTINS_API_TRACE(thread, Segmenter, ResolvedOptions); 104 [[maybe_unused]] EcmaHandleScope scope(thread); 105 106 // 1. Let segmenter be the this value. 107 JSHandle<JSTaggedValue> thisValue = GetThis(argv); 108 109 // 2. Perform ? RequireInternalSlot(segmenter, [[InitializedSegmenter]]). 110 if (!thisValue->IsJSSegmenter()) { 111 THROW_TYPE_ERROR_AND_RETURN(thread, "this is not segmenter object", JSTaggedValue::Exception()); 112 } 113 114 // 3. Let options be OrdinaryObjectCreate(%Object.prototype%). 115 auto ecmaVm = thread->GetEcmaVM(); 116 JSHandle<GlobalEnv> env = ecmaVm->GetGlobalEnv(); 117 ObjectFactory *factory = ecmaVm->GetFactory(); 118 JSHandle<JSFunction> ctor(env->GetObjectFunction()); 119 JSHandle<JSObject> options(factory->NewJSObjectByConstructor(ctor)); 120 121 // 4. perform resolvedOptions 122 JSHandle<JSSegmenter> segmenter = JSHandle<JSSegmenter>::Cast(thisValue); 123 JSSegmenter::ResolvedOptions(thread, segmenter, options); 124 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 125 // 5. Return options. 126 return options.GetTaggedValue(); 127} 128} // namespace panda::ecmascript::builtins