| /* | 
 |  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | 
 |  *  Copyright (C) 2004-2021 Apple Inc. All rights reserved. | 
 |  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com) | 
 |  * | 
 |  *  This library is free software; you can redistribute it and/or | 
 |  *  modify it under the terms of the GNU Library General Public | 
 |  *  License as published by the Free Software Foundation; either | 
 |  *  version 2 of the License, or (at your option) any later version. | 
 |  * | 
 |  *  This library is distributed in the hope that it will be useful, | 
 |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  *  Library General Public License for more details. | 
 |  * | 
 |  *  You should have received a copy of the GNU Library General Public License | 
 |  *  along with this library; see the file COPYING.LIB.  If not, write to | 
 |  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 
 |  *  Boston, MA 02110-1301, USA. | 
 |  * | 
 |  */ | 
 |  | 
 | #include "config.h" | 
 |  | 
 | #include "ArrayBuffer.h" | 
 | #include "BigIntConstructor.h" | 
 | #include "BytecodeCacheError.h" | 
 | #include "CatchScope.h" | 
 | #include "CodeBlock.h" | 
 | #include "CodeCache.h" | 
 | #include "CompilerTimingScope.h" | 
 | #include "Completion.h" | 
 | #include "ConfigFile.h" | 
 | #include "DeferredWorkTimer.h" | 
 | #include "Disassembler.h" | 
 | #include "Exception.h" | 
 | #include "ExceptionHelpers.h" | 
 | #include "HeapSnapshotBuilder.h" | 
 | #include "InitializeThreading.h" | 
 | #include "Interpreter.h" | 
 | #include "JIT.h" | 
 | #include "JITOperationList.h" | 
 | #include "JSArray.h" | 
 | #include "JSArrayBuffer.h" | 
 | #include "JSBigInt.h" | 
 | #include "JSFinalizationRegistry.h" | 
 | #include "JSFunction.h" | 
 | #include "JSInternalPromise.h" | 
 | #include "JSLock.h" | 
 | #include "JSNativeStdFunction.h" | 
 | #include "JSONObject.h" | 
 | #include "JSObjectInlines.h" | 
 | #include "JSSourceCode.h" | 
 | #include "JSString.h" | 
 | #include "JSTypedArrays.h" | 
 | #include "JSWebAssemblyInstance.h" | 
 | #include "JSWebAssemblyMemory.h" | 
 | #include "LLIntThunks.h" | 
 | #include "ObjectConstructor.h" | 
 | #include "ParserError.h" | 
 | #include "ProfilerDatabase.h" | 
 | #include "ReleaseHeapAccessScope.h" | 
 | #include "SamplingProfiler.h" | 
 | #include "SimpleTypedArrayController.h" | 
 | #include "StackVisitor.h" | 
 | #include "StructureInlines.h" | 
 | #include "SuperSampler.h" | 
 | #include "TestRunnerUtils.h" | 
 | #include "TypedArrayInlines.h" | 
 | #include "VMInspector.h" | 
 | #include "WasmCapabilities.h" | 
 | #include "WasmFaultSignalHandler.h" | 
 | #include "WasmMemory.h" | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 | #include <sys/stat.h> | 
 | #include <sys/types.h> | 
 | #include <type_traits> | 
 | #include <wtf/CPUTime.h> | 
 | #include <wtf/FileSystem.h> | 
 | #include <wtf/MainThread.h> | 
 | #include <wtf/MemoryPressureHandler.h> | 
 | #include <wtf/MonotonicTime.h> | 
 | #include <wtf/Scope.h> | 
 | #include <wtf/StringPrintStream.h> | 
 | #include <wtf/URL.h> | 
 | #include <wtf/WallTime.h> | 
 | #include <wtf/text/StringBuilder.h> | 
 | #include <wtf/threads/Signals.h> | 
 |  | 
 | #if OS(WINDOWS) | 
 | #include <direct.h> | 
 | #include <fcntl.h> | 
 | #include <io.h> | 
 | #else | 
 | #include <unistd.h> | 
 | #endif | 
 |  | 
 | #if PLATFORM(COCOA) | 
 | #include <crt_externs.h> | 
 | #endif | 
 |  | 
 | #if PLATFORM(GTK) | 
 | #include <locale.h> | 
 | #endif | 
 |  | 
 | #if HAVE(READLINE) | 
 | // readline/history.h has a Function typedef which conflicts with the WTF::Function template from WTF/Forward.h | 
 | // We #define it to something else to avoid this conflict. | 
 | #define Function ReadlineFunction | 
 | #include <readline/history.h> | 
 | #include <readline/readline.h> | 
 | #undef Function | 
 | #endif | 
 |  | 
 | #if COMPILER(MSVC) | 
 | #include <crtdbg.h> | 
 | #include <mmsystem.h> | 
 | #include <windows.h> | 
 | #endif | 
 |  | 
 | #if OS(DARWIN) && CPU(ARM_THUMB2) | 
 | #include <fenv.h> | 
 | #include <arm/arch.h> | 
 | #endif | 
 |  | 
 | #if OS(DARWIN) | 
 | #include <wtf/spi/darwin/ProcessMemoryFootprint.h> | 
 | #elif OS(LINUX) | 
 | #include <wtf/linux/ProcessMemoryFootprint.h> | 
 | #endif | 
 |  | 
 | #if OS(DARWIN) || OS(LINUX) | 
 | struct MemoryFootprint : ProcessMemoryFootprint { | 
 |     MemoryFootprint(const ProcessMemoryFootprint& src) | 
 |         : ProcessMemoryFootprint(src) | 
 |     { | 
 |     } | 
 | }; | 
 | #else | 
 | struct MemoryFootprint { | 
 |     uint64_t current; | 
 |     uint64_t peak; | 
 |  | 
 |     static MemoryFootprint now() | 
 |     { | 
 |         return { 0L, 0L }; | 
 |     } | 
 |      | 
 |     static void resetPeak() | 
 |     { | 
 |     } | 
 | }; | 
 | #endif | 
 |  | 
 | #if !defined(PATH_MAX) | 
 | #define PATH_MAX 4096 | 
 | #endif | 
 |  | 
 | using namespace JSC; | 
 |  | 
 | namespace { | 
 |  | 
 | #define EXIT_EXCEPTION 3 | 
 |  | 
 | NO_RETURN_WITH_VALUE static void jscExit(int status) | 
 | { | 
 |     waitForAsynchronousDisassembly(); | 
 |      | 
 | #if ENABLE(DFG_JIT) | 
 |     if (DFG::isCrashing()) { | 
 |         for (;;) { | 
 | #if OS(WINDOWS) | 
 |             Sleep(1000); | 
 | #else | 
 |             pause(); | 
 | #endif | 
 |         } | 
 |     } | 
 | #endif // ENABLE(DFG_JIT) | 
 |     exit(status); | 
 | } | 
 |  | 
 | static unsigned asyncTestPasses { 0 }; | 
 | static unsigned asyncTestExpectedPasses { 0 }; | 
 |  | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static bool fillBufferWithContentsOfFile(const String& fileName, Vector& buffer); | 
 | static RefPtr<Uint8Array> fillBufferWithContentsOfFile(const String& fileName); | 
 |  | 
 | class CommandLine; | 
 | class GlobalObject; | 
 | class Workers; | 
 |  | 
 | template<typename Func> | 
 | int runJSC(const CommandLine&, bool isWorker, const Func&); | 
 | static void checkException(GlobalObject*, bool isLastFile, bool hasException, JSValue, const CommandLine&, bool& success); | 
 |  | 
 | class Message : public ThreadSafeRefCounted<Message> { | 
 | public: | 
 | #if ENABLE(WEBASSEMBLY) | 
 |     using Content = Variant<ArrayBufferContents, Ref<Wasm::MemoryHandle>>; | 
 | #else | 
 |     using Content = Variant<ArrayBufferContents>; | 
 | #endif | 
 |     Message(Content&&, int32_t); | 
 |     ~Message(); | 
 |      | 
 |     Content&& releaseContents() { return WTFMove(m_contents); } | 
 |     int32_t index() const { return m_index; } | 
 |  | 
 | private: | 
 |     Content m_contents; | 
 |     int32_t m_index { 0 }; | 
 | }; | 
 |  | 
 | class Worker : public BasicRawSentinelNode<Worker> { | 
 | public: | 
 |     Worker(Workers&); | 
 |     ~Worker(); | 
 |      | 
 |     void enqueue(const AbstractLocker&, RefPtr<Message>); | 
 |     RefPtr<Message> dequeue(); | 
 |      | 
 |     static Worker& current(); | 
 |  | 
 | private: | 
 |     static ThreadSpecific<Worker*>& currentWorker(); | 
 |  | 
 |     Workers& m_workers; | 
 |     Deque<RefPtr<Message>> m_messages; | 
 | }; | 
 |  | 
 | class Workers { | 
 |     WTF_MAKE_FAST_ALLOCATED; | 
 |     WTF_MAKE_NONCOPYABLE(Workers); | 
 | public: | 
 |     Workers(); | 
 |     ~Workers(); | 
 |      | 
 |     template<typename Func> | 
 |     void broadcast(const Func&); | 
 |      | 
 |     void report(const String&); | 
 |     String tryGetReport(); | 
 |     String getReport(); | 
 |      | 
 |     static Workers& singleton(); | 
 |      | 
 | private: | 
 |     friend class Worker; | 
 |      | 
 |     Lock m_lock; | 
 |     Condition m_condition; | 
 |     SentinelLinkedList<Worker, BasicRawSentinelNode<Worker>> m_workers; | 
 |     Deque<String> m_reports; | 
 | }; | 
 |  | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCreateGlobalObject); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCreateHeapBigInt); | 
 | #if USE(BIGINT32) | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCreateBigInt32); | 
 | #endif | 
 | static JSC_DECLARE_HOST_FUNCTION(functionUseBigInt32); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIsBigInt32); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIsHeapBigInt); | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionPrintStdOut); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionPrintStdErr); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDebug); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDescribe); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDescribeArray); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSleepSeconds); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionJSCStack); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionGCAndSweep); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFullGC); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionEdenGC); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionHeapSize); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCreateMemoryFootprint); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionResetMemoryPeak); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionAddressOf); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionVersion); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionRun); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionRunString); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionLoad); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionLoadString); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionReadFile); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCheckSyntax); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionReadline); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionPreciseTime); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionNeverInlineFunction); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionNoDFG); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionNoFTL); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionNoOSRExitFuzzing); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionOptimizeNextInvocation); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionNumberOfDFGCompiles); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCallerIsOMGCompiled); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionJSCOptions); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionReoptimizationRetryCount); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionTransferArrayBuffer); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFailNextNewCodeBlock); | 
 | static NO_RETURN_WITH_VALUE JSC_DECLARE_HOST_FUNCTION(functionQuit); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFalse); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionUndefined1); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionUndefined2); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIsInt32); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIsPureNaN); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionEffectful42); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIdentity); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionMakeMasquerader); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCallMasquerader); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionHasCustomProperties); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDumpTypesForAllVariables); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDrainMicrotasks); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSetTimeout); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionReleaseWeakRefs); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFinalizationRegistryLiveCount); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFinalizationRegistryDeadCount); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIs32BitPlatform); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCheckModuleSyntax); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionPlatformSupportsSamplingProfiler); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionGenerateHeapSnapshot); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionGenerateHeapSnapshotForGCDebugging); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionResetSuperSamplerState); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionEnsureArrayStorage); | 
 | #if ENABLE(SAMPLING_PROFILER) | 
 | static JSC_DECLARE_HOST_FUNCTION(functionStartSamplingProfiler); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSamplingProfilerStackTraces); | 
 | #endif | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionMaxArguments); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionAsyncTestStart); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionAsyncTestPassed); | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 | static JSC_DECLARE_HOST_FUNCTION(functionWebAssemblyMemoryMode); | 
 | #endif | 
 |  | 
 | #if ENABLE(SAMPLING_FLAGS) | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSetSamplingFlags); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionClearSamplingFlags); | 
 | #endif | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionGetRandomSeed); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSetRandomSeed); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionIsRope); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionCallerSourceOrigin); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarCreateRealm); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarEvalScript); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentStart); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentReceiveBroadcast); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentReport); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentSleep); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentBroadcast); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentGetReport); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentLeaving); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDollarAgentMonotonicNow); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionWaitForReport); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionHeapCapacity); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionFlashHeapAccess); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDisableRichSourceInfo); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionMallocInALoop); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionTotalCompileTime); | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionSetUnhandledRejectionCallback); | 
 | static JSC_DECLARE_HOST_FUNCTION(functionAsDoubleNumber); | 
 |  | 
 | static JSC_DECLARE_HOST_FUNCTION(functionDropAllLocks); | 
 |  | 
 | struct Script { | 
 |     enum class StrictMode { | 
 |         Strict, | 
 |         Sloppy | 
 |     }; | 
 |  | 
 |     enum class ScriptType { | 
 |         Script, | 
 |         Module | 
 |     }; | 
 |  | 
 |     enum class CodeSource { | 
 |         File, | 
 |         CommandLine | 
 |     }; | 
 |  | 
 |     StrictMode strictMode; | 
 |     CodeSource codeSource; | 
 |     ScriptType scriptType; | 
 |     char* argument; | 
 |  | 
 |     Script(StrictMode strictMode, CodeSource codeSource, ScriptType scriptType, char *argument) | 
 |         : strictMode(strictMode) | 
 |         , codeSource(codeSource) | 
 |         , scriptType(scriptType) | 
 |         , argument(argument) | 
 |     { | 
 |         if (strictMode == StrictMode::Strict) | 
 |             ASSERT(codeSource == CodeSource::File); | 
 |     } | 
 | }; | 
 |  | 
 | class CommandLine { | 
 | public: | 
 |     CommandLine(int argc, char** argv) | 
 |     { | 
 |         parseArguments(argc, argv); | 
 |     } | 
 |  | 
 |     enum CommandLineForWorkersTag { CommandLineForWorkers }; | 
 |     CommandLine(CommandLineForWorkersTag) | 
 |     { | 
 |     } | 
 |  | 
 |     Vector<Script> m_scripts; | 
 |     Vector<String> m_arguments; | 
 |     String m_profilerOutput; | 
 |     String m_uncaughtExceptionName; | 
 |     bool m_interactive { false }; | 
 |     bool m_dump { false }; | 
 |     bool m_module { false }; | 
 |     bool m_exitCode { false }; | 
 |     bool m_destroyVM { false }; | 
 |     bool m_profile { false }; | 
 |     bool m_treatWatchdogExceptionAsSuccess { false }; | 
 |     bool m_alwaysDumpUncaughtException { false }; | 
 |     bool m_dumpMemoryFootprint { false }; | 
 |     bool m_dumpSamplingProfilerData { false }; | 
 |     bool m_enableRemoteDebugging { false }; | 
 |     bool m_canBlockIsFalse { false }; | 
 |  | 
 |     void parseArguments(int, char**); | 
 | }; | 
 |  | 
 | static const char interactivePrompt[] = ">>> "; | 
 |  | 
 | class StopWatch { | 
 | public: | 
 |     void start(); | 
 |     void stop(); | 
 |     long getElapsedMS(); // call stop() first | 
 |  | 
 | private: | 
 |     MonotonicTime m_startTime; | 
 |     MonotonicTime m_stopTime; | 
 | }; | 
 |  | 
 | void StopWatch::start() | 
 | { | 
 |     m_startTime = MonotonicTime::now(); | 
 | } | 
 |  | 
 | void StopWatch::stop() | 
 | { | 
 |     m_stopTime = MonotonicTime::now(); | 
 | } | 
 |  | 
 | long StopWatch::getElapsedMS() | 
 | { | 
 |     return (m_stopTime - m_startTime).millisecondsAs<long>(); | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static inline String stringFromUTF(const Vector& utf8) | 
 | { | 
 |     return String::fromUTF8WithLatin1Fallback(utf8.data(), utf8.size()); | 
 | } | 
 |  | 
 | static JSC_DECLARE_CUSTOM_GETTER(accessorMakeMasquerader); | 
 | static JSC_DECLARE_CUSTOM_SETTER(testCustomAccessorSetter); | 
 | static JSC_DECLARE_CUSTOM_SETTER(testCustomValueSetter); | 
 |  | 
 | JSC_DEFINE_CUSTOM_GETTER(accessorMakeMasquerader, (JSGlobalObject* globalObject, EncodedJSValue, PropertyName)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     return JSValue::encode(InternalFunction::createFunctionThatMasqueradesAsUndefined(vm, globalObject, 0, "IsHTMLDDA"_s, functionCallMasquerader)); | 
 | } | 
 |  | 
 |  | 
 | class GlobalObject final : public JSGlobalObject { | 
 | public: | 
 |     using Base = JSGlobalObject; | 
 |  | 
 |     static GlobalObject* create(VM& vm, Structure* structure, const Vector<String>& arguments) | 
 |     { | 
 |         GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(vm.heap)) GlobalObject(vm, structure); | 
 |         object->finishCreation(vm, arguments); | 
 |         return object; | 
 |     } | 
 |  | 
 |     DECLARE_INFO; | 
 |     static const GlobalObjectMethodTable s_globalObjectMethodTable; | 
 |  | 
 |     static Structure* createStructure(VM& vm, JSValue prototype) | 
 |     { | 
 |         return Structure::create(vm, nullptr, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); | 
 |     } | 
 |  | 
 |     static RuntimeFlags javaScriptRuntimeFlags(const JSGlobalObject*) { return RuntimeFlags::createAllEnabled(); } | 
 |  | 
 | private: | 
 |     GlobalObject(VM&, Structure*); | 
 |  | 
 |     static constexpr unsigned DontEnum = 0 | PropertyAttribute::DontEnum; | 
 |  | 
 |     void finishCreation(VM& vm, const Vector<String>& arguments) | 
 |     { | 
 |         Base::finishCreation(vm); | 
 |         JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); | 
 |  | 
 |         addFunction(vm, "debug", functionDebug, 1); | 
 |         addFunction(vm, "describe", functionDescribe, 1); | 
 |         addFunction(vm, "describeArray", functionDescribeArray, 1); | 
 |         addFunction(vm, "print", functionPrintStdOut, 1); | 
 |         addFunction(vm, "printErr", functionPrintStdErr, 1); | 
 |         addFunction(vm, "quit", functionQuit, 0); | 
 |         addFunction(vm, "gc", functionGCAndSweep, 0); | 
 |         addFunction(vm, "fullGC", functionFullGC, 0); | 
 |         addFunction(vm, "edenGC", functionEdenGC, 0); | 
 |         addFunction(vm, "gcHeapSize", functionHeapSize, 0); | 
 |         addFunction(vm, "MemoryFootprint", functionCreateMemoryFootprint, 0); | 
 |         addFunction(vm, "resetMemoryPeak", functionResetMemoryPeak, 0); | 
 |         addFunction(vm, "addressOf", functionAddressOf, 1); | 
 |         addFunction(vm, "version", functionVersion, 1); | 
 |         addFunction(vm, "run", functionRun, 1); | 
 |         addFunction(vm, "runString", functionRunString, 1); | 
 |         addFunction(vm, "load", functionLoad, 1); | 
 |         addFunction(vm, "loadString", functionLoadString, 1); | 
 |         addFunction(vm, "readFile", functionReadFile, 2); | 
 |         addFunction(vm, "read", functionReadFile, 2); | 
 |         addFunction(vm, "checkSyntax", functionCheckSyntax, 1); | 
 |         addFunction(vm, "sleepSeconds", functionSleepSeconds, 1); | 
 |         addFunction(vm, "jscStack", functionJSCStack, 1); | 
 |         addFunction(vm, "readline", functionReadline, 0); | 
 |         addFunction(vm, "preciseTime", functionPreciseTime, 0); | 
 |         addFunction(vm, "neverInlineFunction", functionNeverInlineFunction, 1); | 
 |         addFunction(vm, "noInline", functionNeverInlineFunction, 1); | 
 |         addFunction(vm, "noDFG", functionNoDFG, 1); | 
 |         addFunction(vm, "noFTL", functionNoFTL, 1); | 
 |         addFunction(vm, "noOSRExitFuzzing", functionNoOSRExitFuzzing, 1); | 
 |         addFunction(vm, "numberOfDFGCompiles", functionNumberOfDFGCompiles, 1); | 
 |         addFunction(vm, "callerIsOMGCompiled", functionCallerIsOMGCompiled, 0); | 
 |         addFunction(vm, "jscOptions", functionJSCOptions, 0); | 
 |         addFunction(vm, "optimizeNextInvocation", functionOptimizeNextInvocation, 1); | 
 |         addFunction(vm, "reoptimizationRetryCount", functionReoptimizationRetryCount, 1); | 
 |         addFunction(vm, "transferArrayBuffer", functionTransferArrayBuffer, 1); | 
 |         addFunction(vm, "failNextNewCodeBlock", functionFailNextNewCodeBlock, 1); | 
 | #if ENABLE(SAMPLING_FLAGS) | 
 |         addFunction(vm, "setSamplingFlags", functionSetSamplingFlags, 1); | 
 |         addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1); | 
 | #endif | 
 |  | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "OSRExit"), 0, functionUndefined1, OSRExitIntrinsic, DontEnum); | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "isFinalTier"), 0, functionFalse, IsFinalTierIntrinsic, DontEnum); | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "predictInt32"), 0, functionUndefined2, SetInt32HeapPredictionIntrinsic, DontEnum); | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "isInt32"), 0, functionIsInt32, CheckInt32Intrinsic, DontEnum); | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "isPureNaN"), 0, functionIsPureNaN, CheckInt32Intrinsic, DontEnum); | 
 |         putDirectNativeFunction(vm, this, Identifier::fromString(vm, "fiatInt52"), 0, functionIdentity, FiatInt52Intrinsic, DontEnum); | 
 |          | 
 |         addFunction(vm, "effectful42", functionEffectful42, 0); | 
 |         addFunction(vm, "makeMasquerader", functionMakeMasquerader, 0); | 
 |         addFunction(vm, "hasCustomProperties", functionHasCustomProperties, 0); | 
 |  | 
 |         addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0); | 
 |         addFunction(vm, "createHeapBigInt", functionCreateHeapBigInt, 1); | 
 | #if USE(BIGINT32) | 
 |         addFunction(vm, "createBigInt32", functionCreateBigInt32, 1); | 
 | #endif | 
 |         addFunction(vm, "useBigInt32", functionUseBigInt32, 0); | 
 |         addFunction(vm, "isBigInt32", functionIsBigInt32, 1); | 
 |         addFunction(vm, "isHeapBigInt", functionIsHeapBigInt, 1); | 
 |  | 
 |         addFunction(vm, "dumpTypesForAllVariables", functionDumpTypesForAllVariables , 0); | 
 |  | 
 |         addFunction(vm, "drainMicrotasks", functionDrainMicrotasks, 0); | 
 |         addFunction(vm, "setTimeout", functionSetTimeout, 2); | 
 |  | 
 |         addFunction(vm, "releaseWeakRefs", functionReleaseWeakRefs, 0); | 
 |         addFunction(vm, "finalizationRegistryLiveCount", functionFinalizationRegistryLiveCount, 0); | 
 |         addFunction(vm, "finalizationRegistryDeadCount", functionFinalizationRegistryDeadCount, 0); | 
 |          | 
 |         addFunction(vm, "getRandomSeed", functionGetRandomSeed, 0); | 
 |         addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1); | 
 |         addFunction(vm, "isRope", functionIsRope, 1); | 
 |         addFunction(vm, "callerSourceOrigin", functionCallerSourceOrigin, 0); | 
 |  | 
 |         addFunction(vm, "is32BitPlatform", functionIs32BitPlatform, 0); | 
 |  | 
 |         addFunction(vm, "checkModuleSyntax", functionCheckModuleSyntax, 1); | 
 |  | 
 |         addFunction(vm, "platformSupportsSamplingProfiler", functionPlatformSupportsSamplingProfiler, 0); | 
 |         addFunction(vm, "generateHeapSnapshot", functionGenerateHeapSnapshot, 0); | 
 |         addFunction(vm, "generateHeapSnapshotForGCDebugging", functionGenerateHeapSnapshotForGCDebugging, 0); | 
 |         addFunction(vm, "resetSuperSamplerState", functionResetSuperSamplerState, 0); | 
 |         addFunction(vm, "ensureArrayStorage", functionEnsureArrayStorage, 0); | 
 | #if ENABLE(SAMPLING_PROFILER) | 
 |         addFunction(vm, "startSamplingProfiler", functionStartSamplingProfiler, 0); | 
 |         addFunction(vm, "samplingProfilerStackTraces", functionSamplingProfilerStackTraces, 0); | 
 | #endif | 
 |  | 
 |         addFunction(vm, "maxArguments", functionMaxArguments, 0); | 
 |  | 
 |         addFunction(vm, "asyncTestStart", functionAsyncTestStart, 1); | 
 |         addFunction(vm, "asyncTestPassed", functionAsyncTestPassed, 1); | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 |         addFunction(vm, "WebAssemblyMemoryMode", functionWebAssemblyMemoryMode, 1); | 
 | #endif | 
 |  | 
 |         if (!arguments.isEmpty()) { | 
 |             JSArray* array = constructEmptyArray(this, nullptr); | 
 |             for (size_t i = 0; i < arguments.size(); ++i) | 
 |                 array->putDirectIndex(this, i, jsString(vm, arguments[i])); | 
 |             putDirect(vm, Identifier::fromString(vm, "arguments"), array, DontEnum); | 
 |         } | 
 |  | 
 |         putDirect(vm, Identifier::fromString(vm, "console"), jsUndefined(), DontEnum); | 
 |          | 
 |         Structure* plainObjectStructure = JSFinalObject::createStructure(vm, this, objectPrototype(), 0); | 
 |          | 
 |         JSObject* dollar = JSFinalObject::create(vm, plainObjectStructure); | 
 |         putDirect(vm, Identifier::fromString(vm, "$"), dollar, DontEnum); | 
 |         putDirect(vm, Identifier::fromString(vm, "$262"), dollar, DontEnum); | 
 |          | 
 |         addFunction(vm, dollar, "createRealm", functionDollarCreateRealm, 0); | 
 |         addFunction(vm, dollar, "detachArrayBuffer", functionTransferArrayBuffer, 1); | 
 |         addFunction(vm, dollar, "evalScript", functionDollarEvalScript, 1); | 
 |          | 
 |         dollar->putDirect(vm, Identifier::fromString(vm, "global"), this, DontEnum); | 
 |         dollar->putDirectCustomAccessor(vm, Identifier::fromString(vm, "IsHTMLDDA"), | 
 |             CustomGetterSetter::create(vm, accessorMakeMasquerader, nullptr), | 
 |             static_cast<unsigned>(PropertyAttribute::CustomValue) | 
 |         ); | 
 |  | 
 |         JSObject* agent = JSFinalObject::create(vm, plainObjectStructure); | 
 |         dollar->putDirect(vm, Identifier::fromString(vm, "agent"), agent, DontEnum); | 
 |          | 
 |         // The test262 INTERPRETING.md document says that some of these functions are just in the main | 
 |         // thread and some are in the other threads. We just put them in all threads. | 
 |         addFunction(vm, agent, "start", functionDollarAgentStart, 1); | 
 |         addFunction(vm, agent, "receiveBroadcast", functionDollarAgentReceiveBroadcast, 1); | 
 |         addFunction(vm, agent, "report", functionDollarAgentReport, 1); | 
 |         addFunction(vm, agent, "sleep", functionDollarAgentSleep, 1); | 
 |         addFunction(vm, agent, "broadcast", functionDollarAgentBroadcast, 1); | 
 |         addFunction(vm, agent, "getReport", functionDollarAgentGetReport, 0); | 
 |         addFunction(vm, agent, "leaving", functionDollarAgentLeaving, 0); | 
 |         addFunction(vm, agent, "monotonicNow", functionDollarAgentMonotonicNow, 0); | 
 |  | 
 |         addFunction(vm, "waitForReport", functionWaitForReport, 0); | 
 |  | 
 |         addFunction(vm, "heapCapacity", functionHeapCapacity, 0); | 
 |         addFunction(vm, "flashHeapAccess", functionFlashHeapAccess, 0); | 
 |  | 
 |         addFunction(vm, "disableRichSourceInfo", functionDisableRichSourceInfo, 0); | 
 |         addFunction(vm, "mallocInALoop", functionMallocInALoop, 0); | 
 |         addFunction(vm, "totalCompileTime", functionTotalCompileTime, 0); | 
 |  | 
 |         addFunction(vm, "setUnhandledRejectionCallback", functionSetUnhandledRejectionCallback, 1); | 
 |  | 
 |         addFunction(vm, "asDoubleNumber", functionAsDoubleNumber, 1); | 
 |  | 
 |         addFunction(vm, "dropAllLocks", functionDropAllLocks, 1); | 
 |  | 
 |         if (Options::exposeCustomSettersOnGlobalObjectForTesting()) { | 
 |             { | 
 |                 CustomGetterSetter* custom = CustomGetterSetter::create(vm, nullptr, testCustomAccessorSetter); | 
 |                 Identifier identifier = Identifier::fromString(vm, "testCustomAccessorSetter"); | 
 |                 this->putDirectCustomAccessor(vm, identifier, custom, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::CustomAccessor); | 
 |             } | 
 |  | 
 |             { | 
 |                 CustomGetterSetter* custom = CustomGetterSetter::create(vm, nullptr, testCustomValueSetter); | 
 |                 Identifier identifier = Identifier::fromString(vm, "testCustomValueSetter"); | 
 |                 this->putDirectCustomAccessor(vm, identifier, custom, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::CustomValue); | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 | public: | 
 |     static bool testCustomSetterImpl(JSGlobalObject* lexicalGlobalObject, GlobalObject* thisObject, EncodedJSValue encodedValue, const char* propertyName) | 
 |     { | 
 |         VM& vm = lexicalGlobalObject->vm(); | 
 |  | 
 |         Identifier identifier = Identifier::fromString(vm, propertyName); | 
 |         thisObject->putDirect(vm, identifier, JSValue::decode(encodedValue), DontEnum); | 
 |  | 
 |         return true; | 
 |     } | 
 |  | 
 | private: | 
 |     void addFunction(VM& vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments) | 
 |     { | 
 |         Identifier identifier = Identifier::fromString(vm, name); | 
 |         object->putDirect(vm, identifier, JSFunction::create(vm, this, arguments, identifier.string(), function), DontEnum); | 
 |     } | 
 |  | 
 |     void addFunction(VM& vm, const char* name, NativeFunction function, unsigned arguments) | 
 |     { | 
 |         addFunction(vm, this, name, function, arguments); | 
 |     } | 
 |      | 
 |     static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, JSModuleLoader*, JSString*, JSValue, const SourceOrigin&); | 
 |     static Identifier moduleLoaderResolve(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue); | 
 |     static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue); | 
 |     static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue); | 
 |  | 
 |     static void reportUncaughtExceptionAtEventLoop(JSGlobalObject*, Exception*); | 
 | }; | 
 | STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(GlobalObject, JSGlobalObject); | 
 |  | 
 | static bool supportsRichSourceInfo = true; | 
 | static bool shellSupportsRichSourceInfo(const JSGlobalObject*) | 
 | { | 
 |     return supportsRichSourceInfo; | 
 | } | 
 |  | 
 | const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(GlobalObject) }; | 
 | const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { | 
 |     &shellSupportsRichSourceInfo, | 
 |     &shouldInterruptScript, | 
 |     &javaScriptRuntimeFlags, | 
 |     nullptr, // queueTaskToEventLoop | 
 |     &shouldInterruptScriptBeforeTimeout, | 
 |     &moduleLoaderImportModule, | 
 |     &moduleLoaderResolve, | 
 |     &moduleLoaderFetch, | 
 |     &moduleLoaderCreateImportMetaProperties, | 
 |     nullptr, // moduleLoaderEvaluate | 
 |     nullptr, // promiseRejectionTracker | 
 |     &reportUncaughtExceptionAtEventLoop, | 
 |     ¤tScriptExecutionOwner, | 
 |     &scriptExecutionStatus, | 
 |     nullptr, // defaultLanguage | 
 |     nullptr, // compileStreaming | 
 |     nullptr, // instantinateStreaming | 
 | }; | 
 |  | 
 | GlobalObject::GlobalObject(VM& vm, Structure* structure) | 
 |     : JSGlobalObject(vm, structure, &s_globalObjectMethodTable) | 
 | { | 
 | } | 
 |  | 
 | JSC_DEFINE_CUSTOM_SETTER(testCustomAccessorSetter, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue)) | 
 | { | 
 |     VM& vm = lexicalGlobalObject->vm(); | 
 |     RELEASE_ASSERT(JSValue::decode(thisValue).isCell()); | 
 |     JSCell* thisCell = JSValue::decode(thisValue).asCell(); | 
 |     RELEASE_ASSERT(thisCell->type() == PureForwardingProxyType); | 
 |     GlobalObject* thisObject = jsDynamicCast<GlobalObject*>(vm, jsCast<JSProxy*>(thisCell)->target()); | 
 |     RELEASE_ASSERT(thisObject); | 
 |     return GlobalObject::testCustomSetterImpl(lexicalGlobalObject, thisObject, encodedValue, "_testCustomAccessorSetter"); | 
 | } | 
 |  | 
 | JSC_DEFINE_CUSTOM_SETTER(testCustomValueSetter, (JSGlobalObject* lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue)) | 
 | { | 
 |     VM& vm = lexicalGlobalObject->vm(); | 
 |     RELEASE_ASSERT(JSValue::decode(thisValue).isCell()); | 
 |     JSCell* thisCell = JSValue::decode(thisValue).asCell(); | 
 |     GlobalObject* thisObject = jsDynamicCast<GlobalObject*>(vm, thisCell); | 
 |     RELEASE_ASSERT(thisObject); | 
 |     return GlobalObject::testCustomSetterImpl(lexicalGlobalObject, thisObject, encodedValue, "_testCustomValueSetter"); | 
 | } | 
 |  | 
 | static UChar pathSeparator() | 
 | { | 
 | #if OS(WINDOWS) | 
 |     return '\\'; | 
 | #else | 
 |     return '/'; | 
 | #endif | 
 | } | 
 |  | 
 | static URL currentWorkingDirectory() | 
 | { | 
 | #if OS(WINDOWS) | 
 |     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364934.aspx | 
 |     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath | 
 |     // The _MAX_PATH in Windows is 260. If the path of the current working directory is longer than that, _getcwd truncates the result. | 
 |     // And other I/O functions taking a path name also truncate it. To avoid this situation, | 
 |     // | 
 |     // (1). When opening the file in Windows for modules, we always use the abosolute path and add "\\?\" prefix to the path name. | 
 |     // (2). When retrieving the current working directory, use GetCurrentDirectory instead of _getcwd. | 
 |     // | 
 |     // In the path utility functions inside the JSC shell, we does not handle the UNC and UNCW including the network host name. | 
 |     DWORD bufferLength = ::GetCurrentDirectoryW(0, nullptr); | 
 |     if (!bufferLength) | 
 |         return { }; | 
 |     // In Windows, wchar_t is the UTF-16LE. | 
 |     // https://msdn.microsoft.com/en-us/library/dd374081.aspx | 
 |     // https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx | 
 |     Vector<wchar_t> buffer(bufferLength); | 
 |     DWORD lengthNotIncludingNull = ::GetCurrentDirectoryW(bufferLength, buffer.data()); | 
 |     String directoryString(buffer.data(), lengthNotIncludingNull); | 
 |     // We don't support network path like \\host\share\<path name>. | 
 |     if (directoryString.startsWith("\\\\")) | 
 |         return { }; | 
 |  | 
 | #else | 
 |     Vector<char> buffer(PATH_MAX); | 
 |     if (!getcwd(buffer.data(), PATH_MAX)) | 
 |         return { }; | 
 |     String directoryString = String::fromUTF8(buffer.data()); | 
 | #endif | 
 |     if (directoryString.isEmpty()) | 
 |         return { }; | 
 |  | 
 |     // Add a trailing slash if needed so the URL resolves to a directory and not a file. | 
 |     if (directoryString[directoryString.length() - 1] != pathSeparator()) | 
 |         directoryString = makeString(directoryString, pathSeparator()); | 
 |  | 
 |     return URL::fileURLWithFileSystemPath(directoryString); | 
 | } | 
 |  | 
 | static URL absolutePath(const String& fileName) | 
 | { | 
 |     auto directoryName = currentWorkingDirectory(); | 
 |     if (!directoryName.isValid()) | 
 |         return URL::fileURLWithFileSystemPath(fileName); | 
 |  | 
 |     return URL(directoryName, fileName); | 
 | } | 
 |  | 
 | JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, JSModuleLoader*, JSString* moduleNameValue, JSValue parameters, const SourceOrigin& sourceOrigin) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     auto* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); | 
 |  | 
 |     auto rejectWithError = [&](JSValue error) { | 
 |         promise->reject(globalObject, error); | 
 |         return promise; | 
 |     }; | 
 |  | 
 |     auto referrer = sourceOrigin.url(); | 
 |     auto specifier = moduleNameValue->value(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); | 
 |  | 
 |     if (!referrer.isLocalFile()) | 
 |         RELEASE_AND_RETURN(scope, rejectWithError(createError(globalObject, makeString("Could not resolve the referrer's path '", referrer.string(), "', while trying to resolve module '", specifier, "'.")))); | 
 |  | 
 |     if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../")) | 
 |         RELEASE_AND_RETURN(scope, rejectWithError(createTypeError(globalObject, makeString("Module specifier, '"_s, specifier, "' does not start with \"/\", \"./\", or \"../\". Referenced from: "_s, referrer.fileSystemPath())))); | 
 |  | 
 |     URL moduleURL(referrer, specifier); | 
 |     if (!moduleURL.isLocalFile()) | 
 |         RELEASE_AND_RETURN(scope, rejectWithError(createError(globalObject, makeString("Module url, '", moduleURL.string(), "' does not map to a local file.")))); | 
 |  | 
 |     auto result = JSC::importModule(globalObject, Identifier::fromString(vm, moduleURL.string()), parameters, jsUndefined()); | 
 |     RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | Identifier GlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     scope.releaseAssertNoException(); | 
 |     const Identifier key = keyValue.toPropertyKey(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, { }); | 
 |  | 
 |     if (key.isSymbol()) | 
 |         return key; | 
 |  | 
 |     auto resolvePath = [&] (const URL& directoryURL) -> Identifier { | 
 |         String specifier = key.impl(); | 
 |         if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../")) { | 
 |             throwTypeError(globalObject, scope, makeString("Module specifier, '"_s, specifier, "' does not start with \"/\", \"./\", or \"../\". Referenced from: "_s, directoryURL.fileSystemPath())); | 
 |             return { }; | 
 |         } | 
 |  | 
 |         if (!directoryURL.isLocalFile()) { | 
 |             throwException(globalObject, scope, createError(globalObject, makeString("Could not resolve the referrer's path: ", directoryURL.string()))); | 
 |             return { }; | 
 |         } | 
 |  | 
 |         URL resolvedURL(directoryURL, specifier); | 
 |         if (!resolvedURL.isValid()) { | 
 |             throwException(globalObject, scope, createError(globalObject, makeString("Resolved module url is not valid: ", resolvedURL.string()))); | 
 |             return { }; | 
 |         } | 
 |         ASSERT(resolvedURL.isLocalFile()); | 
 |  | 
 |         return Identifier::fromString(vm, resolvedURL.string()); | 
 |     }; | 
 |  | 
 |     if (referrerValue.isUndefined()) | 
 |         return resolvePath(currentWorkingDirectory()); | 
 |  | 
 |     const Identifier referrer = referrerValue.toPropertyKey(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, { }); | 
 |  | 
 |     if (referrer.isSymbol()) | 
 |         return resolvePath(currentWorkingDirectory()); | 
 |  | 
 |     // If the referrer exists, we assume that the referrer is the correct file url. | 
 |     URL url = URL({ }, referrer.impl()); | 
 |     ASSERT(url.isLocalFile()); | 
 |     return resolvePath(url); | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static void convertShebangToJSComment(Vector& buffer) | 
 | { | 
 |     if (buffer.size() >= 2) { | 
 |         if (buffer[0] == '#' && buffer[1] == '!') | 
 |             buffer[0] = buffer[1] = '/'; | 
 |     } | 
 | } | 
 |  | 
 | static RefPtr<Uint8Array> fillBufferWithContentsOfFile(FILE* file) | 
 | { | 
 |     if (fseek(file, 0, SEEK_END) == -1) | 
 |         return nullptr; | 
 |     long bufferCapacity = ftell(file); | 
 |     if (bufferCapacity == -1) | 
 |         return nullptr; | 
 |     if (fseek(file, 0, SEEK_SET) == -1) | 
 |         return nullptr; | 
 |     auto result = Uint8Array::tryCreate(bufferCapacity); | 
 |     if (!result) | 
 |         return nullptr; | 
 |     size_t readSize = fread(result->data(), 1, bufferCapacity, file); | 
 |     if (readSize != static_cast<size_t>(bufferCapacity)) | 
 |         return nullptr; | 
 |     return result; | 
 | } | 
 |  | 
 | static RefPtr<Uint8Array> fillBufferWithContentsOfFile(const String& fileName) | 
 | { | 
 |     FILE* f = fopen(fileName.utf8().data(), "rb"); | 
 |     if (!f) { | 
 |         fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); | 
 |         return nullptr; | 
 |     } | 
 |  | 
 |     RefPtr<Uint8Array> result = fillBufferWithContentsOfFile(f); | 
 |     fclose(f); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static bool fillBufferWithContentsOfFile(FILE* file, Vector& buffer) | 
 | { | 
 |     // We might have injected "use strict"; at the top. | 
 |     size_t initialSize = buffer.size(); | 
 |     if (fseek(file, 0, SEEK_END) == -1) | 
 |         return false; | 
 |     long bufferCapacity = ftell(file); | 
 |     if (bufferCapacity == -1) | 
 |         return false; | 
 |     if (fseek(file, 0, SEEK_SET) == -1) | 
 |         return false; | 
 |     buffer.resize(bufferCapacity + initialSize); | 
 |     size_t readSize = fread(buffer.data() + initialSize, 1, buffer.size(), file); | 
 |     return readSize == buffer.size() - initialSize; | 
 | } | 
 |  | 
 | static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer) | 
 | { | 
 |     FILE* f = fopen(fileName.utf8().data(), "rb"); | 
 |     if (!f) { | 
 |         fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); | 
 |         return false; | 
 |     } | 
 |  | 
 |     bool result = fillBufferWithContentsOfFile(f, buffer); | 
 |     fclose(f); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | static bool fetchScriptFromLocalFileSystem(const String& fileName, Vector<char>& buffer) | 
 | { | 
 |     if (!fillBufferWithContentsOfFile(fileName, buffer)) | 
 |         return false; | 
 |     convertShebangToJSComment(buffer); | 
 |     return true; | 
 | } | 
 |  | 
 | class ShellSourceProvider final : public StringSourceProvider { | 
 | public: | 
 |     static Ref<ShellSourceProvider> create(const String& source, const SourceOrigin& sourceOrigin, String&& sourceURL, const TextPosition& startPosition, SourceProviderSourceType sourceType) | 
 |     { | 
 |         return adoptRef(*new ShellSourceProvider(source, sourceOrigin, WTFMove(sourceURL), startPosition, sourceType)); | 
 |     } | 
 |  | 
 |     ~ShellSourceProvider() final | 
 |     { | 
 |         commitCachedBytecode(); | 
 |     } | 
 |  | 
 |     RefPtr<CachedBytecode> cachedBytecode() const final | 
 |     { | 
 |         if (!m_cachedBytecode) | 
 |             loadBytecode(); | 
 |         return m_cachedBytecode.copyRef(); | 
 |     } | 
 |  | 
 |     void updateCache(const UnlinkedFunctionExecutable* executable, const SourceCode&, CodeSpecializationKind kind, const UnlinkedFunctionCodeBlock* codeBlock) const final | 
 |     { | 
 |         if (!cacheEnabled() || !m_cachedBytecode) | 
 |             return; | 
 |         BytecodeCacheError error; | 
 |         RefPtr<CachedBytecode> cachedBytecode = encodeFunctionCodeBlock(executable->vm(), codeBlock, error); | 
 |         if (cachedBytecode && !error.isValid()) | 
 |             m_cachedBytecode->addFunctionUpdate(executable, kind, *cachedBytecode); | 
 |     } | 
 |  | 
 |     void cacheBytecode(const BytecodeCacheGenerator& generator) const final | 
 |     { | 
 |         if (!cacheEnabled()) | 
 |             return; | 
 |         if (!m_cachedBytecode) | 
 |             m_cachedBytecode = CachedBytecode::create(); | 
 |         auto update = generator(); | 
 |         if (update) | 
 |             m_cachedBytecode->addGlobalUpdate(*update); | 
 |     } | 
 |  | 
 |     void commitCachedBytecode() const final | 
 |     { | 
 |         if (!cacheEnabled() || !m_cachedBytecode || !m_cachedBytecode->hasUpdates()) | 
 |             return; | 
 |  | 
 |         auto clearBytecode = makeScopeExit([&] { | 
 |             m_cachedBytecode = nullptr; | 
 |         }); | 
 |  | 
 |         String filename = cachePath(); | 
 |         auto fd = FileSystem::openAndLockFile(filename, FileSystem::FileOpenMode::Write, {FileSystem::FileLockMode::Exclusive, FileSystem::FileLockMode::Nonblocking}); | 
 |         if (!FileSystem::isHandleValid(fd)) | 
 |             return; | 
 |  | 
 |         auto closeFD = makeScopeExit([&] { | 
 |             FileSystem::unlockAndCloseFile(fd); | 
 |         }); | 
 |  | 
 |         long long fileSize; | 
 |         if (!FileSystem::getFileSize(fd, fileSize)) | 
 |             return; | 
 |  | 
 |         size_t cacheFileSize; | 
 |         if (!WTF::convertSafely(fileSize, cacheFileSize) || cacheFileSize != m_cachedBytecode->size()) { | 
 |             // The bytecode cache has already been updated | 
 |             return; | 
 |         } | 
 |  | 
 |         if (!FileSystem::truncateFile(fd, m_cachedBytecode->sizeForUpdate())) | 
 |             return; | 
 |  | 
 |         m_cachedBytecode->commitUpdates([&] (off_t offset, const void* data, size_t size) { | 
 |             long long result = FileSystem::seekFile(fd, offset, FileSystem::FileSeekOrigin::Beginning); | 
 |             ASSERT_UNUSED(result, result != -1); | 
 |             size_t bytesWritten = static_cast<size_t>(FileSystem::writeToFile(fd, static_cast<const char*>(data), size)); | 
 |             ASSERT_UNUSED(bytesWritten, bytesWritten == size); | 
 |         }); | 
 |     } | 
 |  | 
 | private: | 
 |     String cachePath() const | 
 |     { | 
 |         if (!cacheEnabled()) | 
 |             return static_cast<const char*>(nullptr); | 
 |         const char* cachePath = Options::diskCachePath(); | 
 |         String filename = FileSystem::encodeForFileName(FileSystem::lastComponentOfPathIgnoringTrailingSlash(sourceOrigin().url().fileSystemPath())); | 
 |         return FileSystem::pathByAppendingComponent(cachePath, makeString(source().toString().hash(), '-', filename, ".bytecode-cache")); | 
 |     } | 
 |  | 
 |     void loadBytecode() const | 
 |     { | 
 |         if (!cacheEnabled()) | 
 |             return; | 
 |  | 
 |         String filename = cachePath(); | 
 |         if (filename.isNull()) | 
 |             return; | 
 |  | 
 |         auto fd = FileSystem::openAndLockFile(filename, FileSystem::FileOpenMode::Read, {FileSystem::FileLockMode::Shared, FileSystem::FileLockMode::Nonblocking}); | 
 |         if (!FileSystem::isHandleValid(fd)) | 
 |             return; | 
 |  | 
 |         auto closeFD = makeScopeExit([&] { | 
 |             FileSystem::unlockAndCloseFile(fd); | 
 |         }); | 
 |  | 
 |         bool success; | 
 |         FileSystem::MappedFileData mappedFileData(fd, FileSystem::MappedFileMode::Private, success); | 
 |  | 
 |         if (!success) | 
 |             return; | 
 |  | 
 |         m_cachedBytecode = CachedBytecode::create(WTFMove(mappedFileData)); | 
 |     } | 
 |  | 
 |     ShellSourceProvider(const String& source, const SourceOrigin& sourceOrigin, String&& sourceURL, const TextPosition& startPosition, SourceProviderSourceType sourceType) | 
 |         : StringSourceProvider(source, sourceOrigin, WTFMove(sourceURL), startPosition, sourceType) | 
 |     { | 
 |     } | 
 |  | 
 |     static bool cacheEnabled() | 
 |     { | 
 |         static bool enabled = !!Options::diskCachePath(); | 
 |         return enabled; | 
 |     } | 
 |  | 
 |     mutable RefPtr<CachedBytecode> m_cachedBytecode; | 
 | }; | 
 |  | 
 | static inline SourceCode jscSource(const String& source, const SourceOrigin& sourceOrigin, String sourceURL = String(), const TextPosition& startPosition = TextPosition(), SourceProviderSourceType sourceType = SourceProviderSourceType::Program) | 
 | { | 
 |     return SourceCode(ShellSourceProvider::create(source, sourceOrigin, WTFMove(sourceURL), startPosition, sourceType), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt()); | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static inline SourceCode jscSource(const Vector& utf8, const SourceOrigin& sourceOrigin, const String& filename) | 
 | { | 
 |     // FIXME: This should use an absolute file URL https://bugs.webkit.org/show_bug.cgi?id=193077 | 
 |     String str = stringFromUTF(utf8); | 
 |     return jscSource(str, sourceOrigin, filename); | 
 | } | 
 |  | 
 | template<typename Vector> | 
 | static bool fetchModuleFromLocalFileSystem(const URL& fileURL, Vector& buffer) | 
 | { | 
 |     String fileName = fileURL.fileSystemPath(); | 
 | #if OS(WINDOWS) | 
 |     // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#maxpath | 
 |     // Use long UNC to pass the long path name to the Windows APIs. | 
 |     auto pathName = makeString("\\\\?\\", fileName).wideCharacters(); | 
 |     struct _stat status { }; | 
 |     if (_wstat(pathName.data(), &status)) | 
 |         return false; | 
 |     if ((status.st_mode & S_IFMT) != S_IFREG) | 
 |         return false; | 
 |  | 
 |     FILE* f = _wfopen(pathName.data(), L"rb"); | 
 | #else | 
 |     auto pathName = fileName.utf8(); | 
 |     struct stat status { }; | 
 |     if (stat(pathName.data(), &status)) | 
 |         return false; | 
 |     if ((status.st_mode & S_IFMT) != S_IFREG) | 
 |         return false; | 
 |  | 
 |     FILE* f = fopen(pathName.data(), "r"); | 
 | #endif | 
 |     if (!f) { | 
 |         fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); | 
 |         return false; | 
 |     } | 
 |  | 
 |     bool result = fillBufferWithContentsOfFile(f, buffer); | 
 |     if (result) | 
 |         convertShebangToJSComment(buffer); | 
 |     fclose(f); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | JSInternalPromise* GlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSValue, JSValue) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSInternalPromise* promise = JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); | 
 |  | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     auto rejectWithError = [&](JSValue error) { | 
 |         promise->reject(globalObject, error); | 
 |         return promise; | 
 |     }; | 
 |  | 
 |     String moduleKey = key.toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, promise->rejectWithCaughtException(globalObject, scope)); | 
 |  | 
 |     URL moduleURL({ }, moduleKey); | 
 |     ASSERT(moduleURL.isLocalFile()); | 
 |     // Strip the URI from our key so Errors print canonical system paths. | 
 |     moduleKey = moduleURL.fileSystemPath(); | 
 |  | 
 |     Vector<uint8_t> buffer; | 
 |     if (!fetchModuleFromLocalFileSystem(moduleURL, buffer)) | 
 |         RELEASE_AND_RETURN(scope, rejectWithError(createError(globalObject, makeString("Could not open file '", moduleKey, "'.")))); | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 |     // FileSystem does not have mime-type header. The JSC shell recognizes WebAssembly's magic header. | 
 |     if (buffer.size() >= 4) { | 
 |         if (buffer[0] == '\0' && buffer[1] == 'a' && buffer[2] == 's' && buffer[3] == 'm') { | 
 |             auto source = SourceCode(WebAssemblySourceProvider::create(WTFMove(buffer), SourceOrigin { moduleURL }, WTFMove(moduleKey))); | 
 |             scope.releaseAssertNoException(); | 
 |             auto sourceCode = JSSourceCode::create(vm, WTFMove(source)); | 
 |             scope.release(); | 
 |             promise->resolve(globalObject, sourceCode); | 
 |             return promise; | 
 |         } | 
 |     } | 
 | #endif | 
 |  | 
 |     auto sourceCode = JSSourceCode::create(vm, jscSource(stringFromUTF(buffer), SourceOrigin { moduleURL }, WTFMove(moduleKey), TextPosition(), SourceProviderSourceType::Module)); | 
 |     scope.release(); | 
 |     promise->resolve(globalObject, sourceCode); | 
 |     return promise; | 
 | } | 
 |  | 
 | JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, JSModuleLoader*, JSValue key, JSModuleRecord*, JSValue) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     JSObject* metaProperties = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure()); | 
 |     RETURN_IF_EXCEPTION(scope, nullptr); | 
 |  | 
 |     metaProperties->putDirect(vm, Identifier::fromString(vm, "filename"), key); | 
 |     RETURN_IF_EXCEPTION(scope, nullptr); | 
 |  | 
 |     return metaProperties; | 
 | } | 
 |  | 
 | static CString cStringFromViewWithString(JSGlobalObject* globalObject, ThrowScope& scope, StringViewWithUnderlyingString& viewWithString) | 
 | { | 
 |     Expected<CString, UTF8ConversionError> expectedString = viewWithString.view.tryGetUtf8(); | 
 |     if (expectedString) | 
 |         return expectedString.value(); | 
 |     switch (expectedString.error()) { | 
 |     case UTF8ConversionError::OutOfMemory: | 
 |         throwOutOfMemoryError(globalObject, scope); | 
 |         break; | 
 |     case UTF8ConversionError::IllegalSource: | 
 |         scope.throwException(globalObject, createError(globalObject, "Illegal source encountered during UTF8 conversion")); | 
 |         break; | 
 |     case UTF8ConversionError::SourceExhausted: | 
 |         scope.throwException(globalObject, createError(globalObject, "Source exhausted during UTF8 conversion")); | 
 |         break; | 
 |     default: | 
 |         RELEASE_ASSERT_NOT_REACHED(); | 
 |     } | 
 |     return { }; | 
 | } | 
 |  | 
 | static EncodedJSValue printInternal(JSGlobalObject* globalObject, CallFrame* callFrame, FILE* out) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (asyncTestExpectedPasses) { | 
 |         JSValue value = callFrame->argument(0); | 
 |         if (value.isString() && WTF::equal(asString(value)->value(globalObject).impl(), "Test262:AsyncTestComplete")) { | 
 |             asyncTestPasses++; | 
 |             return JSValue::encode(jsUndefined()); | 
 |         } | 
 |     } | 
 |  | 
 |     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         if (i) | 
 |             if (EOF == fputc(' ', out)) | 
 |                 goto fail; | 
 |  | 
 |         auto* jsString = callFrame->uncheckedArgument(i).toString(globalObject); | 
 |         RETURN_IF_EXCEPTION(scope, { }); | 
 |         auto viewWithString = jsString->viewWithUnderlyingString(globalObject); | 
 |         RETURN_IF_EXCEPTION(scope, { }); | 
 |         auto string = cStringFromViewWithString(globalObject, scope, viewWithString); | 
 |         RETURN_IF_EXCEPTION(scope, { }); | 
 |         fwrite(string.data(), sizeof(char), string.length(), out); | 
 |         if (ferror(out)) | 
 |             goto fail; | 
 |     } | 
 |  | 
 |     fputc('\n', out); | 
 | fail: | 
 |     fflush(out); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionPrintStdOut, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return printInternal(globalObject, callFrame, stdout); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionPrintStdErr, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return printInternal(globalObject, callFrame, stderr); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDebug, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |     auto* jsString = callFrame->argument(0).toString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, { }); | 
 |     auto viewWithString = jsString->viewWithUnderlyingString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, { }); | 
 |     auto string = cStringFromViewWithString(globalObject, scope, viewWithString); | 
 |     RETURN_IF_EXCEPTION(scope, { }); | 
 |     fputs("--> ", stderr); | 
 |     fwrite(string.data(), sizeof(char), string.length(), stderr); | 
 |     fputc('\n', stderr); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDescribe, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     if (callFrame->argumentCount() < 1) | 
 |         return JSValue::encode(jsUndefined()); | 
 |     return JSValue::encode(jsString(vm, toString(callFrame->argument(0)))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDescribeArray, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     if (callFrame->argumentCount() < 1) | 
 |         return JSValue::encode(jsUndefined()); | 
 |     VM& vm = globalObject->vm(); | 
 |     JSObject* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(0)); | 
 |     if (!object) | 
 |         return JSValue::encode(jsNontrivialString(vm, "<not object>"_s)); | 
 |     return JSValue::encode(jsNontrivialString(vm, toString("<Butterfly: ", RawPointer(object->butterfly()), "; public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">"))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionSleepSeconds, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (callFrame->argumentCount() >= 1) { | 
 |         Seconds seconds = Seconds(callFrame->argument(0).toNumber(globalObject)); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |         sleep(seconds); | 
 |     } | 
 |      | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | class FunctionJSCStackFunctor { | 
 | public: | 
 |     FunctionJSCStackFunctor(StringBuilder& trace) | 
 |         : m_trace(trace) | 
 |     { | 
 |     } | 
 |  | 
 |     StackVisitor::Status operator()(StackVisitor& visitor) const | 
 |     { | 
 |         m_trace.append(makeString("    ", visitor->index(), "   ", visitor->toString(), '\n')); | 
 |         return StackVisitor::Continue; | 
 |     } | 
 |  | 
 | private: | 
 |     StringBuilder& m_trace; | 
 | }; | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionJSCStack, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     StringBuilder trace; | 
 |     trace.appendLiteral("--> Stack trace:\n"); | 
 |  | 
 |     FunctionJSCStackFunctor functor(trace); | 
 |     callFrame->iterate(vm, functor); | 
 |     fprintf(stderr, "%s", trace.toString().utf8().data()); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionGCAndSweep, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     vm.heap.collectNow(Sync, CollectionScope::Full); | 
 |     return JSValue::encode(jsNumber(vm.heap.sizeAfterLastFullCollection())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFullGC, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     vm.heap.collectSync(CollectionScope::Full); | 
 |     return JSValue::encode(jsNumber(vm.heap.sizeAfterLastFullCollection())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionEdenGC, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     vm.heap.collectSync(CollectionScope::Eden); | 
 |     return JSValue::encode(jsNumber(vm.heap.sizeAfterLastEdenCollection())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionHeapSize, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     return JSValue::encode(jsNumber(vm.heap.size())); | 
 | } | 
 |  | 
 | class JSCMemoryFootprint : public JSDestructibleObject { | 
 |     using Base = JSDestructibleObject; | 
 | public: | 
 |     template<typename CellType, SubspaceAccess> | 
 |     static CompleteSubspace* subspaceFor(VM& vm) | 
 |     { | 
 |         return &vm.destructibleObjectSpace; | 
 |     } | 
 |  | 
 |     JSCMemoryFootprint(VM& vm, Structure* structure) | 
 |         : Base(vm, structure) | 
 |     { } | 
 |  | 
 |     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) | 
 |     { | 
 |         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); | 
 |     } | 
 |  | 
 |     static JSCMemoryFootprint* create(VM& vm, JSGlobalObject* globalObject) | 
 |     { | 
 |         Structure* structure = createStructure(vm, globalObject, jsNull()); | 
 |         JSCMemoryFootprint* footprint = new (NotNull, allocateCell<JSCMemoryFootprint>(vm.heap)) JSCMemoryFootprint(vm, structure); | 
 |         footprint->finishCreation(vm); | 
 |         return footprint; | 
 |     } | 
 |  | 
 |     void finishCreation(VM& vm) | 
 |     { | 
 |         Base::finishCreation(vm); | 
 |  | 
 |         auto addProperty = [&] (VM& vm, const char* name, JSValue value) { | 
 |             JSCMemoryFootprint::addProperty(vm, name, value); | 
 |         }; | 
 |  | 
 |         MemoryFootprint footprint = MemoryFootprint::now(); | 
 |  | 
 |         addProperty(vm, "current", jsNumber(footprint.current)); | 
 |         addProperty(vm, "peak", jsNumber(footprint.peak)); | 
 |     } | 
 |  | 
 |     DECLARE_INFO; | 
 |  | 
 | private: | 
 |     void addProperty(VM& vm, const char* name, JSValue value) | 
 |     { | 
 |         Identifier identifier = Identifier::fromString(vm, name); | 
 |         putDirect(vm, identifier, value); | 
 |     } | 
 | }; | 
 |  | 
 | const ClassInfo JSCMemoryFootprint::s_info = { "MemoryFootprint", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCMemoryFootprint) }; | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCreateMemoryFootprint, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     return JSValue::encode(JSCMemoryFootprint::create(vm, globalObject)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionResetMemoryPeak, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     MemoryFootprint::resetPeak(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | // This function is not generally very helpful in 64-bit code as the tag and payload | 
 | // share a register. But in 32-bit JITed code the tag may not be checked if an | 
 | // optimization removes type checking requirements, such as in ===. | 
 | JSC_DEFINE_HOST_FUNCTION(functionAddressOf, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     JSValue value = callFrame->argument(0); | 
 |     if (!value.isCell()) | 
 |         return JSValue::encode(jsUndefined()); | 
 |     // Need to cast to uint64_t so bitwise_cast will play along. | 
 |     uint64_t asNumber = reinterpret_cast<uint64_t>(value.asCell()); | 
 |     EncodedJSValue returnValue = JSValue::encode(jsNumber(bitwise_cast<double>(asNumber))); | 
 |     return returnValue; | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionVersion, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     // We need this function for compatibility with the Mozilla JS tests but for now | 
 |     // we don't actually do any version-specific handling | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionRun, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String fileName = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     Vector<char> script; | 
 |     if (!fetchScriptFromLocalFileSystem(fileName, script)) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Could not open file."_s))); | 
 |  | 
 |     GlobalObject* realm = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()); | 
 |  | 
 |     JSArray* array = constructEmptyArray(realm, nullptr); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     for (unsigned i = 1; i < callFrame->argumentCount(); ++i) { | 
 |         array->putDirectIndex(realm, i - 1, callFrame->uncheckedArgument(i)); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     } | 
 |     realm->putDirect(vm, Identifier::fromString(vm, "arguments"), array); | 
 |  | 
 |     NakedPtr<Exception> exception; | 
 |     StopWatch stopWatch; | 
 |     stopWatch.start(); | 
 |     evaluate(realm, jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), JSValue(), exception); | 
 |     stopWatch.stop(); | 
 |  | 
 |     if (exception) { | 
 |         throwException(realm, scope, exception); | 
 |         return JSValue::encode(jsUndefined()); | 
 |     } | 
 |      | 
 |     return JSValue::encode(jsNumber(stopWatch.getElapsedMS())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionRunString, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String source = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     GlobalObject* realm = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()); | 
 |  | 
 |     JSArray* array = constructEmptyArray(realm, nullptr); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     for (unsigned i = 1; i < callFrame->argumentCount(); ++i) { | 
 |         array->putDirectIndex(realm, i - 1, callFrame->uncheckedArgument(i)); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     } | 
 |     realm->putDirect(vm, Identifier::fromString(vm, "arguments"), array); | 
 |  | 
 |     NakedPtr<Exception> exception; | 
 |     evaluate(realm, jscSource(source, callFrame->callerSourceOrigin(vm)), JSValue(), exception); | 
 |  | 
 |     if (exception) { | 
 |         scope.throwException(realm, exception); | 
 |         return JSValue::encode(jsUndefined()); | 
 |     } | 
 |      | 
 |     return JSValue::encode(realm); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionLoad, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     bool callerRelative = callFrame->argument(1).getString(globalObject) == "caller relative"_s; | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     String fileName = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     URL path; | 
 |     if (callerRelative) { | 
 |         path = URL(callFrame->callerSourceOrigin(vm).url(), fileName); | 
 |         if (!path.isLocalFile()) | 
 |             return throwVMException(globalObject, scope, createURIError(globalObject, makeString("caller relative URL path is not a local file: ", path.string()))); | 
 |     } else | 
 |         path = absolutePath(fileName); | 
 |     Vector<char> script; | 
 |     if (!fetchScriptFromLocalFileSystem(path.fileSystemPath(), script)) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Could not open file."_s))); | 
 |  | 
 |     NakedPtr<Exception> evaluationException; | 
 |     JSValue result = evaluate(globalObject, jscSource(script, SourceOrigin { path }, fileName), JSValue(), evaluationException); | 
 |     if (evaluationException) | 
 |         throwException(globalObject, scope, evaluationException); | 
 |     return JSValue::encode(result); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionLoadString, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String sourceCode = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     NakedPtr<Exception> evaluationException; | 
 |     JSValue result = evaluate(globalObject, jscSource(sourceCode, callFrame->callerSourceOrigin(vm)), JSValue(), evaluationException); | 
 |     if (evaluationException) | 
 |         throwException(globalObject, scope, evaluationException); | 
 |     return JSValue::encode(result); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionReadFile, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String fileName = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     bool isBinary = false; | 
 |     if (callFrame->argumentCount() > 1) { | 
 |         String type = callFrame->argument(1).toWTFString(globalObject); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |         if (type != "binary") | 
 |             return throwVMError(globalObject, scope, "Expected 'binary' as second argument."); | 
 |         isBinary = true; | 
 |     } | 
 |  | 
 |     RefPtr<Uint8Array> content = fillBufferWithContentsOfFile(fileName); | 
 |     if (!content) | 
 |         return throwVMError(globalObject, scope, "Could not open file."); | 
 |  | 
 |     if (!isBinary) | 
 |         return JSValue::encode(jsString(vm, String::fromUTF8WithLatin1Fallback(content->data(), content->length()))); | 
 |  | 
 |     Structure* structure = globalObject->typedArrayStructure(TypeUint8); | 
 |     JSObject* result = JSUint8Array::create(vm, structure, WTFMove(content)); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     return JSValue::encode(result); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCheckSyntax, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String fileName = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     Vector<char> script; | 
 |     if (!fetchScriptFromLocalFileSystem(fileName, script)) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Could not open file."_s))); | 
 |  | 
 |     StopWatch stopWatch; | 
 |     stopWatch.start(); | 
 |  | 
 |     JSValue syntaxException; | 
 |     bool validSyntax = checkSyntax(globalObject, jscSource(script, SourceOrigin { absolutePath(fileName) }, fileName), &syntaxException); | 
 |     stopWatch.stop(); | 
 |  | 
 |     if (!validSyntax) | 
 |         throwException(globalObject, scope, syntaxException); | 
 |     return JSValue::encode(jsNumber(stopWatch.getElapsedMS())); | 
 | } | 
 |  | 
 | #if ENABLE(SAMPLING_FLAGS) | 
 | JSC_DEFINE_HOST_FUNCTION(functionSetSamplingFlags, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         unsigned flag = static_cast<unsigned>(callFrame->uncheckedArgument(i).toNumber(globalObject)); | 
 |         if ((flag >= 1) && (flag <= 32)) | 
 |             SamplingFlags::setFlag(flag); | 
 |     } | 
 |     return JSValue::encode(jsNull()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionClearSamplingFlags, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         unsigned flag = static_cast<unsigned>(callFrame->uncheckedArgument(i).toNumber(globalObject)); | 
 |         if ((flag >= 1) && (flag <= 32)) | 
 |             SamplingFlags::clearFlag(flag); | 
 |     } | 
 |     return JSValue::encode(jsNull()); | 
 | } | 
 | #endif | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionGetRandomSeed, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNumber(globalObject->weakRandom().seed())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionSetRandomSeed, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     unsigned seed = callFrame->argument(0).toUInt32(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     globalObject->weakRandom().setSeed(seed); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIsRope, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     JSValue argument = callFrame->argument(0); | 
 |     if (!argument.isString()) | 
 |         return JSValue::encode(jsBoolean(false)); | 
 |     const StringImpl* impl = asString(argument)->tryGetValueImpl(); | 
 |     return JSValue::encode(jsBoolean(!impl)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCallerSourceOrigin, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     SourceOrigin sourceOrigin = callFrame->callerSourceOrigin(vm); | 
 |     if (sourceOrigin.url().isNull()) | 
 |         return JSValue::encode(jsNull()); | 
 |     return JSValue::encode(jsString(vm, sourceOrigin.string())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionReadline, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     Vector<char, 256> line; | 
 |     int c; | 
 |     while ((c = getchar()) != EOF) { | 
 |         // FIXME: Should we also break on \r?  | 
 |         if (c == '\n') | 
 |             break; | 
 |         line.append(c); | 
 |     } | 
 |     line.append('\0'); | 
 |     return JSValue::encode(jsString(globalObject->vm(), line.data())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionPreciseTime, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNumber(WallTime::now().secondsSinceEpoch().value())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionNeverInlineFunction, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(setNeverInline(globalObject, callFrame)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionNoDFG, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(setNeverOptimize(globalObject, callFrame)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionNoFTL, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     if (callFrame->argumentCount()) { | 
 |         FunctionExecutable* executable = getExecutableForFunction(callFrame->argument(0)); | 
 |         if (executable) | 
 |             executable->setNeverFTLOptimize(true); | 
 |     } | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionNoOSRExitFuzzing, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(setCannotUseOSRExitFuzzing(globalObject, callFrame)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionOptimizeNextInvocation, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(optimizeNextInvocation(globalObject, callFrame)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionNumberOfDFGCompiles, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(numberOfDFGCompiles(globalObject, callFrame)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCallerIsOMGCompiled, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (!Options::useBBQTierUpChecks()) | 
 |         return JSValue::encode(jsBoolean(true)); | 
 |  | 
 |     CallerFunctor wasmToJSFrame; | 
 |     StackVisitor::visit(callFrame, vm, wasmToJSFrame); | 
 |     if (!wasmToJSFrame.callerFrame() || !wasmToJSFrame.callerFrame()->isAnyWasmCallee()) | 
 |         return throwVMError(globalObject, scope, "caller is not a wasm->js import function"); | 
 |  | 
 |     // We have a wrapper frame that we generate for imports. If we ever can direct call from wasm we would need to change this. | 
 |     ASSERT(!wasmToJSFrame.callerFrame()->callee().isWasm()); | 
 |     CallerFunctor wasmFrame; | 
 |     StackVisitor::visit(wasmToJSFrame.callerFrame(), vm, wasmFrame); | 
 |     ASSERT(wasmFrame.callerFrame()->callee().isWasm()); | 
 | #if ENABLE(WEBASSEMBLY) | 
 |     auto mode = wasmFrame.callerFrame()->callee().asWasmCallee()->compilationMode(); | 
 |     return JSValue::encode(jsBoolean(mode == Wasm::CompilationMode::OMGMode || mode == Wasm::CompilationMode::OMGForOSREntryMode)); | 
 | #endif | 
 |     RELEASE_ASSERT_NOT_REACHED(); | 
 | } | 
 |  | 
 | Message::Message(Content&& contents, int32_t index) | 
 |     : m_contents(WTFMove(contents)) | 
 |     , m_index(index) | 
 | { | 
 | } | 
 |  | 
 | Message::~Message() | 
 | { | 
 | } | 
 |  | 
 | Worker::Worker(Workers& workers) | 
 |     : m_workers(workers) | 
 | { | 
 |     auto locker = holdLock(m_workers.m_lock); | 
 |     m_workers.m_workers.append(this); | 
 |      | 
 |     *currentWorker() = this; | 
 | } | 
 |  | 
 | Worker::~Worker() | 
 | { | 
 |     auto locker = holdLock(m_workers.m_lock); | 
 |     RELEASE_ASSERT(isOnList()); | 
 |     remove(); | 
 | } | 
 |  | 
 | void Worker::enqueue(const AbstractLocker&, RefPtr<Message> message) | 
 | { | 
 |     m_messages.append(message); | 
 | } | 
 |  | 
 | RefPtr<Message> Worker::dequeue() | 
 | { | 
 |     auto locker = holdLock(m_workers.m_lock); | 
 |     while (m_messages.isEmpty()) | 
 |         m_workers.m_condition.wait(m_workers.m_lock); | 
 |     return m_messages.takeFirst(); | 
 | } | 
 |  | 
 | Worker& Worker::current() | 
 | { | 
 |     return **currentWorker(); | 
 | } | 
 |  | 
 | ThreadSpecific<Worker*>& Worker::currentWorker() | 
 | { | 
 |     static ThreadSpecific<Worker*>* result; | 
 |     static std::once_flag flag; | 
 |     std::call_once( | 
 |         flag, | 
 |         [] () { | 
 |             result = new ThreadSpecific<Worker*>(); | 
 |         }); | 
 |     return *result; | 
 | } | 
 |  | 
 | Workers::Workers() | 
 | { | 
 | } | 
 |  | 
 | Workers::~Workers() | 
 | { | 
 |     UNREACHABLE_FOR_PLATFORM(); | 
 | } | 
 |  | 
 | template<typename Func> | 
 | void Workers::broadcast(const Func& func) | 
 | { | 
 |     auto locker = holdLock(m_lock); | 
 |     for (Worker* worker = m_workers.begin(); worker != m_workers.end(); worker = worker->next()) { | 
 |         if (worker != &Worker::current()) | 
 |             func(locker, *worker); | 
 |     } | 
 |     m_condition.notifyAll(); | 
 | } | 
 |  | 
 | void Workers::report(const String& string) | 
 | { | 
 |     auto locker = holdLock(m_lock); | 
 |     m_reports.append(string.isolatedCopy()); | 
 |     m_condition.notifyAll(); | 
 | } | 
 |  | 
 | String Workers::tryGetReport() | 
 | { | 
 |     auto locker = holdLock(m_lock); | 
 |     if (m_reports.isEmpty()) | 
 |         return String(); | 
 |     return m_reports.takeFirst(); | 
 | } | 
 |  | 
 | String Workers::getReport() | 
 | { | 
 |     auto locker = holdLock(m_lock); | 
 |     while (m_reports.isEmpty()) | 
 |         m_condition.wait(m_lock); | 
 |     return m_reports.takeFirst(); | 
 | } | 
 |  | 
 | Workers& Workers::singleton() | 
 | { | 
 |     static Workers* result; | 
 |     static std::once_flag flag; | 
 |     std::call_once( | 
 |         flag, | 
 |         [] { | 
 |             result = new Workers(); | 
 |         }); | 
 |     return *result; | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarCreateRealm, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     GlobalObject* result = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>()); | 
 |     return JSValue::encode(result->getDirect(vm, Identifier::fromString(vm, "$"))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarEvalScript, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String sourceCode = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |      | 
 |     JSValue global = callFrame->thisValue().get(globalObject, Identifier::fromString(vm, "global")); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     GlobalObject* realm = jsDynamicCast<GlobalObject*>(vm, global); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     if (!realm) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Expected global to point to a global object"_s))); | 
 |      | 
 |     NakedPtr<Exception> evaluationException; | 
 |     JSValue result = evaluate(realm, jscSource(sourceCode, callFrame->callerSourceOrigin(vm)), JSValue(), evaluationException); | 
 |     if (evaluationException) | 
 |         throwException(globalObject, scope, evaluationException); | 
 |     return JSValue::encode(result); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentStart, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String sourceCode = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |      | 
 |     Lock didStartLock; | 
 |     Condition didStartCondition; | 
 |     bool didStart = false; | 
 |  | 
 |     auto isGigacageMemoryExhausted = [&](Gigacage::Kind kind) { | 
 |         if (!Gigacage::isEnabled(kind)) | 
 |             return false; | 
 |         if (Gigacage::footprint(kind) < Gigacage::size(kind) * 0.8) | 
 |             return false; | 
 |         return true; | 
 |     }; | 
 |  | 
 |     if (isGigacageMemoryExhausted(Gigacage::JSValue) || isGigacageMemoryExhausted(Gigacage::Primitive)) | 
 |         return JSValue::encode(throwOutOfMemoryError(globalObject, scope, "Gigacage is exhausted"_s)); | 
 |  | 
 |     String workerPath = "worker"_s; | 
 |     if (!callFrame->argument(1).isUndefined()) { | 
 |         workerPath = callFrame->argument(1).toWTFString(globalObject); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     } | 
 |      | 
 |     Thread::create( | 
 |         "JSC Agent", | 
 |         [sourceCode = sourceCode.isolatedCopy(), workerPath = workerPath.isolatedCopy(), &didStartLock, &didStartCondition, &didStart] () { | 
 |             CommandLine commandLine(CommandLine::CommandLineForWorkers); | 
 |             commandLine.m_interactive = false; | 
 |             runJSC( | 
 |                 commandLine, true, | 
 |                 [&] (VM&, GlobalObject* globalObject, bool& success) { | 
 |                     // Notify the thread that started us that we have registered a worker. | 
 |                     { | 
 |                         auto locker = holdLock(didStartLock); | 
 |                         didStart = true; | 
 |                         didStartCondition.notifyOne(); | 
 |                     } | 
 |                      | 
 |                     NakedPtr<Exception> evaluationException; | 
 |                     JSValue result; | 
 |                     result = evaluate(globalObject, jscSource(sourceCode, SourceOrigin(URL({ }, workerPath))), JSValue(), evaluationException); | 
 |                     if (evaluationException) | 
 |                         result = evaluationException->value(); | 
 |                     checkException(globalObject, true, evaluationException, result, commandLine, success); | 
 |                     if (!success) | 
 |                         exit(1); | 
 |                 }); | 
 |         })->detach(); | 
 |      | 
 |     { | 
 |         auto locker = holdLock(didStartLock); | 
 |         while (!didStart) | 
 |             didStartCondition.wait(didStartLock); | 
 |     } | 
 |      | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentReceiveBroadcast, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     JSValue callback = callFrame->argument(0); | 
 |     auto callData = getCallData(vm, callback); | 
 |     if (callData.type == CallData::Type::None) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Expected callback"_s))); | 
 |      | 
 |     RefPtr<Message> message; | 
 |     { | 
 |         ReleaseHeapAccessScope releaseAccess(vm.heap); | 
 |         message = Worker::current().dequeue(); | 
 |     } | 
 |  | 
 |     auto content = message->releaseContents(); | 
 |     JSValue result = ([&]() -> JSValue { | 
 |         if (WTF::holds_alternative<ArrayBufferContents>(content)) { | 
 |             auto nativeBuffer = ArrayBuffer::create(WTF::get<ArrayBufferContents>(WTFMove(content))); | 
 |             ArrayBufferSharingMode sharingMode = nativeBuffer->sharingMode(); | 
 |             return JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(sharingMode), WTFMove(nativeBuffer)); | 
 |         } | 
 | #if ENABLE(WEBASSEMBLY) | 
 |         if (WTF::holds_alternative<Ref<Wasm::MemoryHandle>>(content)) { | 
 |             JSWebAssemblyMemory* jsMemory = JSC::JSWebAssemblyMemory::tryCreate(globalObject, vm, globalObject->webAssemblyMemoryStructure()); | 
 |             scope.releaseAssertNoException(); | 
 |             Ref<Wasm::Memory> memory = Wasm::Memory::create(WTF::get<Ref<Wasm::MemoryHandle>>(WTFMove(content)), | 
 |                 [&vm] (Wasm::Memory::NotifyPressure) { vm.heap.collectAsync(CollectionScope::Full); }, | 
 |                 [&vm] (Wasm::Memory::SyncTryToReclaim) { vm.heap.collectSync(CollectionScope::Full); }, | 
 |                 [&vm, jsMemory] (Wasm::Memory::GrowSuccess, Wasm::PageCount oldPageCount, Wasm::PageCount newPageCount) { jsMemory->growSuccessCallback(vm, oldPageCount, newPageCount); }); | 
 |             jsMemory->adopt(WTFMove(memory)); | 
 |             return jsMemory; | 
 |         } | 
 | #endif | 
 |         return jsUndefined(); | 
 |     })(); | 
 |  | 
 |     MarkedArgumentBuffer args; | 
 |     args.append(result); | 
 |     args.append(jsNumber(message->index())); | 
 |     if (UNLIKELY(args.hasOverflowed())) | 
 |         return JSValue::encode(throwOutOfMemoryError(globalObject, scope)); | 
 |     RELEASE_AND_RETURN(scope, JSValue::encode(call(globalObject, callback, callData, jsNull(), args))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentReport, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String report = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |      | 
 |     Workers::singleton().report(report); | 
 |      | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentSleep, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (callFrame->argumentCount() >= 1) { | 
 |         Seconds seconds = Seconds::fromMilliseconds(callFrame->argument(0).toNumber(globalObject)); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |         sleep(seconds); | 
 |     } | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentBroadcast, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     int32_t index = callFrame->argument(1).toInt32(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(vm, callFrame->argument(0)); | 
 |     if (jsBuffer && jsBuffer->isShared()) { | 
 |         Workers::singleton().broadcast( | 
 |             [&] (const AbstractLocker& locker, Worker& worker) { | 
 |                 ArrayBuffer* nativeBuffer = jsBuffer->impl(); | 
 |                 ArrayBufferContents contents; | 
 |                 nativeBuffer->transferTo(vm, contents); // "transferTo" means "share" if the buffer is shared. | 
 |                 RefPtr<Message> message = adoptRef(new Message(WTFMove(contents), index)); | 
 |                 worker.enqueue(locker, message); | 
 |             }); | 
 |         return JSValue::encode(jsUndefined()); | 
 |     } | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 |     JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, callFrame->argument(0)); | 
 |     if (memory && memory->memory().sharingMode() == Wasm::MemorySharingMode::Shared) { | 
 |         Workers::singleton().broadcast( | 
 |             [&] (const AbstractLocker& locker, Worker& worker) { | 
 |                 Ref<Wasm::MemoryHandle> handle { memory->memory().handle() }; | 
 |                 RefPtr<Message> message = adoptRef(new Message(WTFMove(handle), index)); | 
 |                 worker.enqueue(locker, message); | 
 |             }); | 
 |         return JSValue::encode(jsUndefined()); | 
 |     } | 
 | #endif | 
 |  | 
 |     return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Not supported object"_s))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentGetReport, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |  | 
 |     String string = Workers::singleton().tryGetReport(); | 
 |     if (!string) | 
 |         return JSValue::encode(jsNull()); | 
 |      | 
 |     return JSValue::encode(jsString(vm, string)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentLeaving, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDollarAgentMonotonicNow, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNumber(MonotonicTime::now().secondsSinceEpoch().milliseconds())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionWaitForReport, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |  | 
 |     String string; | 
 |     { | 
 |         ReleaseHeapAccessScope releaseAccess(vm.heap); | 
 |         string = Workers::singleton().getReport(); | 
 |     } | 
 |     if (!string) | 
 |         return JSValue::encode(jsNull()); | 
 |      | 
 |     return JSValue::encode(jsString(vm, string)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionHeapCapacity, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     return JSValue::encode(jsNumber(vm.heap.capacity())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFlashHeapAccess, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |      | 
 |     double sleepTimeMs = 0; | 
 |     if (callFrame->argumentCount() >= 1) { | 
 |         sleepTimeMs = callFrame->argument(0).toNumber(globalObject); | 
 |         RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     } | 
 |  | 
 |     vm.heap.releaseAccess(); | 
 |     if (sleepTimeMs) | 
 |         sleep(Seconds::fromMilliseconds(sleepTimeMs)); | 
 |     vm.heap.acquireAccess(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDisableRichSourceInfo, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     supportsRichSourceInfo = false; | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionMallocInALoop, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     Vector<void*> ptrs; | 
 |     for (unsigned i = 0; i < 5000; ++i) | 
 |         ptrs.append(fastMalloc(1024 * 2)); | 
 |     for (void* ptr : ptrs) | 
 |         fastFree(ptr); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionTotalCompileTime, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 | #if ENABLE(JIT) | 
 |     return JSValue::encode(jsNumber(JIT::totalCompileTime().milliseconds())); | 
 | #else | 
 |     return JSValue::encode(jsNumber(0)); | 
 | #endif | 
 | } | 
 |  | 
 | template<typename ValueType> | 
 | typename std::enable_if<!std::is_fundamental<ValueType>::value>::type addOption(VM&, JSObject*, const Identifier&, ValueType) { } | 
 |  | 
 | template<typename ValueType> | 
 | typename std::enable_if<std::is_fundamental<ValueType>::value>::type addOption(VM& vm, JSObject* optionsObject, const Identifier& identifier, ValueType value) | 
 | { | 
 |     optionsObject->putDirect(vm, identifier, JSValue(value)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionJSCOptions, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSObject* optionsObject = constructEmptyObject(globalObject); | 
 | #define READ_OPTION(type_, name_, defaultValue_, availability_, description_) \ | 
 |     addOption(vm, optionsObject, Identifier::fromString(vm, #name_), Options::name_()); | 
 |     FOR_EACH_JSC_OPTION(READ_OPTION) | 
 | #undef READ_OPTION | 
 |     return JSValue::encode(optionsObject); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionReoptimizationRetryCount, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     if (callFrame->argumentCount() < 1) | 
 |         return JSValue::encode(jsUndefined()); | 
 |      | 
 |     CodeBlock* block = getSomeBaselineCodeBlockForFunction(callFrame->argument(0)); | 
 |     if (!block) | 
 |         return JSValue::encode(jsNumber(0)); | 
 |      | 
 |     return JSValue::encode(jsNumber(block->reoptimizationRetryCounter())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionTransferArrayBuffer, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (callFrame->argumentCount() < 1) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Not enough arguments"_s))); | 
 |      | 
 |     JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(vm, callFrame->argument(0)); | 
 |     if (!buffer) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Expected an array buffer"_s))); | 
 |      | 
 |     ArrayBufferContents dummyContents; | 
 |     buffer->impl()->transferTo(vm, dummyContents); | 
 |      | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFailNextNewCodeBlock, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     vm.setFailNextNewCodeBlock(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionQuit, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     vm.codeCache()->write(vm); | 
 |  | 
 |     jscExit(EXIT_SUCCESS); | 
 |  | 
 | #if COMPILER(MSVC) | 
 |     // Without this, Visual Studio will complain that this method does not return a value. | 
 |     return JSValue::encode(jsUndefined()); | 
 | #endif | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFalse, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsBoolean(false)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionUndefined1, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionUndefined2, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIsInt32, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     for (size_t i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         if (!callFrame->argument(i).isInt32()) | 
 |             return JSValue::encode(jsBoolean(false)); | 
 |     } | 
 |     return JSValue::encode(jsBoolean(true)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIsPureNaN, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     for (size_t i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         JSValue value = callFrame->argument(i); | 
 |         if (!value.isNumber()) | 
 |             return JSValue::encode(jsBoolean(false)); | 
 |         double number = value.asNumber(); | 
 |         if (!std::isnan(number)) | 
 |             return JSValue::encode(jsBoolean(false)); | 
 |         if (isImpureNaN(number)) | 
 |             return JSValue::encode(jsBoolean(false)); | 
 |     } | 
 |     return JSValue::encode(jsBoolean(true)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIdentity, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(callFrame->argument(0)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionEffectful42, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNumber(42)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionMakeMasquerader, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     return JSValue::encode(InternalFunction::createFunctionThatMasqueradesAsUndefined(vm, globalObject, 0, "IsHTMLDDA"_s, functionCallMasquerader)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCallMasquerader, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNull()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionHasCustomProperties, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     JSValue value = callFrame->argument(0); | 
 |     if (value.isObject()) | 
 |         return JSValue::encode(jsBoolean(asObject(value)->hasCustomProperties(globalObject->vm()))); | 
 |     return JSValue::encode(jsBoolean(false)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDumpTypesForAllVariables, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     vm.dumpTypeProfilerData(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDrainMicrotasks, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     vm.drainMicrotasks(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionSetTimeout, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     // FIXME: This means we can't pass any internal function but I don't think that's common for testing. | 
 |     auto callback = jsDynamicCast<JSFunction*>(vm, callFrame->argument(0)); | 
 |     if (!callback) | 
 |         return throwVMTypeError(globalObject, scope, "First argument is not a JS function"_s); | 
 |  | 
 |     // FIXME: We don't look at the timeout parameter because we don't have a schedule work later API. | 
 |     vm.deferredWorkTimer->addPendingWork(vm, callback, { }); | 
 |     vm.deferredWorkTimer->scheduleWorkSoon(callback, [callback](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) { | 
 |         JSGlobalObject* globalObject = callback->globalObject(); | 
 |         MarkedArgumentBuffer args; | 
 |         call(globalObject, callback, jsUndefined(), args, "You shouldn't see this..."); | 
 |     }); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionReleaseWeakRefs, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     vm.finalizeSynchronousJSExecution(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFinalizationRegistryLiveCount, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     auto* finalizationRegistry = jsDynamicCast<JSFinalizationRegistry*>(vm, callFrame->argument(0)); | 
 |     if (!finalizationRegistry) | 
 |         return throwVMTypeError(globalObject, scope, "first argument is not a finalizationRegistry"_s); | 
 |  | 
 |     auto locker = holdLock(finalizationRegistry->cellLock()); | 
 |     return JSValue::encode(jsNumber(finalizationRegistry->liveCount(locker))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionFinalizationRegistryDeadCount, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     auto* finalizationRegistry = jsDynamicCast<JSFinalizationRegistry*>(vm, callFrame->argument(0)); | 
 |     if (!finalizationRegistry) | 
 |         return throwVMTypeError(globalObject, scope, "first argument is not a finalizationRegistry"_s); | 
 |  | 
 |     auto locker = holdLock(finalizationRegistry->cellLock()); | 
 |     return JSValue::encode(jsNumber(finalizationRegistry->deadCount(locker))); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIs32BitPlatform, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 | #if USE(JSVALUE64) | 
 |     return JSValue::encode(JSValue(JSC::JSValue::JSFalse)); | 
 | #else | 
 |     return JSValue::encode(JSValue(JSC::JSValue::JSTrue)); | 
 | #endif | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCreateGlobalObject, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     return JSValue::encode(GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), Vector<String>())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCreateHeapBigInt, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |     JSValue argument = callFrame->argument(0); | 
 |     JSValue bigInt = argument.toBigInt(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 | #if USE(BIGINT32) | 
 |     if (bigInt.isHeapBigInt()) | 
 |         return JSValue::encode(bigInt); | 
 |     ASSERT(bigInt.isBigInt32()); | 
 |     int32_t value = bigInt.bigInt32AsInt32(); | 
 |     RELEASE_AND_RETURN(scope, JSValue::encode(JSBigInt::createFrom(globalObject, value))); | 
 | #else | 
 |     return JSValue::encode(bigInt); | 
 | #endif | 
 | } | 
 |  | 
 | #if USE(BIGINT32) | 
 | JSC_DEFINE_HOST_FUNCTION(functionCreateBigInt32, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |     JSValue argument = callFrame->argument(0); | 
 |     JSValue bigIntValue = argument.toBigInt(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     if (bigIntValue.isBigInt32()) | 
 |         return JSValue::encode(bigIntValue); | 
 |     ASSERT(bigIntValue.isHeapBigInt()); | 
 |     JSBigInt* bigInt = jsCast<JSBigInt*>(bigIntValue); | 
 |     if (!bigInt->length()) | 
 |         return JSValue::encode(jsBigInt32(0)); | 
 |     if (bigInt->length() == 1) { | 
 |         JSBigInt::Digit digit = bigInt->digit(0); | 
 |         if (bigInt->sign()) { | 
 |             if (digit <= static_cast<uint64_t>(-static_cast<int64_t>(INT32_MIN))) | 
 |                 return JSValue::encode(jsBigInt32(static_cast<int32_t>(-static_cast<int64_t>(digit)))); | 
 |         } else { | 
 |             if (digit <= INT32_MAX) | 
 |                 return JSValue::encode(jsBigInt32(static_cast<int32_t>(digit))); | 
 |         } | 
 |     } | 
 |     throwTypeError(globalObject, scope, "Out of range of BigInt32"_s); | 
 |     return { }; | 
 | } | 
 | #endif | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionUseBigInt32, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 | #if USE(BIGINT32) | 
 |     return JSValue::encode(jsBoolean(true)); | 
 | #else | 
 |     return JSValue::encode(jsBoolean(false)); | 
 | #endif | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIsBigInt32, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 | #if USE(BIGINT32) | 
 |     return JSValue::encode(jsBoolean(callFrame->argument(0).isBigInt32())); | 
 | #else | 
 |     UNUSED_PARAM(callFrame); | 
 |     return JSValue::encode(jsBoolean(false)); | 
 | #endif | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionIsHeapBigInt, (JSGlobalObject*, CallFrame* callFrame)) | 
 | { | 
 |     return JSValue::encode(jsBoolean(callFrame->argument(0).isHeapBigInt())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionCheckModuleSyntax, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     String source = callFrame->argument(0).toWTFString(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |  | 
 |     StopWatch stopWatch; | 
 |     stopWatch.start(); | 
 |  | 
 |     ParserError error; | 
 |     bool validSyntax = checkModuleSyntax(globalObject, jscSource(source, { }, String(), TextPosition(), SourceProviderSourceType::Module), error); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     stopWatch.stop(); | 
 |  | 
 |     if (!validSyntax) | 
 |         throwException(globalObject, scope, jsNontrivialString(vm, toString("SyntaxError: ", error.message(), ":", error.line()))); | 
 |     return JSValue::encode(jsNumber(stopWatch.getElapsedMS())); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionPlatformSupportsSamplingProfiler, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 | #if ENABLE(SAMPLING_PROFILER) | 
 |     return JSValue::encode(JSValue(JSC::JSValue::JSTrue)); | 
 | #else | 
 |     return JSValue::encode(JSValue(JSC::JSValue::JSFalse)); | 
 | #endif | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshot, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     HeapSnapshotBuilder snapshotBuilder(vm.ensureHeapProfiler()); | 
 |     snapshotBuilder.buildSnapshot(); | 
 |  | 
 |     String jsonString = snapshotBuilder.json(); | 
 |     EncodedJSValue result = JSValue::encode(JSONParse(globalObject, jsonString)); | 
 |     scope.releaseAssertNoException(); | 
 |     return result; | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshotForGCDebugging, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSLockHolder lock(vm); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |     String jsonString; | 
 |     { | 
 |         DeferGCForAWhile deferGC(vm.heap); // Prevent concurrent GC from interfering with the full GC that the snapshot does. | 
 |  | 
 |         HeapSnapshotBuilder snapshotBuilder(vm.ensureHeapProfiler(), HeapSnapshotBuilder::SnapshotType::GCDebuggingSnapshot); | 
 |         snapshotBuilder.buildSnapshot(); | 
 |  | 
 |         jsonString = snapshotBuilder.json(); | 
 |     } | 
 |     scope.releaseAssertNoException(); | 
 |     return JSValue::encode(jsString(vm, jsonString)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionResetSuperSamplerState, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     resetSuperSamplerState(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionEnsureArrayStorage, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     for (unsigned i = 0; i < callFrame->argumentCount(); ++i) { | 
 |         if (JSObject* object = jsDynamicCast<JSObject*>(vm, callFrame->argument(i))) | 
 |             object->ensureArrayStorage(vm); | 
 |     } | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | #if ENABLE(SAMPLING_PROFILER) | 
 | JSC_DEFINE_HOST_FUNCTION(functionStartSamplingProfiler, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     SamplingProfiler& samplingProfiler = vm.ensureSamplingProfiler(WTF::Stopwatch::create()); | 
 |     samplingProfiler.noticeCurrentThreadAsJSCExecutionThread(); | 
 |     samplingProfiler.start(); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionSamplingProfilerStackTraces, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (!vm.samplingProfiler()) | 
 |         return JSValue::encode(throwException(globalObject, scope, createError(globalObject, "Sampling profiler was never started"_s))); | 
 |  | 
 |     String jsonString = vm.samplingProfiler()->stackTracesAsJSON(); | 
 |     EncodedJSValue result = JSValue::encode(JSONParse(globalObject, jsonString)); | 
 |     scope.releaseAssertNoException(); | 
 |     return result; | 
 | } | 
 | #endif // ENABLE(SAMPLING_PROFILER) | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionMaxArguments, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     return JSValue::encode(jsNumber(JSC::maxArguments)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionAsyncTestStart, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     JSValue numberOfAsyncPasses = callFrame->argument(0); | 
 |     if (!numberOfAsyncPasses.isUInt32()) | 
 |         return throwVMError(globalObject, scope, "Expected first argument to be a uint32"_s); | 
 |  | 
 |     asyncTestExpectedPasses += numberOfAsyncPasses.asUInt32(); | 
 |     return encodedJSUndefined(); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionAsyncTestPassed, (JSGlobalObject*, CallFrame*)) | 
 | { | 
 |     asyncTestPasses++; | 
 |     return encodedJSUndefined(); | 
 | } | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionWebAssemblyMemoryMode, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |      | 
 |     if (!Wasm::isSupported()) | 
 |         return throwVMTypeError(globalObject, scope, "WebAssemblyMemoryMode should only be called if the useWebAssembly option is set"_s); | 
 |  | 
 |     if (JSObject* object = callFrame->argument(0).getObject()) { | 
 |         if (auto* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, object)) | 
 |             return JSValue::encode(jsString(vm, makeString(memory->memory().mode()))); | 
 |         if (auto* instance = jsDynamicCast<JSWebAssemblyInstance*>(vm, object)) | 
 |             return JSValue::encode(jsString(vm, makeString(instance->memoryMode()))); | 
 |     } | 
 |  | 
 |     return throwVMTypeError(globalObject, scope, "WebAssemblyMemoryMode expects either a WebAssembly.Memory or WebAssembly.Instance"_s); | 
 | } | 
 |  | 
 | #endif // ENABLE(WEBASSEMBLY) | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionSetUnhandledRejectionCallback, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     JSObject* object = callFrame->argument(0).getObject(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |  | 
 |     if (!object || !object->isCallable(vm)) | 
 |         return throwVMTypeError(globalObject, scope); | 
 |  | 
 |     globalObject->setUnhandledRejectionCallback(vm, object); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionAsDoubleNumber, (JSGlobalObject* globalObject, CallFrame* callFrame)) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_THROW_SCOPE(vm); | 
 |     double num = callFrame->argument(0).toNumber(globalObject); | 
 |     RETURN_IF_EXCEPTION(scope, encodedJSValue()); | 
 |     return JSValue::encode(jsDoubleNumber(num)); | 
 | } | 
 |  | 
 | JSC_DEFINE_HOST_FUNCTION(functionDropAllLocks, (JSGlobalObject* globalObject, CallFrame*)) | 
 | { | 
 |     JSLock::DropAllLocks dropAllLocks(globalObject); | 
 |     return JSValue::encode(jsUndefined()); | 
 | } | 
 |  | 
 | // Use SEH for Release builds only to get rid of the crash report dialog | 
 | // (luckily the same tests fail in Release and Debug builds so far). Need to | 
 | // be in a separate main function because the jscmain function requires object | 
 | // unwinding. | 
 |  | 
 | #if COMPILER(MSVC) && !defined(_DEBUG) | 
 | #define TRY       __try { | 
 | #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; } | 
 | #else | 
 | #define TRY | 
 | #define EXCEPT(x) | 
 | #endif | 
 |  | 
 | int jscmain(int argc, char** argv); | 
 |  | 
 | #if OS(DARWIN) || OS(LINUX) | 
 | static size_t memoryLimit; | 
 |  | 
 | static void crashIfExceedingMemoryLimit() | 
 | { | 
 |     if (!memoryLimit) | 
 |         return; | 
 |     MemoryFootprint footprint = MemoryFootprint::now(); | 
 |     if (footprint.current > memoryLimit) { | 
 |         dataLogLn("Crashing because current footprint: ", footprint.current, " exceeds limit: ", memoryLimit); | 
 |         CRASH(); | 
 |     } | 
 | } | 
 |  | 
 | static void startMemoryMonitoringThreadIfNeeded() | 
 | { | 
 |     char* memoryLimitString = getenv("JSCTEST_memoryLimit"); | 
 |     if (!memoryLimitString) | 
 |         return; | 
 |  | 
 |     if (sscanf(memoryLimitString, "%zu", &memoryLimit) != 1) { | 
 |         dataLogLn("WARNING: malformed JSCTEST_memoryLimit environment variable"); | 
 |         return; | 
 |     } | 
 |  | 
 |     if (!memoryLimit) | 
 |         return; | 
 |  | 
 |     Thread::create("jsc Memory Monitor", [=] { | 
 |         while (true) { | 
 |             sleep(Seconds::fromMilliseconds(5)); | 
 |             crashIfExceedingMemoryLimit(); | 
 |         } | 
 |     }); | 
 | } | 
 | #endif // OS(DARWIN) || OS(LINUX) | 
 |  | 
 | static double s_desiredTimeout; | 
 | static double s_timeoutMultiplier = 1.0; | 
 | static Seconds s_timeoutDuration; | 
 | static Seconds s_maxAllowedCPUTime; | 
 | static VM* s_vm; | 
 |  | 
 | static void startTimeoutTimer(Seconds duration) | 
 | { | 
 |     Thread::create("jsc Timeout Thread", [=] () { | 
 |         sleep(duration); | 
 |         VMInspector::forEachVM([&] (VM& vm) -> VMInspector::FunctorStatus { | 
 |             if (&vm != s_vm) | 
 |                 return VMInspector::FunctorStatus::Continue; | 
 |             vm.notifyNeedShellTimeoutCheck(); | 
 |             return VMInspector::FunctorStatus::Done; | 
 |         }); | 
 |  | 
 |         if (const char* timeoutString = getenv("JSCTEST_hardTimeout")) { | 
 |             double hardTimeoutInDouble = 0; | 
 |             if (sscanf(timeoutString, "%lf", &hardTimeoutInDouble) != 1) | 
 |                 dataLog("WARNING: hardTimeout string is malformed, got ", timeoutString, " but expected a number. Not using a timeout.\n"); | 
 |             else { | 
 |                 Seconds hardTimeout { hardTimeoutInDouble }; | 
 |                 sleep(hardTimeout); | 
 |                 dataLogLn("HARD TIMEOUT after ", hardTimeout); | 
 |                 exit(EXIT_FAILURE); | 
 |             } | 
 |         } | 
 |     }); | 
 | } | 
 |  | 
 | static void timeoutCheckCallback(VM& vm) | 
 | { | 
 |     RELEASE_ASSERT(&vm == s_vm); | 
 |     auto cpuTime = CPUTime::forCurrentThread(); | 
 |     if (cpuTime >= s_maxAllowedCPUTime) { | 
 |         dataLog("Timed out after ", s_timeoutDuration, " seconds!\n"); | 
 |         CRASH(); | 
 |     } | 
 |     auto remainingTime = s_maxAllowedCPUTime - cpuTime; | 
 |     startTimeoutTimer(remainingTime); | 
 | } | 
 |  | 
 | static void initializeTimeoutIfNeeded() | 
 | { | 
 |     if (char* timeoutString = getenv("JSCTEST_timeout")) { | 
 |         if (sscanf(timeoutString, "%lf", &s_desiredTimeout) != 1) { | 
 |             dataLog("WARNING: timeout string is malformed, got ", timeoutString, | 
 |                 " but expected a number. Not using a timeout.\n"); | 
 |         } else | 
 |             g_jscConfig.shellTimeoutCheckCallback = timeoutCheckCallback; | 
 |     } | 
 | } | 
 |  | 
 | static void startTimeoutThreadIfNeeded(VM& vm) | 
 | { | 
 |     if (!g_jscConfig.shellTimeoutCheckCallback) | 
 |         return; | 
 |  | 
 |     s_vm = &vm; | 
 |     s_timeoutDuration = Seconds(s_desiredTimeout * s_timeoutMultiplier); | 
 |     s_maxAllowedCPUTime = CPUTime::forCurrentThread() + s_timeoutDuration; | 
 |     Seconds timeoutDuration(s_desiredTimeout * s_timeoutMultiplier); | 
 |     startTimeoutTimer(timeoutDuration); | 
 | } | 
 |  | 
 | int main(int argc, char** argv) | 
 | { | 
 | #if OS(DARWIN) && CPU(ARM_THUMB2) | 
 |     // Enabled IEEE754 denormal support. | 
 |     fenv_t env; | 
 |     fegetenv( &env ); | 
 |     env.__fpscr &= ~0x01000000u; | 
 |     fesetenv( &env ); | 
 | #endif | 
 |  | 
 | #if OS(WINDOWS) | 
 |     // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for | 
 |     // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the | 
 |     // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>. | 
 |     ::SetErrorMode(0); | 
 |  | 
 |     _setmode(_fileno(stdout), _O_BINARY); | 
 |     _setmode(_fileno(stderr), _O_BINARY); | 
 |  | 
 | #if defined(_DEBUG) | 
 |     _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); | 
 |     _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); | 
 |     _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); | 
 |     _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); | 
 |     _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); | 
 |     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); | 
 | #endif | 
 |  | 
 |     timeBeginPeriod(1); | 
 | #endif | 
 |  | 
 | #if PLATFORM(GTK) | 
 |     if (!setlocale(LC_ALL, "")) | 
 |         WTFLogAlways("Locale not supported by C library.\n\tUsing the fallback 'C' locale."); | 
 | #endif | 
 |  | 
 |     // Need to initialize WTF before we start any threads. Cannot initialize JSC | 
 |     // yet, since that would do somethings that we'd like to defer until after we | 
 |     // have a chance to parse options. | 
 |     WTF::initialize(); | 
 |  | 
 |     // We can't use destructors in the following code because it uses Windows | 
 |     // Structured Exception Handling | 
 |     int res = EXIT_SUCCESS; | 
 |     TRY | 
 |         res = jscmain(argc, argv); | 
 |     EXCEPT(res = EXIT_EXCEPTION) | 
 |     finalizeStatsAtEndOfTesting(); | 
 |     if (getenv("JS_SHELL_WAIT_FOR_INPUT_TO_EXIT")) { | 
 |         WTF::fastDisableScavenger(); | 
 |         fprintf(stdout, "\njs shell waiting for input to exit\n"); | 
 |         fflush(stdout); | 
 |         getc(stdin); | 
 |     } | 
 |  | 
 |     jscExit(res); | 
 | } | 
 |  | 
 | static void dumpException(GlobalObject* globalObject, JSValue exception) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_CATCH_SCOPE(vm); | 
 |  | 
 | #define CHECK_EXCEPTION() do { \ | 
 |         if (scope.exception()) { \ | 
 |             scope.clearException(); \ | 
 |             return; \ | 
 |         } \ | 
 |     } while (false) | 
 |  | 
 |     auto exceptionString = exception.toWTFString(globalObject); | 
 |     CHECK_EXCEPTION(); | 
 |     Expected<CString, UTF8ConversionError> expectedCString = exceptionString.tryGetUtf8(); | 
 |     if (expectedCString) | 
 |         printf("Exception: %s\n", expectedCString.value().data()); | 
 |     else | 
 |         printf("Exception: <out of memory while extracting exception string>\n"); | 
 |  | 
 |     Identifier nameID = Identifier::fromString(vm, "name"); | 
 |     CHECK_EXCEPTION(); | 
 |     Identifier fileNameID = Identifier::fromString(vm, "sourceURL"); | 
 |     CHECK_EXCEPTION(); | 
 |     Identifier lineNumberID = Identifier::fromString(vm, "line"); | 
 |     CHECK_EXCEPTION(); | 
 |     Identifier stackID = Identifier::fromString(vm, "stack"); | 
 |     CHECK_EXCEPTION(); | 
 |  | 
 |     JSValue nameValue = exception.get(globalObject, nameID); | 
 |     CHECK_EXCEPTION(); | 
 |     JSValue fileNameValue = exception.get(globalObject, fileNameID); | 
 |     CHECK_EXCEPTION(); | 
 |     JSValue lineNumberValue = exception.get(globalObject, lineNumberID); | 
 |     CHECK_EXCEPTION(); | 
 |     JSValue stackValue = exception.get(globalObject, stackID); | 
 |     CHECK_EXCEPTION(); | 
 |      | 
 |     auto nameString = nameValue.toWTFString(globalObject); | 
 |     CHECK_EXCEPTION(); | 
 |  | 
 |     if (nameString == "SyntaxError" && (!fileNameValue.isUndefinedOrNull() || !lineNumberValue.isUndefinedOrNull())) { | 
 |         auto fileNameString = fileNameValue.toWTFString(globalObject); | 
 |         CHECK_EXCEPTION(); | 
 |         auto lineNumberString = lineNumberValue.toWTFString(globalObject); | 
 |         CHECK_EXCEPTION(); | 
 |         printf("at %s:%s\n", fileNameString.utf8().data(), lineNumberString.utf8().data()); | 
 |     } | 
 |      | 
 |     if (!stackValue.isUndefinedOrNull()) { | 
 |         auto stackString = stackValue.toWTFString(globalObject); | 
 |         CHECK_EXCEPTION(); | 
 |         if (stackString.length()) | 
 |             printf("%s\n", stackString.utf8().data()); | 
 |     } | 
 |  | 
 | #undef CHECK_EXCEPTION | 
 | } | 
 |  | 
 | static bool checkUncaughtException(VM& vm, GlobalObject* globalObject, JSValue exception, const CommandLine& options) | 
 | { | 
 |     const String& expectedExceptionName = options.m_uncaughtExceptionName; | 
 |     auto scope = DECLARE_CATCH_SCOPE(vm); | 
 |     scope.clearException(); | 
 |     if (!exception) { | 
 |         printf("Expected uncaught exception with name '%s' but none was thrown\n", expectedExceptionName.utf8().data()); | 
 |         return false; | 
 |     } | 
 |  | 
 |     JSValue exceptionClass = globalObject->get(globalObject, Identifier::fromString(vm, expectedExceptionName)); | 
 |     if (!exceptionClass.isObject() || scope.exception()) { | 
 |         printf("Expected uncaught exception with name '%s' but given exception class is not defined\n", expectedExceptionName.utf8().data()); | 
 |         return false; | 
 |     } | 
 |  | 
 |     bool isInstanceOfExpectedException = jsCast<JSObject*>(exceptionClass)->hasInstance(globalObject, exception); | 
 |     if (scope.exception()) { | 
 |         printf("Expected uncaught exception with name '%s' but given exception class fails performing hasInstance\n", expectedExceptionName.utf8().data()); | 
 |         return false; | 
 |     } | 
 |     if (isInstanceOfExpectedException) { | 
 |         if (options.m_alwaysDumpUncaughtException) | 
 |             dumpException(globalObject, exception); | 
 |         return true; | 
 |     } | 
 |  | 
 |     printf("Expected uncaught exception with name '%s' but exception value is not instance of this exception class\n", expectedExceptionName.utf8().data()); | 
 |     dumpException(globalObject, exception); | 
 |     return false; | 
 | } | 
 |  | 
 | static void checkException(GlobalObject* globalObject, bool isLastFile, bool hasException, JSValue value, const CommandLine& options, bool& success) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |  | 
 |     if (options.m_treatWatchdogExceptionAsSuccess && value.inherits<TerminatedExecutionError>(vm)) { | 
 |         ASSERT(hasException); | 
 |         return; | 
 |     } | 
 |  | 
 |     if (!options.m_uncaughtExceptionName || !isLastFile) { | 
 |         success = success && !hasException; | 
 |         if (options.m_dump && !hasException) | 
 |             printf("End: %s\n", value.toWTFString(globalObject).utf8().data()); | 
 |         if (hasException) | 
 |             dumpException(globalObject, value); | 
 |     } else | 
 |         success = success && checkUncaughtException(vm, globalObject, (hasException) ? value : JSValue(), options); | 
 | } | 
 |  | 
 | void GlobalObject::reportUncaughtExceptionAtEventLoop(JSGlobalObject* globalObject, Exception* exception) | 
 | { | 
 |     auto* global = jsCast<GlobalObject*>(globalObject); | 
 |     dumpException(global, exception->value()); | 
 |     bool hideNoReturn = true; | 
 |     if (hideNoReturn) | 
 |         jscExit(EXIT_EXCEPTION); | 
 | } | 
 |  | 
 | static void runWithOptions(GlobalObject* globalObject, CommandLine& options, bool& success) | 
 | { | 
 |     Vector<Script>& scripts = options.m_scripts; | 
 |     String fileName; | 
 |     Vector<char> scriptBuffer; | 
 |  | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_CATCH_SCOPE(vm); | 
 |  | 
 | #if ENABLE(SAMPLING_FLAGS) | 
 |     SamplingFlags::start(); | 
 | #endif | 
 |  | 
 |     for (size_t i = 0; i < scripts.size(); i++) { | 
 |         JSInternalPromise* promise = nullptr; | 
 |         bool isModule = options.m_module || scripts[i].scriptType == Script::ScriptType::Module; | 
 |         if (scripts[i].codeSource == Script::CodeSource::File) { | 
 |             fileName = scripts[i].argument; | 
 |             if (scripts[i].strictMode == Script::StrictMode::Strict) | 
 |                 scriptBuffer.append("\"use strict\";\n", strlen("\"use strict\";\n")); | 
 |  | 
 |             if (isModule) { | 
 |                 // If the passed file isn't an absolute path append "./" so the module loader doesn't think this is a bare-name specifier. | 
 |                 fileName = fileName.startsWith('/') ? fileName : makeString("./", fileName); | 
 |                 promise = loadAndEvaluateModule(globalObject, fileName, jsUndefined(), jsUndefined()); | 
 |                 scope.releaseAssertNoException(); | 
 |             } else { | 
 |                 if (!fetchScriptFromLocalFileSystem(fileName, scriptBuffer)) { | 
 |                     success = false; // fail early so we can catch missing files | 
 |                     return; | 
 |                 } | 
 |             } | 
 |         } else { | 
 |             size_t commandLineLength = strlen(scripts[i].argument); | 
 |             scriptBuffer.resize(commandLineLength); | 
 |             std::copy(scripts[i].argument, scripts[i].argument + commandLineLength, scriptBuffer.begin()); | 
 |             fileName = "[Command Line]"_s; | 
 |         } | 
 |  | 
 |         bool isLastFile = i == scripts.size() - 1; | 
 |         SourceOrigin sourceOrigin { absolutePath(fileName) }; | 
 |         if (isModule) { | 
 |             if (!promise) { | 
 |                 // FIXME: This should use an absolute file URL https://bugs.webkit.org/show_bug.cgi?id=193077 | 
 |                 promise = loadAndEvaluateModule(globalObject, jscSource(stringFromUTF(scriptBuffer), sourceOrigin, fileName, TextPosition(), SourceProviderSourceType::Module), jsUndefined()); | 
 |                 RETURN_IF_EXCEPTION(scope, void()); | 
 |             } | 
 |  | 
 |             JSFunction* fulfillHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&success, &options, isLastFile](JSGlobalObject* globalObject, CallFrame* callFrame) { | 
 |                 checkException(jsCast<GlobalObject*>(globalObject), isLastFile, false, callFrame->argument(0), options, success); | 
 |                 return JSValue::encode(jsUndefined()); | 
 |             }); | 
 |  | 
 |             JSFunction* rejectHandler = JSNativeStdFunction::create(vm, globalObject, 1, String(), [&success, &options, isLastFile](JSGlobalObject* globalObject, CallFrame* callFrame) { | 
 |                 checkException(jsCast<GlobalObject*>(globalObject), isLastFile, true, callFrame->argument(0), options, success); | 
 |                 return JSValue::encode(jsUndefined()); | 
 |             }); | 
 |  | 
 |             promise->then(globalObject, fulfillHandler, rejectHandler); | 
 |             scope.releaseAssertNoException(); | 
 |             vm.drainMicrotasks(); | 
 |         } else { | 
 |             NakedPtr<Exception> evaluationException; | 
 |             JSValue returnValue = evaluate(globalObject, jscSource(scriptBuffer, sourceOrigin , fileName), JSValue(), evaluationException); | 
 |             scope.assertNoException(); | 
 |             if (evaluationException) | 
 |                 returnValue = evaluationException->value(); | 
 |             checkException(globalObject, isLastFile, evaluationException, returnValue, options, success); | 
 |         } | 
 |  | 
 |         scriptBuffer.clear(); | 
 |         scope.clearException(); | 
 |     } | 
 |  | 
 | #if ENABLE(REGEXP_TRACING) | 
 |     vm.dumpRegExpTrace(); | 
 | #endif | 
 | } | 
 |  | 
 | #define RUNNING_FROM_XCODE 0 | 
 |  | 
 | static void runInteractive(GlobalObject* globalObject) | 
 | { | 
 |     VM& vm = globalObject->vm(); | 
 |     auto scope = DECLARE_CATCH_SCOPE(vm); | 
 |  | 
 |     URL directoryName = currentWorkingDirectory(); | 
 |     if (!directoryName.isValid()) | 
 |         return; | 
 |     SourceOrigin sourceOrigin(URL(directoryName, "./interpreter"_s)); | 
 |      | 
 |     bool shouldQuit = false; | 
 |     while (!shouldQuit) { | 
 | #if HAVE(READLINE) && !RUNNING_FROM_XCODE | 
 |         ParserError error; | 
 |         String source; | 
 |         do { | 
 |             error = ParserError(); | 
 |             char* line = readline(source.isEmpty() ? interactivePrompt : "... "); | 
 |             shouldQuit = !line; | 
 |             if (!line) | 
 |                 break; | 
 |             source = source + String::fromUTF8(line); | 
 |             source = source + '\n'; | 
 |             checkSyntax(vm, jscSource(source, sourceOrigin), error); | 
 |             if (!line[0]) { | 
 |                 free(line); | 
 |                 break; | 
 |             } | 
 |             add_history(line); | 
 |             free(line); | 
 |         } while (error.syntaxErrorType() == ParserError::SyntaxErrorRecoverable); | 
 |          | 
 |         if (error.isValid()) { | 
 |             printf("%s:%d\n", error.message().utf8().data(), error.line()); | 
 |             continue; | 
 |         } | 
 |          | 
 |          | 
 |         NakedPtr<Exception> evaluationException; | 
 |         JSValue returnValue = evaluate(globalObject, jscSource(source, sourceOrigin), JSValue(), evaluationException); | 
 | #else | 
 |         printf("%s", interactivePrompt); | 
 |         Vector<char, 256> line; | 
 |         int c; | 
 |         while ((c = getchar()) != EOF) { | 
 |             // FIXME: Should we also break on \r?  | 
 |             if (c == '\n') | 
 |                 break; | 
 |             line.append(c); | 
 |         } | 
 |         if (line.isEmpty()) | 
 |             break; | 
 |  | 
 |         NakedPtr<Exception> evaluationException; | 
 |         JSValue returnValue = evaluate(globalObject, jscSource(line, sourceOrigin, sourceOrigin.string()), JSValue(), evaluationException); | 
 | #endif | 
 |         Expected<CString, UTF8ConversionError> utf8; | 
 |         if (evaluationException) { | 
 |             fputs("Exception: ", stdout); | 
 |             utf8 = evaluationException->value().toWTFString(globalObject).tryGetUtf8(); | 
 |         } else | 
 |             utf8 = returnValue.toWTFString(globalObject).tryGetUtf8(); | 
 |  | 
 |         CString result; | 
 |         if (utf8) | 
 |             result = utf8.value(); | 
 |         else if (utf8.error() == UTF8ConversionError::OutOfMemory) | 
 |             result = "OutOfMemory while processing string"; | 
 |         else | 
 |             result = "Error while processing string"; | 
 |         fwrite(result.data(), sizeof(char), result.length(), stdout); | 
 |         putchar('\n'); | 
 |  | 
 |         scope.clearException(); | 
 |         vm.drainMicrotasks(); | 
 |     } | 
 |     printf("\n"); | 
 | } | 
 |  | 
 | static NO_RETURN void printUsageStatement(bool help = false) | 
 | { | 
 |     fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n"); | 
 |     fprintf(stderr, "  -d         Dumps bytecode (debug builds only)\n"); | 
 |     fprintf(stderr, "  -e         Evaluate argument as script code\n"); | 
 |     fprintf(stderr, "  -f         Specifies a source file (deprecated)\n"); | 
 |     fprintf(stderr, "  -h|--help  Prints this help message\n"); | 
 |     fprintf(stderr, "  -i         Enables interactive mode (default if no files are specified)\n"); | 
 |     fprintf(stderr, "  -m         Execute as a module\n"); | 
 | #if OS(UNIX) | 
 |     fprintf(stderr, "  -s         Installs signal handlers that exit on a crash (Unix platforms only, lldb will not work with this option) \n"); | 
 | #endif | 
 |     fprintf(stderr, "  -p <file>  Outputs profiling data to a file\n"); | 
 |     fprintf(stderr, "  -x         Output exit code before terminating\n"); | 
 |     fprintf(stderr, "\n"); | 
 |     fprintf(stderr, "  --sample                   Collects and outputs sampling profiler data\n"); | 
 |     fprintf(stderr, "  --test262-async            Check that some script calls the print function with the string 'Test262:AsyncTestComplete'\n"); | 
 |     fprintf(stderr, "  --strict-file=<file>       Parse the given file as if it were in strict mode (this option may be passed more than once)\n"); | 
 |     fprintf(stderr, "  --module-file=<file>       Parse and evaluate the given file as module (this option may be passed more than once)\n"); | 
 |     fprintf(stderr, "  --exception=<name>         Check the last script exits with an uncaught exception with the specified name\n"); | 
 |     fprintf(stderr, "  --watchdog-exception-ok    Uncaught watchdog exceptions exit with success\n"); | 
 |     fprintf(stderr, "  --dumpException            Dump uncaught exception text\n"); | 
 |     fprintf(stderr, "  --footprint                Dump memory footprint after done executing\n"); | 
 |     fprintf(stderr, "  --options                  Dumps all JSC VM options and exits\n"); | 
 |     fprintf(stderr, "  --dumpOptions              Dumps all non-default JSC VM options before continuing\n"); | 
 |     fprintf(stderr, "  --<jsc VM option>=<value>  Sets the specified JSC VM option\n"); | 
 |     fprintf(stderr, "  --destroy-vm               Destroy VM before exiting\n"); | 
 |     fprintf(stderr, "  --can-block-is-false       Make main thread's Atomics.wait throw\n"); | 
 |     fprintf(stderr, "\n"); | 
 |     fprintf(stderr, "Files with a .mjs extension will always be evaluated as modules.\n"); | 
 |     fprintf(stderr, "\n"); | 
 |  | 
 |     jscExit(help ? EXIT_SUCCESS : EXIT_FAILURE); | 
 | } | 
 |  | 
 | static bool isMJSFile(char *filename) | 
 | { | 
 |     filename = strrchr(filename, '.'); | 
 |  | 
 |     if (filename) | 
 |         return !strcmp(filename, ".mjs"); | 
 |  | 
 |     return false; | 
 | } | 
 |  | 
 | void CommandLine::parseArguments(int argc, char** argv) | 
 | { | 
 |     Options::AllowUnfinalizedAccessScope scope; | 
 |     Options::initialize(); | 
 |     Options::useSharedArrayBuffer() = true; | 
 |     Options::useAtMethod() = true; | 
 |      | 
 | #if PLATFORM(IOS_FAMILY) | 
 |     Options::crashIfCantAllocateJITMemory() = true; | 
 | #endif | 
 |  | 
 |     if (Options::dumpOptions()) { | 
 |         printf("Command line:"); | 
 | #if PLATFORM(COCOA) | 
 |         for (char** envp = *_NSGetEnviron(); *envp; envp++) { | 
 |             const char* env = *envp; | 
 |             if (!strncmp("JSC_", env, 4)) | 
 |                 printf(" %s", env); | 
 |         } | 
 | #endif // PLATFORM(COCOA) | 
 |         for (int i = 0; i < argc; ++i) | 
 |             printf(" %s", argv[i]); | 
 |         printf("\n"); | 
 |     } | 
 |  | 
 |     int i = 1; | 
 |     JSC::Options::DumpLevel dumpOptionsLevel = JSC::Options::DumpLevel::None; | 
 |     bool needToExit = false; | 
 |  | 
 |     bool hasBadJSCOptions = false; | 
 |     for (; i < argc; ++i) { | 
 |         const char* arg = argv[i]; | 
 |         if (!strcmp(arg, "-f")) { | 
 |             if (++i == argc) | 
 |                 printUsageStatement(); | 
 |             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, Script::ScriptType::Script, argv[i])); | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-e")) { | 
 |             if (++i == argc) | 
 |                 printUsageStatement(); | 
 |             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::CommandLine, Script::ScriptType::Script, argv[i])); | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-i")) { | 
 |             m_interactive = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-d")) { | 
 |             m_dump = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-p")) { | 
 |             if (++i == argc) | 
 |                 printUsageStatement(); | 
 |             m_profile = true; | 
 |             m_profilerOutput = argv[i]; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-m")) { | 
 |             m_module = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-s")) { | 
 | #if OS(UNIX) | 
 |             SignalAction (*exit)(Signal, SigInfo&, PlatformRegisters&) = [] (Signal, SigInfo&, PlatformRegisters&) { | 
 |                 dataLogLn("Signal handler hit. Exiting with status 0"); | 
 |                 _exit(0); | 
 |                 return SignalAction::ForceDefault; | 
 |             }; | 
 |  | 
 |             addSignalHandler(Signal::IllegalInstruction, SignalHandler(exit)); | 
 |             addSignalHandler(Signal::AccessFault, SignalHandler(exit)); | 
 |             addSignalHandler(Signal::FloatingPoint, SignalHandler(exit)); | 
 |             // once we do this lldb won't work anymore because we will exit on any breakpoints it sets. | 
 |             addSignalHandler(Signal::Breakpoint, SignalHandler(exit)); | 
 |  | 
 |             activateSignalHandlersFor(Signal::IllegalInstruction); | 
 |             activateSignalHandlersFor(Signal::AccessFault); | 
 |             activateSignalHandlersFor(Signal::FloatingPoint); | 
 |             activateSignalHandlersFor(Signal::Breakpoint); | 
 |  | 
 | #if !OS(DARWIN) | 
 |             addSignalHandler(Signal::Abort, SignalHandler(exit)); | 
 |             activateSignalHandlersFor(Signal::Abort); | 
 | #endif | 
 | #endif | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "-x")) { | 
 |             m_exitCode = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--")) { | 
 |             ++i; | 
 |             break; | 
 |         } | 
 |         if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) | 
 |             printUsageStatement(true); | 
 |  | 
 |         if (!strcmp(arg, "--options")) { | 
 |             dumpOptionsLevel = JSC::Options::DumpLevel::Verbose; | 
 |             needToExit = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--dumpOptions")) { | 
 |             dumpOptionsLevel = JSC::Options::DumpLevel::Overridden; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--sample")) { | 
 |             JSC::Options::useSamplingProfiler() = true; | 
 |             JSC::Options::collectSamplingProfilerDataForJSCShell() = true; | 
 |             m_dumpSamplingProfilerData = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--destroy-vm")) { | 
 |             m_destroyVM = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--can-block-is-false")) { | 
 |             m_canBlockIsFalse = true; | 
 |             continue; | 
 |         } | 
 |         if (!strcmp(arg, "--disableOptionsFreezingForTesting")) { | 
 |             Config::disableFreezingForTesting(); | 
 |             continue; | 
 |         } | 
 |  | 
 |         static const char* timeoutMultiplierOptStr = "--timeoutMultiplier="; | 
 |         static const unsigned timeoutMultiplierOptStrLength = strlen(timeoutMultiplierOptStr); | 
 |         if (!strncmp(arg, timeoutMultiplierOptStr, timeoutMultiplierOptStrLength)) { | 
 |             const char* valueStr = &arg[timeoutMultiplierOptStrLength]; | 
 |             if (sscanf(valueStr, "%lf", &s_timeoutMultiplier) != 1) | 
 |                 dataLog("WARNING: --timeoutMultiplier=", valueStr, " is invalid. Expects a numeric ratio.\n"); | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (!strcmp(arg, "--test262-async")) { | 
 |             asyncTestExpectedPasses++; | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (!strcmp(arg, "--remote-debug")) { | 
 |             m_enableRemoteDebugging = true; | 
 |             continue; | 
 |         } | 
 |  | 
 |         static const unsigned strictFileStrLength = strlen("--strict-file="); | 
 |         if (!strncmp(arg, "--strict-file=", strictFileStrLength)) { | 
 |             m_scripts.append(Script(Script::StrictMode::Strict, Script::CodeSource::File, Script::ScriptType::Script, argv[i] + strictFileStrLength)); | 
 |             continue; | 
 |         } | 
 |  | 
 |         static const unsigned moduleFileStrLength = strlen("--module-file="); | 
 |         if (!strncmp(arg, "--module-file=", moduleFileStrLength)) { | 
 |             m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, Script::ScriptType::Module, argv[i] + moduleFileStrLength)); | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (!strcmp(arg, "--dumpException")) { | 
 |             m_alwaysDumpUncaughtException = true; | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (!strcmp(arg, "--footprint")) { | 
 |             m_dumpMemoryFootprint = true; | 
 |             continue; | 
 |         } | 
 |  | 
 |         static const unsigned exceptionStrLength = strlen("--exception="); | 
 |         if (!strncmp(arg, "--exception=", exceptionStrLength)) { | 
 |             m_uncaughtExceptionName = String(arg + exceptionStrLength); | 
 |             continue; | 
 |         } | 
 |  | 
 |         if (!strcmp(arg, "--watchdog-exception-ok")) { | 
 |             m_treatWatchdogExceptionAsSuccess = true; | 
 |             continue; | 
 |         } | 
 |  | 
 |         // See if the -- option is a JSC VM option. | 
 |         if (strstr(arg, "--") == arg) { | 
 |             if (!JSC::Options::setOption(&arg[2])) { | 
 |                 hasBadJSCOptions = true; | 
 |                 dataLog("ERROR: invalid option: ", arg, "\n"); | 
 |             } | 
 |             continue; | 
 |         } | 
 |  | 
 |         // This arg is not recognized by the VM nor by jsc. Pass it on to the | 
 |         // script. | 
 |         Script::ScriptType scriptType = isMJSFile(argv[i]) ? Script::ScriptType::Module : Script::ScriptType::Script; | 
 |         m_scripts.append(Script(Script::StrictMode::Sloppy, Script::CodeSource::File, scriptType, argv[i])); | 
 |     } | 
 |  | 
 |     if (hasBadJSCOptions && JSC::Options::validateOptions()) | 
 |         CRASH(); | 
 |  | 
 |     if (m_scripts.isEmpty()) | 
 |         m_interactive = true; | 
 |  | 
 |     for (; i < argc; ++i) | 
 |         m_arguments.append(argv[i]); | 
 |  | 
 |     if (dumpOptionsLevel != JSC::Options::DumpLevel::None) { | 
 |         const char* optionsTitle = (dumpOptionsLevel == JSC::Options::DumpLevel::Overridden) | 
 |             ? "Modified JSC runtime options:" | 
 |             : "All JSC runtime options:"; | 
 |         JSC::Options::dumpAllOptions(stderr, dumpOptionsLevel, optionsTitle); | 
 |     } | 
 |     JSC::Options::ensureOptionsAreCoherent(); | 
 |     if (needToExit) | 
 |         jscExit(EXIT_SUCCESS); | 
 | } | 
 |  | 
 | template<typename Func> | 
 | int runJSC(const CommandLine& options, bool isWorker, const Func& func) | 
 | { | 
 |     Worker worker(Workers::singleton()); | 
 |      | 
 |     VM& vm = VM::create(LargeHeap).leakRef(); | 
 |     if (!isWorker && options.m_canBlockIsFalse) | 
 |         vm.m_typedArrayController = adoptRef(new JSC::SimpleTypedArrayController(false)); | 
 | #if ENABLE(WEBASSEMBLY) | 
 |     Wasm::enableFastMemory(); | 
 | #endif | 
 |  | 
 |     int result; | 
 |     bool success = true; | 
 |     GlobalObject* globalObject = nullptr; | 
 |     { | 
 |         JSLockHolder locker(vm); | 
 |  | 
 |         startTimeoutThreadIfNeeded(vm); | 
 |         if (options.m_profile && !vm.m_perBytecodeProfiler) | 
 |             vm.m_perBytecodeProfiler = makeUnique<Profiler::Database>(vm); | 
 |  | 
 |         globalObject = GlobalObject::create(vm, GlobalObject::createStructure(vm, jsNull()), options.m_arguments); | 
 |         globalObject->setRemoteDebuggingEnabled(options.m_enableRemoteDebugging); | 
 |         func(vm, globalObject, success); | 
 |         vm.drainMicrotasks(); | 
 |     } | 
 |     vm.deferredWorkTimer->runRunLoop(); | 
 |     { | 
 |         JSLockHolder locker(vm); | 
 |         if (options.m_interactive && success) | 
 |             runInteractive(globalObject); | 
 |     } | 
 |  | 
 |     result = success && (asyncTestExpectedPasses == asyncTestPasses) ? 0 : 3; | 
 |  | 
 |     if (options.m_exitCode) { | 
 |         printf("jsc exiting %d", result); | 
 |         if (asyncTestExpectedPasses != asyncTestPasses) | 
 |             printf(" because expected: %d async test passes but got: %d async test passes", asyncTestExpectedPasses, asyncTestPasses); | 
 |         printf("\n"); | 
 |     } | 
 |  | 
 |     if (options.m_profile) { | 
 |         JSLockHolder locker(vm); | 
 |         if (!vm.m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data())) | 
 |             fprintf(stderr, "could not save profiler output.\n"); | 
 |     } | 
 |  | 
 | #if ENABLE(JIT) | 
 |     { | 
 |         JSLockHolder locker(vm); | 
 |         if (Options::useExceptionFuzz()) | 
 |             printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks()); | 
 |         bool fireAtEnabled = | 
 |         Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter(); | 
 |         if (Options::useExecutableAllocationFuzz() && (!fireAtEnabled || Options::verboseExecutableAllocationFuzz())) | 
 |             printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks()); | 
 |         if (Options::useOSRExitFuzz() && Options::verboseOSRExitFuzz()) { | 
 |             printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks()); | 
 |             printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks()); | 
 |         } | 
 |  | 
 |          | 
 |         auto compileTimeStats = JIT::compileTimeStats(); | 
 |         Vector<CString> compileTimeKeys; | 
 |         for (auto& entry : compileTimeStats) | 
 |             compileTimeKeys.append(entry.key); | 
 |         std::sort(compileTimeKeys.begin(), compileTimeKeys.end()); | 
 |         for (const CString& key : compileTimeKeys) { | 
 |             if (key.data()) | 
 |                 printf("%40s: %.3lf ms\n", key.data(), compileTimeStats.get(key).milliseconds()); | 
 |         } | 
 |  | 
 |         if (Options::reportTotalPhaseTimes()) | 
 |             logTotalPhaseTimes(); | 
 |     } | 
 | #endif | 
 |  | 
 |     if (Options::gcAtEnd()) { | 
 |         // We need to hold the API lock to do a GC. | 
 |         JSLockHolder locker(&vm); | 
 |         vm.heap.collectNow(Sync, CollectionScope::Full); | 
 |     } | 
 |  | 
 |     if (options.m_dumpSamplingProfilerData) { | 
 | #if ENABLE(SAMPLING_PROFILER) | 
 |         JSLockHolder locker(&vm); | 
 |         vm.samplingProfiler()->reportTopFunctions(); | 
 |         vm.samplingProfiler()->reportTopBytecodes(); | 
 | #else | 
 |         dataLog("Sampling profiler is not enabled on this platform\n"); | 
 | #endif | 
 |     } | 
 |  | 
 |     vm.codeCache()->write(vm); | 
 |  | 
 |     if (options.m_destroyVM || isWorker) { | 
 |         JSLockHolder locker(vm); | 
 |         // This is needed because we don't want the worker's main | 
 |         // thread to die before its compilation threads finish. | 
 |         vm.deref(); | 
 |     } | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | #if ENABLE(JIT_OPERATION_VALIDATION) | 
 | extern const uintptr_t startOfJITOperationsInShell __asm("section$start$__DATA_CONST$__jsc_ops"); | 
 | extern const uintptr_t endOfJITOperationsInShell __asm("section$end$__DATA_CONST$__jsc_ops"); | 
 | #endif | 
 |  | 
 | int jscmain(int argc, char** argv) | 
 | { | 
 |     // Need to override and enable restricted options before we start parsing options below. | 
 |     Config::enableRestrictedOptions(); | 
 |  | 
 |     WTF::initializeMainThread(); | 
 |  | 
 |     // Note that the options parsing can affect VM creation, and thus | 
 |     // comes first. | 
 |     CommandLine options(argc, argv); | 
 |  | 
 |     { | 
 |         Options::AllowUnfinalizedAccessScope scope; | 
 |         processConfigFile(Options::configFile(), "jsc"); | 
 |         if (options.m_dump) | 
 |             Options::dumpGeneratedBytecodes() = true; | 
 |     } | 
 |  | 
 |     JSC::initialize(); | 
 | #if ENABLE(JIT_OPERATION_VALIDATION) | 
 |     JSC::JITOperationList::populatePointersInEmbedder(&startOfJITOperationsInShell, &endOfJITOperationsInShell); | 
 | #endif | 
 |     initializeTimeoutIfNeeded(); | 
 |  | 
 | #if OS(DARWIN) || OS(LINUX) | 
 |     startMemoryMonitoringThreadIfNeeded(); | 
 | #endif | 
 |  | 
 |     if (Options::useSuperSampler()) | 
 |         enableSuperSampler(); | 
 |  | 
 |     bool gigacageDisableRequested = false; | 
 | #if GIGACAGE_ENABLED && !COMPILER(MSVC) | 
 |     if (char* gigacageEnabled = getenv("GIGACAGE_ENABLED")) { | 
 |         if (!strcasecmp(gigacageEnabled, "no") || !strcasecmp(gigacageEnabled, "false") || !strcasecmp(gigacageEnabled, "0")) | 
 |             gigacageDisableRequested = true; | 
 |     } | 
 | #endif | 
 |     if (!gigacageDisableRequested) | 
 |         Gigacage::forbidDisablingPrimitiveGigacage(); | 
 |  | 
 | #if PLATFORM(COCOA) | 
 |     auto& memoryPressureHandler = MemoryPressureHandler::singleton(); | 
 |     { | 
 |         dispatch_queue_t queue = dispatch_queue_create("jsc shell memory pressure handler", DISPATCH_QUEUE_SERIAL); | 
 |         memoryPressureHandler.setDispatchQueue(queue); | 
 |         dispatch_release(queue); | 
 |     } | 
 |     Box<Critical> memoryPressureCriticalState = Box<Critical>::create(Critical::No); | 
 |     Box<Synchronous> memoryPressureSynchronousState = Box<Synchronous>::create(Synchronous::No); | 
 |     memoryPressureHandler.setLowMemoryHandler([=] (Critical critical, Synchronous synchronous) { | 
 |         crashIfExceedingMemoryLimit(); | 
 |  | 
 |         // We set these racily with respect to reading them from the JS execution thread. | 
 |         *memoryPressureCriticalState = critical; | 
 |         *memoryPressureSynchronousState = synchronous; | 
 |     }); | 
 |     memoryPressureHandler.setShouldLogMemoryMemoryPressureEvents(false); | 
 |     memoryPressureHandler.install(); | 
 |  | 
 |     auto onEachMicrotaskTick = [&] (VM& vm) { | 
 |         if (*memoryPressureCriticalState == Critical::No) | 
 |             return; | 
 |  | 
 |         *memoryPressureCriticalState = Critical::No; | 
 |         bool isSynchronous = *memoryPressureSynchronousState == Synchronous::Yes; | 
 |  | 
 |         WTF::releaseFastMallocFreeMemory(); | 
 |         vm.deleteAllCode(DeleteAllCodeIfNotCollecting); | 
 |  | 
 |         if (!vm.heap.isCurrentThreadBusy()) { | 
 |             if (isSynchronous) { | 
 |                 vm.heap.collectNow(Sync, CollectionScope::Full); | 
 |                 WTF::releaseFastMallocFreeMemory(); | 
 |             } else | 
 |                 vm.heap.collectNowFullIfNotDoneRecently(Async); | 
 |         } | 
 |     }; | 
 | #endif | 
 |  | 
 |     int result = runJSC( | 
 |         options, false, | 
 |         [&] (VM& vm, GlobalObject* globalObject, bool& success) { | 
 |             UNUSED_PARAM(vm); | 
 | #if PLATFORM(COCOA) | 
 |             vm.setOnEachMicrotaskTick(WTFMove(onEachMicrotaskTick)); | 
 | #endif | 
 |             runWithOptions(globalObject, options, success); | 
 |         }); | 
 |  | 
 |     printSuperSamplerState(); | 
 |  | 
 |     if (options.m_dumpMemoryFootprint) { | 
 |         MemoryFootprint footprint = MemoryFootprint::now(); | 
 |  | 
 |         printf("Memory Footprint:\n    Current Footprint: %" PRIu64 "\n    Peak Footprint: %" PRIu64 "\n", footprint.current, footprint.peak); | 
 |     } | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | #if OS(WINDOWS) | 
 | extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[]) | 
 | { | 
 |     return main(argc, const_cast<char**>(argv)); | 
 | } | 
 | #endif |