/* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2004-2022 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 "APICast.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 "DeferTermination.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 "JITSizeStatistics.h" #include "JSArray.h" #include "JSArrayBuffer.h" #include "JSBasePrivate.h" #include "JSBigInt.h" #include "JSFinalizationRegistry.h" #include "JSFunction.h" #include "JSFunctionInlines.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 "LinkBuffer.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 "VMTrapsInlines.h" #include "WasmCapabilities.h" #include "WasmFaultSignalHandler.h" #include "WasmMemory.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if OS(WINDOWS) #include #include #include #else #include #endif #if PLATFORM(COCOA) #include #include #endif #if PLATFORM(GTK) #include #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 #include #undef Function #endif #if COMPILER(MSVC) #include #include #include #endif #if OS(DARWIN) && CPU(ARM_THUMB2) #include #include #endif #if OS(DARWIN) #include #elif OS(LINUX) #include #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 static bool fillBufferWithContentsOfFile(const String& fileName, Vector& buffer); static RefPtr fillBufferWithContentsOfFile(const String& fileName); class CommandLine; class GlobalObject; class Workers; template 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 { public: #if ENABLE(WEBASSEMBLY) using Content = std::variant>; #else using Content = std::variant; #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 { public: Worker(Workers&, bool isMain); ~Worker(); void enqueue(const AbstractLocker&, RefPtr); RefPtr dequeue(); bool isMain() const { return m_isMain; } static Worker& current(); private: static ThreadSpecific& currentWorker(); Workers& m_workers; Deque> m_messages; const bool m_isMain; }; class Workers { WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(Workers); public: Workers(); ~Workers(); template 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> m_workers; Deque 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(functionCreateNonRopeNonAtomString); static JSC_DECLARE_HOST_FUNCTION(functionPrintStdOut); static JSC_DECLARE_HOST_FUNCTION(functionPrintStdErr); static JSC_DECLARE_HOST_FUNCTION(functionPrettyPrint); 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(functionMemoryUsageStatistics); 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(functionOpenFile); 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(functionCallerIsBBQOrOMGCompiled); 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(functionCheckScriptSyntax); 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(functionDollarGC); static JSC_DECLARE_HOST_FUNCTION(functionDollarClearKeptObjects); static JSC_DECLARE_HOST_FUNCTION(functionDollarGlobalObjectFor); static JSC_DECLARE_HOST_FUNCTION(functionDollarIsRemoteFunction); 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 }; explicit CommandLine(CommandLineForWorkersTag); Vector