[INTL] Implement supportedLocalesOf on Intl Constructors
[WebKit.git] / Source / JavaScriptCore / runtime / IntlCollatorConstructor.cpp
1 /*
2  * Copyright (C) 2015 Andy VanWagoner (thetalecrafter@gmail.com)
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26
27 #include "config.h"
28 #include "IntlCollatorConstructor.h"
29
30 #if ENABLE(INTL)
31
32 #include "Error.h"
33 #include "IntlCollator.h"
34 #include "IntlCollatorPrototype.h"
35 #include "IntlObject.h"
36 #include "JSCJSValueInlines.h"
37 #include "JSCellInlines.h"
38 #include "Lookup.h"
39 #include "SlotVisitorInlines.h"
40 #include "StructureInlines.h"
41
42 namespace JSC {
43
44 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(IntlCollatorConstructor);
45
46 static EncodedJSValue JSC_HOST_CALL IntlCollatorConstructorFuncSupportedLocalesOf(ExecState*);
47
48 }
49
50 #include "IntlCollatorConstructor.lut.h"
51
52 namespace JSC {
53
54 const ClassInfo IntlCollatorConstructor::s_info = { "Function", &InternalFunction::s_info, &collatorConstructorTable, CREATE_METHOD_TABLE(IntlCollatorConstructor) };
55
56 /* Source for IntlCollatorConstructor.lut.h
57 @begin collatorConstructorTable
58   supportedLocalesOf             IntlCollatorConstructorFuncSupportedLocalesOf             DontEnum|Function 1
59 @end
60 */
61
62 IntlCollatorConstructor* IntlCollatorConstructor::create(VM& vm, Structure* structure, IntlCollatorPrototype* collatorPrototype, Structure* collatorStructure)
63 {
64     IntlCollatorConstructor* constructor = new (NotNull, allocateCell<IntlCollatorConstructor>(vm.heap)) IntlCollatorConstructor(vm, structure);
65     constructor->finishCreation(vm, collatorPrototype, collatorStructure);
66     return constructor;
67 }
68
69 Structure* IntlCollatorConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
70 {
71     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
72 }
73
74 IntlCollatorConstructor::IntlCollatorConstructor(VM& vm, Structure* structure)
75     : InternalFunction(vm, structure)
76 {
77 }
78
79 void IntlCollatorConstructor::finishCreation(VM& vm, IntlCollatorPrototype* collatorPrototype, Structure* collatorStructure)
80 {
81     Base::finishCreation(vm, ASCIILiteral("Collator"));
82     putDirectWithoutTransition(vm, vm.propertyNames->prototype, collatorPrototype, DontEnum | DontDelete | ReadOnly);
83     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum | DontDelete);
84     m_collatorStructure.set(vm, this, collatorStructure);
85 }
86
87 EncodedJSValue JSC_HOST_CALL constructIntlCollator(ExecState* exec)
88 {
89     // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0)
90     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
91     JSValue newTarget = exec->newTarget();
92     if (!newTarget || newTarget.isUndefined())
93         newTarget = exec->callee();
94
95     // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%).
96     VM& vm = exec->vm();
97     IntlCollator* collator = IntlCollator::create(vm, jsCast<IntlCollatorConstructor*>(exec->callee()));
98     if (collator && !jsDynamicCast<IntlCollatorConstructor*>(newTarget)) {
99         JSValue proto = asObject(newTarget)->getDirect(vm, vm.propertyNames->prototype);
100         asObject(collator)->setPrototypeWithCycleCheck(exec, proto);
101     }
102
103     // 3. ReturnIfAbrupt(collator).
104     ASSERT(collator);
105
106     // 4. Return InitializeCollator(collator, locales, options).
107     // FIXME: return JSValue::encode(InitializeCollator(collator, locales, options));
108
109     return JSValue::encode(collator);
110 }
111
112 EncodedJSValue JSC_HOST_CALL callIntlCollator(ExecState* exec)
113 {
114     // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0)
115     // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
116     // NewTarget is always undefined when called as a function.
117
118     // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%).
119     VM& vm = exec->vm();
120     IntlCollator* collator = IntlCollator::create(vm, jsCast<IntlCollatorConstructor*>(exec->callee()));
121
122     // 3. ReturnIfAbrupt(collator).
123     ASSERT(collator);
124
125     // 4. Return InitializeCollator(collator, locales, options).
126     // FIXME: return JSValue::encode(InitializeCollator(collator, locales, options));
127
128     return JSValue::encode(collator);
129 }
130
131 ConstructType IntlCollatorConstructor::getConstructData(JSCell*, ConstructData& constructData)
132 {
133     constructData.native.function = constructIntlCollator;
134     return ConstructTypeHost;
135 }
136
137 CallType IntlCollatorConstructor::getCallData(JSCell*, CallData& callData)
138 {
139     callData.native.function = callIntlCollator;
140     return CallTypeHost;
141 }
142
143 bool IntlCollatorConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
144 {
145     return getStaticFunctionSlot<InternalFunction>(exec, collatorConstructorTable, jsCast<IntlCollatorConstructor*>(object), propertyName, slot);
146 }
147
148 EncodedJSValue JSC_HOST_CALL IntlCollatorConstructorFuncSupportedLocalesOf(ExecState* exec)
149 {
150     // 10.2.2 Intl.Collator.supportedLocalesOf(locales [, options]) (ECMA-402 2.0)
151
152     // 1. Let requestedLocales be CanonicalizeLocaleList(locales).
153     JSArray* requestedLocales = canonicalizeLocaleList(exec, exec->argument(0));
154
155     // 2. ReturnIfAbrupt(requestedLocales).
156     if (exec->hadException())
157         return JSValue::encode(jsUndefined());
158
159     // 3. Return SupportedLocales(%Collator%.[[availableLocales]], requestedLocales, options).
160     JSGlobalObject* globalObject = exec->callee()->globalObject();
161     return JSValue::encode(supportedLocales(exec, globalObject->intlCollatorAvailableLocales(), requestedLocales, exec->argument(1)));
162 }
163
164 void IntlCollatorConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
165 {
166     IntlCollatorConstructor* thisObject = jsCast<IntlCollatorConstructor*>(cell);
167     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
168
169     Base::visitChildren(thisObject, visitor);
170
171     visitor.append(&thisObject->m_collatorStructure);
172 }
173
174 } // namespace JSC
175
176 #endif // ENABLE(INTL)