tor-browser

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

WeakMapObject-inl.h (3182B)


      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 #ifndef builtin_WeakMapObject_inl_h
      8 #define builtin_WeakMapObject_inl_h
      9 
     10 #include "builtin/WeakMapObject.h"
     11 
     12 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
     13 #include "js/Prefs.h"
     14 #include "js/Wrapper.h"
     15 #include "gc/WeakMap-inl.h"
     16 #include "vm/JSObject-inl.h"
     17 
     18 namespace js {
     19 
     20 static bool TryPreserveReflector(JSContext* cx, HandleObject obj) {
     21  if (!MaybePreserveDOMWrapper(cx, obj)) {
     22    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
     23                              JSMSG_BAD_WEAKMAP_KEY);
     24    return false;
     25  }
     26 
     27  return true;
     28 }
     29 
     30 static MOZ_ALWAYS_INLINE bool EnsureObjectHasWeakMap(
     31    JSContext* cx, WeakCollectionObject* obj) {
     32  if (obj->getMap()) {
     33    return true;
     34  }
     35  auto newMap = cx->make_unique<WeakCollectionObject::Map>(cx, obj);
     36  if (!newMap) {
     37    return false;
     38  }
     39  WeakCollectionObject::Map* map = newMap.release();
     40  InitReservedSlot(obj, WeakCollectionObject::DataSlot, map,
     41                   MemoryUse::WeakMapObject);
     42  return true;
     43 }
     44 
     45 static MOZ_ALWAYS_INLINE bool PreserveReflectorAndAssertValidEntry(
     46    JSContext* cx, Handle<WeakCollectionObject*> obj, HandleValue key,
     47    HandleValue value) {
     48  if (key.isObject()) {
     49    RootedObject keyObj(cx, &key.toObject());
     50 
     51    // Preserve wrapped native keys to prevent wrapper optimization.
     52    if (!TryPreserveReflector(cx, keyObj)) {
     53      return false;
     54    }
     55 
     56    RootedObject delegate(cx, UncheckedUnwrapWithoutExpose(keyObj));
     57    if (delegate && !TryPreserveReflector(cx, delegate)) {
     58      return false;
     59    }
     60  }
     61 
     62  MOZ_ASSERT_IF(key.isObject(),
     63                key.toObject().compartment() == obj->compartment());
     64  MOZ_ASSERT_IF(value.isGCThing(),
     65                gc::ToMarkable(value)->zoneFromAnyThread() == obj->zone() ||
     66                    gc::ToMarkable(value)->zoneFromAnyThread()->isAtomsZone());
     67  MOZ_ASSERT_IF(value.isObject(),
     68                value.toObject().compartment() == obj->compartment());
     69  return true;
     70 }
     71 
     72 static MOZ_ALWAYS_INLINE bool WeakCollectionPutEntryInternal(
     73    JSContext* cx, Handle<WeakCollectionObject*> obj, HandleValue key,
     74    HandleValue value) {
     75  if (!EnsureObjectHasWeakMap(cx, obj)) {
     76    return false;
     77  }
     78 
     79  if (!PreserveReflectorAndAssertValidEntry(cx, obj, key, value)) {
     80    return false;
     81  }
     82 
     83  if (!obj->getMap()->put(key, value)) {
     84    JS_ReportOutOfMemory(cx);
     85    return false;
     86  }
     87  return true;
     88 }
     89 
     90 static unsigned GetErrorNumber(bool isWeakMap) {
     91  bool symbolsAsWeakMapKeysEnabled =
     92      JS::Prefs::experimental_symbols_as_weakmap_keys();
     93 
     94  if (symbolsAsWeakMapKeysEnabled) {
     95    return isWeakMap ? JSMSG_WEAKMAP_KEY_CANT_BE_HELD_WEAKLY
     96                     : JSMSG_WEAKSET_VAL_CANT_BE_HELD_WEAKLY;
     97  }
     98 
     99  return isWeakMap ? JSMSG_WEAKMAP_KEY_MUST_BE_AN_OBJECT
    100                   : JSMSG_WEAKSET_VAL_MUST_BE_AN_OBJECT;
    101 }
    102 
    103 }  // namespace js
    104 
    105 #endif /* builtin_WeakMapObject_inl_h */