tor-browser

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

ObjectWithStashedPointer.cpp (2418B)


      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 #include "js/ObjectWithStashedPointer.h"
      8 #include "jsapi.h"         // JS_NewObject
      9 #include "vm/JSContext.h"  // CHECK_THREAD
     10 
     11 namespace JS::detail {
     12 
     13 static const size_t DATA_SLOT = 0;
     14 static const size_t FREE_FUNC_SLOT = 1;
     15 
     16 static void ObjectWithUntypedStashedPointerFinalize(JS::GCContext*,
     17                                                    JSObject* obj) {
     18  AutoAssertNoGC nogc;
     19 
     20  void* freeFunc = GetMaybePtrFromReservedSlot<void>(obj, FREE_FUNC_SLOT);
     21  void* data = GetMaybePtrFromReservedSlot<void>(obj, DATA_SLOT);
     22 
     23  reinterpret_cast<UntypedFreeFunction>(freeFunc)(data);
     24 }
     25 
     26 static const JSClassOps classOps = {
     27    nullptr,  // addProperty
     28    nullptr,  // delProperty
     29    nullptr,  // enumerate
     30    nullptr,  // newEnumerate
     31    nullptr,  // resolve
     32    nullptr,  // mayResolve
     33    ObjectWithUntypedStashedPointerFinalize,
     34    nullptr,  // call
     35    nullptr,  // construct
     36    nullptr,  // trace
     37 };
     38 
     39 static const JSClass DataOnlyClass = {
     40    "Object",
     41    JSCLASS_HAS_RESERVED_SLOTS(1),
     42 };
     43 
     44 static const JSClass FreeFuncClass = {
     45    "Object",
     46    JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_FOREGROUND_FINALIZE,
     47    &classOps,
     48 };
     49 
     50 JSObject* NewObjectWithUntypedStashedPointer(JSContext* cx, void* ptr,
     51                                             UntypedFreeFunction freeFunc) {
     52  if (!freeFunc) {
     53    JSObject* retval = JS_NewObject(cx, &DataOnlyClass);
     54    if (!retval) {
     55      return nullptr;
     56    }
     57    JS::SetReservedSlot(retval, DATA_SLOT, JS::PrivateValue(ptr));
     58    return retval;
     59  }
     60 
     61  JSObject* retval = JS_NewObject(cx, &FreeFuncClass);
     62  if (!retval) {
     63    return nullptr;
     64  }
     65  JS::SetReservedSlot(retval, DATA_SLOT, JS::PrivateValue(ptr));
     66  JS::SetReservedSlot(retval, FREE_FUNC_SLOT,
     67                      JS::PrivateValue(reinterpret_cast<void*>(freeFunc)));
     68  return retval;
     69 }
     70 
     71 void* ObjectGetUntypedStashedPointer(JSContext* cx, JSObject* obj) {
     72  MOZ_ASSERT(
     73      obj->getClass() == &FreeFuncClass || obj->getClass() == &DataOnlyClass,
     74      "wrong type of object");
     75  return JS::GetMaybePtrFromReservedSlot<void>(obj, DATA_SLOT);
     76 }
     77 
     78 }  // namespace JS::detail