tor-browser

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

jsshell.h (7693B)


      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 jsshell_js_h
      8 #define jsshell_js_h
      9 
     10 #include "mozilla/Atomics.h"
     11 #include "mozilla/Maybe.h"
     12 #include "mozilla/TimeStamp.h"
     13 
     14 #include "builtin/MapObject.h"
     15 #include "js/CompileOptions.h"
     16 #include "js/GCVector.h"
     17 #include "shell/ModuleLoader.h"
     18 #include "threading/ConditionVariable.h"
     19 #include "threading/LockGuard.h"
     20 #include "threading/Mutex.h"
     21 #include "threading/Thread.h"
     22 #include "vm/GeckoProfiler.h"
     23 #include "vm/Monitor.h"
     24 
     25 // Some platform hooks must be implemented for single-step profiling.
     26 #if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS64) || \
     27    defined(JS_SIMULATOR_ARM64) || defined(JS_SIMULATOR_LOONG64)
     28 #  define SINGLESTEP_PROFILING
     29 #endif
     30 
     31 namespace js {
     32 namespace shell {
     33 
     34 // Define use of application-specific slots on the shell's global object.
     35 enum GlobalAppSlot { GlobalAppSlotModuleRegistry, GlobalAppSlotCount };
     36 static_assert(GlobalAppSlotCount <= JSCLASS_GLOBAL_APPLICATION_SLOTS,
     37              "Too many applications slots defined for shell global");
     38 
     39 enum JSShellErrNum {
     40 #define MSG_DEF(name, count, exception, format) name,
     41 #include "jsshell.msg"
     42 #undef MSG_DEF
     43  JSShellErr_Limit
     44 };
     45 
     46 const JSErrorFormatString* my_GetErrorMessage(void* userRef,
     47                                              const unsigned errorNumber);
     48 
     49 void WarningReporter(JSContext* cx, JSErrorReport* report);
     50 
     51 class MOZ_STACK_CLASS AutoReportException {
     52  JSContext* cx;
     53 
     54 public:
     55  explicit AutoReportException(JSContext* cx) : cx(cx) {}
     56  ~AutoReportException();
     57 };
     58 
     59 bool GenerateInterfaceHelp(JSContext* cx, JS::HandleObject obj,
     60                           const char* name);
     61 
     62 JSString* FileAsString(JSContext* cx, JS::HandleString pathnameStr);
     63 
     64 class AutoCloseFile {
     65 private:
     66  FILE* f_;
     67 
     68 public:
     69  explicit AutoCloseFile(FILE* f) : f_(f) {}
     70  ~AutoCloseFile() { (void)release(); }
     71  bool release() {
     72    bool success = true;
     73    if (f_ && f_ != stdin && f_ != stdout && f_ != stderr) {
     74      success = !fclose(f_);
     75    }
     76    f_ = nullptr;
     77    return success;
     78  }
     79 };
     80 
     81 // Reference counted file.
     82 struct RCFile {
     83  FILE* fp;
     84  uint32_t numRefs;
     85 
     86  RCFile() : fp(nullptr), numRefs(0) {}
     87  explicit RCFile(FILE* fp) : fp(fp), numRefs(0) {}
     88 
     89  void acquire() { numRefs++; }
     90 
     91  // Starts out with a ref count of zero.
     92  static RCFile* create(JSContext* cx, const char* filename, const char* mode);
     93 
     94  void close();
     95  bool isOpen() const { return fp; }
     96  bool release();
     97 };
     98 
     99 // Shell command-line arguments and count.
    100 extern int sArgc;
    101 extern char** sArgv;
    102 
    103 // Shell state set once at startup.
    104 extern const char* selfHostedXDRPath;
    105 extern bool encodeSelfHostedCode;
    106 extern bool enableCodeCoverage;
    107 extern bool enableDisassemblyDumps;
    108 extern bool offthreadBaselineCompilation;
    109 extern bool offthreadIonCompilation;
    110 extern JS::DelazificationOption defaultDelazificationMode;
    111 extern bool enableAsmJS;
    112 extern bool enableWasm;
    113 extern bool enableSharedMemory;
    114 extern bool enableWasmBaseline;
    115 extern bool enableWasmOptimizing;
    116 extern bool enableTestWasmAwaitTier2;
    117 extern bool enableSourcePragmas;
    118 extern bool enableAsyncStacks;
    119 extern bool enableAsyncStackCaptureDebuggeeOnly;
    120 extern bool enableWeakRefs;
    121 extern bool enableToSource;
    122 extern bool enablePropertyErrorMessageFix;
    123 extern bool enableIteratorHelpers;
    124 extern bool enableShadowRealms;
    125 extern bool enableArrayGrouping;
    126 extern bool enableWellFormedUnicodeStrings;
    127 extern bool enableArrayBufferTransfer;
    128 extern bool enableArrayBufferResizable;
    129 extern bool enableSymbolsAsWeakMapKeys;
    130 extern bool enableNewSetMethods;
    131 extern bool enableDestructuringFuse;
    132 #ifdef JS_GC_ZEAL
    133 extern uint32_t gZealBits;
    134 extern uint32_t gZealFrequency;
    135 #endif
    136 extern bool printTiming;
    137 extern RCFile* gErrFile;
    138 extern RCFile* gOutFile;
    139 extern bool reportWarnings;
    140 extern bool compileOnly;
    141 extern bool disableOOMFunctions;
    142 extern bool defaultToSameCompartment;
    143 
    144 #ifdef DEBUG
    145 extern bool dumpEntrainedVariables;
    146 extern bool OOM_printAllocationCount;
    147 #endif
    148 
    149 extern bool useFdlibmForSinCosTan;
    150 
    151 extern UniqueChars processWideModuleLoadPath;
    152 
    153 // Alias the global dstName to namespaceObj.srcName. For example, if dstName is
    154 // "snarf", namespaceObj represents "os.file", and srcName is "readFile", then
    155 // this is equivalent to the JS code:
    156 //
    157 //   snarf = os.file.readFile;
    158 //
    159 // This provides a mechanism for namespacing the various JS shell helper
    160 // functions without breaking backwards compatibility with things that use the
    161 // global names.
    162 bool CreateAlias(JSContext* cx, const char* dstName,
    163                 JS::HandleObject namespaceObj, const char* srcName);
    164 
    165 class NonShrinkingValueVector
    166    : public GCVector<HeapPtr<Value>, 0, SystemAllocPolicy> {
    167  using Base = GCVector<HeapPtr<Value>, 0, SystemAllocPolicy>;
    168 
    169 public:
    170  bool traceWeak(JSTracer* trc) {
    171    for (HeapPtr<Value>& value : *this) {
    172      if (value.isGCThing()) {
    173        Zone* zone = value.toGCThing()->zoneFromAnyThread();
    174        if (zone->isGCSweeping() || zone->isGCCompacting()) {
    175          TraceWeakEdge(trc, &value, "NonShrinkingValueVector element");
    176        }
    177      }
    178    }
    179    return true;
    180  }
    181 };
    182 
    183 using MarkBitObservers = JS::WeakCache<NonShrinkingValueVector>;
    184 
    185 #ifdef SINGLESTEP_PROFILING
    186 using StackChars = Vector<char16_t, 0, SystemAllocPolicy>;
    187 #endif
    188 
    189 class OffThreadJob;
    190 
    191 // Per-context shell state.
    192 struct ShellContext {
    193  enum IsWorkerEnum { Worker = true, MainThread = false };
    194 
    195  explicit ShellContext(JSContext* cx, IsWorkerEnum isWorker_);
    196  bool registerWithCx(JSContext* cx);
    197  ~ShellContext();
    198 
    199  JSContext* cx_;
    200 
    201  const IsWorkerEnum isWorker;
    202  bool lastWarningEnabled;
    203 
    204  // Track promise rejections and report unhandled rejections.
    205  bool trackUnhandledRejections;
    206 
    207  double timeoutInterval;
    208  double startTime;
    209  mozilla::Atomic<bool> serviceInterrupt;
    210  mozilla::Atomic<bool> haveInterruptFunc;
    211  JS::PersistentRootedValue interruptFunc;
    212  JS::PersistentRootedValue lastWarning;
    213  JS::PersistentRootedValue promiseRejectionTrackerCallback;
    214 
    215  // Rejected promises that are not yet handled. Added when rejection
    216  // happens, and removed when rejection is handled. This uses SetObject to
    217  // report unhandled rejections in the rejected order.
    218  JS::PersistentRooted<SetObject*> unhandledRejectedPromises;
    219 
    220 #ifdef SINGLESTEP_PROFILING
    221  Vector<StackChars, 0, SystemAllocPolicy> stacks;
    222 #endif
    223 
    224  /*
    225   * Watchdog thread state.
    226   */
    227  js::Mutex watchdogLock MOZ_UNANNOTATED;
    228  js::ConditionVariable watchdogWakeup;
    229  mozilla::Maybe<js::Thread> watchdogThread;
    230  mozilla::Maybe<mozilla::TimeStamp> watchdogTimeout;
    231 
    232  js::ConditionVariable sleepWakeup;
    233 
    234  int exitCode;
    235  bool quitting;
    236 
    237  JS::UniqueChars readLineBuf;
    238  size_t readLineBufPos;
    239 
    240  js::shell::RCFile** errFilePtr;
    241  js::shell::RCFile** outFilePtr;
    242 
    243  UniquePtr<ProfilingStack> geckoProfilingStack;
    244 
    245  UniquePtr<ModuleLoader> moduleLoader;
    246 
    247  UniquePtr<MarkBitObservers> markObservers;
    248 
    249  // Off-thread parse state.
    250  js::Monitor offThreadMonitor MOZ_UNANNOTATED;
    251  Vector<OffThreadJob*, 0, SystemAllocPolicy> offThreadJobs;
    252 
    253  // Queued task callbacks that run after the microtask queue.
    254 
    255  using ObjectVector = GCVector<JSObject*, 0, SystemAllocPolicy>;
    256  JS::PersistentRooted<ObjectVector> taskCallbacks;
    257 };
    258 
    259 extern ShellContext* GetShellContext(JSContext* cx);
    260 
    261 [[nodiscard]] extern bool PrintStackTrace(JSContext* cx,
    262                                          JS::Handle<JSObject*> stackObj);
    263 
    264 } /* namespace shell */
    265 } /* namespace js */
    266 
    267 #endif