1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 2 * vim: set ts=8 sts=4 et sw=4 tw=99: 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 #include "mozilla/Variant.h" 14 15 #include "jsapi.h" 16 17 #include "js/GCVector.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 #define SINGLESTEP_PROFILING 28 #endif 29 30 namespace js { 31 namespace shell { 32 33 enum JSShellErrNum { 34 #define MSG_DEF(name, count, exception, format) name, 35 #include "jsshell.msg" 36 #undef MSG_DEF 37 JSShellErr_Limit 38 }; 39 40 const JSErrorFormatString* my_GetErrorMessage(void* userRef, 41 const unsigned errorNumber); 42 43 void WarningReporter(JSContext* cx, JSErrorReport* report); 44 45 class MOZ_STACK_CLASS AutoReportException { 46 JSContext* cx; 47 48 public: AutoReportException(JSContext * cx)49 explicit AutoReportException(JSContext* cx) : cx(cx) {} 50 ~AutoReportException(); 51 }; 52 53 bool GenerateInterfaceHelp(JSContext* cx, JS::HandleObject obj, 54 const char* name); 55 56 JSString* FileAsString(JSContext* cx, JS::HandleString pathnameStr); 57 58 class AutoCloseFile { 59 private: 60 FILE* f_; 61 62 public: AutoCloseFile(FILE * f)63 explicit AutoCloseFile(FILE* f) : f_(f) {} ~AutoCloseFile()64 ~AutoCloseFile() { (void)release(); } release()65 bool release() { 66 bool success = true; 67 if (f_ && f_ != stdin && f_ != stdout && f_ != stderr) 68 success = !fclose(f_); 69 f_ = nullptr; 70 return success; 71 } 72 }; 73 74 // Reference counted file. 75 struct RCFile { 76 FILE* fp; 77 uint32_t numRefs; 78 RCFileRCFile79 RCFile() : fp(nullptr), numRefs(0) {} RCFileRCFile80 explicit RCFile(FILE* fp) : fp(fp), numRefs(0) {} 81 acquireRCFile82 void acquire() { numRefs++; } 83 84 // Starts out with a ref count of zero. 85 static RCFile* create(JSContext* cx, const char* filename, const char* mode); 86 87 void close(); isOpenRCFile88 bool isOpen() const { return fp; } 89 bool release(); 90 }; 91 92 // Alias the global dstName to namespaceObj.srcName. For example, if dstName is 93 // "snarf", namespaceObj represents "os.file", and srcName is "readFile", then 94 // this is equivalent to the JS code: 95 // 96 // snarf = os.file.readFile; 97 // 98 // This provides a mechanism for namespacing the various JS shell helper 99 // functions without breaking backwards compatibility with things that use the 100 // global names. 101 bool CreateAlias(JSContext* cx, const char* dstName, 102 JS::HandleObject namespaceObj, const char* srcName); 103 104 enum class ScriptKind { Script, DecodeScript, Module }; 105 106 class NonshrinkingGCObjectVector 107 : public GCVector<JSObject*, 0, SystemAllocPolicy> { 108 public: sweep()109 void sweep() { 110 for (uint32_t i = 0; i < this->length(); i++) { 111 if (JS::GCPolicy<JSObject*>::needsSweep(&(*this)[i])) 112 (*this)[i] = nullptr; 113 } 114 } 115 }; 116 117 using MarkBitObservers = JS::WeakCache<NonshrinkingGCObjectVector>; 118 119 #ifdef SINGLESTEP_PROFILING 120 using StackChars = Vector<char16_t, 0, SystemAllocPolicy>; 121 #endif 122 123 class OffThreadJob; 124 125 // Per-context shell state. 126 struct ShellContext { 127 explicit ShellContext(JSContext* cx); 128 ~ShellContext(); 129 130 bool isWorker; 131 double timeoutInterval; 132 double startTime; 133 mozilla::Atomic<bool> serviceInterrupt; 134 mozilla::Atomic<bool> haveInterruptFunc; 135 JS::PersistentRootedValue interruptFunc; 136 bool lastWarningEnabled; 137 JS::PersistentRootedValue lastWarning; 138 JS::PersistentRootedValue promiseRejectionTrackerCallback; 139 #ifdef SINGLESTEP_PROFILING 140 Vector<StackChars, 0, SystemAllocPolicy> stacks; 141 #endif 142 143 /* 144 * Watchdog thread state. 145 */ 146 js::Mutex watchdogLock; 147 js::ConditionVariable watchdogWakeup; 148 mozilla::Maybe<js::Thread> watchdogThread; 149 mozilla::Maybe<mozilla::TimeStamp> watchdogTimeout; 150 151 js::ConditionVariable sleepWakeup; 152 153 int exitCode; 154 bool quitting; 155 156 JS::UniqueChars readLineBuf; 157 size_t readLineBufPos; 158 159 js::shell::RCFile** errFilePtr; 160 js::shell::RCFile** outFilePtr; 161 162 UniquePtr<PseudoStack> geckoProfilingStack; 163 164 JS::UniqueChars moduleLoadPath; 165 UniquePtr<MarkBitObservers> markObservers; 166 167 // Off-thread parse state. 168 js::Monitor offThreadMonitor; 169 Vector<OffThreadJob*, 0, SystemAllocPolicy> offThreadJobs; 170 }; 171 172 extern ShellContext* GetShellContext(JSContext* cx); 173 174 } /* namespace shell */ 175 } /* namespace js */ 176 177 #endif 178