/* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2004-2018 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 "ArrayPrototype.h" #include "BuiltinNames.h" #include "ButterflyInlines.h" #include "BytecodeCacheError.h" #include "CatchScope.h" #include "CodeBlock.h" #include "CodeCache.h" #include "Completion.h" #include "ConfigFile.h" #include "Disassembler.h" #include "Exception.h" #include "ExceptionHelpers.h" #include "HeapProfiler.h" #include "HeapSnapshotBuilder.h" #include "InitializeThreading.h" #include "Interpreter.h" #include "JIT.h" #include "JSArray.h" #include "JSArrayBuffer.h" #include "JSBigInt.h" #include "JSCInlines.h" #include "JSFunction.h" #include "JSInternalPromise.h" #include "JSInternalPromiseDeferred.h" #include "JSLock.h" #include "JSModuleLoader.h" #include "JSNativeStdFunction.h" #include "JSONObject.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 "PromiseDeferredTimer.h" #include "ProtoCallFrame.h" #include "ReleaseHeapAccessScope.h" #include "SamplingProfiler.h" #include "StackVisitor.h" #include "StructureInlines.h" #include "StructureRareDataInlines.h" #include "SuperSampler.h" #include "TestRunnerUtils.h" #include "TypedArrayInlines.h" #include "WasmCapabilities.h" #include "WasmContext.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 #include #include #if OS(WINDOWS) #include #include #include #else #include #endif #if PLATFORM(COCOA) #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 HAVE(SYS_TIME_H) #include #endif #if HAVE(SIGNAL_H) #include #endif #if COMPILER(MSVC) #include #include #include #endif #if PLATFORM(IOS_FAMILY) && CPU(ARM_THUMB2) #include #include #endif #if __has_include() #include #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 { 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); } class Masquerader : public JSNonFinalObject { public: Masquerader(VM& vm, Structure* structure) : Base(vm, structure) { } typedef JSNonFinalObject Base; static const unsigned StructureFlags = Base::StructureFlags | JSC::MasqueradesAsUndefined; static Masquerader* create(VM& vm, JSGlobalObject* globalObject) { globalObject->masqueradesAsUndefinedWatchpoint()->fireAll(vm, "Masquerading object allocated"); Structure* structure = createStructure(vm, globalObject, jsNull()); Masquerader* result = new (NotNull, allocateCell(vm.heap, sizeof(Masquerader))) Masquerader(vm, structure); result->finishCreation(vm); return result; } static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) { return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); } DECLARE_INFO; }; const ClassInfo Masquerader::s_info = { "Masquerader", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(Masquerader) }; 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(ExecState*, GlobalObject*, bool isLastFile, bool hasException, JSValue, CommandLine&, bool& success); class Message : public ThreadSafeRefCounted { public: Message(ArrayBufferContents&&, int32_t); ~Message(); ArrayBufferContents&& releaseContents() { return WTFMove(m_contents); } int32_t index() const { return m_index; } private: ArrayBufferContents m_contents; int32_t m_index { 0 }; }; class Worker : public BasicRawSentinelNode { public: Worker(Workers&); ~Worker(); void enqueue(const AbstractLocker&, RefPtr); RefPtr dequeue(); static Worker& current(); private: static ThreadSpecific& currentWorker(); Workers& m_workers; Deque> m_messages; }; 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 EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*); static EncodedJSValue JSC_HOST_CALL functionPrintStdOut(ExecState*); static EncodedJSValue JSC_HOST_CALL functionPrintStdErr(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDebug(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDescribe(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDescribeArray(ExecState*); static EncodedJSValue JSC_HOST_CALL functionSleepSeconds(ExecState*); static EncodedJSValue JSC_HOST_CALL functionJSCStack(ExecState*); static EncodedJSValue JSC_HOST_CALL functionGCAndSweep(ExecState*); static EncodedJSValue JSC_HOST_CALL functionFullGC(ExecState*); static EncodedJSValue JSC_HOST_CALL functionEdenGC(ExecState*); static EncodedJSValue JSC_HOST_CALL functionForceGCSlowPaths(ExecState*); static EncodedJSValue JSC_HOST_CALL functionHeapSize(ExecState*); static EncodedJSValue JSC_HOST_CALL functionCreateMemoryFootprint(ExecState*); static EncodedJSValue JSC_HOST_CALL functionResetMemoryPeak(ExecState*); static EncodedJSValue JSC_HOST_CALL functionAddressOf(ExecState*); static EncodedJSValue JSC_HOST_CALL functionVersion(ExecState*); static EncodedJSValue JSC_HOST_CALL functionRun(ExecState*); static EncodedJSValue JSC_HOST_CALL functionRunString(ExecState*); static EncodedJSValue JSC_HOST_CALL functionLoad(ExecState*); static EncodedJSValue JSC_HOST_CALL functionLoadString(ExecState*); static EncodedJSValue JSC_HOST_CALL functionReadFile(ExecState*); static EncodedJSValue JSC_HOST_CALL functionCheckSyntax(ExecState*); static EncodedJSValue JSC_HOST_CALL functionReadline(ExecState*); static EncodedJSValue JSC_HOST_CALL functionPreciseTime(ExecState*); static EncodedJSValue JSC_HOST_CALL functionNeverInlineFunction(ExecState*); static EncodedJSValue JSC_HOST_CALL functionNoDFG(ExecState*); static EncodedJSValue JSC_HOST_CALL functionNoFTL(ExecState*); static EncodedJSValue JSC_HOST_CALL functionNoOSRExitFuzzing(ExecState*); static EncodedJSValue JSC_HOST_CALL functionOptimizeNextInvocation(ExecState*); static EncodedJSValue JSC_HOST_CALL functionNumberOfDFGCompiles(ExecState*); static EncodedJSValue JSC_HOST_CALL functionJSCOptions(ExecState*); static EncodedJSValue JSC_HOST_CALL functionReoptimizationRetryCount(ExecState*); static EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState*); static EncodedJSValue JSC_HOST_CALL functionFailNextNewCodeBlock(ExecState*); static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*); static EncodedJSValue JSC_HOST_CALL functionFalse(ExecState*); static EncodedJSValue JSC_HOST_CALL functionUndefined1(ExecState*); static EncodedJSValue JSC_HOST_CALL functionUndefined2(ExecState*); static EncodedJSValue JSC_HOST_CALL functionIsInt32(ExecState*); static EncodedJSValue JSC_HOST_CALL functionIsPureNaN(ExecState*); static EncodedJSValue JSC_HOST_CALL functionEffectful42(ExecState*); static EncodedJSValue JSC_HOST_CALL functionIdentity(ExecState*); static EncodedJSValue JSC_HOST_CALL functionMakeMasquerader(ExecState*); static EncodedJSValue JSC_HOST_CALL functionHasCustomProperties(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDumpTypesForAllVariables(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDrainMicrotasks(ExecState*); static EncodedJSValue JSC_HOST_CALL functionReleaseWeakRefs(ExecState*); static EncodedJSValue JSC_HOST_CALL functionIs32BitPlatform(ExecState*); static EncodedJSValue JSC_HOST_CALL functionCheckModuleSyntax(ExecState*); static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*); static EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState*); static EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshotForGCDebugging(ExecState*); static EncodedJSValue JSC_HOST_CALL functionResetSuperSamplerState(ExecState*); static EncodedJSValue JSC_HOST_CALL functionEnsureArrayStorage(ExecState*); #if ENABLE(SAMPLING_PROFILER) static EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState*); static EncodedJSValue JSC_HOST_CALL functionSamplingProfilerStackTraces(ExecState*); #endif static EncodedJSValue JSC_HOST_CALL functionMaxArguments(ExecState*); static EncodedJSValue JSC_HOST_CALL functionAsyncTestStart(ExecState*); static EncodedJSValue JSC_HOST_CALL functionAsyncTestPassed(ExecState*); #if ENABLE(WEBASSEMBLY) static EncodedJSValue JSC_HOST_CALL functionWebAssemblyMemoryMode(ExecState*); #endif #if ENABLE(SAMPLING_FLAGS) static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*); static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*); #endif static EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState*); static EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState*); static EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState*); static EncodedJSValue JSC_HOST_CALL functionCallerSourceOrigin(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarCreateRealm(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarDetachArrayBuffer(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarEvalScript(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentStart(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentReceiveBroadcast(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentReport(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentSleep(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentBroadcast(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentGetReport(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentLeaving(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDollarAgentMonotonicNow(ExecState*); static EncodedJSValue JSC_HOST_CALL functionWaitForReport(ExecState*); static EncodedJSValue JSC_HOST_CALL functionHeapCapacity(ExecState*); static EncodedJSValue JSC_HOST_CALL functionFlashHeapAccess(ExecState*); static EncodedJSValue JSC_HOST_CALL functionDisableRichSourceInfo(ExecState*); static EncodedJSValue JSC_HOST_CALL functionMallocInALoop(ExecState*); static EncodedJSValue JSC_HOST_CALL functionTotalCompileTime(ExecState*); 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); } Vector