/ runtime / IntlListFormatConstructor.cpp
IntlListFormatConstructor.cpp
  1  /*
  2   * Copyright (C) 2020 Apple Inc. All rights reserved.
  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  #include "config.h"
 27  #include "IntlListFormatConstructor.h"
 28  
 29  #include "IntlListFormat.h"
 30  #include "IntlListFormatPrototype.h"
 31  #include "JSCInlines.h"
 32  
 33  namespace JSC {
 34  
 35  STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(IntlListFormatConstructor);
 36  
 37  static JSC_DECLARE_HOST_FUNCTION(IntlListFormatConstructorSupportedLocalesOf);
 38  
 39  }
 40  
 41  #include "IntlListFormatConstructor.lut.h"
 42  
 43  namespace JSC {
 44  
 45  const ClassInfo IntlListFormatConstructor::s_info = { "Function", &Base::s_info, &listFormatConstructorTable, nullptr, CREATE_METHOD_TABLE(IntlListFormatConstructor) };
 46  
 47  /* Source for IntlListFormatConstructor.lut.h
 48  @begin listFormatConstructorTable
 49    supportedLocalesOf             IntlListFormatConstructorSupportedLocalesOf             DontEnum|Function 1
 50  @end
 51  */
 52  
 53  IntlListFormatConstructor* IntlListFormatConstructor::create(VM& vm, Structure* structure, IntlListFormatPrototype* listFormatPrototype)
 54  {
 55      auto* constructor = new (NotNull, allocateCell<IntlListFormatConstructor>(vm.heap)) IntlListFormatConstructor(vm, structure);
 56      constructor->finishCreation(vm, listFormatPrototype);
 57      return constructor;
 58  }
 59  
 60  Structure* IntlListFormatConstructor::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 61  {
 62      return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
 63  }
 64  
 65  static JSC_DECLARE_HOST_FUNCTION(callIntlListFormat);
 66  static JSC_DECLARE_HOST_FUNCTION(constructIntlListFormat);
 67  
 68  IntlListFormatConstructor::IntlListFormatConstructor(VM& vm, Structure* structure)
 69      : Base(vm, structure, callIntlListFormat, constructIntlListFormat)
 70  {
 71  }
 72  
 73  void IntlListFormatConstructor::finishCreation(VM& vm, IntlListFormatPrototype* listFormatPrototype)
 74  {
 75      Base::finishCreation(vm, 0, "ListFormat"_s, PropertyAdditionMode::WithoutStructureTransition);
 76      putDirectWithoutTransition(vm, vm.propertyNames->prototype, listFormatPrototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
 77      listFormatPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, this, static_cast<unsigned>(PropertyAttribute::DontEnum));
 78  }
 79  
 80  // https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
 81  JSC_DEFINE_HOST_FUNCTION(constructIntlListFormat, (JSGlobalObject* globalObject, CallFrame* callFrame))
 82  {
 83      VM& vm = globalObject->vm();
 84      auto scope = DECLARE_THROW_SCOPE(vm);
 85  
 86      JSObject* newTarget = asObject(callFrame->newTarget());
 87      Structure* structure = newTarget == callFrame->jsCallee()
 88          ? globalObject->listFormatStructure()
 89          : InternalFunction::createSubclassStructure(globalObject, newTarget, getFunctionRealm(vm, newTarget)->listFormatStructure());
 90      RETURN_IF_EXCEPTION(scope, { });
 91  
 92      IntlListFormat* listFormat = IntlListFormat::create(vm, structure);
 93      ASSERT(listFormat);
 94  
 95      scope.release();
 96      listFormat->initializeListFormat(globalObject, callFrame->argument(0), callFrame->argument(1));
 97      return JSValue::encode(listFormat);
 98  }
 99  
100  // https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat
101  JSC_DEFINE_HOST_FUNCTION(callIntlListFormat, (JSGlobalObject* globalObject, CallFrame*))
102  {
103      VM& vm = globalObject->vm();
104      auto scope = DECLARE_THROW_SCOPE(vm);
105  
106      return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(globalObject, scope, "ListFormat"));
107  }
108  
109  JSC_DEFINE_HOST_FUNCTION(IntlListFormatConstructorSupportedLocalesOf, (JSGlobalObject* globalObject, CallFrame* callFrame))
110  {
111      VM& vm = globalObject->vm();
112      auto scope = DECLARE_THROW_SCOPE(vm);
113      // Intl.ListFormat.supportedLocalesOf(locales [, options])
114      // https://tc39.es/proposal-intl-list-format/#sec-Intl.ListFormat.supportedLocalesOf
115  
116      // 1. Let availableLocales be %ListFormat%.[[availableLocales]].
117      const HashSet<String>& availableLocales = intlListFormatAvailableLocales();
118  
119      // 2. Let requestedLocales be CanonicalizeLocaleList(locales).
120      Vector<String> requestedLocales = canonicalizeLocaleList(globalObject, callFrame->argument(0));
121      RETURN_IF_EXCEPTION(scope, encodedJSValue());
122  
123      // 3. Return SupportedLocales(availableLocales, requestedLocales, options).
124      RELEASE_AND_RETURN(scope, JSValue::encode(supportedLocales(globalObject, availableLocales, requestedLocales, callFrame->argument(1))));
125  }
126  
127  
128  } // namespace JSC