diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt index 52a497a59c4c5..7642a869c748e 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt @@ -652,12 +652,20 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS bytecode/SuperSampler.h bytecode/ToThisStatus.h bytecode/TypeLocation.h - bytecode/UnlinkedCodeBlock.h - bytecode/UnlinkedEvalCodeBlock.h + bytecode/UnlinkedModuleProgramCodeBlockInlines.h + bytecode/UnlinkedModuleProgramCodeBlock.h + bytecode/UnlinkedProgramCodeBlock.h + bytecode/UnlinkedProgramCodeBlockInlines.h + bytecode/UnlinkedMetadataTable.h bytecode/UnlinkedFunctionExecutable.h + bytecode/UnlinkedFunctionExecutableInlines.h + bytecode/UnlinkedFunctionCodeBlockInlines.h bytecode/UnlinkedFunctionCodeBlock.h + bytecode/UnlinkedEvalCodeBlockInlines.h + bytecode/UnlinkedEvalCodeBlock.h + bytecode/UnlinkedCodeBlockGenerator.h + bytecode/UnlinkedCodeBlock.h bytecode/UnlinkedGlobalCodeBlock.h - bytecode/UnlinkedMetadataTable.h bytecode/ValueProfile.h bytecode/ValueRecovery.h bytecode/VariableWriteFireDetail.h @@ -888,12 +896,15 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS llint/LLIntThunks.h parser/Lexer.h + parser/Nodes.h parser/ParserArena.h parser/ParserError.h + parser/ParserFunctionInfo.h parser/ParserModes.h parser/ParserTokens.h parser/ResultType.h parser/SourceCode.h + parser/SourceCodeKey.h parser/SourceProvider.h parser/SourceProviderCache.h parser/SourceProviderCacheItem.h @@ -901,6 +912,9 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS parser/UnlinkedSourceCode.h parser/VariableEnvironment.h + bytecode/ParseHash.h + bytecompiler/Label.h + profiler/ProfilerBytecode.h profiler/ProfilerBytecodeSequence.h profiler/ProfilerBytecodes.h diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp index 061434d8eb0cd..368a2ef9628c1 100644 --- a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp +++ b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp @@ -257,6 +257,12 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S } } else { RELEASE_ASSERT(error.isValid()); +#if ASSERT_ENABLED + if (error.type() != ParserError::StackOverflow) { + WTFLogAlways("Error parsing builtin: %s\n", error.message().utf8().data()); + CRASH(); + } +#endif RELEASE_ASSERT(error.type() == ParserError::StackOverflow); } } diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp index e274c5e14f59f..ffc22522e8745 100644 --- a/Source/JavaScriptCore/parser/Lexer.cpp +++ b/Source/JavaScriptCore/parser/Lexer.cpp @@ -974,12 +974,18 @@ template ALWAYS_INLINE JSTokenType Lexer::p const Identifier* ident = nullptr; if (shouldCreateIdentifier || m_parsingBuiltinFunction) { - std::span identifierSpan { identifierStart, static_cast(currentSourcePtr() - identifierStart) }; + const std::span identifierSpan { identifierStart, static_cast(currentSourcePtr() - identifierStart) }; if (m_parsingBuiltinFunction && isBuiltinName) { if (isWellKnownSymbol) ident = &m_arena->makeIdentifier(m_vm, m_vm.propertyNames->builtinNames().lookUpWellKnownSymbol(identifierSpan)); - else + else { + if constexpr (ASSERT_ENABLED) { + auto *symbol = m_vm.propertyNames->builtinNames().lookUpPrivateName(identifierSpan); + ASSERT_WITH_MESSAGE(symbol, "Private symbol not found: %s", identifierSpan.data()); + } + ident = &m_arena->makeIdentifier(m_vm, m_vm.propertyNames->builtinNames().lookUpPrivateName(identifierSpan)); + } if (!ident) return INVALID_PRIVATE_NAME_ERRORTOK; } else { diff --git a/Source/JavaScriptCore/parser/SourceCodeKey.h b/Source/JavaScriptCore/parser/SourceCodeKey.h index 4a415cd089e66..dcd1f727f40de 100644 --- a/Source/JavaScriptCore/parser/SourceCodeKey.h +++ b/Source/JavaScriptCore/parser/SourceCodeKey.h @@ -113,7 +113,11 @@ class SourceCodeKey { && m_functionConstructorParametersEndPosition == other.m_functionConstructorParametersEndPosition && m_name == other.m_name && host() == other.host() +#if USE(BUN_JSC_ADDITIONS) + ; +#else && (m_sourceCode == other.m_sourceCode || string() == other.string()); +#endif } struct Hash { diff --git a/Source/JavaScriptCore/runtime/CachePayload.cpp b/Source/JavaScriptCore/runtime/CachePayload.cpp index a8c895222d182..fefa2512dce0a 100644 --- a/Source/JavaScriptCore/runtime/CachePayload.cpp +++ b/Source/JavaScriptCore/runtime/CachePayload.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "CachePayload.h" +#include namespace JSC { @@ -43,18 +44,28 @@ CachePayload CachePayload::makeEmptyPayload() return CachePayload(std::pair { nullptr, 0 }); } +CachePayload CachePayload::makePayloadWithDestructor(std::span data, Destructor&& destructor) +{ + return CachePayload(data, WTFMove(destructor)); +} + CachePayload::CachePayload(CachePayload&& other) { m_data = WTFMove(other.m_data); + m_destructor = WTFMove(other.m_destructor); other.m_data = std::pair { nullptr, 0 }; + other.m_destructor = nullptr; } -CachePayload::CachePayload(std::variant, size_t>>&& data) - : m_data(WTFMove(data)) +CachePayload::CachePayload(std::variant, size_t>, std::span> && data, Destructor&& destructor) + : m_data(WTFMove(data)), m_destructor(WTFMove(destructor)) { } -CachePayload::~CachePayload() = default; +CachePayload::~CachePayload() { + if (m_destructor) + m_destructor(data()); +} const uint8_t* CachePayload::data() const { @@ -63,6 +74,8 @@ const uint8_t* CachePayload::data() const return data.span().data(); }, [](const std::pair, size_t>& data) -> const uint8_t* { return data.first.get(); + }, [](const std::span& data) -> const uint8_t* { + return data.data(); } ); } @@ -74,6 +87,8 @@ size_t CachePayload::size() const return data.size(); }, [](const std::pair, size_t>& data) -> size_t { return data.second; + }, [](const std::span& data) -> size_t { + return data.size(); } ); } diff --git a/Source/JavaScriptCore/runtime/CachePayload.h b/Source/JavaScriptCore/runtime/CachePayload.h index 776aac9606632..9bea13f4f4cf8 100644 --- a/Source/JavaScriptCore/runtime/CachePayload.h +++ b/Source/JavaScriptCore/runtime/CachePayload.h @@ -34,8 +34,10 @@ namespace JSC { class CachePayload { public: + using Destructor = WTF::Function; JS_EXPORT_PRIVATE static CachePayload makeMappedPayload(FileSystem::MappedFileData&&); JS_EXPORT_PRIVATE static CachePayload makeMallocPayload(MallocPtr&&, size_t); + JS_EXPORT_PRIVATE static CachePayload makePayloadWithDestructor(std::span, Destructor&&); JS_EXPORT_PRIVATE static CachePayload makeEmptyPayload(); JS_EXPORT_PRIVATE CachePayload(CachePayload&&); @@ -45,11 +47,12 @@ class CachePayload { std::span span() const { return { data(), size() }; } private: - CachePayload(std::variant, size_t>>&&); + CachePayload(std::variant, size_t>, std::span>&&, Destructor&& = {nullptr}); JS_EXPORT_PRIVATE const uint8_t* data() const; - std::variant, size_t>> m_data; + std::variant, size_t>, std::span> m_data; + Destructor m_destructor { nullptr }; }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/CachedBytecode.h b/Source/JavaScriptCore/runtime/CachedBytecode.h index ea222c47fa9dc..18a0582526f84 100644 --- a/Source/JavaScriptCore/runtime/CachedBytecode.h +++ b/Source/JavaScriptCore/runtime/CachedBytecode.h @@ -56,6 +56,11 @@ class CachedBytecode : public RefCounted { return adoptRef(*new CachedBytecode(CachePayload::makeMallocPayload(WTFMove(data), size), WTFMove(leafExecutables))); } + static Ref create(std::span data, CachePayload::Destructor&& destructor, LeafExecutableMap&& leafExecutables) + { + return adoptRef(*new CachedBytecode(CachePayload::makePayloadWithDestructor(data, WTFMove(destructor)), WTFMove(leafExecutables))); + } + LeafExecutableMap& leafExecutables() { return m_leafExecutables; } JS_EXPORT_PRIVATE void addGlobalUpdate(Ref); diff --git a/Source/JavaScriptCore/runtime/CachedTypes.cpp b/Source/JavaScriptCore/runtime/CachedTypes.cpp index 191f6a327c817..39a5bfb3156e9 100644 --- a/Source/JavaScriptCore/runtime/CachedTypes.cpp +++ b/Source/JavaScriptCore/runtime/CachedTypes.cpp @@ -2526,6 +2526,12 @@ class CacheEntry : public GenericCacheEntry { return true; } + bool decode(Decoder& decoder, SourceCodeKey& key) const + { + m_key.decode(decoder, key); + return true; + } + CachedSourceCodeKey m_key; CachedPtr> m_codeBlock; }; @@ -2551,6 +2557,24 @@ bool GenericCacheEntry::decode(Decoder& decoder, std::pair*>(this)->decode(decoder, key); + case CachedModuleCodeBlockTag: + return bitwise_cast*>(this)->decode(decoder, key); + case CachedEvalCodeBlockTag: + // We do not cache eval code blocks + return false; + } + + return false; +} + bool GenericCacheEntry::isStillValid(Decoder& decoder, const SourceCodeKey& key, CachedCodeBlockTag tag) const { if (!isUpToDate(decoder)) @@ -2604,6 +2628,16 @@ RefPtr encodeFunctionCodeBlock(VM& vm, const UnlinkedFunctionCod return encoder.release(error); } +std::optional decodeSourceCodeKey(VM& vm, Ref cachedBytecode) +{ + const auto* cachedEntry = bitwise_cast(cachedBytecode->span().data()); + Ref decoder = Decoder::create(vm, WTFMove(cachedBytecode)); + + SourceCodeKey key; + if (!cachedEntry->decode(decoder.get(), key)) + return std::nullopt; + return key; +} UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, Ref cachedBytecode) { const auto* cachedEntry = bitwise_cast(cachedBytecode->span().data()); diff --git a/Source/JavaScriptCore/runtime/CachedTypes.h b/Source/JavaScriptCore/runtime/CachedTypes.h index f2d8328682c44..02555160eb5b1 100644 --- a/Source/JavaScriptCore/runtime/CachedTypes.h +++ b/Source/JavaScriptCore/runtime/CachedTypes.h @@ -122,6 +122,8 @@ UnlinkedCodeBlockType* decodeCodeBlock(VM& vm, const SourceCodeKey& key, Ref(decodeCodeBlockImpl(vm, key, WTFMove(cachedBytecode))); } +std::optional decodeSourceCodeKey(VM& vm, Ref cachedBytecode); + JS_EXPORT_PRIVATE RefPtr encodeFunctionCodeBlock(VM&, const UnlinkedFunctionCodeBlock*, BytecodeCacheError&); JS_EXPORT_PRIVATE void decodeFunctionCodeBlock(Decoder&, int32_t cachedFunctionCodeBlockOffset, WriteBarrier&, const JSCell*); diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp index 45e69de14020d..f50759a59bece 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.cpp +++ b/Source/JavaScriptCore/runtime/CodeCache.cpp @@ -67,13 +67,28 @@ static void generateUnlinkedCodeBlockForFunctions(VM& vm, UnlinkedCodeBlock* unl // FIXME: We should also generate CodeBlocks for CodeForConstruct // https://bugs.webkit.org/show_bug.cgi?id=193823 - for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionDecls(); i++) - generate(unlinkedCodeBlock->functionDecl(i), CodeForCall); - for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionExprs(); i++) - generate(unlinkedCodeBlock->functionExpr(i), CodeForCall); + // + // NOTE: We changed this in Bun. We check if the function is a constructor + // and if it is, we generate a CodeForConstruct block. + for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionDecls(); i++) { + auto* functionDecl = unlinkedCodeBlock->functionDecl(i); + if (functionDecl->isConstructor()) { + generate(functionDecl, CodeForConstruct); + } else { + generate(functionDecl, CodeForCall); + } + } + for (unsigned i = 0; i < unlinkedCodeBlock->numberOfFunctionExprs(); i++) { + auto* functionExpr = unlinkedCodeBlock->functionExpr(i); + if (functionExpr->isConstructor()) { + generate(functionExpr, CodeForConstruct); + } else { + generate(functionExpr, CodeForCall); + } + } } -template +template UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& source, LexicallyScopedFeatures lexicallyScopedFeatures, JSParserScriptMode scriptMode, OptionSet codeGenerationMode, ParserError& error, EvalContextType evalContextType, DerivedContextType derivedContextType, bool isArrowFunctionContext, const TDZEnvironment* variablesUnderTDZ = nullptr, const PrivateNameEnvironment* privateNameEnvironment = nullptr, ExecutableType* executable = nullptr) { typedef typename CacheTypes::RootNode RootNode; @@ -119,7 +134,7 @@ UnlinkedCodeBlockType* generateUnlinkedCodeBlockImpl(VM& vm, const SourceCode& s return unlinkedCodeBlock; } -template +template UnlinkedCodeBlockType* generateUnlinkedCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserScriptMode scriptMode, OptionSet codeGenerationMode, ParserError& error, EvalContextType evalContextType, const TDZEnvironment* variablesUnderTDZ = nullptr, const PrivateNameEnvironment* privateNameEnvironment = nullptr) { return generateUnlinkedCodeBlockImpl(vm, source, executable->lexicallyScopedFeatures(), scriptMode, codeGenerationMode, error, evalContextType, executable->derivedContextType(), executable->isArrowFunctionContext(), variablesUnderTDZ, privateNameEnvironment, executable); @@ -130,7 +145,7 @@ UnlinkedEvalCodeBlock* generateUnlinkedCodeBlockForDirectEval(VM& vm, DirectEval return generateUnlinkedCodeBlock(vm, executable, source, scriptMode, codeGenerationMode, error, evalContextType, variablesUnderTDZ, privateNameEnvironment); } -template +template std::enable_if_t::value, UnlinkedCodeBlockType*> recursivelyGenerateUnlinkedCodeBlock(VM& vm, const SourceCode& source, LexicallyScopedFeatures lexicallyScopedFeatures, JSParserScriptMode scriptMode, OptionSet codeGenerationMode, ParserError& error, EvalContextType evalContextType) { @@ -153,7 +168,7 @@ UnlinkedModuleProgramCodeBlock* recursivelyGenerateUnlinkedCodeBlockForModulePro return recursivelyGenerateUnlinkedCodeBlock(vm, source, lexicallyScopedFeatures, scriptMode, codeGenerationMode, error, evalContextType); } -template +template UnlinkedCodeBlockType* CodeCache::getUnlinkedGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserScriptMode scriptMode, OptionSet codeGenerationMode, ParserError& error, EvalContextType evalContextType) { DerivedContextType derivedContextType = executable->derivedContextType(); @@ -245,7 +260,7 @@ UnlinkedFunctionExecutable* CodeCache::getUnlinkedGlobalFunctionExecutable(VM& v ASSERT(metadata); if (!metadata) return nullptr; - + metadata->overrideName(name); metadata->setEndPosition(positionBeforeLastNewline); // The Function constructor only has access to global variables, so no variables will be under TDZ unless they're @@ -294,13 +309,13 @@ static SourceCodeKey sourceCodeKeyForSerializedBytecode(VM&, const SourceCode& s SourceCodeKey sourceCodeKeyForSerializedProgram(VM& vm, const SourceCode& sourceCode) { JSParserScriptMode scriptMode = JSParserScriptMode::Classic; - return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ProgramType, NoLexicallyScopedFeatures, scriptMode, { }); + return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ProgramType, NoLexicallyScopedFeatures, scriptMode, {}); } SourceCodeKey sourceCodeKeyForSerializedModule(VM& vm, const SourceCode& sourceCode) { JSParserScriptMode scriptMode = JSParserScriptMode::Module; - return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, StrictModeLexicallyScopedFeature, scriptMode, { }); + return sourceCodeKeyForSerializedBytecode(vm, sourceCode, SourceCodeType::ModuleType, StrictModeLexicallyScopedFeature, scriptMode, {}); } RefPtr serializeBytecode(VM& vm, UnlinkedCodeBlock* codeBlock, const SourceCode& source, SourceCodeType codeType, LexicallyScopedFeatures lexicallyScopedFeatures, JSParserScriptMode scriptMode, FileSystem::PlatformFileHandle fd, BytecodeCacheError& error, OptionSet codeGenerationMode) diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h index 33cc400f96d56..46457b5b4483c 100644 --- a/Source/JavaScriptCore/runtime/CodeCache.h +++ b/Source/JavaScriptCore/runtime/CodeCache.h @@ -170,6 +170,8 @@ class CodeCacheMap { if (isMainThread()) RELEASE_ASSERT(codeBlock); } + dataLogLnIf(codeBlock && Options::verboseDiskCache(), "[Disk Cache] Cache hit for sourceCode"); + dataLogLnIf(!codeBlock && Options::verboseDiskCache(), "[Disk Cache] Cache miss for sourceCode"); return codeBlock; } else { UNUSED_PARAM(vm); diff --git a/Source/JavaScriptCore/runtime/JSCBytecodeCacheVersion.cpp b/Source/JavaScriptCore/runtime/JSCBytecodeCacheVersion.cpp index 1ea8716a9df39..4f5d056d309f6 100644 --- a/Source/JavaScriptCore/runtime/JSCBytecodeCacheVersion.cpp +++ b/Source/JavaScriptCore/runtime/JSCBytecodeCacheVersion.cpp @@ -47,7 +47,7 @@ static constexpr bool verbose = false; uint32_t computeJSCBytecodeCacheVersion() { -#if OS(DARWIN) +#if OS(DARWIN) && !USE(BUN_JSC_ADDITIONS) static LazyNeverDestroyed cacheVersion; static std::once_flag onceFlag; std::call_once(onceFlag, [] { diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index eb9dc96c783f0..48c1905e2570a 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -859,12 +859,16 @@ JSC_DEFINE_HOST_FUNCTION(globalFuncImportModule, (JSGlobalObject* globalObject, RETURN_IF_EXCEPTION(scope, JSValue::encode(JSPromise::rejectedPromiseWithCaughtException(globalObject, scope))); scope.release(); + + auto* promise = JSPromise::create(vm, globalObject->promiseStructure()); + if (internalPromise->status(vm) == JSPromise::Status::Fulfilled) { - return JSValue::encode(JSPromise::resolvedPromise(globalObject, internalPromise->result(vm))); + auto result = internalPromise->result(vm); + promise->fulfill(globalObject, result); + } else { + promise->resolve(globalObject, internalPromise); } - auto* promise = JSPromise::create(vm, globalObject->promiseStructure()); - promise->resolve(globalObject, internalPromise); return JSValue::encode(promise); } diff --git a/Source/JavaScriptCore/runtime/JSModuleLoader.cpp b/Source/JavaScriptCore/runtime/JSModuleLoader.cpp index a0135e86f7a3f..1fa09164e9859 100644 --- a/Source/JavaScriptCore/runtime/JSModuleLoader.cpp +++ b/Source/JavaScriptCore/runtime/JSModuleLoader.cpp @@ -358,7 +358,7 @@ JSC_DEFINE_HOST_FUNCTION(moduleLoaderParseModule, (JSGlobalObject* globalObject, auto* moduleRecord = SyntheticModuleRecord::parseJSONModule(globalObject, moduleKey, WTFMove(sourceCode)); RETURN_IF_EXCEPTION(scope, JSValue::encode(promise->rejectWithCaughtException(globalObject, scope))); scope.release(); - promise->resolve(globalObject, moduleRecord); + promise->fulfillWithNonPromise(globalObject, moduleRecord); return JSValue::encode(promise); } case SourceProviderSourceType::Synthetic: { @@ -372,7 +372,7 @@ JSC_DEFINE_HOST_FUNCTION(moduleLoaderParseModule, (JSGlobalObject* globalObject, RETURN_IF_EXCEPTION(scope, JSValue::encode(promise->rejectWithCaughtException(globalObject, scope))); scope.release(); - promise->resolve(globalObject, moduleRecord); + promise->fulfillWithNonPromise(globalObject, moduleRecord); return JSValue::encode(promise); } default: { @@ -398,7 +398,7 @@ JSC_DEFINE_HOST_FUNCTION(moduleLoaderParseModule, (JSGlobalObject* globalObject, } scope.release(); - promise->resolve(globalObject, result.value()); + promise->fulfillWithNonPromise(globalObject, result.value()); return JSValue::encode(promise); } diff --git a/Source/JavaScriptCore/runtime/JSPromise.cpp b/Source/JavaScriptCore/runtime/JSPromise.cpp index 99efec83b6691..05e1886d580ef 100644 --- a/Source/JavaScriptCore/runtime/JSPromise.cpp +++ b/Source/JavaScriptCore/runtime/JSPromise.cpp @@ -205,12 +205,37 @@ void JSPromise::resolve(JSGlobalObject* lexicalGlobalObject, JSValue value) } } +void JSPromise::fulfill(JSGlobalObject* lexicalGlobalObject, JSValue value) +{ + ASSERT(!value.inherits()); + + if (!value.isCell() || !(value.asCell()->type() == JSPromiseType)) + fulfillWithNonPromise(lexicalGlobalObject, value); + else + resolve(lexicalGlobalObject, value); +} + +void JSPromise::fulfillWithNonPromise(JSGlobalObject* lexicalGlobalObject, JSValue value) +{ + VM& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + uint32_t flags = this->flags(); + ASSERT_WITH_MESSAGE(!value.inherits(), "Promise fulfilled with exception"); + ASSERT_WITH_MESSAGE(!value.inherits(), "Promise fulfilled with another promise"); + + if (!(flags & isFirstResolvingFunctionCalledFlag)) { + ASSERT(internalField(Field::ReactionsOrResult).get().isUndefined()); + internalField(Field::Flags).set(vm, this, jsNumber(flags | isFirstResolvingFunctionCalledFlag | static_cast(Status::Fulfilled))); + internalField(Field::ReactionsOrResult).set(vm, this, value); + } +} + void JSPromise::reject(JSGlobalObject* lexicalGlobalObject, JSValue value) { VM& vm = lexicalGlobalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); uint32_t flags = this->flags(); - ASSERT(!value.inherits()); + ASSERT_WITH_MESSAGE(!value.inherits(), "Promise rejected with exception. Use exception.value() instead."); if (!(flags & isFirstResolvingFunctionCalledFlag)) { internalField(Field::Flags).set(vm, this, jsNumber(flags | isFirstResolvingFunctionCalledFlag)); JSGlobalObject* globalObject = this->globalObject(); diff --git a/Source/JavaScriptCore/runtime/JSPromise.h b/Source/JavaScriptCore/runtime/JSPromise.h index 516410320d921..fff138368af9a 100644 --- a/Source/JavaScriptCore/runtime/JSPromise.h +++ b/Source/JavaScriptCore/runtime/JSPromise.h @@ -81,6 +81,8 @@ class JSPromise : public JSInternalFieldObjectImpl<2> { JS_EXPORT_PRIVATE static JSPromise* rejectedPromiseWithCaughtException(JSGlobalObject*, ThrowScope&); JS_EXPORT_PRIVATE void resolve(JSGlobalObject*, JSValue); + JS_EXPORT_PRIVATE void fulfill(JSGlobalObject*, JSValue value); + JS_EXPORT_PRIVATE void fulfillWithNonPromise(JSGlobalObject*, JSValue value); JS_EXPORT_PRIVATE void reject(JSGlobalObject*, JSValue); JS_EXPORT_PRIVATE void rejectAsHandled(JSGlobalObject*, JSValue); JS_EXPORT_PRIVATE void reject(JSGlobalObject*, Exception*); diff --git a/Source/JavaScriptCore/runtime/OptionsList.h b/Source/JavaScriptCore/runtime/OptionsList.h index b14f27b10f64c..4d06b2853935b 100644 --- a/Source/JavaScriptCore/runtime/OptionsList.h +++ b/Source/JavaScriptCore/runtime/OptionsList.h @@ -542,6 +542,7 @@ bool hasCapacityToUseLargeGigacage(); v(Bool, traceBaselineJITExecution, false, Normal, nullptr) \ v(Unsigned, thresholdForGlobalLexicalBindingEpoch, UINT_MAX, Normal, "Threshold for global lexical binding epoch. If the epoch reaches to this value, CodeBlock metadata for scope operations will be revised globally. It needs to be greater than 1."_s) \ v(OptionString, diskCachePath, nullptr, Restricted, nullptr) \ + v(Bool, verboseDiskCache, false, Normal, "If true, we will log cache hits and misses."_s) \ v(Bool, forceDiskCache, false, Restricted, nullptr) \ v(Bool, validateAbstractInterpreterState, false, Restricted, nullptr) \ v(Double, validateAbstractInterpreterStateProbability, 0.5, Normal, nullptr) \