IntlCollatorConstructor.cpp
1 /* 2 * Copyright (C) 2015 Andy VanWagoner (andy@vanwagoner.family) 3 * Copyright (C) 2015 Sukolsak Sakshuwong (sukolsak@gmail.com) 4 * Copyright (C) 2016-2020 Apple Inc. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 25 * THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "config.h" 29 #include "IntlCollatorConstructor.h" 30 31 #include "IntlCollator.h" 32 #include "IntlCollatorPrototype.h" 33 #include "IntlObject.h" 34 #include "JSCInlines.h" 35 36 namespace JSC { 37 38 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(IntlCollatorConstructor); 39 40 static JSC_DECLARE_HOST_FUNCTION(IntlCollatorConstructorFuncSupportedLocalesOf); 41 42 } 43 44 #include "IntlCollatorConstructor.lut.h" 45 46 namespace JSC { 47 48 static JSC_DECLARE_HOST_FUNCTION(callIntlCollator); 49 static JSC_DECLARE_HOST_FUNCTION(constructIntlCollator); 50 51 const ClassInfo IntlCollatorConstructor::s_info = { "Function", &InternalFunction::s_info, &collatorConstructorTable, nullptr, CREATE_METHOD_TABLE(IntlCollatorConstructor) }; 52 53 /* Source for IntlCollatorConstructor.lut.h 54 @begin collatorConstructorTable 55 supportedLocalesOf IntlCollatorConstructorFuncSupportedLocalesOf DontEnum|Function 1 56 @end 57 */ 58 59 IntlCollatorConstructor* IntlCollatorConstructor::create(VM& vm, Structure* structure, IntlCollatorPrototype* collatorPrototype) 60 { 61 IntlCollatorConstructor* constructor = new (NotNull, allocateCell<IntlCollatorConstructor>(vm.heap)) IntlCollatorConstructor(vm, structure); 62 constructor->finishCreation(vm, collatorPrototype); 63 return constructor; 64 } 65 66 Structure* IntlCollatorConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 67 { 68 return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info()); 69 } 70 71 IntlCollatorConstructor::IntlCollatorConstructor(VM& vm, Structure* structure) 72 : InternalFunction(vm, structure, callIntlCollator, constructIntlCollator) 73 { 74 } 75 76 void IntlCollatorConstructor::finishCreation(VM& vm, IntlCollatorPrototype* collatorPrototype) 77 { 78 Base::finishCreation(vm, 0, "Collator"_s, PropertyAdditionMode::WithoutStructureTransition); 79 putDirectWithoutTransition(vm, vm.propertyNames->prototype, collatorPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); 80 collatorPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum)); 81 } 82 83 JSC_DEFINE_HOST_FUNCTION(constructIntlCollator, (JSGlobalObject* globalObject, CallFrame* callFrame)) 84 { 85 VM& vm = globalObject->vm(); 86 auto scope = DECLARE_THROW_SCOPE(vm); 87 // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0) 88 // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. 89 // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%). 90 // 3. ReturnIfAbrupt(collator). 91 JSObject* newTarget = asObject(callFrame->newTarget()); 92 Structure* structure = newTarget == callFrame->jsCallee() 93 ? globalObject->collatorStructure() 94 : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->collatorStructure()); 95 RETURN_IF_EXCEPTION(scope, { }); 96 97 IntlCollator* collator = IntlCollator::create(vm, structure); 98 ASSERT(collator); 99 100 // 4. Return InitializeCollator(collator, locales, options). 101 scope.release(); 102 collator->initializeCollator(globalObject, callFrame->argument(0), callFrame->argument(1)); 103 return JSValue::encode(collator); 104 } 105 106 JSC_DEFINE_HOST_FUNCTION(callIntlCollator, (JSGlobalObject* globalObject, CallFrame* callFrame)) 107 { 108 // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0) 109 // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. 110 // NewTarget is always undefined when called as a function. 111 112 VM& vm = globalObject->vm(); 113 // Collator does not require the workaround for ECMA-402 1.0 compatibility. 114 // https://bugs.webkit.org/show_bug.cgi?id=153679 115 116 // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%). 117 // 3. ReturnIfAbrupt(collator). 118 IntlCollator* collator = IntlCollator::create(vm, globalObject->collatorStructure()); 119 ASSERT(collator); 120 121 // 4. Return InitializeCollator(collator, locales, options). 122 collator->initializeCollator(globalObject, callFrame->argument(0), callFrame->argument(1)); 123 return JSValue::encode(collator); 124 } 125 126 JSC_DEFINE_HOST_FUNCTION(IntlCollatorConstructorFuncSupportedLocalesOf, (JSGlobalObject* globalObject, CallFrame* callFrame)) 127 { 128 VM& vm = globalObject->vm(); 129 auto scope = DECLARE_THROW_SCOPE(vm); 130 // 10.2.2 Intl.Collator.supportedLocalesOf(locales [, options]) (ECMA-402 2.0) 131 132 // 1. Let requestedLocales be CanonicalizeLocaleList(locales). 133 Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, callFrame->argument(0)); 134 135 // 2. ReturnIfAbrupt(requestedLocales). 136 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 137 138 // 3. Return SupportedLocales(%Collator%.[[availableLocales]], requestedLocales, options). 139 RELEASE_AND_RETURN(scope, JSValue::encode(supportedLocales(globalObject, intlCollatorAvailableLocales(), requestedLocales, callFrame->argument(1)))); 140 } 141 142 } // namespace JSC