tor-browser

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

mozJSLoaderUtils.cpp (2483B)


      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 "mozilla/scache/StartupCache.h"
      8 
      9 #include "jsapi.h"
     10 #include "jsfriendapi.h"
     11 #include "js/CompileOptions.h"
     12 #include "js/Transcoding.h"
     13 #include "js/experimental/JSStencil.h"
     14 
     15 #include "mozilla/BasePrincipal.h"
     16 #include "mozilla/Span.h"
     17 
     18 using namespace JS;
     19 using namespace mozilla::scache;
     20 using mozilla::UniquePtr;
     21 
     22 static nsresult HandleTranscodeResult(JSContext* cx,
     23                                      JS::TranscodeResult result) {
     24  if (result == JS::TranscodeResult::Ok) {
     25    return NS_OK;
     26  }
     27 
     28  if (result == JS::TranscodeResult::Throw) {
     29    JS_ClearPendingException(cx);
     30    return NS_ERROR_OUT_OF_MEMORY;
     31  }
     32 
     33  MOZ_ASSERT(IsTranscodeFailureResult(result));
     34  return NS_ERROR_FAILURE;
     35 }
     36 
     37 nsresult ReadCachedStencil(StartupCache* cache, nsACString& cachePath,
     38                           JSContext* cx,
     39                           const JS::ReadOnlyDecodeOptions& options,
     40                           JS::Stencil** stencilOut) {
     41  MOZ_ASSERT(options.borrowBuffer);
     42  MOZ_ASSERT(!options.usePinnedBytecode);
     43 
     44  const char* buf;
     45  uint32_t len;
     46  nsresult rv =
     47      cache->GetBuffer(PromiseFlatCString(cachePath).get(), &buf, &len);
     48  if (NS_FAILED(rv)) {
     49    return rv;  // don't warn since NOT_AVAILABLE is an ok error
     50  }
     51 
     52  JS::TranscodeRange range(AsBytes(mozilla::Span(buf, len)));
     53  JS::TranscodeResult code = JS::DecodeStencil(cx, options, range, stencilOut);
     54  return HandleTranscodeResult(cx, code);
     55 }
     56 
     57 nsresult WriteCachedStencil(StartupCache* cache, nsACString& cachePath,
     58                            JSContext* cx, JS::Stencil* stencil) {
     59  JS::TranscodeBuffer buffer;
     60  JS::TranscodeResult code = JS::EncodeStencil(cx, stencil, buffer);
     61  if (code != JS::TranscodeResult::Ok) {
     62    return HandleTranscodeResult(cx, code);
     63  }
     64 
     65  size_t size = buffer.length();
     66  if (size > UINT32_MAX) {
     67    return NS_ERROR_FAILURE;
     68  }
     69 
     70  // Move the vector buffer into a unique pointer buffer.
     71  mozilla::UniqueFreePtr<char[]> buf(
     72      reinterpret_cast<char*>(buffer.extractOrCopyRawBuffer()));
     73  nsresult rv = cache->PutBuffer(PromiseFlatCString(cachePath).get(),
     74                                 std::move(buf), size);
     75  return rv;
     76 }