tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CommonFunctions.cpp (5525B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* Operations used to implement multiple Intl.* classes. */
      8 
      9 #include "builtin/intl/CommonFunctions.h"
     10 
     11 #include "mozilla/Assertions.h"
     12 #include "mozilla/intl/ICUError.h"
     13 #include "mozilla/TextUtils.h"
     14 
     15 #include <algorithm>
     16 
     17 #include "gc/GCEnum.h"
     18 #include "gc/ZoneAllocator.h"
     19 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_INTERNAL_INTL_ERROR
     20 #include "js/Value.h"
     21 #include "vm/JSAtomState.h"
     22 #include "vm/JSContext.h"
     23 #include "vm/JSObject.h"
     24 #include "vm/SelfHosting.h"
     25 #include "vm/Stack.h"
     26 #include "vm/StringType.h"
     27 
     28 #include "gc/GCContext-inl.h"
     29 
     30 bool js::intl::InitializeObject(JSContext* cx, JS::Handle<JSObject*> obj,
     31                                JS::Handle<PropertyName*> initializer,
     32                                JS::Handle<JS::Value> locales,
     33                                JS::Handle<JS::Value> options) {
     34  FixedInvokeArgs<3> args(cx);
     35 
     36  args[0].setObject(*obj);
     37  args[1].set(locales);
     38  args[2].set(options);
     39 
     40  RootedValue ignored(cx);
     41  if (!CallSelfHostedFunction(cx, initializer, JS::NullHandleValue, args,
     42                              &ignored)) {
     43    return false;
     44  }
     45 
     46  MOZ_ASSERT(ignored.isUndefined(),
     47             "Unexpected return value from Intl object initializer");
     48  return true;
     49 }
     50 
     51 bool js::intl::InitializeDateTimeFormatObject(
     52    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> thisValue,
     53    JS::Handle<JS::Value> locales, JS::Handle<JS::Value> options,
     54    JS::Handle<JSString*> required, JS::Handle<JSString*> defaults,
     55    JS::Handle<JS::Value> toLocaleStringTimeZone,
     56    DateTimeFormatOptions dtfOptions, JS::MutableHandle<JS::Value> result) {
     57  Handle<PropertyName*> initializer = cx->names().InitializeDateTimeFormat;
     58 
     59  FixedInvokeArgs<8> args(cx);
     60 
     61  args[0].setObject(*obj);
     62  args[1].set(thisValue);
     63  args[2].set(locales);
     64  args[3].set(options);
     65  args[4].setString(required);
     66  args[5].setString(defaults);
     67  args[6].set(toLocaleStringTimeZone);
     68  args[7].setBoolean(dtfOptions == DateTimeFormatOptions::EnableMozExtensions);
     69 
     70  if (!CallSelfHostedFunction(cx, initializer, NullHandleValue, args, result)) {
     71    return false;
     72  }
     73 
     74  MOZ_ASSERT(result.isObject(),
     75             "Intl.DateTimeFormat initializer must return an object");
     76  return true;
     77 }
     78 
     79 bool js::intl::InitializeNumberFormatObject(
     80    JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> thisValue,
     81    JS::Handle<JS::Value> locales, JS::Handle<JS::Value> options,
     82    JS::MutableHandle<JS::Value> result) {
     83  Handle<PropertyName*> initializer = cx->names().InitializeNumberFormat;
     84 
     85  FixedInvokeArgs<4> args(cx);
     86 
     87  args[0].setObject(*obj);
     88  args[1].set(thisValue);
     89  args[2].set(locales);
     90  args[3].set(options);
     91 
     92  if (!CallSelfHostedFunction(cx, initializer, NullHandleValue, args, result)) {
     93    return false;
     94  }
     95 
     96  MOZ_ASSERT(result.isObject(),
     97             "Intl.NumberFormat initializer must return an object");
     98  return true;
     99 }
    100 
    101 JSObject* js::intl::GetInternalsObject(JSContext* cx,
    102                                       JS::Handle<JSObject*> obj) {
    103  FixedInvokeArgs<1> args(cx);
    104 
    105  args[0].setObject(*obj);
    106 
    107  RootedValue v(cx);
    108  if (!js::CallSelfHostedFunction(cx, cx->names().getInternals, NullHandleValue,
    109                                  args, &v)) {
    110    return nullptr;
    111  }
    112 
    113  return &v.toObject();
    114 }
    115 
    116 void js::intl::ReportInternalError(JSContext* cx) {
    117  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
    118                            JSMSG_INTERNAL_INTL_ERROR);
    119 }
    120 
    121 void js::intl::ReportInternalError(JSContext* cx,
    122                                   mozilla::intl::ICUError error) {
    123  switch (error) {
    124    case mozilla::intl::ICUError::OutOfMemory:
    125      ReportOutOfMemory(cx);
    126      return;
    127    case mozilla::intl::ICUError::InternalError:
    128      ReportInternalError(cx);
    129      return;
    130    case mozilla::intl::ICUError::OverflowError:
    131      ReportAllocationOverflow(cx);
    132      return;
    133  }
    134  MOZ_CRASH("Unexpected ICU error");
    135 }
    136 
    137 const js::intl::OldStyleLanguageTagMapping
    138    js::intl::oldStyleLanguageTagMappings[] = {
    139        {"pa-PK", "pa-Arab-PK"}, {"zh-CN", "zh-Hans-CN"},
    140        {"zh-HK", "zh-Hant-HK"}, {"zh-SG", "zh-Hans-SG"},
    141        {"zh-TW", "zh-Hant-TW"},
    142 };
    143 
    144 js::UniqueChars js::intl::EncodeLocale(JSContext* cx, JSString* locale) {
    145  MOZ_ASSERT(locale->length() > 0);
    146 
    147  js::UniqueChars chars = EncodeAscii(cx, locale);
    148  if (!chars) {
    149    return nullptr;
    150  }
    151 
    152  // Ensure the returned value contains only valid BCP 47 characters.
    153  MOZ_ASSERT(mozilla::IsAsciiAlpha(chars[0]));
    154  MOZ_ASSERT(std::all_of(
    155      chars.get(), chars.get() + locale->length(),
    156      [](char c) { return mozilla::IsAsciiAlphanumeric(c) || c == '-'; }));
    157 
    158  return chars;
    159 }
    160 
    161 void js::intl::AddICUCellMemory(JSObject* obj, size_t nbytes) {
    162  // Account the (estimated) number of bytes allocated by an ICU object against
    163  // the JSObject's zone.
    164  AddCellMemory(obj, nbytes, MemoryUse::ICUObject);
    165 }
    166 
    167 void js::intl::RemoveICUCellMemory(JSObject* obj, size_t nbytes) {
    168  RemoveCellMemory(obj, nbytes, MemoryUse::ICUObject);
    169 }
    170 
    171 void js::intl::RemoveICUCellMemory(JS::GCContext* gcx, JSObject* obj,
    172                                   size_t nbytes) {
    173  gcx->removeCellMemory(obj, nbytes, MemoryUse::ICUObject);
    174 }