diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/assembler/ARM64EAssembler.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/assembler/ARM64EAssembler.h index ac9ffc669cd..2f7fd5d5091 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/assembler/ARM64EAssembler.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/assembler/ARM64EAssembler.h @@ -261,12 +261,12 @@ class ARM64EAssembler : public ARM64Assembler { ALWAYS_INLINE void braaz(RegisterID dest) { - insn(encodeGroup4(Group4Op::BLRAAZ, dest)); + insn(encodeGroup4(Group4Op::BRAAZ, dest)); } ALWAYS_INLINE void brabz(RegisterID dest) { - insn(encodeGroup4(Group4Op::BLRABZ, dest)); + insn(encodeGroup4(Group4Op::BRABZ, dest)); } ALWAYS_INLINE void blraaz(RegisterID dest) diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/builtins/ArrayConstructor.js b/modules/javafx.web/src/main/native/Source/JavaScriptCore/builtins/ArrayConstructor.js index 2a3cd7170be..569c6e6f5fc 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/builtins/ArrayConstructor.js +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/builtins/ArrayConstructor.js @@ -120,10 +120,12 @@ function isArray(array) @linkTimeConstant @visibility=PrivateRecursive -async function defaultAsyncFromAsyncIterator(result, iterator, mapFn, thisArg) +async function defaultAsyncFromAsyncIterator(iterator, mapFn, thisArg) { "use strict"; + var result = this !== @Array && @isConstructor(this) ? new this() : []; + var k = 0; // Since for-of loop once more looks up the @@iterator property of a given iterable, @@ -202,14 +204,12 @@ function fromAsync(asyncItems /*, mapFn, thisArg */) } } - var result = this !== @Array && @isConstructor(this) ? new this() : []; - if (!@isUndefinedOrNull(usingAsyncIterator)) - return @defaultAsyncFromAsyncIterator(result, usingAsyncIterator.@call(asyncItems), mapFn, thisArg); + return @defaultAsyncFromAsyncIterator.@call(this, usingAsyncIterator.@call(asyncItems), mapFn, thisArg); if (!@isUndefinedOrNull(usingSyncIterator)) { var iterator = usingSyncIterator.@call(asyncItems); - return @defaultAsyncFromAsyncIterator(result, @createAsyncFromSyncIterator(iterator, iterator.next), mapFn, thisArg); + return @defaultAsyncFromAsyncIterator.@call(this, @createAsyncFromSyncIterator(iterator, iterator.next), mapFn, thisArg); } return @defaultAsyncFromAsyncArrayLike.@call(this, asyncItems, mapFn, thisArg); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index f51719877c3..983e4d4a092 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -602,8 +602,10 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke SymbolTableEntry entry(varOffset); functionSymbolTable->set(NoLockingNecessary, name, entry); +IGNORE_GCC_WARNINGS_BEGIN("dangling-reference") const Identifier& ident = static_cast(parameters.at(i).first)->boundProperty(); +IGNORE_GCC_WARNINGS_END varOrAnonymous = addConstant(ident); } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index 8db0a369a30..203c9491620 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -5019,18 +5019,18 @@ Node* ByteCodeParser::load( ObjectPropertyCondition ByteCodeParser::presenceConditionIfConsistent(JSObject* knownBase, UniquedStringImpl* uid, PropertyOffset offset, const StructureSet& set) { - if (set.isEmpty()) - return ObjectPropertyCondition(); + Structure* structure = knownBase->structure(); unsigned attributes; - PropertyOffset firstOffset = set[0]->getConcurrently(uid, attributes); - if (firstOffset != offset) + PropertyOffset baseOffset = structure->getConcurrently(uid, attributes); + if (offset != baseOffset) return ObjectPropertyCondition(); - for (unsigned i = 1; i < set.size(); ++i) { - unsigned otherAttributes; - PropertyOffset otherOffset = set[i]->getConcurrently(uid, otherAttributes); - if (otherOffset != offset || otherAttributes != attributes) - return ObjectPropertyCondition(); - } + + // We need to check set contains knownBase's structure because knownBase's GetOwnPropertySlot could normally prevent access + // to this property, for example via a cross-origin restriction check. So unless we've executed this access before we can't assume + // just because knownBase has a property uid at offset we're allowed to access. + if (!set.contains(structure)) + return ObjectPropertyCondition(); + return ObjectPropertyCondition::presenceWithoutBarrier(knownBase, uid, offset, attributes); } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/Heap.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/Heap.cpp index 49781240764..f3cd29bf5db 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/Heap.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/heap/Heap.cpp @@ -973,7 +973,8 @@ size_t Heap::extraMemorySize() checkedTotal += m_arrayBuffers.size(); size_t total = UNLIKELY(checkedTotal.hasOverflowed()) ? std::numeric_limits::max() : checkedTotal.value(); - ASSERT(m_objectSpace.capacity() >= m_objectSpace.size()); + // It would be nice to have `ASSERT(m_objectSpace.capacity() >= m_objectSpace.size());` here but `m_objectSpace.size()` + // requires having heap access which thread might not. Specifically, we might be called from the resource usage thread. return std::min(total, std::numeric_limits::max() - m_objectSpace.capacity()); } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/jit/JITCode.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/jit/JITCode.h index b110c672afd..e58cce59990 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/jit/JITCode.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/jit/JITCode.h @@ -72,7 +72,7 @@ enum class JITType : uint8_t { static constexpr unsigned widthOfJITType = 3; static_assert(WTF::getMSBSetConstexpr(static_cast>(JITType::FTLJIT)) + 1 == widthOfJITType); -#if USE(JSVALUE64) +#if CPU(ADDRESS64) template class JITConstant { static_assert(sizeof(ByteSizedEnumType) == 1); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/jsc.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/jsc.cpp index 8271ff4635e..3a41f2df0ff 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/jsc.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/jsc.cpp @@ -146,6 +146,7 @@ #include #include #endif + #if OS(DARWIN) && PLATFORM(MAC) #include #endif @@ -285,6 +286,7 @@ class Workers { SentinelLinkedList> m_workers; Deque m_reports; }; + WTF_MAKE_TZONE_ALLOCATED_IMPL(Workers); @@ -416,6 +418,7 @@ static JSC_DECLARE_HOST_FUNCTION(functionDropAllLocks); #if ENABLE(FUZZILLI) static JSC_DECLARE_HOST_FUNCTION(functionFuzzilli); #endif + struct Script { enum class StrictMode { Strict, @@ -563,6 +566,7 @@ class GlobalObject final : public JSGlobalObject { propertyNames.add(propertyName); } } + private: GlobalObject(VM&, Structure*); @@ -577,30 +581,39 @@ class GlobalObject final : public JSGlobalObject { if (result.isNewEntry) m_strings.append(uid); } + bool contains(UniquedStringImpl* name) const { return m_names.contains(name); } const HashSet& names() const { return m_names; } + private: Vector m_strings; // To keep the UniqueStringImpls alive. HashSet m_names; }; + void finishCreation(VM& vm, const Vector& arguments) { auto& filter = ensurePropertyFilter(); + auto addFunction = [&] (VM& vm, ASCIILiteral name, NativeFunction function, unsigned arguments, unsigned attributes = static_cast(PropertyAttribute::DontEnum)) { addFunctionImpl(filter, vm, name, function, arguments, attributes); }; + auto addFunctionToObject = [&] (VM& vm, JSObject* owner, ASCIILiteral name, NativeFunction function, unsigned arguments, unsigned attributes = static_cast(PropertyAttribute::DontEnum)) { addFunctionToObjectImpl(filter, vm, owner, name, function, arguments, attributes); }; + auto putDirect = [&] (VM& vm, PropertyName propertyName, JSValue value, unsigned attributes = 0) -> bool { return putDirectImpl(filter, vm, propertyName, value, attributes); }; + auto putDirectWithoutTransition = [&] (VM& vm, PropertyName propertyName, JSValue value, unsigned attributes) { putDirectWithoutTransitionImpl(filter, vm, propertyName, value, attributes); }; + auto putDirectNativeFunction = [&] (VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, unsigned functionLength, NativeFunction nativeFunction, ImplementationVisibility implementationVisibility, Intrinsic intrinsic, unsigned attributes) -> bool { return putDirectNativeFunctionImpl(filter, vm, globalObject, propertyName, functionLength, nativeFunction, implementationVisibility, intrinsic, attributes); }; + Base::finishCreation(vm); JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); @@ -776,10 +789,12 @@ class GlobalObject final : public JSGlobalObject { #if ENABLE(FUZZILLI) addFunction(vm, "fuzzilli"_s, functionFuzzilli, 2); #endif + if (Options::exposeCustomSettersOnGlobalObjectForTesting()) { auto putDirectCustomAccessor = [&] (VM& vm, PropertyName propertyName, JSValue value, unsigned attributes) -> bool { return putDirectCustomAccessorImpl(filter, vm, propertyName, value, attributes); }; + { CustomGetterSetter* custom = CustomGetterSetter::create(vm, nullptr, testCustomAccessorSetter); Identifier identifier = Identifier::fromString(vm, "testCustomAccessorSetter"_s); @@ -792,6 +807,7 @@ class GlobalObject final : public JSGlobalObject { putDirectCustomAccessor(vm, identifier, custom, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::CustomValue); } } + if (Options::useDollarVM()) { // $vm is added in JSGlobalObject but we also want it filtered out. Just add it to the filter here. Identifier dollarVMIdentifier = Identifier::fromString(vm, "$vm"_s); @@ -1193,6 +1209,7 @@ static bool fillBufferWithContentsOfFile(const String& fileName, Vector& b fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); return false; } + if ((statBuf.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, "Trying to open a non-file: %s\n", fileName.utf8().data()); return false; @@ -1339,7 +1356,6 @@ class ShellSourceProvider final : public StringSourceProvider { // bytecode cache, which results in intermittent test failures. As $.agent.start is only // a rarely used testing facility, we simply do not cache bytecode on these threads. , m_cacheEnabled(Worker::current().isMain() && !!Options::diskCachePath()) - { } @@ -3232,19 +3248,30 @@ JSC_DEFINE_HOST_FUNCTION(functionDropAllLocks, (JSGlobalObject* globalObject, Ca JSLock::DropAllLocks dropAllLocks(globalObject); return JSValue::encode(jsUndefined()); } + #if ENABLE(FUZZILLI) + +// We have to assume that the fuzzer will be able to call this function e.g. by +// enumerating the properties of the global object and eval'ing them. As such +// this function is implemented in a way that requires passing some magic value +// as first argument (with the idea being that the fuzzer won't be able to +// generate this value) which then also acts as a selector for the operation +// to perform. JSC_DEFINE_HOST_FUNCTION(functionFuzzilli, (JSGlobalObject* globalObject, CallFrame* callFrame)) { VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (!callFrame->argument(0).isString()) { + // We directly require a string as argument for simplicity. return JSValue::encode(jsUndefined()); } auto operation = callFrame->argument(0).toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, { }); + if (operation == "FUZZILLI_CRASH"_s) { int32_t command = callFrame->argument(1).toInt32(globalObject); RETURN_IF_EXCEPTION(scope, { }); + switch (command) { case 0: *reinterpret_cast(0x41414141) = 0x1337; @@ -3256,14 +3283,18 @@ JSC_DEFINE_HOST_FUNCTION(functionFuzzilli, (JSGlobalObject* globalObject, CallFr ASSERT(0); break; } + } else if (operation == "FUZZILLI_PRINT"_s) { String string = callFrame->argument(1).toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, { }); + Fuzzilli::logFile().println(string); Fuzzilli::logFile().flush(); } + return JSValue::encode(jsUndefined()); } + #endif // ENABLE(FUZZILLI) // Use SEH for Release builds only to get rid of the crash report dialog @@ -3638,6 +3669,7 @@ static void runWithOptions(GlobalObject* globalObject, CommandLine& options, boo for (size_t i = 0; i < scripts.size(); i++) { JSInternalPromise* promise = nullptr; bool isModule = options.m_module || scripts[i].scriptType == Script::ScriptType::Module; + switch (scripts[i].codeSource) { case Script::CodeSource::File: { fileName = String::fromLatin1(scripts[i].argument); @@ -4047,6 +4079,7 @@ void CommandLine::parseArguments(int argc, char** argv) } continue; } + // See if the -- option is a JSC VM option. if (strstr(arg, "--") == arg) { if (!JSC::Options::setOption(&arg[2], /* verify = */ false)) { @@ -4096,16 +4129,20 @@ int runJSC(const CommandLine& options, bool isWorker, const Func& func) int result; bool success; + #if ENABLE(FUZZILLI) + // Let parent know we are ready. if (options.m_reprl) { Fuzzilli::initializeReprl(); } #endif // ENABLE(FUZZILLI) + do { #if ENABLE(FUZZILLI) if (options.m_reprl) Fuzzilli::waitForCommand(); #endif // ENABLE(FUZZILLI) + success = true; GlobalObject* globalObject = nullptr; { @@ -4120,6 +4157,7 @@ int runJSC(const CommandLine& options, bool isWorker, const Func& func) vm.deferredWorkTimer->runRunLoop(); { JSLockHolder locker(vm); + if (!options.m_reprl && options.m_interactive && success) runInteractive(globalObject); } @@ -4152,7 +4190,6 @@ int runJSC(const CommandLine& options, bool isWorker, const Func& func) printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks()); } - auto compileTimeStats = JIT::compileTimeStats(); Vector compileTimeKeys; for (auto& entry : compileTimeStats) @@ -4196,6 +4233,7 @@ int runJSC(const CommandLine& options, bool isWorker, const Func& func) } #endif // ENABLE(FUZZILLI) } while (options.m_reprl); + vm.codeCache()->write(); if (options.m_destroyVM || isWorker) { diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.cpp index b3bbbf99e71..85edf96b609 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.cpp @@ -45,7 +45,7 @@ void MarkedVectorBase::addMarkSet(JSValue v) void ArgList::getSlice(int startIndex, ArgList& result) const { - if (startIndex <= 0 || startIndex >= m_argCount) { + if (startIndex <= 0 || static_cast(startIndex) >= m_argCount) { result = ArgList(); return; } @@ -60,7 +60,7 @@ void MarkedVectorBase::markLists(Visitor& visitor, ListSet& markSet) ListSet::iterator end = markSet.end(); for (ListSet::iterator it = markSet.begin(); it != end; ++it) { MarkedVectorBase* list = *it; - for (int i = 0; i < list->m_size; ++i) + for (unsigned i = 0; i < list->m_size; ++i) visitor.appendUnbarriered(JSValue::decode(list->slotFor(i))); } } @@ -86,7 +86,7 @@ auto MarkedVectorBase::expandCapacity() -> Status return expandCapacity(checkedNewCapacity); } -auto MarkedVectorBase::expandCapacity(int newCapacity) -> Status +auto MarkedVectorBase::expandCapacity(unsigned newCapacity) -> Status { setNeedsOverflowCheck(); ASSERT(m_capacity < newCapacity); @@ -96,7 +96,7 @@ auto MarkedVectorBase::expandCapacity(int newCapacity) -> Status EncodedJSValue* newBuffer = static_cast(Gigacage::tryMalloc(Gigacage::JSValue, checkedSize)); if (!newBuffer) return Status::Overflowed; - for (int i = 0; i < m_size; ++i) { + for (unsigned i = 0; i < m_size; ++i) { newBuffer[i] = m_buffer[i]; addMarkSet(JSValue::decode(m_buffer[i])); } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.h index 4321c8f5c67..59ca86ffec3 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/ArgList.h @@ -83,14 +83,14 @@ class alignas(alignof(EncodedJSValue)) MarkedVectorBase { } Status expandCapacity(); - Status expandCapacity(int newCapacity); + Status expandCapacity(unsigned newCapacity); JS_EXPORT_PRIVATE Status slowEnsureCapacity(size_t requestedCapacity); void addMarkSet(JSValue); JS_EXPORT_PRIVATE Status slowAppend(JSValue); - EncodedJSValue& slotFor(int item) const + EncodedJSValue& slotFor(unsigned item) const { return m_buffer[item]; } @@ -114,8 +114,8 @@ class alignas(alignof(EncodedJSValue)) MarkedVectorBase { void setNeedsOverflowCheck() { } void clearNeedsOverflowCheck() { } #endif // ASSERT_ENABLED - int m_size; - int m_capacity; + unsigned m_size; + unsigned m_capacity; EncodedJSValue* m_buffer; ListSet* m_markSet; }; @@ -136,7 +136,7 @@ class MarkedVector : public OverflowHandler, public MarkedVectorBase { } } - auto at(int i) const -> decltype(auto) + auto at(unsigned i) const -> decltype(auto) { if constexpr (std::is_same_v) { if (i >= m_size) @@ -276,13 +276,13 @@ class ArgList { { } - ArgList(EncodedJSValue* args, int count) + ArgList(EncodedJSValue* args, unsigned count) : m_args(args) , m_argCount(count) { } - JSValue at(int i) const + JSValue at(unsigned i) const { if (i >= m_argCount) return jsUndefined(); @@ -298,7 +298,7 @@ class ArgList { private: EncodedJSValue* m_args { nullptr }; - int m_argCount { 0 }; + unsigned m_argCount { 0 }; }; } // namespace JSC diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CommonSlowPaths.h index 79463ea3171..75c81124405 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CommonSlowPaths.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CommonSlowPaths.h @@ -180,7 +180,15 @@ static ALWAYS_INLINE void putDirectWithReify(VM& vm, JSGlobalObject* globalObjec auto scope = DECLARE_THROW_SCOPE(vm); bool isJSFunction = baseObject->inherits(); if (isJSFunction) { - jsCast(baseObject)->reifyLazyPropertyIfNeeded<>(vm, globalObject, propertyName); + JSFunction* jsFunction = jsCast(baseObject); + + if (propertyName == vm.propertyNames->prototype) { + slot.disableCaching(); + if (FunctionRareData* rareData = jsFunction->rareData()) + rareData->clear("Store to prototype property of a function"); + } + + jsFunction->reifyLazyPropertyIfNeeded<>(vm, globalObject, propertyName); RETURN_IF_EXCEPTION(scope, void()); } @@ -201,16 +209,18 @@ static ALWAYS_INLINE void putDirectWithReify(VM& vm, JSGlobalObject* globalObjec static ALWAYS_INLINE void putDirectAccessorWithReify(VM& vm, JSGlobalObject* globalObject, JSObject* baseObject, PropertyName propertyName, GetterSetter* accessor, unsigned attribute) { + // baseObject is either JSFinalObject during object literal construction, or a userland JSFunction class + // constructor, both of which are guaranteed to be extensible and without non-configurable |propertyName|. + // Please also note that static "prototype" accessor in a `class` literal is a syntax error. + auto scope = DECLARE_THROW_SCOPE(vm); bool isJSFunction = baseObject->inherits(); if (isJSFunction) { + ASSERT(propertyName != vm.propertyNames->prototype); jsCast(baseObject)->reifyLazyPropertyIfNeeded<>(vm, globalObject, propertyName); RETURN_IF_EXCEPTION(scope, void()); } - // baseObject is either JSFinalObject during object literal construction, or a userland JSFunction class - // constructor, both of which are guaranteed to be extensible and without non-configurable |propertyName|. - // Please also note that static "prototype" accessor in a `class` literal is a syntax error. ASSERT(canPutDirectFast(vm, originalStructureBeforePut(baseObject), propertyName, isJSFunction)); scope.release(); baseObject->putDirectAccessor(globalObject, propertyName, accessor, attribute); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CustomGetterSetter.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CustomGetterSetter.h index 6b875fc933a..82e1692a28c 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CustomGetterSetter.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/CustomGetterSetter.h @@ -35,7 +35,7 @@ namespace JSC { class CustomGetterSetter : public JSCell { public: using Base = JSCell; - static constexpr unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; + static constexpr unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesPut | StructureIsImmortal; using CustomGetter = GetValueFunc; using CustomSetter = PutValueFunc; @@ -60,6 +60,13 @@ class CustomGetterSetter : public JSCell { DECLARE_EXPORT_INFO; + static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } + static bool put(JSCell*, JSGlobalObject*, PropertyName, JSValue, PutPropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } + static bool putByIndex(JSCell*, JSGlobalObject*, unsigned, JSValue, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } + static bool setPrototype(JSObject*, JSGlobalObject*, JSValue, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } + static bool defineOwnProperty(JSObject*, JSGlobalObject*, PropertyName, const PropertyDescriptor&, bool) { RELEASE_ASSERT_NOT_REACHED(); return false; } + static bool deleteProperty(JSCell*, JSGlobalObject*, PropertyName, DeletePropertySlot&) { RELEASE_ASSERT_NOT_REACHED(); return false; } + protected: CustomGetterSetter(VM& vm, Structure* structure, CustomGetter getter, CustomSetter setter) : JSCell(vm, structure) diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/InternalFunction.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/InternalFunction.cpp index c46d734aed0..9b420379bb4 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/InternalFunction.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/runtime/InternalFunction.cpp @@ -144,6 +144,11 @@ Structure* InternalFunction::createSubclassStructure(JSGlobalObject* globalObjec if (UNLIKELY(!targetFunction || !targetFunction->canUseAllocationProfiles())) { JSValue prototypeValue = newTarget->get(globalObject, vm.propertyNames->prototype); RETURN_IF_EXCEPTION(scope, nullptr); + // .prototype getter could have triggered having a bad time so need to recheck array structures. + if (UNLIKELY(baseGlobalObject->isHavingABadTime())) { + if (baseGlobalObject->isOriginalArrayStructure(baseClass)) + baseClass = baseGlobalObject->arrayStructureForIndexingTypeDuringAllocation(baseClass->indexingType()); + } if (JSObject* prototype = jsDynamicCast(prototypeValue)) { // This only happens if someone Reflect.constructs our builtin constructor with another builtin constructor or weird .prototype property on a // JSFunction as the new.target. Thus, we don't care about the cost of looking up the structure from our hash table every time. diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp index f86c5e7c5a7..af2872c1900 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp @@ -345,12 +345,13 @@ class B3IRGenerator { return m_callSiteIndex; } - B3IRGenerator(const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry, TierUpCount*); - B3IRGenerator(B3IRGenerator& inlineCaller, B3IRGenerator& inlineRoot, unsigned functionIndex, BasicBlock* returnContinuation, Vector args); + B3IRGenerator(CalleeGroup&, const ModuleInformation&, OptimizingJITCallee&, Procedure&, Vector&, unsigned& osrEntryScratchBufferSize, MemoryMode, CompilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry, TierUpCount*); + B3IRGenerator(B3IRGenerator& inlineCaller, B3IRGenerator& inlineRoot, CalleeGroup&, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args); void computeStackCheckSize(bool& needsOverflowCheck, int32_t& checkSize); // SIMD + bool usesSIMD() { return m_info.usesSIMD(m_functionIndex); } void notifyFunctionUsesSIMD() { ASSERT(m_info.usesSIMD(m_functionIndex)); } PartialResult WARN_UNUSED_RETURN addSIMDLoad(ExpressionType pointer, uint32_t offset, ExpressionType& result); PartialResult WARN_UNUSED_RETURN addSIMDStore(ExpressionType value, ExpressionType pointer, uint32_t offset); @@ -902,6 +903,7 @@ class B3IRGenerator { void traceCF(Args&&... info); FunctionParser* m_parser { nullptr }; + CalleeGroup& m_calleeGroup; const ModuleInformation& m_info; OptimizingJITCallee* m_callee; const MemoryMode m_mode { MemoryMode::BoundsChecking }; @@ -1008,8 +1010,9 @@ void B3IRGenerator::restoreWasmContextInstance(BasicBlock* block, Value* arg) }); } -B3IRGenerator::B3IRGenerator(B3IRGenerator& parentCaller, B3IRGenerator& rootCaller, unsigned functionIndex, BasicBlock* returnContinuation, Vector args) - : m_info(rootCaller.m_info) +B3IRGenerator::B3IRGenerator(B3IRGenerator& parentCaller, B3IRGenerator& rootCaller, CalleeGroup& calleeGroup, unsigned functionIndex, std::optional hasExceptionHandlers, BasicBlock* returnContinuation, Vector args) + : m_calleeGroup(calleeGroup) + , m_info(rootCaller.m_info) , m_callee(parentCaller.m_callee) , m_mode(rootCaller.m_mode) , m_compilationMode(CompilationMode::OMGMode) @@ -1025,7 +1028,7 @@ B3IRGenerator::B3IRGenerator(B3IRGenerator& parentCaller, B3IRGenerator& rootCal , m_unlinkedWasmToWasmCalls(rootCaller.m_unlinkedWasmToWasmCalls) , m_osrEntryScratchBufferSize(nullptr) , m_constantInsertionValues(m_proc) - , m_hasExceptionHandlers(false) + , m_hasExceptionHandlers(hasExceptionHandlers) , m_numImportFunctions(m_info.importFunctionCount()) , m_tryCatchDepth(parentCaller.m_tryCatchDepth) , m_callSiteIndex(0) @@ -1036,6 +1039,8 @@ B3IRGenerator::B3IRGenerator(B3IRGenerator& parentCaller, B3IRGenerator& rootCal m_instanceValue = rootCaller.m_instanceValue; m_baseMemoryValue = rootCaller.m_baseMemoryValue; m_boundsCheckingSizeValue = rootCaller.m_boundsCheckingSizeValue; + if (parentCaller.m_hasExceptionHandlers && *parentCaller.m_hasExceptionHandlers) + m_hasExceptionHandlers = { true }; } void B3IRGenerator::computeStackCheckSize(bool& needsOverflowCheck, int32_t& checkSize) @@ -1074,8 +1079,9 @@ void B3IRGenerator::computeStackCheckSize(bool& needsOverflowCheck, int32_t& che needsOverflowCheck = needsOverflowCheck || needUnderflowCheck; } -B3IRGenerator::B3IRGenerator(const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry, TierUpCount* tierUp) - : m_info(info) +B3IRGenerator::B3IRGenerator(CalleeGroup& calleeGroup, const ModuleInformation& info, OptimizingJITCallee& callee, Procedure& procedure, Vector& unlinkedWasmToWasmCalls, unsigned& osrEntryScratchBufferSize, MemoryMode mode, CompilationMode compilationMode, unsigned functionIndex, std::optional hasExceptionHandlers, unsigned loopIndexForOSREntry, TierUpCount* tierUp) + : m_calleeGroup(calleeGroup) + , m_info(info) , m_callee(&callee) , m_mode(mode) , m_compilationMode(compilationMode) @@ -4276,7 +4282,7 @@ PatchpointExceptionHandle B3IRGenerator::preparePatchpointForExceptions(BasicBlo bool mustSaveState = m_tryCatchDepth; if (!mustSaveState) - return { m_hasExceptionHandlers }; + return { m_hasExceptionHandlers, callSiteIndex() }; Vector liveValues; Origin origin = this->origin(); @@ -4299,6 +4305,8 @@ PatchpointExceptionHandle B3IRGenerator::preparePatchpointForExceptions(BasicBlo if (ControlType::isAnyCatch(data)) liveValues.append(get(block, data.exception())); } + for (Variable* value : currentFrame->m_parser->expressionStack()) + liveValues.append(get(block, value)); } patch->effects.exitsSideways = true; @@ -4375,6 +4383,10 @@ Value* B3IRGenerator::emitCatchImpl(CatchKind kind, ControlType& data, unsigned auto& expressionStack = currentFrame->m_parser->controlStack()[controlIndex].enclosedExpressionStack; connectControlAtEntrypoint(indexInBuffer, pointer, controlData, expressionStack, data); } + + auto& topControlData = currentFrame->m_parser->controlStack().last().controlData; + auto& topExpressionStack = currentFrame->m_parser->expressionStack(); + connectControlAtEntrypoint(indexInBuffer, pointer, topControlData, topExpressionStack, data); } set(data.exception(), exception); @@ -4405,6 +4417,7 @@ auto B3IRGenerator::addDelegateToUnreachable(ControlType& target, ControlType& d auto B3IRGenerator::addThrow(unsigned exceptionIndex, Vector& args, Stack&) -> PartialResult { TRACE_CF("THROW"); + PatchpointValue* patch = m_proc.add(B3::Void, origin(), cloningForbidden(Patchpoint)); patch->effects.terminal = true; patch->append(instanceValue(), ValueRep::reg(GPRInfo::argumentGPR0)); @@ -4431,6 +4444,7 @@ auto B3IRGenerator::addThrow(unsigned exceptionIndex, Vector& ar auto B3IRGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult { TRACE_CF("RETHROW"); + PatchpointValue* patch = m_proc.add(B3::Void, origin(), cloningForbidden(Patchpoint)); patch->clobber(RegisterSetBuilder::registersToSaveForJSCall(m_proc.usesSIMD() ? RegisterSetBuilder::allRegisters() : RegisterSetBuilder::allScalarRegisters())); patch->effects.terminal = true; @@ -4648,7 +4662,7 @@ B3::PatchpointValue* B3IRGenerator::createCallPatchpoint(BasicBlock* block, Valu if (jsCalleeAnchor) constrainedPatchArgs.append(B3::ConstrainedValue(jsCalleeAnchor, wasmCalleeInfo.thisArgument)); - Box exceptionHandle = Box::create(m_hasExceptionHandlers); + Box exceptionHandle = Box::create(m_hasExceptionHandlers, callSiteIndex()); PatchpointValue* patchpoint = m_proc.add(returnType, origin()); patchpoint->effects.writesPinned = true; @@ -4782,7 +4796,14 @@ auto B3IRGenerator::emitInlineDirectCall(uint32_t calleeFunctionIndex, const Typ auto firstInlineCSI = advanceCallSiteIndex(); const FunctionData& function = m_info.functions[calleeFunctionIndex]; - m_protectedInlineeGenerators.append(makeUnique(*this, *m_inlineRoot, calleeFunctionIndex, continuation, WTFMove(getArgs))); + std::optional inlineeHasExceptionHandlers; + { + Locker locker { m_calleeGroup.m_lock }; + unsigned calleeFunctionIndexSpace = calleeFunctionIndex + m_numImportFunctions; + auto& inlineCallee = m_calleeGroup.wasmEntrypointCalleeFromFunctionIndexSpace(locker, calleeFunctionIndexSpace); + inlineeHasExceptionHandlers = inlineCallee.hasExceptionHandlers(); + } + m_protectedInlineeGenerators.append(makeUnique(*this, *m_inlineRoot, m_calleeGroup, calleeFunctionIndex, inlineeHasExceptionHandlers, continuation, WTFMove(getArgs))); auto& irGenerator = *m_protectedInlineeGenerators.last(); m_protectedInlineeParsers.append(makeUnique>(irGenerator, function.data.data(), function.data.size(), calleeSignature, m_info)); auto& parser = *m_protectedInlineeParsers.last(); @@ -4807,9 +4828,8 @@ auto B3IRGenerator::emitInlineDirectCall(uint32_t calleeFunctionIndex, const Typ dataLogLnIf(WasmB3IRGeneratorInternal::verboseInlining, "Block ", *m_currentBlock, " is going to do an inline call to block ", *irGenerator.m_topLevelBlock, " then continue at ", *continuation); - bool mayHaveExceptionHandlers = !m_hasExceptionHandlers || m_hasExceptionHandlers.value(); m_currentBlock->appendNew(m_proc, B3::Store, origin(), - m_currentBlock->appendIntConstant(m_proc, origin(), Int32, mayHaveExceptionHandlers ? PatchpointExceptionHandle::s_invalidCallSiteIndex : firstInlineCSI), + m_currentBlock->appendIntConstant(m_proc, origin(), Int32, firstInlineCSI), framePointer(), safeCast(CallFrameSlot::argumentCountIncludingThis * sizeof(Register) + TagOffset)); m_currentBlock->appendNewControlValue(m_proc, B3::Jump, origin(), FrequentedBlock(irGenerator.m_topLevelBlock)); @@ -4821,7 +4841,7 @@ auto B3IRGenerator::emitInlineDirectCall(uint32_t calleeFunctionIndex, const Typ auto lastInlineCSI = advanceCallSiteIndex(); m_currentBlock->appendNew(m_proc, B3::Store, origin(), - m_currentBlock->appendIntConstant(m_proc, origin(), Int32, mayHaveExceptionHandlers ? PatchpointExceptionHandle::s_invalidCallSiteIndex : advanceCallSiteIndex()), + m_currentBlock->appendIntConstant(m_proc, origin(), Int32, advanceCallSiteIndex()), framePointer(), safeCast(CallFrameSlot::argumentCountIncludingThis * sizeof(Register) + TagOffset)); m_callee->addCodeOrigin(firstInlineCSI, lastInlineCSI, m_info, calleeFunctionIndex + m_numImportFunctions); @@ -5172,7 +5192,7 @@ static bool shouldDumpIRFor(uint32_t functionIndex) return dumpAllowlist->shouldDumpWasmFunction(functionIndex); } -Expected, String> parseAndCompileB3(CompilationContext& compilationContext, OptimizingJITCallee& callee, const FunctionData& function, const TypeDefinition& signature, Vector& unlinkedWasmToWasmCalls, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, std::optional hasExceptionHandlers, uint32_t loopIndexForOSREntry, TierUpCount* tierUp) +Expected, String> parseAndCompileB3(CompilationContext& compilationContext, OptimizingJITCallee& callee, const FunctionData& function, const TypeDefinition& signature, Vector& unlinkedWasmToWasmCalls, CalleeGroup& calleeGroup, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, std::optional hasExceptionHandlers, uint32_t loopIndexForOSREntry, TierUpCount* tierUp) { CompilerTimingScope totalScope("B3", "Total WASM compilation"); @@ -5213,7 +5233,7 @@ Expected, String> parseAndCompileB3(Compilatio procedure.code().setForceIRCRegisterAllocation(); - B3IRGenerator irGenerator(info, callee, procedure, unlinkedWasmToWasmCalls, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry, tierUp); + B3IRGenerator irGenerator(calleeGroup, info, callee, procedure, unlinkedWasmToWasmCalls, result->osrEntryScratchBufferSize, mode, compilationMode, functionIndex, hasExceptionHandlers, loopIndexForOSREntry, tierUp); FunctionParser parser(irGenerator, function.data.data(), function.data.size(), signature, info); WASM_FAIL_IF_HELPER_FAILS(parser.parse()); @@ -5775,7 +5795,7 @@ using namespace B3; #if !USE(JSVALUE64) // On 32-bit platforms, we stub out the entire B3 generator -Expected, String> parseAndCompileB3(CompilationContext&, OptimizingJITCallee&, const FunctionData&, const TypeDefinition&, Vector&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t, std::optional, uint32_t, TierUpCount*) +Expected, String> parseAndCompileB3(CompilationContext&, OptimizingJITCallee&, const FunctionData&, const TypeDefinition&, Vector&, CalleeGroup&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t, std::optional, uint32_t, TierUpCount*) { UNREACHABLE_FOR_PLATFORM(); } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h index e84a71bfb25..c6d04a845ea 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h @@ -49,7 +49,9 @@ namespace JSC { namespace Wasm { -Expected, String> parseAndCompileB3(CompilationContext&, OptimizingJITCallee&, const FunctionData&, const TypeDefinition&, Vector&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, std::optional hasExceptionHandlers, uint32_t loopIndexForOSREntry, TierUpCount* = nullptr); +class CalleeGroup; + +Expected, String> parseAndCompileB3(CompilationContext&, OptimizingJITCallee&, const FunctionData&, const TypeDefinition&, Vector&, CalleeGroup&, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, std::optional hasExceptionHandlers, uint32_t loopIndexForOSREntry, TierUpCount* = nullptr); } } // namespace JSC::Wasm diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp index 02a4febf3e9..9184bbe875a 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp @@ -3958,6 +3958,25 @@ void BBQJIT::returnValuesFromCall(Vector& results, const FunctionSigna ASSERT(m_validFPRs.contains(returnLocation.asFPR(), Width::Width128)); m_fprSet.add(returnLocation.asFPR(), Width::Width128); } + } else { + ASSERT(returnLocation.isStackArgument()); + // FIXME: Ideally, we would leave these values where they are but a subsequent call could clobber them before they are used. + // That said, stack results are very rare so this isn't too painful. + // Even if we did leave them where they are, we'd need to flush them to their canonical location at the next branch otherwise + // we could have something like (assume no result regs for simplicity): + // call (result i32 i32) $foo + // if (result i32) // Stack: i32(StackArgument:8) i32(StackArgument:0) + // // Stack: i32(StackArgument:8) + // else + // call (result i32 i32) $bar // Stack: i32(StackArgument:8) we have to flush the stack argument to make room for the result of bar + // drop // Stack: i32(Stack:X) i32(StackArgument:8) i32(StackArgument:0) + // drop // Stack: i32(Stack:X) i32(StackArgument:8) + // end + // return // Stack i32(*Conflicting locations*) + + Location canonicalLocation = canonicalSlot(result); + emitMoveMemory(result.type(), returnLocation, canonicalLocation); + returnLocation = canonicalLocation; } } bind(result, returnLocation); @@ -4181,6 +4200,11 @@ ALWAYS_INLINE void BBQJIT::didParseOpcode() // SIMD +bool BBQJIT::usesSIMD() +{ + return m_usesSIMD; +} + void BBQJIT::dump(const ControlStack&, const Stack*) { } void BBQJIT::didFinishParsingLocals() { } void BBQJIT::didPopValueFromStack(ExpressionType, String) { } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.h index 6c4d7ef7e50..8a4ef5bd5ca 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmBBQJIT.h @@ -1780,6 +1780,8 @@ class BBQJIT { // SIMD + bool usesSIMD(); + void notifyFunctionUsesSIMD(); PartialResult addSIMDLoad(ExpressionType, uint32_t, ExpressionType&); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmConstExprGenerator.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmConstExprGenerator.cpp index f85009c2b7e..119328eef33 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmConstExprGenerator.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmConstExprGenerator.cpp @@ -654,6 +654,7 @@ class ConstExprGenerator { PartialResult WARN_UNUSED_RETURN addCallRef(const TypeDefinition&, Vector&, ResultList&) CONST_EXPR_STUB PartialResult WARN_UNUSED_RETURN addUnreachable() CONST_EXPR_STUB PartialResult WARN_UNUSED_RETURN addCrash() CONST_EXPR_STUB + bool usesSIMD() { return false; } void notifyFunctionUsesSIMD() { } PartialResult WARN_UNUSED_RETURN addSIMDLoad(ExpressionType, uint32_t, ExpressionType&) CONST_EXPR_STUB PartialResult WARN_UNUSED_RETURN addSIMDStore(ExpressionType, ExpressionType, uint32_t) CONST_EXPR_STUB diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmFunctionParser.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmFunctionParser.h index 059e8a9cafb..46838eb2027 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmFunctionParser.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmFunctionParser.h @@ -331,6 +331,7 @@ class FunctionParser : public Parser, public FunctionParserTypes, public FunctionParserTypes +auto FunctionParser::parseBlockSignatureAndNotifySIMDUseIfNeeded(BlockSignature& signature) -> PartialResult +{ + auto result = parseBlockSignature(m_info, signature); + + // This check ensures the valid result and the non empty signature. + if (!result || !signature) + return result; + + if (m_context.usesSIMD()) { + if (!Context::tierSupportsSIMD) + WASM_TRY_ADD_TO_CONTEXT(addCrash()); + return result; + } + + if (signature->hasReturnVector()) { + m_context.notifyFunctionUsesSIMD(); + if (!Context::tierSupportsSIMD) + WASM_TRY_ADD_TO_CONTEXT(addCrash()); + } + return result; +} + template static bool isTryOrCatch(ControlType& data) { @@ -2723,6 +2747,7 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE) WASM_PARSER_FAIL_IF(!Options::useWebAssemblyTypedFunctionReferences(), "function references are not enabled"); TypedExpression ref; WASM_TRY_POP_EXPRESSION_STACK_INTO(ref, "ref.as_non_null"); + WASM_VALIDATOR_FAIL_IF(!isRefType(ref.type()), "ref.as_non_null ref to type ", ref.type(), " expected a reference type"); ExpressionType result; WASM_TRY_ADD_TO_CONTEXT(addRefAsNonNull(ref, result)); @@ -3064,7 +3089,7 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE) return { }; BlockSignature inlineSignature; - WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get block's signature"); + WASM_PARSER_FAIL_IF(!parseBlockSignatureAndNotifySIMDUseIfNeeded(inlineSignature), "can't get block's signature"); WASM_VALIDATOR_FAIL_IF(m_expressionStack.size() < inlineSignature->argumentCount(), "Too few values on stack for block. Block expects ", inlineSignature->argumentCount(), ", but only ", m_expressionStack.size(), " were present. Block has inlineSignature: ", inlineSignature->toString()); unsigned offset = m_expressionStack.size() - inlineSignature->argumentCount(); @@ -3086,7 +3111,7 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE) case Loop: { BlockSignature inlineSignature; - WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get loop's signature"); + WASM_PARSER_FAIL_IF(!parseBlockSignatureAndNotifySIMDUseIfNeeded(inlineSignature), "can't get loop's signature"); WASM_VALIDATOR_FAIL_IF(m_expressionStack.size() < inlineSignature->argumentCount(), "Too few values on stack for loop block. Loop expects ", inlineSignature->argumentCount(), ", but only ", m_expressionStack.size(), " were present. Loop has inlineSignature: ", inlineSignature->toString()); unsigned offset = m_expressionStack.size() - inlineSignature->argumentCount(); @@ -3110,7 +3135,7 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE) case If: { BlockSignature inlineSignature; TypedExpression condition; - WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get if's signature"); + WASM_PARSER_FAIL_IF(!parseBlockSignatureAndNotifySIMDUseIfNeeded(inlineSignature), "can't get if's signature"); WASM_TRY_POP_EXPRESSION_STACK_INTO(condition, "if condition"); WASM_VALIDATOR_FAIL_IF(!condition.type().isI32(), "if condition must be i32, got ", condition.type()); @@ -3146,7 +3171,7 @@ FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE) case Try: { BlockSignature inlineSignature; - WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get try's signature"); + WASM_PARSER_FAIL_IF(!parseBlockSignatureAndNotifySIMDUseIfNeeded(inlineSignature), "can't get try's signature"); WASM_VALIDATOR_FAIL_IF(m_expressionStack.size() < inlineSignature->argumentCount(), "Too few arguments on stack for try block. Try expects ", inlineSignature->argumentCount(), ", but only ", m_expressionStack.size(), " were present. Try block has signature: ", inlineSignature->toString()); unsigned offset = m_expressionStack.size() - inlineSignature->argumentCount(); @@ -3555,7 +3580,7 @@ auto FunctionParser::parseUnreachableExpression() -> PartialResult case Block: { m_unreachableBlocks++; BlockSignature unused; - WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, unused), "can't get inline type for ", m_currentOpcode, " in unreachable context"); + WASM_PARSER_FAIL_IF(!parseBlockSignatureAndNotifySIMDUseIfNeeded(unused), "can't get inline type for ", m_currentOpcode, " in unreachable context"); return { }; } diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp index 359256c3dcc..88137a48c47 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp @@ -200,6 +200,7 @@ class IPIntGenerator { // SIMD + bool usesSIMD() { return m_usesSIMD; } void notifyFunctionUsesSIMD() { ASSERT(Options::useWebAssemblySIMD()); m_usesSIMD = true; } PartialResult WARN_UNUSED_RETURN addSIMDLoad(ExpressionType, uint32_t, ExpressionType&); PartialResult WARN_UNUSED_RETURN addSIMDStore(ExpressionType, ExpressionType, uint32_t); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h index acb6938e743..e446b7e54f0 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h @@ -46,8 +46,9 @@ struct PatchpointExceptionHandleBase { #if ENABLE(WEBASSEMBLY_OMGJIT) struct PatchpointExceptionHandle : public PatchpointExceptionHandleBase { - PatchpointExceptionHandle(std::optional hasExceptionHandlers) + PatchpointExceptionHandle(std::optional hasExceptionHandlers, unsigned callSiteIndex) : m_hasExceptionHandlers(hasExceptionHandlers) + , m_callSiteIndex(callSiteIndex) { } PatchpointExceptionHandle(std::optional hasExceptionHandlers, unsigned callSiteIndex, unsigned numLiveValues) @@ -59,26 +60,26 @@ struct PatchpointExceptionHandle : public PatchpointExceptionHandleBase { template void generate(CCallHelpers& jit, const B3::StackmapGenerationParams& params, Generator* generator) const { - if (m_callSiteIndex == s_invalidCallSiteIndex) { - if (!m_hasExceptionHandlers || m_hasExceptionHandlers.value()) + JIT_COMMENT(jit, "Store call site index ", m_callSiteIndex, " at throw or call site."); jit.store32(CCallHelpers::TrustedImm32(m_callSiteIndex), CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); + + if (m_hasExceptionHandlers && !*m_hasExceptionHandlers) + return; + if (!m_numLiveValues) return; - } - StackMap values(m_numLiveValues); - unsigned paramsOffset = params.size() - m_numLiveValues; - unsigned childrenOffset = params.value()->numChildren() - m_numLiveValues; - for (unsigned i = 0; i < m_numLiveValues; ++i) + StackMap values(*m_numLiveValues); + unsigned paramsOffset = params.size() - *m_numLiveValues; + unsigned childrenOffset = params.value()->numChildren() - *m_numLiveValues; + for (unsigned i = 0; i < *m_numLiveValues; ++i) values[i] = OSREntryValue(params[i + paramsOffset], params.value()->child(i + childrenOffset)->type()); generator->addStackMap(m_callSiteIndex, WTFMove(values)); - JIT_COMMENT(jit, "Store call site index ", m_callSiteIndex, " at throw or call site."); - jit.store32(CCallHelpers::TrustedImm32(m_callSiteIndex), CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); } std::optional m_hasExceptionHandlers; unsigned m_callSiteIndex { s_invalidCallSiteIndex }; - unsigned m_numLiveValues; + std::optional m_numLiveValues { }; }; #else diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp index 67e72cc370b..b162ad2a2e5 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp @@ -257,6 +257,7 @@ class LLIntGenerator : public BytecodeGeneratorBase { } void didPopValueFromStack(ExpressionType, String) { --m_stackSize; } + bool usesSIMD() { return m_usesSIMD; } void notifyFunctionUsesSIMD() { ASSERT(Options::useWebAssemblySIMD()); m_usesSIMD = true; } PartialResult WARN_UNUSED_RETURN addDrop(ExpressionType); diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp index bbb17c66731..1da200ef190 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp @@ -114,7 +114,7 @@ void OMGPlan::work(CompilationEffort) Vector unlinkedCalls; CompilationContext context; - auto parseAndCompileResult = parseAndCompileB3(context, callee.get(), function, signature, unlinkedCalls, m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex, m_hasExceptionHandlers, UINT32_MAX); + auto parseAndCompileResult = parseAndCompileB3(context, callee.get(), function, signature, unlinkedCalls, m_calleeGroup.get(), m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex, m_hasExceptionHandlers, UINT32_MAX); if (UNLIKELY(!parseAndCompileResult)) { Locker locker { m_lock }; diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp index b094c34a497..dafccb9442d 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp @@ -107,7 +107,7 @@ void OSREntryPlan::work(CompilationEffort) Vector unlinkedCalls; CompilationContext context; - auto parseAndCompileResult = parseAndCompileB3(context, callee.get(), function, signature, unlinkedCalls, m_moduleInformation.get(), m_mode, targetCompilationMode, m_functionIndex, m_hasExceptionHandlers, m_loopIndex); + auto parseAndCompileResult = parseAndCompileB3(context, callee.get(), function, signature, unlinkedCalls, m_calleeGroup.get(), m_moduleInformation.get(), m_mode, targetCompilationMode, m_functionIndex, m_hasExceptionHandlers, m_loopIndex); if (UNLIKELY(!parseAndCompileResult)) { Locker locker { m_lock }; diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmTypeDefinition.h b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmTypeDefinition.h index c5b8888b0c6..dc78ea5f26f 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmTypeDefinition.h +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/wasm/WasmTypeDefinition.h @@ -355,6 +355,15 @@ class FunctionSignature { return n; } + bool hasReturnVector() const + { + for (size_t i = 0; i < returnCount(); ++i) { + if (returnType(i).isV128()) + return true; + } + return false; + } + bool operator==(const FunctionSignature& other) const { // Function signatures are unique because it is just an view class over TypeDefinition and diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrInterpreter.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrInterpreter.cpp index c7a83860464..93a1e767bde 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrInterpreter.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrInterpreter.cpp @@ -954,6 +954,21 @@ class Interpreter { ASSERT(term.type == ByteTerm::Type::BackReference); BackTrackInfoBackReference* backTrack = reinterpret_cast(context->frame + term.frameLocation); + // Initialize backtracking info first before we check for possible null matches. + switch (term.atom.quantityType) { + case QuantifierType::NonGreedy: + backTrack->matchAmount = 0; + FALLTHROUGH; + + case QuantifierType::FixedCount: + backTrack->begin = input.getPos(); + break; + + case QuantifierType::Greedy: + backTrack->matchAmount = 0; + break; + } + unsigned subpatternId; if (auto duplicateNamedGroupId = term.duplicateNamedGroupId()) { @@ -984,7 +999,6 @@ class Interpreter { switch (term.atom.quantityType) { case QuantifierType::FixedCount: { - backTrack->begin = input.getPos(); for (unsigned matchAmount = 0; matchAmount < term.atom.quantityMaxCount; ++matchAmount) { if (!tryConsumeBackReference(matchBegin, matchEnd, term)) { input.setPos(backTrack->begin); @@ -999,13 +1013,10 @@ class Interpreter { while ((matchAmount < term.atom.quantityMaxCount) && tryConsumeBackReference(matchBegin, matchEnd, term)) ++matchAmount; backTrack->matchAmount = matchAmount; - backTrack->backReferenceSize = matchEnd - matchBegin; return true; } case QuantifierType::NonGreedy: - backTrack->begin = input.getPos(); - backTrack->matchAmount = 0; return true; } @@ -1018,8 +1029,19 @@ class Interpreter { ASSERT(term.type == ByteTerm::Type::BackReference); BackTrackInfoBackReference* backTrack = reinterpret_cast(context->frame + term.frameLocation); - unsigned matchBegin = output[(term.subpatternId() << 1)]; - unsigned matchEnd = output[(term.subpatternId() << 1) + 1]; + unsigned subpatternId; + + if (auto duplicateNamedGroupId = term.duplicateNamedGroupId()) { + subpatternId = output[pattern->offsetForDuplicateNamedGroupId(duplicateNamedGroupId)]; + if (subpatternId < 1) { + // If we don't have a subpattern that matched, then the string to match is empty. + return false; + } + } else + subpatternId = term.subpatternId(); + + unsigned matchBegin = output[(subpatternId << 1)]; + unsigned matchEnd = output[(subpatternId << 1) + 1]; if (matchBegin == offsetNoMatch) return false; diff --git a/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrPattern.cpp b/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrPattern.cpp index 0e12e4d27a8..00613785b73 100644 --- a/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrPattern.cpp +++ b/modules/javafx.web/src/main/native/Source/JavaScriptCore/yarr/YarrPattern.cpp @@ -228,8 +228,9 @@ class CharacterClassConstructor { for (auto* set = canonicalCharacterSetInfo(info->value, m_canonicalMode); (ch = *set); ++set) addChar(ch); } else { - addChar(ch); - addChar(getCanonicalPair(info, ch)); + char32_t canonicalChar = getCanonicalPair(info, ch); + addChar(std::min(ch, canonicalChar)); + addChar(std::max(ch, canonicalChar)); } } @@ -777,6 +778,7 @@ class CharacterClassConstructor { if (ch > chunkHi) break; + ASSERT(ch >= chunkLo); lhsChunkBitSet.set(ch - chunkLo); } @@ -788,8 +790,10 @@ class CharacterClassConstructor { auto begin = std::max(chunkLo, range.begin); auto end = std::min(range.end, chunkHi); - for (char32_t ch = begin; ch <= end; ch++) + for (char32_t ch = begin; ch <= end; ch++) { + ASSERT(ch >= chunkLo); lhsChunkBitSet.set(ch - chunkLo); + } if (range.end > chunkHi) break; @@ -800,6 +804,7 @@ class CharacterClassConstructor { if (ch > chunkHi) break; + ASSERT(ch >= chunkLo); rhsChunkBitSet.set(ch - chunkLo); } @@ -811,8 +816,10 @@ class CharacterClassConstructor { auto begin = std::max(chunkLo, range.begin); auto end = std::min(range.end, chunkHi); - for (char32_t ch = begin; ch <= end; ch++) + for (char32_t ch = begin; ch <= end; ch++) { + ASSERT(ch >= chunkLo); rhsChunkBitSet.set(ch - chunkLo); + } if (range.end > chunkHi) break; diff --git a/modules/javafx.web/src/main/native/Source/WTF/wtf/Deque.h b/modules/javafx.web/src/main/native/Source/WTF/wtf/Deque.h index 681563774cd..2bd3d83edd6 100644 --- a/modules/javafx.web/src/main/native/Source/WTF/wtf/Deque.h +++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/Deque.h @@ -116,6 +116,10 @@ template class Deque final { template iterator findIf(const Predicate&); template const_iterator findIf(const Predicate&) const; + template bool containsIf(const Predicate& predicate) const + { + return findIf(predicate) != end(); + } private: friend class DequeIteratorBase; diff --git a/modules/javafx.web/src/main/native/Source/WTF/wtf/UniStdExtras.h b/modules/javafx.web/src/main/native/Source/WTF/wtf/UniStdExtras.h index b79dfe7dcfe..7e93dc3dc10 100644 --- a/modules/javafx.web/src/main/native/Source/WTF/wtf/UniStdExtras.h +++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/UniStdExtras.h @@ -32,6 +32,7 @@ namespace WTF { WTF_EXPORT_PRIVATE bool setCloseOnExec(int fileDescriptor); +WTF_EXPORT_PRIVATE bool unsetCloseOnExec(int fileDescriptor); WTF_EXPORT_PRIVATE int dupCloseOnExec(int fileDescriptor); inline int closeWithRetry(int fileDescriptor) @@ -57,6 +58,7 @@ WTF_EXPORT_PRIVATE bool setNonBlock(int fileDescriptor); using WTF::closeWithRetry; using WTF::dupCloseOnExec; using WTF::setCloseOnExec; +using WTF::unsetCloseOnExec; using WTF::setNonBlock; #endif // UniStdExtras_h diff --git a/modules/javafx.web/src/main/native/Source/WTF/wtf/unix/UniStdExtrasUnix.cpp b/modules/javafx.web/src/main/native/Source/WTF/wtf/unix/UniStdExtrasUnix.cpp index 115f770ebba..b9a63fbc76a 100644 --- a/modules/javafx.web/src/main/native/Source/WTF/wtf/unix/UniStdExtrasUnix.cpp +++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/unix/UniStdExtrasUnix.cpp @@ -42,6 +42,18 @@ bool setCloseOnExec(int fileDescriptor) return returnValue != -1; } +bool unsetCloseOnExec(int fileDescriptor) +{ + int returnValue = -1; + do { + int flags = fcntl(fileDescriptor, F_GETFD); + if (flags == -1) + returnValue = fcntl(fileDescriptor, F_SETFD, flags & ~FD_CLOEXEC); + } while (returnValue == -1 && errno == EINTR); + + return returnValue != -1; +} + int dupCloseOnExec(int fileDescriptor) { int duplicatedFileDescriptor = -1; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp index e10c5d255d4..56b2dabbaab 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp @@ -280,6 +280,9 @@ void FetchBodyOwner::blobLoadingSucceeded() } m_body->loadingSucceeded(contentType()); + if (!m_blobLoader) + return; + finishBlobLoading(); } @@ -320,6 +323,12 @@ void FetchBodyOwner::BlobLoader::didFail(const ResourceError&) owner.blobLoadingFailed(); } +void FetchBodyOwner::BlobLoader::didSucceed(const NetworkLoadMetrics&) +{ + Ref protectedOwner = Ref { owner }; + protectedOwner->blobLoadingSucceeded(); +} + ExceptionOr> FetchBodyOwner::readableStream(JSC::JSGlobalObject& state) { if (isBodyNullOrOpaque()) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.h index bb7678ae011..d4dede473e9 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/fetch/FetchBodyOwner.h @@ -120,7 +120,7 @@ class FetchBodyOwner : public RefCounted, public ActiveDOMObject void didReceiveResponse(const ResourceResponse&) final; void didReceiveData(const SharedBuffer& buffer) final { owner.blobChunk(buffer); } void didFail(const ResourceError&) final; - void didSucceed(const NetworkLoadMetrics&) final { owner.blobLoadingSucceeded(); } + void didSucceed(const NetworkLoadMetrics&) final; FetchBodyOwner& owner; std::unique_ptr loader; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp index 47c0c040947..5b708a0ad83 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp @@ -236,18 +236,19 @@ static void processRemoteTracks(RTCRtpTransceiver& transceiver, PeerConnectionBa transceiver.setFiredDirection(state.firedDirection); } -void PeerConnectionBackend::setLocalDescriptionSucceeded(std::optional&& descriptionStates, std::optional&& transceiverStates, std::unique_ptr&& sctpBackend) +void PeerConnectionBackend::setLocalDescriptionSucceeded(std::optional&& descriptionStates, std::optional&& transceiverStates, std::unique_ptr&& sctpBackend, std::optional maxMessageSize) { ASSERT(isMainThread()); ALWAYS_LOG(LOGIDENTIFIER); - + if (transceiverStates) + DEBUG_LOG(LOGIDENTIFIER, "Transceiver states: ", *transceiverStates); ASSERT(m_setDescriptionCallback); - m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend)]() mutable { + m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend), maxMessageSize]() mutable { if (m_peerConnection.isClosed()) return; m_peerConnection.updateTransceiversAfterSuccessfulLocalDescription(); - m_peerConnection.updateSctpBackend(WTFMove(sctpBackend)); + m_peerConnection.updateSctpBackend(WTFMove(sctpBackend), maxMessageSize); if (descriptionStates) { m_peerConnection.updateDescriptions(WTFMove(*descriptionStates)); @@ -321,13 +322,15 @@ void PeerConnectionBackend::setRemoteDescription(const RTCSessionDescription& se doSetRemoteDescription(sessionDescription); } -void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional&& descriptionStates, std::optional&& transceiverStates, std::unique_ptr&& sctpBackend) +void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional&& descriptionStates, std::optional&& transceiverStates, std::unique_ptr&& sctpBackend, std::optional maxMessageSize) { ASSERT(isMainThread()); ALWAYS_LOG(LOGIDENTIFIER, "Set remote description succeeded"); + if (transceiverStates) + DEBUG_LOG(LOGIDENTIFIER, "Transceiver states: ", *transceiverStates); ASSERT(m_setDescriptionCallback); - m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend), events = WTFMove(m_pendingTrackEvents)]() mutable { + m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend), maxMessageSize, events = WTFMove(m_pendingTrackEvents)]() mutable { if (m_peerConnection.isClosed()) return; @@ -344,7 +347,7 @@ void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional toJSONObject(const PeerConnectionBackend::TransceiverState& transceiverState) +{ + auto object = JSON::Object::create(); + object->setString("mid"_s, transceiverState.mid); + + auto receiverStreams = JSON::Array::create(); + for (auto receiverStream : transceiverState.receiverStreams) + receiverStreams->pushString(receiverStream->id()); + object->setArray("receiverStreams"_s, WTFMove(receiverStreams)); + + if (auto firedDirection = transceiverState.firedDirection) + object->setString("firedDirection"_s, convertEnumerationToString(*firedDirection)); + + return object; +} + +static Ref toJSONArray(const PeerConnectionBackend::TransceiverStates& transceiverStates) +{ + auto array = JSON::Array::create(); + for (auto transceiverState : transceiverStates) + array->pushObject(toJSONObject(transceiverState)); + + return array; +} + +static String toJSONString(const PeerConnectionBackend::TransceiverState& transceiverState) +{ + return toJSONObject(transceiverState)->toJSONString(); +} + +static String toJSONString(const PeerConnectionBackend::TransceiverStates& transceiverStates) +{ + return toJSONArray(transceiverStates)->toJSONString(); +} + } // namespace WebCore +namespace WTF { + +String LogArgument::toString(const WebCore::PeerConnectionBackend::TransceiverState& transceiverState) +{ + return toJSONString(transceiverState); +} + +String LogArgument::toString(const WebCore::PeerConnectionBackend::TransceiverStates& transceiverStates) +{ + return toJSONString(transceiverStates); +} + +} + #endif // ENABLE(WEB_RTC) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h index e9604852a54..a43d0112097 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h @@ -220,10 +220,10 @@ class PeerConnectionBackend void createAnswerSucceeded(String&&); void createAnswerFailed(Exception&&); - void setLocalDescriptionSucceeded(std::optional&&, std::optional&&, std::unique_ptr&&); + void setLocalDescriptionSucceeded(std::optional&&, std::optional&&, std::unique_ptr&&, std::optional); void setLocalDescriptionFailed(Exception&&); - void setRemoteDescriptionSucceeded(std::optional&&, std::optional&&, std::unique_ptr&&); + void setRemoteDescriptionSucceeded(std::optional&&, std::optional&&, std::unique_ptr&&, std::optional); void setRemoteDescriptionFailed(Exception&&); void validateSDP(const String&) const; @@ -279,7 +279,23 @@ inline PeerConnectionBackend::DescriptionStates PeerConnectionBackend::Descripti WTFMove(pendingRemoteDescriptionSdp).isolatedCopy() }; } - } // namespace WebCore +namespace WTF { + +template +struct LogArgument; + +template <> +struct LogArgument { + static String toString(const WebCore::PeerConnectionBackend::TransceiverState&); +}; + +template <> +struct LogArgument { + static String toString(const WebCore::PeerConnectionBackend::TransceiverStates&); +}; + +} + #endif // ENABLE(WEB_RTC) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index c9b5d4060f4..2ddcdf1c015 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -1063,16 +1063,14 @@ void RTCPeerConnection::updateTransceiversAfterSuccessfulRemoteDescription() updateTransceiverTransports(); } -void RTCPeerConnection::updateSctpBackend(std::unique_ptr&& sctpBackend) +void RTCPeerConnection::updateSctpBackend(std::unique_ptr&& sctpBackend, std::optional maxMessageSize) { if (!sctpBackend) { m_sctpTransport = nullptr; return; } - if (m_sctpTransport && m_sctpTransport->backend() == *sctpBackend) { - m_sctpTransport->update(); - return; - } + + if (!m_sctpTransport || m_sctpTransport->backend() != *sctpBackend) { RefPtr context = scriptExecutionContext(); if (!context) return; @@ -1081,6 +1079,9 @@ void RTCPeerConnection::updateSctpBackend(std::unique_ptrupdateMaxMessageSize(maxMessageSize); } #if !RELEASE_LOG_DISABLED diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 8992c18d2d9..cbd9c11d4a5 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -191,7 +191,7 @@ class RTCPeerConnection final void updateDescriptions(PeerConnectionBackend::DescriptionStates&&); void updateTransceiversAfterSuccessfulLocalDescription(); void updateTransceiversAfterSuccessfulRemoteDescription(); - void updateSctpBackend(std::unique_ptr&&); + void updateSctpBackend(std::unique_ptr&&, std::optional); void processIceTransportStateChange(RTCIceTransport&); void processIceTransportChanges(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.cpp index bf7745a1c60..eb7f7590af9 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.cpp @@ -75,8 +75,7 @@ void RTCSctpTransport::onStateChanged(RTCSctpTransportState state, std::optional if (m_state == RTCSctpTransportState::Closed) return; - if (maxMessageSize) - m_maxMessageSize = *maxMessageSize; + m_maxMessageSize = maxMessageSize; if (maxChannels) m_maxChannels = *maxChannels; @@ -87,6 +86,11 @@ void RTCSctpTransport::onStateChanged(RTCSctpTransportState state, std::optional }); } +void RTCSctpTransport::updateMaxMessageSize(std::optional maxMessageSize) +{ + m_maxMessageSize = maxMessageSize; +} + } // namespace WebCore #endif // ENABLE(WEB_RTC) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.h index 76987a83abf..4a8ad6bde51 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCSctpTransport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Apple Inc. All rights reserved. + * Copyright (C) 2021-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,10 +46,10 @@ class RTCSctpTransport final : public RefCounted, public Activ RTCDtlsTransport& transport() { return m_transport.get(); } RTCSctpTransportState state() const { return m_state; } - double maxMessageSize() const { return m_maxMessageSize; } + double maxMessageSize() const { return m_maxMessageSize.value_or(std::numeric_limits::infinity()); } std::optional maxChannels() const { return m_maxChannels; } - void update() { } + void updateMaxMessageSize(std::optional); const RTCSctpTransportBackend& backend() const { return m_backend.get(); } @@ -73,7 +73,7 @@ class RTCSctpTransport final : public RefCounted, public Activ UniqueRef m_backend; Ref m_transport; RTCSctpTransportState m_state { RTCSctpTransportState::Connecting }; - double m_maxMessageSize { std::numeric_limits::max() }; + std::optional m_maxMessageSize; std::optional m_maxChannels; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCStatsReport.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCStatsReport.h index 58f0120f9ca..2c8bc5bd0b3 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCStatsReport.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/RTCStatsReport.h @@ -61,7 +61,7 @@ class RTCStatsReport : public RefCounted { Certificate, }; struct Stats { - double timestamp; + double timestamp { 0 }; Type type; String id; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp index 1b68dfd1859..b8a43717130 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp @@ -656,6 +656,7 @@ class SctpTransportState { public: explicit SctpTransportState(rtc::scoped_refptr&&); std::unique_ptr createBackend(); + std::optional maxMessageSize() const; private: rtc::scoped_refptr m_transport; @@ -676,6 +677,11 @@ std::unique_ptr SctpTransportState::createBackend return makeUnique(WTFMove(m_transport), m_information.dtls_transport()); } +std::optional SctpTransportState::maxMessageSize() const +{ + return m_information.MaxMessageSize() ? std::make_optional(*m_information.MaxMessageSize()) : std::nullopt; +} + struct LibWebRTCMediaEndpointTransceiverState { String mid; Vector receiverStreamIds; @@ -733,7 +739,7 @@ void LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded() }); return { WTFMove(state.mid), WTFMove(streams), state.firedDirection }; }); - protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded(WTFMove(descriptions), WTFMove(transceiverStates), sctpState.createBackend()); + protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded(WTFMove(descriptions), WTFMove(transceiverStates), sctpState.createBackend(), sctpState.maxMessageSize()); }); } @@ -760,7 +766,7 @@ void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded() }); return { WTFMove(state.mid), WTFMove(streams), state.firedDirection }; }); - protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded(WTFMove(descriptions), WTFMove(transceiverStates), sctpState.createBackend()); + protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded(WTFMove(descriptions), WTFMove(transceiverStates), sctpState.createBackend(), sctpState.maxMessageSize()); }); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.cpp index 993d808b166..939d8d0a1c7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.cpp @@ -34,7 +34,7 @@ namespace WebCore { -MainThreadPermissionObserver::MainThreadPermissionObserver(ThreadSafeWeakPtr&& permissionStatus, ScriptExecutionContextIdentifier contextIdentifier, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, SingleThreadWeakPtr&& page, ClientOrigin&& origin) +MainThreadPermissionObserver::MainThreadPermissionObserver(ThreadSafeWeakPtr&& permissionStatus, ScriptExecutionContextIdentifier contextIdentifier, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, WeakPtr&& page, ClientOrigin&& origin) : m_permissionStatus(WTFMove(permissionStatus)) , m_contextIdentifier(contextIdentifier) , m_state(state) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.h index 38cc5d5dcd7..4cf44e17d1e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/MainThreadPermissionObserver.h @@ -42,7 +42,7 @@ class MainThreadPermissionObserver final : public PermissionObserver { WTF_MAKE_NONCOPYABLE(MainThreadPermissionObserver); WTF_MAKE_FAST_ALLOCATED; public: - MainThreadPermissionObserver(ThreadSafeWeakPtr&&, ScriptExecutionContextIdentifier, PermissionState, PermissionDescriptor, PermissionQuerySource, SingleThreadWeakPtr&&, ClientOrigin&&); + MainThreadPermissionObserver(ThreadSafeWeakPtr&&, ScriptExecutionContextIdentifier, PermissionState, PermissionDescriptor, PermissionQuerySource, WeakPtr&&, ClientOrigin&&); ~MainThreadPermissionObserver(); private: @@ -52,14 +52,14 @@ class MainThreadPermissionObserver final : public PermissionObserver { const ClientOrigin& origin() const final { return m_origin; } PermissionDescriptor descriptor() const final { return m_descriptor; } PermissionQuerySource source() const final { return m_source; } - const SingleThreadWeakPtr& page() const final { return m_page; } + const WeakPtr& page() const final { return m_page; } ThreadSafeWeakPtr m_permissionStatus; ScriptExecutionContextIdentifier m_contextIdentifier; PermissionState m_state; PermissionDescriptor m_descriptor; PermissionQuerySource m_source; - SingleThreadWeakPtr m_page; + WeakPtr m_page; ClientOrigin m_origin; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionController.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionController.h index 871c920a33f..8aedcc95680 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionController.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionController.h @@ -47,7 +47,7 @@ class PermissionController : public ThreadSafeRefCounted { WEBCORE_EXPORT static void setSharedController(Ref&&); virtual ~PermissionController() = default; - virtual void query(ClientOrigin&&, PermissionDescriptor, const SingleThreadWeakPtr&, PermissionQuerySource, CompletionHandler)>&&) = 0; + virtual void query(ClientOrigin&&, PermissionDescriptor, const WeakPtr&, PermissionQuerySource, CompletionHandler)>&&) = 0; virtual void addObserver(PermissionObserver&) = 0; virtual void removeObserver(PermissionObserver&) = 0; virtual void permissionChanged(PermissionName, const SecurityOriginData&) = 0; @@ -60,7 +60,7 @@ class DummyPermissionController final : public PermissionController { static Ref create() { return adoptRef(*new DummyPermissionController); } private: DummyPermissionController() = default; - void query(ClientOrigin&&, PermissionDescriptor, const SingleThreadWeakPtr&, PermissionQuerySource, CompletionHandler)>&& callback) final { callback({ }); } + void query(ClientOrigin&&, PermissionDescriptor, const WeakPtr&, PermissionQuerySource, CompletionHandler)>&& callback) final { callback({ }); } void addObserver(PermissionObserver&) final { } void removeObserver(PermissionObserver&) final { } void permissionChanged(PermissionName, const SecurityOriginData&) final { } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionObserver.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionObserver.h index ee3898165a5..bf15785854c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionObserver.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionObserver.h @@ -46,7 +46,7 @@ class PermissionObserver : public CanMakeWeakPtr { virtual const ClientOrigin& origin() const = 0; virtual PermissionDescriptor descriptor() const = 0; virtual PermissionQuerySource source() const = 0; - virtual const SingleThreadWeakPtr& page() const = 0; + virtual const WeakPtr& page() const = 0; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.cpp index e6e99ded275..8da274acb18 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.cpp @@ -54,14 +54,14 @@ static HashMap PermissionStatus::create(ScriptExecutionContext& context, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, SingleThreadWeakPtr&& page) +Ref PermissionStatus::create(ScriptExecutionContext& context, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, WeakPtr&& page) { auto status = adoptRef(*new PermissionStatus(context, state, descriptor, source, WTFMove(page))); status->suspendIfNeeded(); return status; } -PermissionStatus::PermissionStatus(ScriptExecutionContext& context, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, SingleThreadWeakPtr&& page) +PermissionStatus::PermissionStatus(ScriptExecutionContext& context, PermissionState state, PermissionDescriptor descriptor, PermissionQuerySource source, WeakPtr&& page) : ActiveDOMObject(&context) , m_state(state) , m_descriptor(descriptor) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.h index 11d9197eb65..dac934c8b72 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/permissions/PermissionStatus.h @@ -42,7 +42,7 @@ class ScriptExecutionContext; class PermissionStatus final : public ActiveDOMObject, public ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr, public EventTarget { WTF_MAKE_ISO_ALLOCATED(PermissionStatus); public: - static Ref create(ScriptExecutionContext&, PermissionState, PermissionDescriptor, PermissionQuerySource, SingleThreadWeakPtr&&); + static Ref create(ScriptExecutionContext&, PermissionState, PermissionDescriptor, PermissionQuerySource, WeakPtr&&); ~PermissionStatus(); PermissionState state() const { return m_state; } @@ -54,7 +54,7 @@ class PermissionStatus final : public ActiveDOMObject, public ThreadSafeRefCount using ThreadSafeRefCountedAndCanMakeThreadSafeWeakPtr::deref; private: - PermissionStatus(ScriptExecutionContext&, PermissionState, PermissionDescriptor, PermissionQuerySource, SingleThreadWeakPtr&&); + PermissionStatus(ScriptExecutionContext&, PermissionState, PermissionDescriptor, PermissionQuerySource, WeakPtr&&); // ActiveDOMObject const char* activeDOMObjectName() const final; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.cpp index ffcd79b0396..fd26cb4318e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.cpp @@ -144,6 +144,19 @@ AudioBuffer::AudioBuffer(AudioBus& bus) m_channelWrappers = FixedVector { m_channels.size() }; } +// FIXME: We don't currently implement "acquire the content" [1] and +// AudioBuffer::getChannelData() correctly. As a result, the audio thread +// may be reading an array buffer that the JS can detach. To guard against +// this, we mark the array buffers as non-detachable as soon as their content +// has been acquired. +// [1] https://www.w3.org/TR/webaudio/#acquire-the-content +void AudioBuffer::markBuffersAsNonDetachable() +{ + Locker locker { m_channelsLock }; + for (auto& channel : m_channels) + channel->setDetachable(false); +} + void AudioBuffer::invalidate() { releaseMemory(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.h index ce0246ced77..cedd79a3f8a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBuffer.h @@ -59,6 +59,8 @@ class AudioBuffer : public RefCounted { size_t length() const { return hasDetachedChannelBuffer() ? 0 : m_originalLength; } double duration() const { return length() / static_cast(sampleRate()); } + void markBuffersAsNonDetachable(); + // Channel data access unsigned numberOfChannels() const { return m_channels.size(); } ExceptionOr getChannelData(JSDOMGlobalObject&, unsigned channelIndex); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp index 66e716a38f8..12b599beda7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp @@ -328,9 +328,16 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination virtualReadIndex = readIndex; } else if (!pitchRate) { unsigned readIndex = static_cast(virtualReadIndex); + int deltaFrames = static_cast(virtualDeltaFrames); + maxFrame = static_cast(virtualMaxFrame); + + if (readIndex >= maxFrame) + readIndex -= deltaFrames; for (unsigned i = 0; i < numberOfChannels; ++i) std::fill_n(destinationChannels[i] + writeIndex, framesToProcess, sourceChannels[i][readIndex]); + + virtualReadIndex = readIndex; } else if (reverse) { unsigned maxFrame = static_cast(virtualMaxFrame); unsigned minFrame = static_cast(floorf(virtualMinFrame)); @@ -343,6 +350,12 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination if (readIndex2 >= maxFrame) readIndex2 = m_isLooping ? minFrame : readIndex; + // Final sanity check on buffer access. + // FIXME: as an optimization, try to get rid of this inner-loop check and + // put assertions and guards before the loop. + if (readIndex >= bufferLength || readIndex2 >= bufferLength) + break; + // Linear interpolation. for (unsigned i = 0; i < numberOfChannels; ++i) { float* destination = destinationChannels[i]; @@ -409,6 +422,15 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* bus, unsigned destination return true; } +void AudioBufferSourceNode::acquireBufferContent() +{ + ASSERT(isMainThread()); + + // FIXME: We should implement https://www.w3.org/TR/webaudio/#acquire-the-content. + if (m_buffer) + m_buffer->markBuffersAsNonDetachable(); +} + ExceptionOr AudioBufferSourceNode::setBufferForBindings(RefPtr&& buffer) { ASSERT(isMainThread()); @@ -446,6 +468,9 @@ ExceptionOr AudioBufferSourceNode::setBufferForBindings(RefPtr AudioBufferSourceNode::startPlaying(double when, double grainO adjustGrainParameters(); + acquireBufferContent(); m_playbackState = SCHEDULED_STATE; return { }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h index 79573a03d40..0561402748c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h @@ -85,6 +85,8 @@ class AudioBufferSourceNode final : public AudioScheduledSourceNode { private: AudioBufferSourceNode(BaseAudioContext&); + void acquireBufferContent() WTF_REQUIRES_LOCK(m_processLock); + double tailTime() const final { return 0; } double latencyTime() const final { return 0; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp index 628ccb66017..ce78c1b8957 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioDestinationNode.cpp @@ -87,8 +87,10 @@ void AudioDestinationNode::renderQuantum(AudioBus* destinationBus, size_t number context().handlePreRenderTasks(outputPosition); RefPtr workletGlobalScope; - if (RefPtr audioWorkletProxy = context().audioWorklet().proxy()) - workletGlobalScope = audioWorkletProxy->workletThread().globalScope(); + if (RefPtr audioWorkletProxy = context().audioWorklet().proxy()) { + if (Ref workletThread = audioWorkletProxy->workletThread(); workletThread->thread() == &Thread::current()) + workletGlobalScope = workletThread->globalScope(); + } if (workletGlobalScope) workletGlobalScope->handlePreRenderTasks(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.cpp index 9588bdc6bfa..f7e6848ef53 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.cpp @@ -578,6 +578,11 @@ void AudioNode::incrementConnectionCount() // In this case, we need to re-enable. enableOutputsIfNecessary(); + { + Locker locker { context().graphLock() }; + unmarkNodeForDeletionIfNecessary(); + } + #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "%p: %d: AudioNode::incrementConnectionCount() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); #endif @@ -640,10 +645,27 @@ void AudioNode::markNodeForDeletionIfNecessary() m_isMarkedForDeletion = true; } +void AudioNode::unmarkNodeForDeletionIfNecessary() +{ + ASSERT(context().isGraphOwner()); + if (!m_isMarkedForDeletion) + return; + if (!m_connectionRefCount && !m_normalRefCount) + return; + + m_isMarkedForDeletion = false; + context().unmarkForDeletion(*this); +} + void AudioNode::ref() { ++m_normalRefCount; + { + Locker locker { context().graphLock() }; + const_cast(this)->unmarkNodeForDeletionIfNecessary(); + } + #if DEBUG_AUDIONODE_REFERENCES fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); #endif diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.h index 6119988cc32..3c9efc17ef6 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioNode.h @@ -206,6 +206,7 @@ class AudioNode void addOutput(unsigned numberOfChannels); void markNodeForDeletionIfNecessary(); + void unmarkNodeForDeletionIfNecessary(); void derefWithLock(); struct DefaultAudioNodeOptions { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp index fcc4edcc7e5..bf1cb86c072 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletGlobalScope.cpp @@ -188,9 +188,8 @@ AudioWorkletThread& AudioWorkletGlobalScope::thread() const void AudioWorkletGlobalScope::handlePreRenderTasks() { // This makes sure that we only drain the MicroTask queue after each render quantum. - // It is only safe to grab the lock if we are on the context thread. We might get called on - // another thread if audio rendering started before the audio worklet got started. - if (isContextThread()) + // It is only safe to grab the lock if we are on the context thread. + RELEASE_ASSERT(isContextThread()); m_delayMicrotaskDrainingDuringRendering = script()->vm().drainMicrotaskDelayScope(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletMessagingProxy.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletMessagingProxy.cpp index f206a9022e1..dd7c154f6d7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletMessagingProxy.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/AudioWorkletMessagingProxy.cpp @@ -60,6 +60,7 @@ static WorkletParameters generateWorkletParameters(AudioWorklet& worklet) document->settingsValues(), document->referrerPolicy(), worklet.audioContext() ? !worklet.audioContext()->isOfflineContext() : false, + document->advancedPrivacyProtections(), document->noiseInjectionHashSalt() }; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp index 94034b17c59..89cd3db5344 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp @@ -708,6 +708,15 @@ void BaseAudioContext::markForDeletion(AudioNode& node) removeAutomaticPullNode(node); } +void BaseAudioContext::unmarkForDeletion(AudioNode& node) +{ + ASSERT(isGraphOwner()); + ASSERT_WITH_MESSAGE(node.nodeType() != AudioNode::NodeTypeDestination, "Destination node is owned by the BaseAudioContext"); + + m_nodesToDelete.removeFirst(&node); + m_nodesMarkedForDeletion.removeFirst(&node); +} + void BaseAudioContext::scheduleNodeDeletion() { bool isGood = m_isInitialized && isGraphOwner(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.h b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.h index b77ec48f4c1..eb614afc6da 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webaudio/BaseAudioContext.h @@ -161,6 +161,10 @@ class BaseAudioContext // We schedule deletion of all marked nodes at the end of each realtime render quantum. void markForDeletion(AudioNode&); void deleteMarkedNodes(); + // In some cases, a node marked for deletion may get ref'd. We need to make sure we no + // longer mark the node for deletion or it may get deleted while someone is holding a + // Ref / RefPtr to it. + void unmarkForDeletion(AudioNode&); void addTailProcessingNode(AudioNode&); void removeTailProcessingNode(AudioNode&); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webcodecs/WebCodecsVideoFrameAlgorithms.cpp b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webcodecs/WebCodecsVideoFrameAlgorithms.cpp index ea510f13838..58df88dd587 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Modules/webcodecs/WebCodecsVideoFrameAlgorithms.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/Modules/webcodecs/WebCodecsVideoFrameAlgorithms.cpp @@ -111,6 +111,8 @@ ExceptionOr parseVisibleRect(const DOMRectInit& defaultRect, const { auto sourceRect = defaultRect; if (overrideRect) { + if (!std::isfinite(overrideRect->width) || !std::isfinite(overrideRect->height) || !std::isfinite(overrideRect->x) || !std::isfinite(overrideRect->y)) + return Exception { ExceptionCode::TypeError, "overrideRect is not valid"_s }; if (overrideRect->width <= 0 || overrideRect->height <= 0 || overrideRect->x < 0 || overrideRect->y < 0) return Exception { ExceptionCode::TypeError, "overrideRect is not valid"_s }; if (overrideRect->x + overrideRect->width > codedWidth) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecLatin1.cpp b/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecLatin1.cpp index 5c5d845e7a8..f01cd286a57 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecLatin1.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecLatin1.cpp @@ -97,11 +97,16 @@ void TextCodecLatin1::registerCodecs(TextCodecRegistrar registrar) }); } -String TextCodecLatin1::decode(const char* bytes, size_t length, bool, bool, bool&) +String TextCodecLatin1::decode(const char* bytes, size_t length, bool, bool, bool& sawException) { LChar* characters; if (!length) return emptyString(); + if (UNLIKELY(length > std::numeric_limits::max())) { + ASSERT_NOT_REACHED(); + sawException = true; + return emptyString(); + } String result = String::createUninitialized(length, characters); const uint8_t* source = reinterpret_cast(bytes); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecUTF8.cpp b/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecUTF8.cpp index 6b5c85ce374..41d7537b381 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecUTF8.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/PAL/pal/text/TextCodecUTF8.cpp @@ -301,7 +301,12 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool // Each input byte might turn into a character. // That includes all bytes in the partial-sequence buffer because // each byte in an invalid sequence will turn into a replacement character. - StringBuffer buffer(m_partialSequenceSize + length); + size_t bufferSize = length + m_partialSequenceSize; + if (bufferSize > std::numeric_limits::max()) { + sawError = true; + return { }; + } + StringBuffer buffer(bufferSize); const uint8_t* source = reinterpret_cast(bytes); const uint8_t* end = source + length; @@ -383,7 +388,7 @@ String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool return String::adopt(WTFMove(buffer)); upConvertTo16Bit: - StringBuffer buffer16(m_partialSequenceSize + length); + StringBuffer buffer16(bufferSize); UChar* destination16 = buffer16.characters(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/Scripts/SettingsTemplates/InternalSettingsGenerated.h.erb b/modules/javafx.web/src/main/native/Source/WebCore/Scripts/SettingsTemplates/InternalSettingsGenerated.h.erb index 7bed1a22806..ff490b7032b 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/Scripts/SettingsTemplates/InternalSettingsGenerated.h.erb +++ b/modules/javafx.web/src/main/native/Source/WebCore/Scripts/SettingsTemplates/InternalSettingsGenerated.h.erb @@ -49,7 +49,7 @@ public: <%- end -%> private: - SingleThreadWeakPtr m_page; + WeakPtr m_page; <%- for @setting in @allSettingsSet.settings do -%> <%- if @setting.excludeFromInternalSettings == false and @setting.idlType -%> diff --git a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp index 17c6607329b..abbb0e7997c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityListBoxOption.cpp @@ -89,24 +89,20 @@ bool AccessibilityListBoxOption::isSelectedOptionActive() const LayoutRect AccessibilityListBoxOption::elementRect() const { - LayoutRect rect; - if (!m_optionElement) - return rect; - - HTMLSelectElement* listBoxParentNode = listBoxOptionParentNode(); - if (!listBoxParentNode) - return rect; - - RenderElement* listBoxRenderer = listBoxParentNode->renderer(); - if (!listBoxRenderer) - return rect; + auto* optionParent = listBoxOptionParentNode(); + CheckedPtr parentRenderer = optionParent ? dynamicDowncast(optionParent->renderer()) : nullptr; + if (!parentRenderer) + return { }; - LayoutRect parentRect = listBoxRenderer->document().axObjectCache()->getOrCreate(listBoxRenderer)->boundingBoxRect(); + auto* cache = parentRenderer->document().axObjectCache(); + if (RefPtr axObject = cache ? cache->getOrCreate(parentRenderer.get()) : nullptr) { int index = listBoxOptionIndex(); - if (index != -1) - rect = downcast(*listBoxRenderer).itemBoundingBoxRect(parentRect.location(), index); - - return rect; + if (index != -1) { + auto parentRect = axObject->boundingBoxRect(); + return parentRenderer->itemBoundingBoxRect(parentRect.location(), index); + } + } + return { }; } bool AccessibilityListBoxOption::computeAccessibilityIsIgnored() const diff --git a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.cpp b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.cpp index b924d899326..b51fbbd7128 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.cpp @@ -2151,22 +2151,16 @@ void AccessibilityObject::clearChildren() m_childrenInitialized = false; } -AccessibilityObject* AccessibilityObject::anchorElementForNode(Node* node) +AccessibilityObject* AccessibilityObject::anchorElementForNode(Node& node) { - RenderObject* obj = node->renderer(); - if (!obj) - return nullptr; - - RefPtr axObj = obj->document().axObjectCache()->getOrCreate(obj); - Element* anchor = axObj->anchorElement(); - if (!anchor) - return nullptr; - - RenderObject* anchorRenderer = anchor->renderer(); - if (!anchorRenderer) + CheckedPtr renderer = node.renderer(); + if (!renderer) return nullptr; - return anchorRenderer->document().axObjectCache()->getOrCreate(anchorRenderer); + WeakPtr cache = renderer->document().axObjectCache(); + RefPtr axObject = cache ? cache->getOrCreate(renderer.get()) : nullptr; + auto* anchor = axObject ? axObject->anchorElement() : nullptr; + return anchor ? cache->getOrCreate(anchor->renderer()) : nullptr; } AccessibilityObject* AccessibilityObject::headingElementForNode(Node* node) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.h b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.h index 77f17010c49..af14d7e478c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/AccessibilityObject.h @@ -424,7 +424,7 @@ class AccessibilityObject : public AXCoreObject, public CanMakeWeakPtr popoverTargetElement() const { return nullptr; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h index 5a60f3b987d..e2fb789df8c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/atspi/AccessibilityRootAtspi.h @@ -64,7 +64,7 @@ class AccessibilityRootAtspi final : public RefCounted, static GDBusInterfaceVTable s_socketFunctions; static GDBusInterfaceVTable s_componentFunctions; - SingleThreadWeakPtr m_page; + WeakPtr m_page; String m_path; String m_parentUniqueName; String m_parentPath; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp index 6047240d898..3740526b7ae 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/accessibility/isolatedtree/AXIsolatedTree.cpp @@ -393,7 +393,10 @@ Vector AXIsolatedTree::resolveAppends() double counter = 0; Vector resolvedAppends; resolvedAppends.reserveInitialCapacity(m_unresolvedPendingAppends.size()); - for (const auto& unresolvedAppend : m_unresolvedPendingAppends) { + // The process of resolving appends can add more IDs to m_unresolvedPendingAppends as we iterate over it, so + // iterate over an exchanged map instead. Any late-appended IDs will get picked up in the next cycle. + auto unresolvedPendingAppends = std::exchange(m_unresolvedPendingAppends, { }); + for (const auto& unresolvedAppend : unresolvedPendingAppends) { if (m_replacingTree) { ++counter; if (MonotonicTime::now() - lastFeedbackTime > CreationFeedbackInterval) { @@ -408,7 +411,6 @@ Vector AXIsolatedTree::resolveAppends() } } resolvedAppends.shrinkToFit(); - m_unresolvedPendingAppends.clear(); if (m_replacingTree) reportCreationProgress(*cache, 100); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/SerializedScriptValue.cpp b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/SerializedScriptValue.cpp index dc800e75691..ef90dcbff91 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/SerializedScriptValue.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/bindings/js/SerializedScriptValue.cpp @@ -106,6 +106,7 @@ #include #include #include +#include #include #include @@ -944,6 +945,10 @@ class CloneBase { #else ALWAYS_INLINE void appendObjectPoolTag(SerializationTag) { } #endif + bool isSafeToRecurse() + { + return m_stackCheck.isSafeToRecurse(); + } JSGlobalObject* const m_lexicalGlobalObject; bool m_failed; @@ -952,6 +957,7 @@ class CloneBase { #if ASSERT_ENABLED Vector m_objectPoolTags; #endif + StackCheck m_stackCheck; }; #if ENABLE(WEB_CRYPTO) @@ -3650,6 +3656,8 @@ class CloneDeserializer : public CloneBase { template bool readArrayBufferViewImpl(VM& vm, JSValue& arrayBufferView) { + if (!isSafeToRecurse()) + return false; ArrayBufferViewSubtag arrayBufferViewSubtag; if (!readArrayBufferViewSubtag(arrayBufferViewSubtag)) return false; @@ -3729,6 +3737,8 @@ class CloneDeserializer : public CloneBase { bool readArrayBufferView(VM& vm, JSValue& arrayBufferView) { + if (!isSafeToRecurse()) + return false; if (m_majorVersion < 10) return readArrayBufferViewImpl(vm, arrayBufferView); return readArrayBufferViewImpl(vm, arrayBufferView); @@ -4476,7 +4486,8 @@ class CloneDeserializer : public CloneBase { return JSValue(); Vector fingerprints; - fingerprints.reserveInitialCapacity(size); + if (!fingerprints.tryReserveInitialCapacity(size)) + return JSValue(); for (unsigned i = 0; i < size; i++) { CachedStringRef algorithm; if (!readStringData(algorithm)) @@ -4752,6 +4763,8 @@ class CloneDeserializer : public CloneBase { JSValue readTerminal() { + if (!isSafeToRecurse()) + return JSValue(); SerializationTag tag = readTag(); if (!isTypeExposedToGlobalObject(*m_globalObject, tag)) { SERIALIZE_TRACE("FAIL deserialize"); @@ -4878,11 +4891,14 @@ class CloneDeserializer : public CloneBase { return JSValue(); } - if (length && (IntSize(width, height).area() * 4) != length) { + if (length) { + auto area = IntSize(width, height).area() * 4; + if (area.hasOverflowed() || area.value() != length) { SERIALIZE_TRACE("FAIL deserialize"); fail(); return JSValue(); } + } if (!m_isDOMGlobalObject) return jsNull(); @@ -4947,7 +4963,8 @@ class CloneDeserializer : public CloneBase { if (!readStringData(flags)) return JSValue(); auto reFlags = Yarr::parseFlags(flags->string()); - ASSERT(reFlags.has_value()); + if (!reFlags.has_value()) + return JSValue(); VM& vm = m_lexicalGlobalObject->vm(); RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags.value()); return RegExpObject::create(vm, m_globalObject->regExpStructure(), regExp); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/css/ComputedStyleExtractor.cpp b/modules/javafx.web/src/main/native/Source/WebCore/css/ComputedStyleExtractor.cpp index 0b31c0ef412..59be00334b4 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/css/ComputedStyleExtractor.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/css/ComputedStyleExtractor.cpp @@ -369,6 +369,10 @@ static Ref fontSizeAdjustFromStyle(const RenderStyle& style) auto metric = fontSizeAdjust.metric; auto value = fontSizeAdjust.isFromFont() ? fontSizeAdjust.resolve(style.computedFontSize(), style.metricsOfPrimaryFont()) : fontSizeAdjust.value.asOptional(); + + if (!value) + return CSSPrimitiveValue::create(CSSValueNone); + if (metric == FontSizeAdjust::Metric::ExHeight) return CSSPrimitiveValue::create(*value); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/css/FontFace.cpp b/modules/javafx.web/src/main/native/Source/WebCore/css/FontFace.cpp index 6eee7ed8598..4c29794d6cf 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/css/FontFace.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/css/FontFace.cpp @@ -62,6 +62,11 @@ Ref FontFace::create(ScriptExecutionContext& context, const String& fa auto result = adoptRef(*new FontFace(*context.cssFontSelector())); result->suspendIfNeeded(); +#if COMPILER(GCC) && CPU(ARM64) + // FIXME: Workaround for GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033 + // that is related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115135 as well. + volatile +#endif bool dataRequiresAsynchronousLoading = true; auto setFamilyResult = result->setFamily(context, family); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/css/ShorthandSerializer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/css/ShorthandSerializer.cpp index 9fc5487f5c7..c495fdba01a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/css/ShorthandSerializer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/css/ShorthandSerializer.cpp @@ -1168,16 +1168,15 @@ String ShorthandSerializer::serializeGridTemplate() const return hasAtLeastOneTrackSize; }; - // For the rows we need to return early if the value of grid-template-rows is none because otherwise - // we will iteratively build up that portion of the shorthand and check to see if the value is a valid - // at the appropriate position in the shorthand. For the columns we must check the entire - // value of grid-template-columns beforehand because we append the value as a whole to the shorthand - if (isLonghandValueNone(rowsIndex) || (!isLonghandValueNone(columnsIndex) && !isValidExplicitTrackList(longhandValue(columnsIndex)))) + Ref rowTrackSizes = longhandValue(rowsIndex); + + // Make sure the longhands can be expressed in this version of the shorthand. + if (!rowTrackSizes->isValueList() || (!isLonghandValueNone(columnsIndex) && !isValidExplicitTrackList(longhandValue(columnsIndex)))) return String(); StringBuilder result; unsigned row = 0; - for (auto& currentValue : downcast(longhandValue(rowsIndex))) { + for (auto& currentValue : downcast(rowTrackSizes).get()) { if (!result.isEmpty()) result.append(' '); if (auto lineNames = dynamicDowncast(currentValue)) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.cpp b/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.cpp index 855a4035791..2951e672911 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.cpp @@ -10354,13 +10354,18 @@ void Document::resetObservationSizeForContainIntrinsicSize(Element& target) NoiseInjectionPolicy Document::noiseInjectionPolicy() const { - if (RefPtr loader = topDocument().loader()) { - if (loader->advancedPrivacyProtections().contains(AdvancedPrivacyProtections::FingerprintingProtections)) + if (advancedPrivacyProtections().contains(AdvancedPrivacyProtections::FingerprintingProtections)) return NoiseInjectionPolicy::Minimal; - } return NoiseInjectionPolicy::None; } +OptionSet Document::advancedPrivacyProtections() const +{ + if (RefPtr loader = topDocument().loader()) + return loader->advancedPrivacyProtections(); + return { }; +} + std::optional Document::noiseInjectionHashSalt() const { if (!page() || noiseInjectionPolicy() == NoiseInjectionPolicy::None) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.h b/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.h index 4cb9e16db56..362285f4752 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/Document.h @@ -1388,6 +1388,8 @@ class Document WEBCORE_EXPORT void exitPointerLock(); #endif + OptionSet advancedPrivacyProtections() const final; + std::optional noiseInjectionHashSalt() const final; NoiseInjectionPolicy noiseInjectionPolicy() const; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/Element.cpp b/modules/javafx.web/src/main/native/Source/WebCore/dom/Element.cpp index f489fe389e1..6a9617179be 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/Element.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/Element.cpp @@ -1047,7 +1047,7 @@ inline ScrollAlignment toScrollAlignmentForBlockDirection(std::optional, LayoutRect>> listBoxElementScrollIntoView(const Element& element) +static std::optional, LayoutRect>> listBoxElementScrollIntoView(const Element& element) { auto owningSelectElement = [](const Element& element) -> HTMLSelectElement* { if (auto* optionElement = dynamicDowncast(element)) @@ -1074,7 +1074,7 @@ static std::optional, LayoutRect>> listBoxEl itemIndex = 0; auto itemLocalRect = renderListBox->itemBoundingBoxRect({ }, itemIndex); - return std::pair, LayoutRect> { renderListBox.releaseNonNull(), itemLocalRect }; + return std::pair, LayoutRect> { renderListBox.releaseNonNull(), itemLocalRect }; } void Element::scrollIntoView(std::optional>&& arg) @@ -1084,7 +1084,7 @@ void Element::scrollIntoView(std::optionalupdateLayoutIgnorePendingStylesheets(LayoutOptions::UpdateCompositingLayers); - CheckedPtr renderer; + SingleThreadWeakPtr renderer; bool insideFixed = false; LayoutRect absoluteBounds; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/EmptyScriptExecutionContext.h b/modules/javafx.web/src/main/native/Source/WebCore/dom/EmptyScriptExecutionContext.h index 057c3e1f67e..4272548d425 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/EmptyScriptExecutionContext.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/EmptyScriptExecutionContext.h @@ -25,6 +25,7 @@ #pragma once +#include "AdvancedPrivacyProtections.h" #include "EventLoop.h" #include "Microtasks.h" #include "ReferrerPolicy.h" @@ -70,6 +71,7 @@ class EmptyScriptExecutionContext final : public RefCounted advancedPrivacyProtections() const final { return { }; } std::optional noiseInjectionHashSalt() const { return std::nullopt; } void postTask(Task&&) final { ASSERT_NOT_REACHED(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptElement.cpp b/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptElement.cpp index 69460be1f35..0349476ac27 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptElement.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptElement.cpp @@ -85,7 +85,7 @@ ScriptElement::ScriptElement(Element& element, bool parserInserted, bool already void ScriptElement::didFinishInsertingNode() { - ASSERT(m_parserInserted == ParserInserted::No); + if (m_parserInserted == ParserInserted::No) prepareScript(); // FIXME: Provide a real starting line number here. } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptExecutionContext.h b/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptExecutionContext.h index 972d7cf5a28..2dafc0dd259 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptExecutionContext.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/ScriptExecutionContext.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,7 @@ class ServiceWorker; class ServiceWorkerContainer; class SocketProvider; class WebCoreOpaqueRoot; +enum class AdvancedPrivacyProtections : uint16_t; enum class LoadedFromOpaqueSource : bool; enum class TaskSource : uint8_t; @@ -141,6 +143,7 @@ class ScriptExecutionContext : public SecurityContext, public TimerAlignment { virtual GraphicsClient* graphicsClient() { return nullptr; } + virtual OptionSet advancedPrivacyProtections() const = 0; virtual std::optional noiseInjectionHashSalt() const = 0; virtual RefPtr createRTCDataChannelRemoteHandlerConnection(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/TreeScope.cpp b/modules/javafx.web/src/main/native/Source/WebCore/dom/TreeScope.cpp index 3b9d965650c..267d46282e7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/TreeScope.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/TreeScope.cpp @@ -103,40 +103,6 @@ void TreeScope::decrementPtrCount() const checkedDowncast(m_rootNode).decrementPtrCount(); } -#if CHECKED_POINTER_DEBUG -void TreeScope::registerCheckedPtr(const void* pointer) const -{ - if (auto* document = dynamicDowncast(m_rootNode)) - document->registerCheckedPtr(pointer); - else - checkedDowncast(m_rootNode).registerCheckedPtr(pointer); -} - -void TreeScope::copyCheckedPtr(const void* source, const void* destination) const -{ - if (auto* document = dynamicDowncast(m_rootNode)) - document->copyCheckedPtr(source, destination); - else - checkedDowncast(m_rootNode).copyCheckedPtr(source, destination); -} - -void TreeScope::moveCheckedPtr(const void* source, const void* destination) const -{ - if (auto* document = dynamicDowncast(m_rootNode)) - document->moveCheckedPtr(source, destination); - else - checkedDowncast(m_rootNode).moveCheckedPtr(source, destination); -} - -void TreeScope::unregisterCheckedPtr(const void* pointer) const -{ - if (auto* document = dynamicDowncast(m_rootNode)) - document->unregisterCheckedPtr(pointer); - else - checkedDowncast(m_rootNode).unregisterCheckedPtr(pointer); -} -#endif // CHECKED_POINTER_DEBUG - IdTargetObserverRegistry& TreeScope::ensureIdTargetObserverRegistry() { if (!m_idTargetObserverRegistry) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/dom/WindowEventLoop.h b/modules/javafx.web/src/main/native/Source/WebCore/dom/WindowEventLoop.h index 74f307406e0..2b5e8374c96 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/dom/WindowEventLoop.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/dom/WindowEventLoop.h @@ -89,7 +89,7 @@ class WindowEventLoop final : public EventLoop { HashSet> m_activeObservers; HashSet> m_suspendedObservers; - SingleThreadWeakHashMap m_pagesWithRenderingOpportunity; + WeakHashMap m_pagesWithRenderingOpportunity; std::unique_ptr m_customElementQueue; bool m_processingBackupElementQueue { false }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/editing/CompositeEditCommand.cpp b/modules/javafx.web/src/main/native/Source/WebCore/editing/CompositeEditCommand.cpp index e20c433368c..c091c4f9b66 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/editing/CompositeEditCommand.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/editing/CompositeEditCommand.cpp @@ -287,8 +287,10 @@ void EditCommandComposition::reapply() if (!document->editor().willReapplyEditing(*this)) return; - for (auto& command : m_commands) + for (size_t i = 0; i < m_commands.size(); ++i) { + RefPtr command = m_commands[i].get(); command->doReapply(); + } document->editor().reappliedEditing(*this); @@ -325,8 +327,10 @@ void EditCommandComposition::setRangeDeletedByUnapply(const VisiblePositionIndex #ifndef NDEBUG void EditCommandComposition::getNodesInCommand(HashSet>& nodes) { - for (auto& command : m_commands) + for (size_t i = 0; i < m_commands.size(); ++i) { + RefPtr command = m_commands[i].get(); command->getNodesInCommand(nodes); + } } #endif diff --git a/modules/javafx.web/src/main/native/Source/WebCore/editing/Editor.cpp b/modules/javafx.web/src/main/native/Source/WebCore/editing/Editor.cpp index dad5d446b88..b85b758699f 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/editing/Editor.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/editing/Editor.cpp @@ -1278,6 +1278,7 @@ void Editor::appliedEditing(CompositeEditCommand& command) bool Editor::willUnapplyEditing(const EditCommandComposition& composition) const { + TypingCommand::closeTyping(protectedDocument()); return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyUndo"_s, IsInputMethodComposing::No); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/history/BackForwardController.h b/modules/javafx.web/src/main/native/Source/WebCore/history/BackForwardController.h index 4964568d969..4bb0c15fecb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/history/BackForwardController.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/history/BackForwardController.h @@ -72,7 +72,7 @@ class BackForwardController : public CanMakeCheckedPtr { Ref protectedPage() const; Ref protectedClient() const; - SingleThreadWeakRef m_page; + WeakRef m_page; Ref m_client; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.cpp b/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.cpp index fa196f03ec2..f9bc9984e09 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.cpp @@ -116,7 +116,7 @@ class CachedPageRestorationScope { } private: - SingleThreadWeakRef m_page; + WeakRef m_page; }; void CachedPage::restore(Page& page) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.h b/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.h index e65eda49816..51291799fe4 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/history/CachedPage.h @@ -63,7 +63,7 @@ class CachedPage : public CanMakeCheckedPtr { void markForContentsSizeChanged() { m_needsUpdateContentsSize = true; } private: - SingleThreadWeakRef m_page; + WeakRef m_page; MonotonicTime m_expirationTime; std::unique_ptr m_cachedMainFrame; #if ENABLE(VIDEO) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.cpp b/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.cpp index c97db6bbbff..6a9328c31e3 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.cpp @@ -55,10 +55,11 @@ extern "C" { extern void notifyHistoryItemDestroyed(const JLObject&); } #endif - -HistoryItem::HistoryItem(Client& client, const String& urlString, std::optional identifier) +HistoryItem::HistoryItem(Client& client, const String& urlString, const String& title, const String& alternateTitle, std::optional identifier) : m_urlString(urlString) , m_originalURLString(urlString) + , m_title(title) + , m_displayTitle(alternateTitle) , m_pruningReason(PruningReason::None) , m_identifier(identifier ? *identifier : BackForwardItemIdentifier::generate()) , m_client(client) @@ -82,6 +83,8 @@ HistoryItem::HistoryItem(const HistoryItem& item) , m_originalURLString(item.m_originalURLString) , m_referrer(item.m_referrer) , m_target(item.m_target) + , m_title(item.m_title) + , m_displayTitle(item.m_displayTitle) , m_scrollPosition(item.m_scrollPosition) , m_pageScaleFactor(item.m_pageScaleFactor) , m_children(item.m_children.map([](auto& child) { return child->copy(); })) @@ -116,6 +119,8 @@ void HistoryItem::reset() m_originalURLString = String(); m_referrer = String(); m_target = nullAtom(); + m_title = String(); + m_displayTitle = String(); m_lastVisitWasFailure = false; m_isTargetItem = false; @@ -143,6 +148,16 @@ const String& HistoryItem::originalURLString() const return m_originalURLString; } +const String& HistoryItem::title() const +{ + return m_title; +} + +const String& HistoryItem::alternateTitle() const +{ + return m_displayTitle; +} + bool HistoryItem::hasCachedPageExpired() const { return m_cachedPage ? m_cachedPage->hasExpired() : false; @@ -184,6 +199,12 @@ const AtomString& HistoryItem::target() const return m_target; } +void HistoryItem::setAlternateTitle(const String& alternateTitle) +{ + m_displayTitle = alternateTitle; + notifyChanged(); +} + void HistoryItem::setURLString(const String& urlString) { m_urlString = urlString; @@ -209,6 +230,12 @@ void HistoryItem::setReferrer(const String& referrer) notifyChanged(); } +void HistoryItem::setTitle(const String& title) +{ + m_title = title; + notifyChanged(); +} + void HistoryItem::setTarget(const AtomString& target) { m_target = target; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.h b/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.h index 778e24fc194..260485f5324 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/history/HistoryItem.h @@ -76,9 +76,9 @@ class HistoryItem : public RefCounted, public CanMakeWeakPtr create(Client& client, const String& urlString = { }, std::optional identifier = { }) + static Ref create(Client& client, const String& urlString = { }, const String& title = { }, const String& alternateTitle = { }, std::optional identifier = { }) { - return adoptRef(*new HistoryItem(client, urlString, identifier)); + return adoptRef(*new HistoryItem(client, urlString, title, alternateTitle, identifier)); } WEBCORE_EXPORT ~HistoryItem(); @@ -92,10 +92,13 @@ class HistoryItem : public RefCounted, public CanMakeWeakPtr, public CanMakeWeakPtr&&); @@ -219,7 +223,7 @@ class HistoryItem : public RefCounted, public CanMakeWeakPtr); + WEBCORE_EXPORT HistoryItem(Client&, const String& urlString, const String& title, const String& alternateTitle, std::optional); void setCachedPage(std::unique_ptr&&); std::unique_ptr takeCachedPage(); @@ -234,6 +238,8 @@ class HistoryItem : public RefCounted, public CanMakeWeakPtrsupportsProgressMonitoring()) return; @@ -5088,6 +5091,9 @@ void HTMLMediaElement::updateCaptionContainer() void HTMLMediaElement::layoutSizeChanged() { auto task = [this] { + if (isContextStopped()) + return; + if (auto root = userAgentShadowRoot()) root->dispatchEvent(Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No)); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/html/ValidatedFormListedElement.cpp b/modules/javafx.web/src/main/native/Source/WebCore/html/ValidatedFormListedElement.cpp index c429b3ff2c8..cf823728488 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/html/ValidatedFormListedElement.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/html/ValidatedFormListedElement.cpp @@ -168,9 +168,8 @@ void ValidatedFormListedElement::focusAndShowValidationMessage(Ref // focus() will scroll the element into view and this scroll may happen asynchronously. // Because scrolling the view hides the validation message, we need to show the validation // message asynchronously as well. - callOnMainThread([this, protectedThis, validationAnchor] { - updateVisibleValidationMessage(validationAnchor); - }); + if (RefPtr page = validationAnchor->document().page()) + page->scheduleValidationMessageUpdate(*this, validationAnchor); } void ValidatedFormListedElement::reportNonFocusableControlError() diff --git a/modules/javafx.web/src/main/native/Source/WebCore/html/canvas/WebGLUtilities.h b/modules/javafx.web/src/main/native/Source/WebCore/html/canvas/WebGLUtilities.h index 5ecaea73650..7b3910148f0 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/html/canvas/WebGLUtilities.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/html/canvas/WebGLUtilities.h @@ -53,14 +53,14 @@ class ScopedInspectorShaderProgramHighlight { void hideHighlight(); struct { - GCGLfloat color[4]; - GCGLenum equationRGB; - GCGLenum equationAlpha; - GCGLenum srcRGB; - GCGLenum dstRGB; - GCGLenum srcAlpha; - GCGLenum dstAlpha; - GCGLboolean enabled; + GCGLfloat color[4] { 0, 0, 0, 0 }; + GCGLenum equationRGB { GraphicsContextGL::NONE }; + GCGLenum equationAlpha { GraphicsContextGL::NONE }; + GCGLenum srcRGB { GraphicsContextGL::ONE }; + GCGLenum dstRGB { GraphicsContextGL::ZERO }; + GCGLenum srcAlpha { GraphicsContextGL::ONE }; + GCGLenum dstAlpha { GraphicsContextGL::ZERO }; + GCGLboolean enabled { false }; } m_savedBlend; WebGLRenderingContextBase* const m_context; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendAPIDispatcher.h b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendAPIDispatcher.h index 6ec5afe08f5..f2b8e3938d5 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendAPIDispatcher.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendAPIDispatcher.h @@ -90,7 +90,7 @@ class InspectorFrontendAPIDispatcher final void invalidatePendingResponses(); ValueOrException evaluateExpression(const String&); - SingleThreadWeakPtr m_frontendPage; + WeakPtr m_frontendPage; Vector> m_queuedEvaluations; HashMap, EvaluationResultHandler> m_pendingResponses; bool m_frontendLoaded { false }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendClientLocal.h b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendClientLocal.h index b0c30d8f2c6..6731eacaf67 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendClientLocal.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendClientLocal.h @@ -145,7 +145,7 @@ class InspectorFrontendClientLocal : public InspectorFrontendClient { std::optional evaluationResultToBoolean(InspectorFrontendAPIDispatcher::EvaluationResult); InspectorController* m_inspectedPageController { nullptr }; - SingleThreadWeakPtr m_frontendPage; + WeakPtr m_frontendPage; // TODO(yurys): this ref shouldn't be needed. RefPtr m_frontendHost; std::unique_ptr m_settings; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendHost.h b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendHost.h index e8497937e6f..4a2556f3480 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendHost.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/inspector/InspectorFrontendHost.h @@ -187,7 +187,7 @@ class InspectorFrontendHost : public RefCounted { WEBCORE_EXPORT InspectorFrontendHost(InspectorFrontendClient*, Page* frontendPage); InspectorFrontendClient* m_client; - SingleThreadWeakPtr m_frontendPage; + WeakPtr m_frontendPage; #if ENABLE(CONTEXT_MENUS) FrontendMenuProvider* m_menuProvider; #endif diff --git a/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp index e50db2c782c..a5c5e1bbee0 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp @@ -201,16 +201,19 @@ std::optional> InlineContentBalancer::computeBalanceConstrain for (auto chunkSize : chunkSizes) { bool isFirstChunk = !startLine; auto rangeToBalance = InlineItemRange { m_originalLineInlineItemRanges[startLine].startIndex(), m_originalLineInlineItemRanges[startLine + chunkSize - 1].endIndex() }; + std::optional> balancedLineWidthsForChunk; + + if (rangeToBalance.startIndex() < rangeToBalance.endIndex()) { InlineLayoutUnit totalWidth = 0; for (size_t i = 0; i < chunkSize; i++) totalWidth += m_originalLineWidths[startLine + i]; InlineLayoutUnit idealLineWidth = totalWidth / chunkSize; - std::optional> balancedLineWidthsForChunk; if (m_numberOfLinesInOriginalLayout <= maximumLinesToBalanceWithLineRequirement) balancedLineWidthsForChunk = balanceRangeWithLineRequirement(rangeToBalance, idealLineWidth, chunkSize, isFirstChunk); else balancedLineWidthsForChunk = balanceRangeWithNoLineRequirement(rangeToBalance, idealLineWidth, isFirstChunk); + } if (!balancedLineWidthsForChunk) { for (size_t i = 0; i < chunkSize; i++) @@ -228,6 +231,8 @@ std::optional> InlineContentBalancer::computeBalanceConstrain std::optional> InlineContentBalancer::balanceRangeWithLineRequirement(InlineItemRange range, InlineLayoutUnit idealLineWidth, size_t numberOfLines, bool isFirstChunk) { + ASSERT(range.startIndex() < range.endIndex()); + // breakOpportunities holds the indices i such that a line break can occur before m_inlineItemList[i]. auto breakOpportunities = computeBreakOpportunities(m_inlineItemList, range); @@ -329,6 +334,8 @@ std::optional> InlineContentBalancer::balanceRangeWithLineReq std::optional> InlineContentBalancer::balanceRangeWithNoLineRequirement(InlineItemRange range, InlineLayoutUnit idealLineWidth, bool isFirstChunk) { + ASSERT(range.startIndex() < range.endIndex()); + // breakOpportunities holds the indices i such that a line break can occur before m_inlineItemList[i]. auto breakOpportunities = computeBreakOpportunities(m_inlineItemList, range); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp b/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp index 480ab92c2b6..226d8aec7d3 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/layout/formattingContexts/inline/invalidation/InlineInvalidation.cpp @@ -159,7 +159,8 @@ static const InlineDisplay::Box* leadingContentDisplayForLineIndex(size_t lineIn for (auto firstContentDisplayBoxIndex = rootInlineBoxIndexOnLine() + 1; firstContentDisplayBoxIndex < displayBoxes.size(); ++firstContentDisplayBoxIndex) { auto& displayBox = displayBoxes[firstContentDisplayBoxIndex]; - ASSERT(!displayBox.isRootInlineBox()); + if (displayBox.isRootInlineBox()) + return nullptr; if (!displayBox.isNonRootInlineBox() || displayBox.isFirstForLayoutBox()) return &displayBox; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/EmptyClients.cpp b/modules/javafx.web/src/main/native/Source/WebCore/loader/EmptyClients.cpp index 305b852657e..5cee4d5dd49 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/EmptyClients.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/EmptyClients.cpp @@ -293,7 +293,7 @@ class EmptyEditorClient final : public EditorClient { void registerRedoStep(UndoStep&) final; void clearUndoRedoOperations() final { } - DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, const String&) final { return DOMPasteAccessResponse::DeniedForGesture; } + DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, FrameIdentifier, const String&) final { return DOMPasteAccessResponse::DeniedForGesture; } bool canCopyCut(LocalFrame*, bool defaultValue) const final { return defaultValue; } bool canPaste(LocalFrame*, bool defaultValue) const final { return defaultValue; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp b/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp index e2c93b831ae..f5e2c3349d7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/FrameLoader.cpp @@ -248,7 +248,7 @@ class PageLevelForbidScope { ~PageLevelForbidScope() = default; - SingleThreadWeakPtr m_page; + WeakPtr m_page; }; struct ForbidPromptsScope : public PageLevelForbidScope { @@ -4365,6 +4365,8 @@ void FrameLoader::didChangeTitle(DocumentLoader* loader) m_client->didChangeTitle(loader); if (loader == m_documentLoader) { + // Must update the entries in the back-forward list too. + history().setCurrentItemTitle(loader->title()); // This must go through the WebFrame because it has the right notion of the current b/f item. m_client->setTitle(loader->title(), loader->urlForHistory()); m_client->setMainFrameDocumentReady(true); // update observers with new DOMDocument diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.cpp b/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.cpp index 114312289a3..7d640711743 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.cpp @@ -635,6 +635,13 @@ void HistoryController::setCurrentItem(Ref&& item) m_previousItem = std::exchange(m_currentItem, WTFMove(item)); } +void HistoryController::setCurrentItemTitle(const StringWithDirection& title) +{ + // FIXME: This ignores the title's direction. + if (RefPtr currentItem = m_currentItem) + currentItem->setTitle(title.string); +} + bool HistoryController::currentItemShouldBeReplaced() const { // From the HTML5 spec for location.assign(): @@ -686,8 +693,12 @@ void HistoryController::initializeItem(HistoryItem& item) if (originalURL.isEmpty()) originalURL = aboutBlankURL(); + StringWithDirection title = documentLoader->title(); + item.setURL(url); item.setTarget(m_frame->tree().uniqueName()); + // FIXME: Should store the title direction as well. + item.setTitle(title.string); item.setOriginalURLString(originalURL.string()); if (!unreachableURL.isEmpty() || documentLoader->response().httpStatusCode() >= 400) @@ -881,7 +892,7 @@ void HistoryController::updateCurrentItem() } } -void HistoryController::pushState(RefPtr&& stateObject, const String& urlString) +void HistoryController::pushState(RefPtr&& stateObject, const String& title, const String& urlString) { if (!m_currentItem) return; @@ -909,6 +920,7 @@ void HistoryController::pushState(RefPtr&& stateObject, c // Override data in the current item (created by createItemTree) to reflect // the pushState() arguments. RefPtr currentItem = m_currentItem; + currentItem->setTitle(title); currentItem->setStateObject(WTFMove(stateObject)); currentItem->setURLString(urlString); currentItem->setShouldRestoreScrollPosition(shouldRestoreScrollPosition); @@ -924,7 +936,7 @@ void HistoryController::pushState(RefPtr&& stateObject, c frame->checkedLoader()->client().updateGlobalHistory(); } -void HistoryController::replaceState(RefPtr&& stateObject, const String& urlString) +void HistoryController::replaceState(RefPtr&& stateObject, const String& title, const String& urlString) { RefPtr currentItem = m_currentItem; if (!currentItem) @@ -934,6 +946,7 @@ void HistoryController::replaceState(RefPtr&& stateObject if (!urlString.isEmpty()) currentItem->setURLString(urlString); + currentItem->setTitle(title); currentItem->setStateObject(WTFMove(stateObject)); currentItem->setFormData(nullptr); currentItem->setFormContentType(String()); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.h b/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.h index 8ad74abb11e..5fdd7fb3c5d 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/HistoryController.h @@ -76,6 +76,7 @@ class HistoryController : public CanMakeCheckedPtr { HistoryItem* currentItem() const { return m_currentItem.get(); } RefPtr protectedCurrentItem() const; WEBCORE_EXPORT void setCurrentItem(Ref&&); + void setCurrentItemTitle(const StringWithDirection&); bool currentItemShouldBeReplaced() const; WEBCORE_EXPORT void replaceCurrentItem(RefPtr&&); @@ -87,8 +88,8 @@ class HistoryController : public CanMakeCheckedPtr { RefPtr protectedProvisionalItem() const; void setProvisionalItem(RefPtr&&); - void pushState(RefPtr&&, const String& url); - void replaceState(RefPtr&&, const String& url); + void pushState(RefPtr&&, const String& title, const String& url); + void replaceState(RefPtr&&, const String& title, const String& url); void setDefersLoading(bool); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/loader/ProgressTracker.h b/modules/javafx.web/src/main/native/Source/WebCore/loader/ProgressTracker.h index 93a02888f3a..94a15cd04f4 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/loader/ProgressTracker.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/loader/ProgressTracker.h @@ -74,7 +74,7 @@ class ProgressTracker : public CanMakeCheckedPtr { void progressHeartbeatTimerFired(); Ref protectedPage() const; - SingleThreadWeakRef m_page; + WeakRef m_page; UniqueRef m_client; RefPtr m_originatingProgressFrame; HashMap> m_progressItems; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/EditorClient.h b/modules/javafx.web/src/main/native/Source/WebCore/page/EditorClient.h index cdcc30bb477..44c5bd488bf 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/EditorClient.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/EditorClient.h @@ -27,6 +27,7 @@ #pragma once #include "EditorInsertAction.h" +#include "FrameIdentifier.h" #include "SerializedAttachmentData.h" #include "TextAffinity.h" #include "TextChecking.h" @@ -110,7 +111,7 @@ class EditorClient : public CanMakeWeakPtr, public CanMakeCheckedP virtual void requestCandidatesForSelection(const VisibleSelection&) { } virtual void handleAcceptedCandidateWithSoftSpaces(TextCheckingResult) { } - virtual DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, const String& originIdentifier) = 0; + virtual DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, FrameIdentifier, const String& originIdentifier) = 0; // Notify an input method that a composition was voluntarily discarded by WebCore, so that it could clean up too. // This function is not called when a composition is closed per a request from an input method. diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/EventHandler.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/EventHandler.cpp index 4ed7d8b2afe..35fbe9df300 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/EventHandler.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/EventHandler.cpp @@ -4561,7 +4561,10 @@ void EventHandler::defaultBackspaceEventHandler(KeyboardEvent& event) void EventHandler::stopKeyboardScrolling() { - if (auto animator = m_frame->page()->currentKeyboardScrollingAnimator()) + RefPtr page = m_frame->page(); + if (!page) + return; + if (auto animator = page->currentKeyboardScrollingAnimator()) animator->handleKeyUpEvent(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/Frame.h b/modules/javafx.web/src/main/native/Source/WebCore/page/Frame.h index ac13e1e2cb0..87d91b1c349 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/Frame.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/Frame.h @@ -107,7 +107,7 @@ class Frame : public ThreadSafeRefCounted, private: virtual DOMWindow* virtualWindow() const = 0; - SingleThreadWeakPtr m_page; + WeakPtr m_page; const FrameIdentifier m_frameID; mutable FrameTree m_treeNode; Ref m_windowProxy; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/History.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/History.cpp index c3486a6e7a4..7b337248afa 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/History.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/History.cpp @@ -200,7 +200,7 @@ URL History::urlForState(const String& urlString) return frame->document()->completeURL(urlString); } -ExceptionOr History::stateObjectAdded(RefPtr&& data, const String& urlString, StateObjectType stateObjectType) +ExceptionOr History::stateObjectAdded(RefPtr&& data, const String& title, const String& urlString, StateObjectType stateObjectType) { m_cachedState.clear(); @@ -266,10 +266,14 @@ ExceptionOr History::stateObjectAdded(RefPtr&& data return Exception { ExceptionCode::SecurityError, makeString("Attempt to use history.pushState() more than ", perStateObjectTimeSpanLimit, " times per ", stateObjectTimeSpan.seconds(), " seconds") }; } + Checked titleSize = title.length(); + titleSize *= 2; + Checked urlSize = fullURL.string().length(); urlSize *= 2; - Checked payloadSize = urlSize; + Checked payloadSize = titleSize; + payloadSize += urlSize; payloadSize += data ? data->wireBytes().size() : 0; Checked newTotalUsage = mainHistory.m_totalStateObjectUsage; @@ -293,10 +297,10 @@ ExceptionOr History::stateObjectAdded(RefPtr&& data frame->document()->updateURLForPushOrReplaceState(fullURL); if (stateObjectType == StateObjectType::Push) { - frame->loader().history().pushState(WTFMove(data), fullURL.string()); + frame->loader().history().pushState(WTFMove(data), title, fullURL.string()); frame->loader().client().dispatchDidPushStateWithinPage(); } else if (stateObjectType == StateObjectType::Replace) { - frame->loader().history().replaceState(WTFMove(data), fullURL.string()); + frame->loader().history().replaceState(WTFMove(data), title, fullURL.string()); frame->loader().client().dispatchDidReplaceStateWithinPage(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/History.h b/modules/javafx.web/src/main/native/Source/WebCore/page/History.h index 176f8268f1b..463a8409822 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/History.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/History.h @@ -65,14 +65,14 @@ class History final : public ScriptWrappable, public RefCounted, public bool isSameAsCurrentState(SerializedScriptValue*) const; - ExceptionOr pushState(RefPtr&& data, const String&, const String& urlString); - ExceptionOr replaceState(RefPtr&& data, const String&, const String& urlString); + ExceptionOr pushState(RefPtr&& data, const String& title, const String& urlString); + ExceptionOr replaceState(RefPtr&& data, const String& title, const String& urlString); private: explicit History(LocalDOMWindow&); enum class StateObjectType { Push, Replace }; - ExceptionOr stateObjectAdded(RefPtr&&, const String& url, StateObjectType); + ExceptionOr stateObjectAdded(RefPtr&&, const String& title, const String& url, StateObjectType); bool stateChanged() const; URL urlForState(const String& url); @@ -92,14 +92,14 @@ class History final : public ScriptWrappable, public RefCounted, public uint64_t m_mostRecentStateObjectUsage { 0 }; }; -inline ExceptionOr History::pushState(RefPtr&& data, const String&, const String& urlString) +inline ExceptionOr History::pushState(RefPtr&& data, const String& title, const String& urlString) { - return stateObjectAdded(WTFMove(data), urlString, StateObjectType::Push); + return stateObjectAdded(WTFMove(data), title, urlString, StateObjectType::Push); } -inline ExceptionOr History::replaceState(RefPtr&& data, const String&, const String& urlString) +inline ExceptionOr History::replaceState(RefPtr&& data, const String& title, const String& urlString) { - return stateObjectAdded(WTFMove(data), urlString, StateObjectType::Replace); + return stateObjectAdded(WTFMove(data), title, urlString, StateObjectType::Replace); } } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/History.idl b/modules/javafx.web/src/main/native/Source/WebCore/page/History.idl index 1b7b69dbfd4..4c7197afa42 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/History.idl +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/History.idl @@ -36,8 +36,9 @@ [CallWith=RelevantDocument] undefined forward(); [CallWith=RelevantDocument] undefined go(optional long delta = 0); - undefined pushState(SerializedScriptValue data, DOMString unused, optional USVString? url = null); - undefined replaceState(SerializedScriptValue data, DOMString unused, optional USVString? url = null); + // FIXME: title should not be nullable as per the HTML specification. + undefined pushState(SerializedScriptValue data, DOMString? title, optional USVString? url = null); + undefined replaceState(SerializedScriptValue data, DOMString? title, optional USVString? url = null); }; enum ScrollRestoration { "auto", "manual" }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/ImageAnalysisQueue.h b/modules/javafx.web/src/main/native/Source/WebCore/page/ImageAnalysisQueue.h index 9c847977e0f..8c753e87485 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/ImageAnalysisQueue.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/ImageAnalysisQueue.h @@ -80,7 +80,7 @@ class ImageAnalysisQueue { // FIXME: Refactor the source and target LIDs into either a std::pair<> of strings, or its own named struct. String m_sourceLanguageIdentifier; String m_targetLanguageIdentifier; - SingleThreadWeakPtr m_page; + WeakPtr m_page; Timer m_resumeProcessingTimer; WeakHashMap m_queuedElements; PriorityQueue m_queue; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/ImageOverlayController.h b/modules/javafx.web/src/main/native/Source/WebCore/page/ImageOverlayController.h index 2056b88540a..03e26a6c640 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/ImageOverlayController.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/ImageOverlayController.h @@ -91,7 +91,7 @@ class ImageOverlayController final : private PageOverlay::Client void platformUpdateElementUnderMouse(LocalFrame&, Element* elementUnderMouse); bool platformHandleMouseEvent(const PlatformMouseEvent&); - SingleThreadWeakPtr m_page; + WeakPtr m_page; RefPtr m_overlay; WeakPtr m_hostElementForSelection; Vector m_selectionQuads; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.cpp index 7c8ec4fd3a6..298c0009187 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.cpp @@ -634,7 +634,7 @@ bool LocalFrame::requestDOMPasteAccess(DOMPasteAccessCategory pasteAccessCategor if (!client) return false; - auto response = client->requestDOMPasteAccess(pasteAccessCategory, m_doc->originIdentifierForPasteboard()); + auto response = client->requestDOMPasteAccess(pasteAccessCategory, frameID(), m_doc->originIdentifierForPasteboard()); gestureToken->didRequestDOMPasteAccess(response); switch (response) { case DOMPasteAccessResponse::GrantedForCommand: diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.h b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.h index 415386db2ae..760965de5cf 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrame.h @@ -152,7 +152,7 @@ class LocalFrame final : public Frame { EventHandler& eventHandler() { return m_eventHandler; } const EventHandler& eventHandler() const { return m_eventHandler; } - CheckedRef checkedEventHandler(); + WEBCORE_EXPORT CheckedRef checkedEventHandler(); CheckedRef checkedEventHandler() const; const FrameLoader& loader() const { return m_loader.get(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrameView.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrameView.cpp index 7e94b7a1b12..e3ee2912965 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrameView.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/LocalFrameView.cpp @@ -175,7 +175,7 @@ Pagination::Mode paginationModeForRenderStyle(const RenderStyle& style) // paged-x always corresponds to LeftToRightPaginated or RightToLeftPaginated. If the WritingMode // is horizontal, then we use TextDirection to choose between those options. If the WritingMode - // is vertical, then the direction of the verticality dictates the choice. + // is vertical, then the block flow direction dictates the choice. if (overflow == Overflow::PagedX) { if ((isHorizontalWritingMode && textDirection == TextDirection::LTR) || blockFlowDirection == BlockFlowDirection::LeftToRight) return Pagination::Mode::LeftToRightPaginated; @@ -183,7 +183,7 @@ Pagination::Mode paginationModeForRenderStyle(const RenderStyle& style) } // paged-y always corresponds to TopToBottomPaginated or BottomToTopPaginated. If the WritingMode - // is horizontal, then the direction of the horizontality dictates the choice. If the WritingMode + // is horizontal, then the block flow direction dictates the choice. If the WritingMode // is vertical, then we use TextDirection to choose between those options. if (blockFlowDirection == BlockFlowDirection::TopToBottom || (!isHorizontalWritingMode && textDirection == TextDirection::RTL)) return Pagination::Mode::TopToBottomPaginated; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/OpportunisticTaskScheduler.h b/modules/javafx.web/src/main/native/Source/WebCore/page/OpportunisticTaskScheduler.h index 283929a8f0e..d6f5b48d450 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/OpportunisticTaskScheduler.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/OpportunisticTaskScheduler.h @@ -120,7 +120,7 @@ class OpportunisticTaskScheduler final : public RefCounted m_page; + WeakPtr m_page; uint64_t m_imminentlyScheduledWorkCount { 0 }; uint64_t m_runloopCountAfterBeingScheduled { 0 }; MonotonicTime m_currentDeadline; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/Page.cpp b/modules/javafx.web/src/main/native/Source/WebCore/page/Page.cpp index 80e28117b3e..a48f5f9a8d0 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/Page.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/Page.cpp @@ -21,6 +21,7 @@ #include "Page.h" #include "ActivityStateChangeObserver.h" +#include "AdvancedPrivacyProtections.h" #include "AlternativeTextClient.h" #include "AnimationFrameRate.h" #include "AppHighlightStorage.h" @@ -212,9 +213,9 @@ namespace WebCore { -static HashSet>& allPages() +static HashSet>& allPages() { - static NeverDestroyed>> set; + static NeverDestroyed>> set; return set; } @@ -244,6 +245,19 @@ void Page::updateValidationBubbleStateIfNeeded() client->updateValidationBubbleStateIfNeeded(); } +void Page::scheduleValidationMessageUpdate(ValidatedFormListedElement& element, HTMLElement& anchor) +{ + m_validationMessageUpdates.append({ element, anchor }); +} + +void Page::updateValidationMessages() +{ + for (auto& item : std::exchange(m_validationMessageUpdates, { })) { + if (RefPtr anchor = item.second.get()) + item.first->updateVisibleValidationMessage(*anchor); + } +} + static void networkStateChanged(bool isOnLine) { Vector> frames; @@ -1986,6 +2000,8 @@ void Page::doAfterUpdateRendering() updateElementsWithTextRecognitionResults(); #endif + updateValidationMessages(); + prioritizeVisibleResources(); m_renderingUpdateRemainingSteps.last().remove(RenderingUpdateStep::EventRegionUpdate); @@ -4443,7 +4459,7 @@ ModelPlayerProvider& Page::modelPlayerProvider() return m_modelPlayerProvider.get(); } -void Page::setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData& topOrigin, const String& referrerPolicy) +void Page::setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData& topOrigin, const String& referrerPolicy, OptionSet advancedPrivacyProtections) { RefPtr localMainFrame = dynamicDowncast(mainFrame()); if (!localMainFrame) @@ -4459,6 +4475,9 @@ void Page::setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData& document->setSiteForCookies(originAsURL); document->setFirstPartyForCookies(originAsURL); + if (RefPtr documentLoader = localMainFrame->checkedLoader()->documentLoader()) + documentLoader->setAdvancedPrivacyProtections(advancedPrivacyProtections); + if (document->settings().storageBlockingPolicy() != StorageBlockingPolicy::BlockThirdParty) document->setDomainForCachePartition(String { emptyString() }); else diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/Page.h b/modules/javafx.web/src/main/native/Source/WebCore/page/Page.h index 004bc0f7dc8..2639e13f925 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/Page.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/Page.h @@ -164,6 +164,7 @@ class UserContentProvider; class UserContentURLPattern; class UserScript; class UserStyleSheet; +class ValidatedFormListedElement; class ValidationMessageClient; class VisibleSelection; class VisitedLinkStore; @@ -180,6 +181,7 @@ using PlatformDisplayID = uint32_t; using SharedStringHash = uint32_t; enum class ActivityState : uint16_t; +enum class AdvancedPrivacyProtections : uint16_t; enum class CanWrap : bool; enum class DidWrap : bool; enum class DisabledAdaptations : uint8_t; @@ -280,7 +282,7 @@ constexpr auto allRenderingUpdateSteps = updateRenderingSteps | OptionSet, public Supplementable, public CanMakeSingleThreadWeakPtr { +class Page : public RefCounted, public Supplementable, public CanMakeWeakPtr { WTF_MAKE_NONCOPYABLE(Page); WTF_MAKE_FAST_ALLOCATED; friend class SettingsBase; @@ -292,7 +294,7 @@ class Page : public RefCounted, public Supplementable, public CanMak WEBCORE_EXPORT static void updateStyleForAllPagesAfterGlobalChangeInEnvironment(); WEBCORE_EXPORT static void clearPreviousItemFromAllPages(HistoryItem*); - WEBCORE_EXPORT void setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData& topOrigin, const String& referrerPolicy); + WEBCORE_EXPORT void setupForRemoteWorker(const URL& scriptURL, const SecurityOriginData& topOrigin, const String& referrerPolicy, OptionSet); WEBCORE_EXPORT void updateStyleAfterChangeInEnvironment(); @@ -396,6 +398,7 @@ class Page : public RefCounted, public Supplementable, public CanMak ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient.get(); } void updateValidationBubbleStateIfNeeded(); + void scheduleValidationMessageUpdate(ValidatedFormListedElement&, HTMLElement&); WEBCORE_EXPORT ScrollingCoordinator* scrollingCoordinator(); WEBCORE_EXPORT RefPtr protectedScrollingCoordinator(); @@ -1093,6 +1096,8 @@ class Page : public RefCounted, public Supplementable, public CanMak explicit Page(PageConfiguration&&); #endif + void updateValidationMessages(); + struct Navigation { RegistrableDomain domain; FrameLoadType type; @@ -1176,6 +1181,7 @@ class Page : public RefCounted, public Supplementable, public CanMak RefPtr m_pluginData; std::unique_ptr m_validationMessageClient; + Vector, WeakPtr>> m_validationMessageUpdates; std::unique_ptr m_diagnosticLoggingClient; std::unique_ptr m_performanceLoggingClient; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/PageGroup.h b/modules/javafx.web/src/main/native/Source/WebCore/page/PageGroup.h index f6333a1ba2f..cceb1af25a9 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/PageGroup.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/PageGroup.h @@ -45,7 +45,7 @@ class PageGroup : public CanMakeWeakPtr { WEBCORE_EXPORT static PageGroup* pageGroup(const String& groupName); - const SingleThreadWeakHashSet& pages() const { return m_pages; } + const WeakHashSet& pages() const { return m_pages; } void addPage(Page&); void removePage(Page&); @@ -61,7 +61,7 @@ class PageGroup : public CanMakeWeakPtr { private: String m_name; - SingleThreadWeakHashSet m_pages; + WeakHashSet m_pages; unsigned m_identifier; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/PageOverlay.h b/modules/javafx.web/src/main/native/Source/WebCore/page/PageOverlay.h index 7d9bdf5de7e..9d675433b6d 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/PageOverlay.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/PageOverlay.h @@ -131,7 +131,7 @@ class PageOverlay final : public RefCounted, public CanMakeWeakPtr< void fadeAnimationTimerFired(); Client& m_client; - SingleThreadWeakPtr m_page; + WeakPtr m_page; Timer m_fadeAnimationTimer; WallTime m_fadeAnimationStartTime; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/SettingsBase.h b/modules/javafx.web/src/main/native/Source/WebCore/page/SettingsBase.h index b8252afb3d5..9e29fba0010 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/SettingsBase.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/SettingsBase.h @@ -167,7 +167,7 @@ class SettingsBase { void sampleBufferContentKeySessionSupportEnabledChanged(); #endif - SingleThreadWeakPtr m_page; + WeakPtr m_page; Seconds m_minimumDOMTimerInterval; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/UserContentProvider.h b/modules/javafx.web/src/main/native/Source/WebCore/page/UserContentProvider.h index f0a806ca412..592b896c6fc 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/UserContentProvider.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/UserContentProvider.h @@ -84,7 +84,7 @@ class UserContentProvider : public RefCounted { WEBCORE_EXPORT void invalidateInjectedStyleSheetCacheInAllFramesInAllPages(); private: - SingleThreadWeakHashSet m_pages; + WeakHashSet m_pages; WeakHashSet m_userMessageHandlerInvalidationClients; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/VisitedLinkStore.h b/modules/javafx.web/src/main/native/Source/WebCore/page/VisitedLinkStore.h index bd9053d69e6..33a28d43410 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/VisitedLinkStore.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/VisitedLinkStore.h @@ -50,7 +50,7 @@ class VisitedLinkStore : public RefCounted { WEBCORE_EXPORT void invalidateStylesForLink(SharedStringHash); private: - SingleThreadWeakHashSet m_pages; + WeakHashSet m_pages; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingCoordinator.h b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingCoordinator.h index 044da6f0b8a..3d38036d09b 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingCoordinator.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/page/scrolling/ScrollingCoordinator.h @@ -226,7 +226,7 @@ class ScrollingCoordinator : public ThreadSafeRefCountedAndCanMakeThreadSafeWeak virtual void willCommitTree() { } - SingleThreadWeakPtr m_page; // FIXME: ideally this would be a WeakRef but it gets nulled on async teardown. + WeakPtr m_page; // FIXME: ideally this would be a WeakRef but it gets nulled on async teardown. private: virtual bool hasVisibleSlowRepaintViewportConstrainedObjects(const LocalFrameView&) const; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/SharedBuffer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/SharedBuffer.cpp index 38324fd9285..567abce5293 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/SharedBuffer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/SharedBuffer.cpp @@ -195,6 +195,10 @@ String FragmentedSharedBuffer::toHexString() const RefPtr FragmentedSharedBuffer::tryCreateArrayBuffer() const { + if (size() > std::numeric_limits::max()) { + WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size is too large (%zu)\n", size()); + return nullptr; + } auto arrayBuffer = ArrayBuffer::tryCreateUninitialized(static_cast(size()), 1); if (!arrayBuffer) { WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size was %zu\n", size()); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.cpp index 2a4e0c79b13..c44df274cbb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.cpp @@ -42,19 +42,8 @@ namespace WebCore { MultiChannelResampler::MultiChannelResampler(double scaleFactor, unsigned numberOfChannels, unsigned requestFrames, Function&& provideInput) : m_numberOfChannels(numberOfChannels) , m_provideInput(WTFMove(provideInput)) - , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames, false)) + , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames)) { - // As an optimization, we will use the buffer passed to provideInputForChannel() as channel memory for the first channel so we - // only need to allocate memory if there is more than one channel. - if (numberOfChannels > 1) { - m_channelsMemory = Vector>(numberOfChannels - 1, [&](size_t i) { - size_t channelIndex = i + 1; - auto floatArray = makeUnique(requestFrames); - m_multiChannelBus->setChannelMemory(channelIndex, floatArray->data(), requestFrames); - return floatArray; - }); - } - // Create each channel's resampler. m_kernels = Vector>(numberOfChannels, [&](size_t channelIndex) { return makeUnique(scaleFactor, requestFrames, std::bind(&MultiChannelResampler::provideInputForChannel, this, std::placeholders::_1, std::placeholders::_2, channelIndex)); @@ -93,16 +82,10 @@ void MultiChannelResampler::process(AudioBus* destination, size_t framesToProces void MultiChannelResampler::provideInputForChannel(std::span buffer, size_t framesToProcess, unsigned channelIndex) { ASSERT(channelIndex < m_multiChannelBus->numberOfChannels()); - ASSERT(framesToProcess == m_multiChannelBus->length()); + ASSERT(framesToProcess <= m_multiChannelBus->length()); - if (!channelIndex) { - // As an optimization, we use the provided buffer as memory for the first channel in the AudioBus. This avoids - // having to memcpy() for the first channel. - RELEASE_ASSERT(framesToProcess <= buffer.size()); - m_multiChannelBus->setChannelMemory(0, buffer.data(), framesToProcess); + if (!channelIndex) m_provideInput(m_multiChannelBus.get(), framesToProcess); - return; - } // Copy the channel data from what we received from m_multiChannelProvider. memcpySpan(buffer.subspan(0, framesToProcess), m_multiChannelBus->channel(channelIndex)->span().subspan(0, framesToProcess)); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.h index 2010f885eb6..4cc16979506 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/MultiChannelResampler.h @@ -29,7 +29,6 @@ #ifndef MultiChannelResampler_h #define MultiChannelResampler_h -#include "AudioArray.h" #include #include #include @@ -62,7 +61,6 @@ class MultiChannelResampler final { size_t m_outputFramesReady { 0 }; Function m_provideInput; RefPtr m_multiChannelBus; - Vector> m_channelsMemory; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp index 8f8058844cb..68c6299b55c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp @@ -112,6 +112,11 @@ PlatformMediaSessionManager::PlatformMediaSessionManager() { } +PlatformMediaSessionManager::~PlatformMediaSessionManager() +{ + m_taskGroup.cancel(); +} + static inline unsigned indexFromMediaType(PlatformMediaSession::MediaType type) { return static_cast(type); @@ -469,7 +474,7 @@ void PlatformMediaSessionManager::sessionCanProduceAudioChanged() return; m_alreadyScheduledSessionStatedUpdate = true; - callOnMainThread([this] { + enqueueTaskOnMainThread([this] { m_alreadyScheduledSessionStatedUpdate = false; maybeActivateAudioSession(); updateSessionState(); @@ -633,7 +638,7 @@ void PlatformMediaSessionManager::scheduleUpdateSessionState() return; m_hasScheduledSessionStateUpdate = true; - callOnMainThread([this] { + enqueueTaskOnMainThread([this] { updateSessionState(); m_hasScheduledSessionStateUpdate = false; }); @@ -823,6 +828,13 @@ void PlatformMediaSessionManager::setMediaCapabilityGrantsEnabled(bool mediaCapa } #endif +void PlatformMediaSessionManager::enqueueTaskOnMainThread(Function&& task) +{ + callOnMainThread(CancellableTask(m_taskGroup, [task = WTFMove(task)] () mutable { + task(); + })); +} + #if !RELEASE_LOG_DISABLED WTFLogChannel& PlatformMediaSessionManager::logChannel() const { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.h index 63da933c584..38a52b6b72a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/audio/PlatformMediaSessionManager.h @@ -30,6 +30,7 @@ #include "RemoteCommandListener.h" #include "Timer.h" #include +#include #include #include #include @@ -80,7 +81,7 @@ class PlatformMediaSessionManager WEBCORE_EXPORT static void setMediaCapabilityGrantsEnabled(bool); #endif - virtual ~PlatformMediaSessionManager() = default; + virtual ~PlatformMediaSessionManager(); virtual void scheduleSessionStatusUpdate() { } @@ -214,6 +215,8 @@ class PlatformMediaSessionManager std::optional supportsSpatialAudioPlayback() { return m_supportsSpatialAudioPlayback; } + void enqueueTaskOnMainThread(Function&&); + private: friend class Internals; @@ -240,6 +243,8 @@ class PlatformMediaSessionManager WeakHashSet m_audioCaptureSources; bool m_hasScheduledSessionStateUpdate { false }; + TaskCancellationGroup m_taskGroup; + #if ENABLE(WEBM_FORMAT_READER) static bool m_webMFormatReaderEnabled; #endif diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNeonParallelApplier.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNeonParallelApplier.cpp index 04d855fa6d7..5f4250d87b6 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNeonParallelApplier.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/cpu/arm/filters/FELightingNeonParallelApplier.cpp @@ -542,14 +542,14 @@ void FELightingNeonParallelApplier::applyPlatformParallel(const LightingData& da floatArguments.colorBlue = color.blue; floatArguments.padding4 = 0; - if (data.lightSource->type() == LS_POINT) { + if (data.lightSource->type() == LightType::LS_POINT) { neonData.flags |= FLAG_POINT_LIGHT; auto& pointLightSource = downcast(*data.lightSource); floatArguments.lightX = pointLightSource.position().x(); floatArguments.lightY = pointLightSource.position().y(); floatArguments.lightZ = pointLightSource.position().z(); floatArguments.padding2 = 0; - } else if (data.lightSource->type() == LS_SPOT) { + } else if (data.lightSource->type() == LightType::LS_SPOT) { neonData.flags |= FLAG_SPOT_LIGHT; auto& spotLightSource = downcast(*data.lightSource); floatArguments.lightX = spotLightSource.position().x(); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/filters/FELighting.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/filters/FELighting.h index 918657c43e4..27546b040d0 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/filters/FELighting.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/filters/FELighting.h @@ -68,11 +68,6 @@ class FELighting : public FilterEffect { std::unique_ptr createSoftwareApplier() const override; -#if CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC_COMPATIBLE) - static int getPowerCoefficients(float exponent); - inline void platformApplyNeon(const LightingData&, const LightSource::PaintingData&); -#endif - Color m_lightingColor; float m_surfaceScale; float m_diffuseConstant; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp index d833de69279..8457dcebb43 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp @@ -914,10 +914,15 @@ void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly() // Update the image contents only when the image layer is visible and the native image changed. auto& layerState = m_nicosia.imageBacking->layerState(); - layerState.imageID = imageID; - layerState.update.isVisible = transformedVisibleRect().intersects(IntRect(contentsRect())); - if (layerState.update.isVisible && (!nativeImageID || layerState.update.nativeImageID != nativeImageID)) { + bool nativeImageChanged = layerState.update.nativeImageID != nativeImageID; + if (nativeImageChanged) layerState.update.nativeImageID = nativeImageID; + + bool wasVisible = layerState.update.isVisible; + layerState.update.isVisible = transformedVisibleRect().intersects(IntRect(contentsRect())); + + // Update the image contents only when the image layer is visible and it was previously hidden or the native image changed. + if (layerState.update.isVisible && (!wasVisible || nativeImageChanged)) { layerState.update.imageBackingStore = m_coordinator->imageBackingStore(nativeImageID, [&] { auto buffer = Nicosia::Buffer::create(IntSize(image.size()), diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp index 4446074cf81..9292f3efea1 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateGStreamer.cpp @@ -137,6 +137,7 @@ void MediaRecorderPrivateBackend::stopRecording(CompletionHandler&& comp GST_DEBUG_OBJECT(m_transcoder.get(), "Stop requested, pushing EOS event"); auto scopeExit = makeScopeExit([this, completionHandler = WTFMove(completionHandler)]() mutable { + unregisterPipeline(m_pipeline); m_pipeline.clear(); GST_DEBUG_OBJECT(m_transcoder.get(), "Stopping"); m_transcoder.clear(); @@ -297,12 +298,11 @@ GRefPtr MediaRecorderPrivateBackend::containerProfi void MediaRecorderPrivateBackend::setSource(GstElement* element) { auto selectedTracks = MediaRecorderPrivate::selectTracks(stream()); - bool onlyTrack = (selectedTracks.audioTrack && !selectedTracks.videoTrack) || (selectedTracks.videoTrack && !selectedTracks.audioTrack); auto* src = WEBKIT_MEDIA_STREAM_SRC(element); if (selectedTracks.audioTrack) - webkitMediaStreamSrcAddTrack(src, selectedTracks.audioTrack, onlyTrack); + webkitMediaStreamSrcAddTrack(src, selectedTracks.audioTrack); if (selectedTracks.videoTrack) - webkitMediaStreamSrcAddTrack(src, selectedTracks.videoTrack, onlyTrack); + webkitMediaStreamSrcAddTrack(src, selectedTracks.videoTrack); if (m_selectTracksCallback) { auto& callback = *m_selectTracksCallback; callback(selectedTracks); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/mediastream/RTCRtpTransceiverDirection.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/mediastream/RTCRtpTransceiverDirection.h index 7c0d67db592..15d7136bdc1 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/mediastream/RTCRtpTransceiverDirection.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/mediastream/RTCRtpTransceiverDirection.h @@ -27,6 +27,8 @@ #if ENABLE(WEB_RTC) +#include + namespace WebCore { enum class RTCRtpTransceiverDirection { @@ -36,6 +38,8 @@ enum class RTCRtpTransceiverDirection { Inactive }; +String convertEnumerationToString(RTCRtpTransceiverDirection); // in JSRTCRtpTransceiverDirection.h + } // namespace WebCore #endif diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/text/SegmentedString.h b/modules/javafx.web/src/main/native/Source/WebCore/platform/text/SegmentedString.h index 7602a3651c1..06ff28c51fe 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/text/SegmentedString.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/text/SegmentedString.h @@ -97,10 +97,10 @@ class SegmentedString { unsigned originalLength { 0 }; unsigned length { 0 }; union { - const LChar* currentCharacter8; + const LChar* currentCharacter8 { nullptr }; const UChar* currentCharacter16; }; - bool is8Bit; + bool is8Bit { true }; bool doNotExcludeLineNumbers { true }; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/platform/xdg/MIMETypeRegistryXdg.cpp b/modules/javafx.web/src/main/native/Source/WebCore/platform/xdg/MIMETypeRegistryXdg.cpp index 595b30a77b5..e32a6184679 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/platform/xdg/MIMETypeRegistryXdg.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/platform/xdg/MIMETypeRegistryXdg.cpp @@ -29,6 +29,7 @@ #define XDG_PREFIX _wk_xdg #include "xdgmime.h" +#define MAX_EXTENSION_COUNT 10 namespace WebCore { String MIMETypeRegistry::mimeTypeForExtension(StringView string) @@ -69,10 +70,19 @@ String MIMETypeRegistry::preferredExtensionForMIMEType(const String& mimeType) return returnValue; } -Vector MIMETypeRegistry::extensionsForMIMEType(const String&) +Vector MIMETypeRegistry::extensionsForMIMEType(const String& mimeType) { - ASSERT_NOT_IMPLEMENTED_YET(); + if (mimeType.isEmpty()) return { }; + + Vector returnValue; + char* extensions[MAX_EXTENSION_COUNT]; + int n = xdg_mime_get_simple_globs(mimeType.utf8().data(), extensions, MAX_EXTENSION_COUNT); + for (int i = 0; i < n; ++i) { + returnValue.append(String::fromUTF8(extensions[i])); + free(extensions[i]); + } + return returnValue; } } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/plugins/PluginInfoProvider.h b/modules/javafx.web/src/main/native/Source/WebCore/plugins/PluginInfoProvider.h index f9d8a3f67a8..4e4ab9ff13b 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/plugins/PluginInfoProvider.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/plugins/PluginInfoProvider.h @@ -47,7 +47,7 @@ class WEBCORE_EXPORT PluginInfoProvider : public RefCounted, private: virtual void refreshPlugins() = 0; - SingleThreadWeakHashSet m_pages; + WeakHashSet m_pages; }; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/InlineBoxPainter.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/InlineBoxPainter.cpp index 14770df62bc..18ca5678ee3 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/InlineBoxPainter.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/InlineBoxPainter.cpp @@ -238,7 +238,7 @@ void InlineBoxPainter::paintDecorations() if (!BackgroundPainter::boxShadowShouldBeAppliedToBackground(renderer(), adjustedPaintoffset, BackgroundBleedNone, m_inlineBox)) paintBoxShadow(ShadowStyle::Normal, paintRect); - auto color = style.visitedDependentColor(CSSPropertyBackgroundColor); + auto color = style.visitedDependentColor(CSSPropertyBackgroundColor, m_paintInfo.paintBehavior); auto compositeOp = renderer().document().compositeOperatorForBackgroundColor(color, renderer()); color = style.colorByApplyingColorFilter(color); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp index a0b024dcd2e..213d3d3ca7e 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayer.cpp @@ -2166,11 +2166,11 @@ bool RenderLayer::cannotBlitToWindow() const RenderLayer* RenderLayer::transparentPaintingAncestor() { - if (isComposited()) + if (isComposited() || paintsIntoProvidedBacking()) return nullptr; for (RenderLayer* curr = stackingContext(); curr; curr = curr->stackingContext()) { - if (curr->isComposited()) + if (curr->isComposited() || curr->paintsIntoProvidedBacking()) break; if (curr->isTransparent()) return curr; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerCompositor.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerCompositor.cpp index 8e12f3ad858..ae08a7f907f 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerCompositor.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderLayerCompositor.cpp @@ -3854,11 +3854,13 @@ static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, auto appendOverflowLayerNodeID = [&scrollingNodes] (const RenderLayer& overflowLayer) { ASSERT(overflowLayer.isComposited()); - auto scrollingNodeID = overflowLayer.backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling); - if (scrollingNodeID) + if (overflowLayer.isComposited()) { + if (auto scrollingNodeID = overflowLayer.backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling)) { scrollingNodes.append(scrollingNodeID); - else - LOG(Scrolling, "Layer %p doesn't have scrolling node ID yet", &overflowLayer); + return; + } + } + LOG(Scrolling, "Layer %p isn't composited or doesn't have scrolling node ID yet", &overflowLayer); }; // Collect all the composited scrollers which affect the position of this layer relative to its compositing ancestor (which might be inside the scroller or the scroller itself). diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderListBox.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderListBox.cpp index 3a40dd4b456..0bf71eaec43 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderListBox.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderListBox.cpp @@ -484,7 +484,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint& const auto& listItems = selectElement().listItems(); RefPtr listItemElement = listItems[listIndex].get(); - auto itemStyle = listItemElement->computedStyle(); + auto itemStyle = listItemElement->computedStyleForEditability(); if (!itemStyle) return; @@ -544,7 +544,7 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& { const auto& listItems = selectElement().listItems(); RefPtr listItemElement = listItems[listIndex].get(); - auto itemStyle = listItemElement->computedStyle(); + auto itemStyle = listItemElement->computedStyleForEditability(); if (!itemStyle) return; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderMenuList.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderMenuList.cpp index cde4c2706ae..bcf0bc70645 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderMenuList.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/RenderMenuList.cpp @@ -216,7 +216,7 @@ void RenderMenuList::updateOptionsWidth() if (theme().popupOptionSupportsTextIndent()) { // Add in the option's text indent. We can't calculate percentage values for now. float optionWidth = 0; - if (auto* optionStyle = option->computedStyle()) + if (auto* optionStyle = option->computedStyleForEditability()) optionWidth += minimumValueForLength(optionStyle->textIndent(), 0); if (!text.isEmpty()) { const FontCascade& font = style().fontCascade(); @@ -265,7 +265,7 @@ void RenderMenuList::setTextFromOption(int optionIndex) if (i >= 0 && i < size) { if (RefPtr option = dynamicDowncast(*listItems[i])) { text = option->textIndentedToRespectGroupLabel(); - auto* style = option->computedStyle(); + auto* style = option->computedStyleForEditability(); m_optionStyle = style ? RenderStyle::clonePtr(*style) : nullptr; } } @@ -515,9 +515,12 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const bool itemHasCustomBackgroundColor; getItemBackgroundColor(listIndex, itemBackgroundColor, itemHasCustomBackgroundColor); - auto& style = *element->computedStyle(); - return PopupMenuStyle(style.visitedDependentColorWithColorFilter(CSSPropertyColor), itemBackgroundColor, style.fontCascade(), style.visibility() == Visibility::Visible, - style.display() == DisplayType::None, true, style.textIndent(), style.direction(), isOverride(style.unicodeBidi()), + auto* style = element->computedStyleForEditability(); + if (!style) + return menuStyle(); + + return PopupMenuStyle(style->visitedDependentColorWithColorFilter(CSSPropertyColor), itemBackgroundColor, style->fontCascade(), style->visibility() == Visibility::Visible, + style->display() == DisplayType::None, true, style->textIndent(), style->direction(), isOverride(style->unicodeBidi()), itemHasCustomBackgroundColor ? PopupMenuStyle::CustomBackgroundColor : PopupMenuStyle::DefaultBackgroundColor); } @@ -531,7 +534,10 @@ void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackg } HTMLElement* element = listItems[listIndex].get(); - Color backgroundColor = element->computedStyle()->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor); + Color backgroundColor; + if (auto* style = element->computedStyleForEditability()) + backgroundColor = style->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor); + itemHasCustomBackgroundColor = backgroundColor.isValid() && backgroundColor.isVisible(); // If the item has an opaque background color, return that. if (backgroundColor.isOpaque()) { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/style/StyleGradientImage.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/style/StyleGradientImage.cpp index 29b8bcd4f72..549c9f82fad 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/style/StyleGradientImage.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/style/StyleGradientImage.cpp @@ -568,9 +568,12 @@ GradientColorStops StyleGradientImage::computeStops(GradientAdapter& gradientAda // We can't just push this logic down into the platform-specific Gradient code, // because we have to know the extent of the gradient, and possible move the end points. if (repeating == CSSGradientRepeat::Repeating && numberOfStops > 1) { + float maxExtent = gradientAdapter.maxExtent(maxLengthForRepeat, gradientLength); // If the difference in the positions of the first and last color-stops is 0, // the gradient defines a solid-color image with the color of the last color-stop in the rule. float gradientRange = *stops.last().offset - *stops.first().offset; + if (maxExtent > 1) + gradientRange /= maxExtent; if (!gradientRange) { stops.first().offset = 0; stops.first().color = stops.last().color; @@ -587,7 +590,6 @@ GradientColorStops StyleGradientImage::computeStops(GradientAdapter& gradientAda } else { // Since the gradient range is deemed big enough, the amount of necessary stops is // calculated for both the [0, first-offset] and the [last-offset, maxExtent] ranges. - float maxExtent = gradientAdapter.maxExtent(maxLengthForRepeat, gradientLength); CheckedSize numberOfGeneratedStopsBeforeFirst; CheckedSize numberOfGeneratedStopsAfterLast; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.cpp index a14ac6d9149..25271d06c7d 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.cpp @@ -310,6 +310,11 @@ std::unique_ptr SVGResources::buildCachedResources(const RenderEle void SVGResources::layoutDifferentRootIfNeeded(const RenderElement& resourcesClient) { + if (m_inLayoutForDifferentRoot) + return; + + SetForScope inLayoutForDifferentRoot(m_inLayoutForDifferentRoot, true); + const LegacyRenderSVGRoot* clientRoot = nullptr; auto layoutDifferentRootIfNeeded = [&](LegacyRenderSVGResourceContainer* container) { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.h b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.h index 3727907a4de..7deacd6661b 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/svg/SVGResources.h @@ -144,6 +144,7 @@ class SVGResources { std::unique_ptr m_markerData; std::unique_ptr m_fillStrokeData; SingleThreadWeakPtr m_linkedResource; + bool m_inLayoutForDifferentRoot { false }; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp index 00a5d39d920..7fe258f7cbb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilder.cpp @@ -852,32 +852,32 @@ void RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(RenderObject& rendere return *destroyRoot; }; - auto& destroyRoot = destroyRootIncludingAnonymous(); + WeakPtr destroyRoot = destroyRootIncludingAnonymous(); auto clearFloatsAndOutOfFlowPositionedObjects = [&] { // Remove floats and out-of-flow positioned objects from their containing block before detaching // the renderer from the tree. It includes all the anonymous block descendants that we are about // to destroy as well as part of the cleanup process below. - auto* destroyRootElement = dynamicDowncast(destroyRoot); + WeakPtr destroyRootElement = dynamicDowncast(destroyRoot.get()); if (!destroyRootElement) return; for (auto& descendant : descendantsOfType(*destroyRootElement)) { if (descendant.isFloatingOrOutOfFlowPositioned()) descendant.removeFloatingOrPositionedChildFromBlockLists(); } - if (CheckedPtr box = dynamicDowncast(destroyRoot); box && box->isFloatingOrOutOfFlowPositioned()) + if (CheckedPtr box = dynamicDowncast(destroyRoot.get()); box && box->isFloatingOrOutOfFlowPositioned()) box->removeFloatingOrPositionedChildFromBlockLists(); }; clearFloatsAndOutOfFlowPositionedObjects(); auto collapseAndDestroyAnonymousSiblings = [&] { // FIXME: Probably need to handle other table parts here as well. - if (CheckedPtr cell = dynamicDowncast(destroyRoot)) { + if (CheckedPtr cell = dynamicDowncast(destroyRoot.get())) { tableBuilder().collapseAndDestroyAnonymousSiblingCells(*cell); return; } - if (CheckedPtr row = dynamicDowncast(destroyRoot)) { + if (CheckedPtr row = dynamicDowncast(destroyRoot.get())) { tableBuilder().collapseAndDestroyAnonymousSiblingRows(*row); return; } @@ -885,12 +885,15 @@ void RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(RenderObject& rendere collapseAndDestroyAnonymousSiblings(); // FIXME: Do not try to collapse/cleanup the anonymous wrappers inside destroy (see webkit.org/b/186746). - WeakPtr destroyRootParent = *destroyRoot.parent(); - if (&rendererToDestroy != &destroyRoot) { + WeakPtr destroyRootParent = destroyRoot->parent(); + if (&rendererToDestroy != destroyRoot.get()) { // Destroy the child renderer first, before we start tearing down the anonymous wrapper ancestor chain. destroy(rendererToDestroy); } - destroy(destroyRoot); + + if (destroyRoot) + destroy(*destroyRoot); + if (!destroyRootParent) return; removeAnonymousWrappersForInlineChildrenIfNeeded(*destroyRootParent); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp index 4b9b01d431e..429a8b85950 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp @@ -271,10 +271,18 @@ RenderElement& RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild if (!child.isRenderText() && child.style().display() == DisplayType::Ruby && parent.style().display() == DisplayType::RubyBlock) return parent; - if (parent.style().display() == DisplayType::RubyBlock && parent.firstChild()) { + if (parent.style().display() == DisplayType::RubyBlock) { // See if we have an anonymous ruby box already. - ASSERT(parent.firstChild()->style().display() == DisplayType::Ruby); - return downcast(*parent.firstChild()); + // FIXME: It should be the immediate child but continuations can break this assumption. + for (CheckedPtr first = parent.firstChild(); first; first = first->firstChildSlow()) { + if (!first->isAnonymous()) { + // is valid and still requires construction of an anonymous inline ruby box. + ASSERT(first->style().display() == DisplayType::Ruby); + break; + } + if (first->style().display() == DisplayType::Ruby) + return downcast(*first); + } } if (parent.style().display() != DisplayType::Ruby) { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGElement.cpp b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGElement.cpp index c188c0cd5b5..f2bc3173f2a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGElement.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/svg/SVGElement.cpp @@ -1042,13 +1042,13 @@ Node::InsertedIntoAncestorResult SVGElement::insertedIntoAncestor(InsertionType else if (RefPtr parentElement = dynamicDowncast(parentNode()); parentElement && &parentOfInsertedTree == parentNode()) parentElement->updateRelativeLengthsInformationForChild(hasRelativeLengths(), *this); + hideNonce(); + if (needsPendingResourceHandling() && insertionType.connectedToDocument && !isInShadowTree()) { if (treeScopeForSVGReferences().isIdOfPendingSVGResource(getIdAttribute())) return InsertedIntoAncestorResult::NeedsPostInsertionCallback; } - hideNonce(); - return InsertedIntoAncestorResult::Done; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/testing/InternalSettings.h b/modules/javafx.web/src/main/native/Source/WebCore/testing/InternalSettings.h index 2a6eedea7b8..b3eba11e8f7 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/testing/InternalSettings.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/testing/InternalSettings.h @@ -165,7 +165,7 @@ class InternalSettings : public InternalSettingsGenerated { bool m_shouldDeactivateAudioSession; }; - SingleThreadWeakPtr m_page; + WeakPtr m_page; Backup m_backup; }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/Worker.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/Worker.cpp index 99668d09c5d..67aaf3aae78 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/Worker.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/Worker.cpp @@ -222,6 +222,7 @@ void Worker::notifyFinished() WorkerInitializationData initializationData { m_scriptLoader->takeServiceWorkerData(), m_clientIdentifier, + m_scriptLoader->advancedPrivacyProtections(), context->userAgent(m_scriptLoader->responseURL()) }; m_contextProxy.startWorkerGlobalScope(m_scriptLoader->responseURL(), *sessionID, m_options.name, WTFMove(initializationData), m_scriptLoader->script(), contentSecurityPolicyResponseHeaders, m_shouldBypassMainWorldContentSecurityPolicy, m_scriptLoader->crossOriginEmbedderPolicy(), m_workerCreationTime, referrerPolicy, m_options.type, m_options.credentials, m_runtimeFlags); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerGlobalScope.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerGlobalScope.cpp index abf2146a4e3..4c6351b284a 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerGlobalScope.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerGlobalScope.cpp @@ -97,7 +97,7 @@ static WorkQueue& sharedFileSystemStorageQueue() WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerGlobalScope); WorkerGlobalScope::WorkerGlobalScope(WorkerThreadType type, const WorkerParameters& params, Ref&& origin, WorkerThread& thread, Ref&& topOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, std::unique_ptr&& workerClient) - : WorkerOrWorkletGlobalScope(type, params.sessionID, isMainThread() ? Ref { commonVM() } : JSC::VM::create(), params.referrerPolicy, &thread, params.noiseInjectionHashSalt, params.clientIdentifier) + : WorkerOrWorkletGlobalScope(type, params.sessionID, isMainThread() ? Ref { commonVM() } : JSC::VM::create(), params.referrerPolicy, &thread, params.noiseInjectionHashSalt, params.advancedPrivacyProtections, params.clientIdentifier) , m_url(params.scriptURL) , m_ownerURL(params.ownerURL) , m_inspectorIdentifier(params.inspectorIdentifier) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerInitializationData.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerInitializationData.h index f2a73bd6848..eab8d841996 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerInitializationData.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerInitializationData.h @@ -25,9 +25,11 @@ #pragma once +#include "AdvancedPrivacyProtections.h" #include "ScriptExecutionContextIdentifier.h" #include "ServiceWorkerData.h" #include +#include #include namespace WebCore { @@ -35,6 +37,7 @@ namespace WebCore { struct WorkerInitializationData { std::optional serviceWorkerData; std::optional clientIdentifier; + OptionSet advancedPrivacyProtections; String userAgent; WorkerInitializationData isolatedCopy() const; @@ -45,6 +48,7 @@ inline WorkerInitializationData WorkerInitializationData::isolatedCopy() const return { crossThreadCopy(serviceWorkerData), clientIdentifier, + advancedPrivacyProtections, userAgent.isolatedCopy() }; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerMessagingProxy.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerMessagingProxy.cpp index 76d9dc74baa..e4630e51c30 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerMessagingProxy.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerMessagingProxy.cpp @@ -149,6 +149,7 @@ void WorkerMessagingProxy::startWorkerGlobalScope(const URL& scriptURL, PAL::Ses WorkerParameters params { scriptURL, m_scriptExecutionContext->url(), name, identifier, WTFMove(initializationData.userAgent), isOnline, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, crossOriginEmbedderPolicy, timeOrigin, referrerPolicy, workerType, credentials, m_scriptExecutionContext->settingsValues(), WorkerThreadMode::CreateNewThread, sessionID, WTFMove(initializationData.serviceWorkerData), initializationData.clientIdentifier.value_or(ScriptExecutionContextIdentifier { }), + m_scriptExecutionContext->advancedPrivacyProtections(), m_scriptExecutionContext->noiseInjectionHashSalt() }; auto thread = DedicatedWorkerThread::create(params, sourceCode, *this, *this, *this, *this, startMode, m_scriptExecutionContext->topOrigin(), proxy, socketProvider, runtimeFlags); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp index 45feab347dc..97be22eda70 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.cpp @@ -40,7 +40,7 @@ namespace WebCore { WTF_MAKE_ISO_ALLOCATED_IMPL(WorkerOrWorkletGlobalScope); -WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(WorkerThreadType type, PAL::SessionID sessionID, Ref&& vm, ReferrerPolicy referrerPolicy, WorkerOrWorkletThread* thread, std::optional noiseInjectionHashSalt, ScriptExecutionContextIdentifier contextIdentifier) +WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(WorkerThreadType type, PAL::SessionID sessionID, Ref&& vm, ReferrerPolicy referrerPolicy, WorkerOrWorkletThread* thread, std::optional noiseInjectionHashSalt, OptionSet advancedPrivacyProtections, ScriptExecutionContextIdentifier contextIdentifier) : ScriptExecutionContext(Type::WorkerOrWorkletGlobalScope, contextIdentifier) , m_script(makeUnique(type, WTFMove(vm), this)) , m_moduleLoader(makeUnique(this, ScriptModuleLoader::OwnerType::WorkerOrWorklet)) @@ -49,6 +49,7 @@ WorkerOrWorkletGlobalScope::WorkerOrWorkletGlobalScope(WorkerThreadType type, PA , m_sessionID(sessionID) , m_referrerPolicy(referrerPolicy) , m_noiseInjectionHashSalt(noiseInjectionHashSalt) + , m_advancedPrivacyProtections(advancedPrivacyProtections) { relaxAdoptionRequirement(); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h index fc64ee1a76e..9dd71ea166f 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletGlobalScope.h @@ -39,6 +39,8 @@ class WorkerInspectorController; class WorkerOrWorkletScriptController; class WorkerOrWorkletThread; +enum class AdvancedPrivacyProtections : uint16_t; + class WorkerOrWorkletGlobalScope : public RefCounted, public ScriptExecutionContext, public EventTarget { WTF_MAKE_ISO_ALLOCATED(WorkerOrWorkletGlobalScope); WTF_MAKE_NONCOPYABLE(WorkerOrWorkletGlobalScope); @@ -83,9 +85,10 @@ class WorkerOrWorkletGlobalScope : public RefCounted virtual FetchOptions::Destination destination() const = 0; ReferrerPolicy referrerPolicy() const final { return m_referrerPolicy; } std::optional noiseInjectionHashSalt() const final { return m_noiseInjectionHashSalt; } + OptionSet advancedPrivacyProtections() const final { return m_advancedPrivacyProtections; } protected: - WorkerOrWorkletGlobalScope(WorkerThreadType, PAL::SessionID, Ref&&, ReferrerPolicy, WorkerOrWorkletThread*, std::optional, ScriptExecutionContextIdentifier = { }); + WorkerOrWorkletGlobalScope(WorkerThreadType, PAL::SessionID, Ref&&, ReferrerPolicy, WorkerOrWorkletThread*, std::optional, OptionSet, ScriptExecutionContextIdentifier = { }); // ScriptExecutionContext. bool isJSExecutionForbidden() const final; @@ -116,6 +119,7 @@ class WorkerOrWorkletGlobalScope : public RefCounted ReferrerPolicy m_referrerPolicy; bool m_isClosing { false }; std::optional m_noiseInjectionHashSalt; + OptionSet m_advancedPrivacyProtections; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletThread.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletThread.cpp index 3b4af74f137..fdd0d19b68c 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletThread.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerOrWorkletThread.cpp @@ -110,7 +110,7 @@ void WorkerOrWorkletThread::runEventLoop() { // Does not return until terminated. if (is(m_runLoop.get())) - downcast(m_runLoop.get()).run(m_globalScope.get()); + downcast(m_runLoop.get()).run(RefPtr { m_globalScope }.get()); } void WorkerOrWorkletThread::workerOrWorkletThread() diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.cpp index 90cdca9a00f..a20fd013e10 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.cpp @@ -76,6 +76,7 @@ std::optional WorkerScriptLoader::loadSynchronously(ScriptExecutionCo m_source = source; m_destination = FetchOptions::Destination::Script; m_isCOEPEnabled = scriptExecutionContext->settingsValues().crossOriginEmbedderPolicyEnabled; + m_advancedPrivacyProtections = scriptExecutionContext->advancedPrivacyProtections(); auto* serviceWorkerGlobalScope = dynamicDowncast(workerGlobalScope); if (serviceWorkerGlobalScope) { @@ -131,6 +132,7 @@ void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext& scriptExecut m_destination = fetchOptions.destination; m_isCOEPEnabled = scriptExecutionContext.settingsValues().crossOriginEmbedderPolicyEnabled; m_clientIdentifier = clientIdentifier; + m_advancedPrivacyProtections = scriptExecutionContext.advancedPrivacyProtections(); ASSERT(scriptRequest.httpMethod() == "GET"_s); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.h index 9f1008a55d5..f34644853f8 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerScriptLoader.h @@ -26,6 +26,7 @@ #pragma once +#include "AdvancedPrivacyProtections.h" #include "CertificateInfo.h" #include "ContentSecurityPolicyResponseHeaders.h" #include "CrossOriginEmbedderPolicy.h" @@ -40,6 +41,7 @@ #include "ThreadableLoaderClient.h" #include #include +#include #include #include #include @@ -70,6 +72,8 @@ class WorkerScriptLoader : public RefCounted, public Threada void notifyError(); + OptionSet advancedPrivacyProtections() const { return m_advancedPrivacyProtections; } + const ScriptBuffer& script() const { return m_script; } const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy() const { return m_contentSecurityPolicy; } const String& referrerPolicy() const { return m_referrerPolicy; } @@ -160,6 +164,7 @@ class WorkerScriptLoader : public RefCounted, public Threada RefPtr m_serviceWorkerDataManager; WeakPtr m_context; String m_userAgentForSharedWorker; + OptionSet m_advancedPrivacyProtections; }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.cpp index 369b08df253..0071043bfd2 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.cpp @@ -27,6 +27,7 @@ #include "config.h" #include "WorkerThread.h" +#include "AdvancedPrivacyProtections.h" #include "IDBConnectionProxy.h" #include "ScriptSourceCode.h" #include "SecurityOrigin.h" @@ -71,6 +72,7 @@ WorkerParameters WorkerParameters::isolatedCopy() const sessionID, crossThreadCopy(serviceWorkerData), clientIdentifier, + advancedPrivacyProtections, noiseInjectionHashSalt }; } @@ -198,6 +200,7 @@ SocketProvider* WorkerThread::socketProvider() WorkerGlobalScope* WorkerThread::globalScope() { + ASSERT(!thread() || thread() == &Thread::current()); return downcast(WorkerOrWorkletThread::globalScope()); } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.h index 4be2244ed1a..75a7bb8f9b5 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/WorkerThread.h @@ -62,6 +62,8 @@ namespace IDBClient { class IDBConnectionProxy; } +enum class AdvancedPrivacyProtections : uint16_t; + struct WorkerThreadStartupData; struct WorkerParameters { @@ -84,6 +86,7 @@ struct WorkerParameters { PAL::SessionID sessionID; std::optional serviceWorkerData; ScriptExecutionContextIdentifier clientIdentifier; + OptionSet advancedPrivacyProtections; std::optional noiseInjectionHashSalt; WorkerParameters isolatedCopy() const; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.cpp index fe962e0cbcc..71c82fd8ed6 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "ServiceWorkerClientData.h" +#include "AdvancedPrivacyProtections.h" #include "Document.h" #include "DocumentLoader.h" #include "FrameDestructionObserverInlines.h" @@ -59,12 +60,12 @@ static ServiceWorkerClientFrameType toServiceWorkerClientFrameType(ScriptExecuti ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() const & { - return { identifier, type, frameType, url.isolatedCopy(), ownerURL.isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(ancestorOrigins) }; + return { identifier, type, frameType, url.isolatedCopy(), ownerURL.isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, advancedPrivacyProtections, isVisible, isFocused, focusOrder, crossThreadCopy(ancestorOrigins) }; } ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() && { - return { identifier, type, frameType, WTFMove(url).isolatedCopy(), WTFMove(ownerURL).isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, isVisible, isFocused, focusOrder, crossThreadCopy(WTFMove(ancestorOrigins)) }; + return { identifier, type, frameType, WTFMove(url).isolatedCopy(), WTFMove(ownerURL).isolatedCopy(), pageIdentifier, frameIdentifier, lastNavigationWasAppInitiated, advancedPrivacyProtections, isVisible, isFocused, focusOrder, crossThreadCopy(WTFMove(ancestorOrigins)) }; } ServiceWorkerClientData ServiceWorkerClientData::from(ScriptExecutionContext& context) @@ -89,6 +90,7 @@ ServiceWorkerClientData ServiceWorkerClientData::from(ScriptExecutionContext& co document->pageID(), document->frameID(), lastNavigationWasAppInitiated, + context.advancedPrivacyProtections(), !document->hidden(), document->hasFocus(), 0, @@ -107,6 +109,7 @@ ServiceWorkerClientData ServiceWorkerClientData::from(ScriptExecutionContext& co { }, { }, LastNavigationWasAppInitiated::No, + context.advancedPrivacyProtections(), false, false, 0, diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.h index 759302e6c67..b57de45f447 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/ServiceWorkerClientData.h @@ -38,6 +38,7 @@ namespace WebCore { class SWClientConnection; class ScriptExecutionContext; +enum class AdvancedPrivacyProtections : uint16_t; enum class LastNavigationWasAppInitiated : bool { No, Yes }; struct ServiceWorkerClientData { @@ -51,6 +52,7 @@ struct ServiceWorkerClientData { std::optional pageIdentifier; std::optional frameIdentifier; LastNavigationWasAppInitiated lastNavigationWasAppInitiated; + OptionSet advancedPrivacyProtections; bool isVisible { false }; bool isFocused { false }; uint64_t focusOrder { 0 }; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp index 619651bdfb7..cbbb2f46057 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "ServiceWorkerThread.h" +#include "AdvancedPrivacyProtections.h" #include "BackgroundFetchManager.h" #include "BackgroundFetchUpdateUIEvent.h" #include "CacheStorageProvider.h" @@ -81,7 +82,7 @@ class DummyServiceWorkerThreadProxy : public WorkerObjectProxy { // FIXME: Use a valid WorkerObjectProxy // FIXME: Use valid runtime flags -static WorkerParameters generateWorkerParameters(const ServiceWorkerContextData& contextData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, PAL::SessionID sessionID, std::optional noiseInjectionHashSalt) +static WorkerParameters generateWorkerParameters(const ServiceWorkerContextData& contextData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, PAL::SessionID sessionID, OptionSet advancedPrivacyProtections, std::optional noiseInjectionHashSalt) { return { contextData.scriptURL, @@ -102,12 +103,13 @@ static WorkerParameters generateWorkerParameters(const ServiceWorkerContextData& sessionID, { }, { }, + advancedPrivacyProtections, noiseInjectionHashSalt }; } -ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, WorkerBadgeProxy& badgeProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider, std::unique_ptr&& notificationClient, PAL::SessionID sessionID, std::optional noiseInjectionHashSalt) - : WorkerThread(generateWorkerParameters(contextData, WTFMove(userAgent), workerThreadMode, settingsValues, sessionID, noiseInjectionHashSalt), contextData.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), badgeProxy, WorkerThreadStartMode::Normal, contextData.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled()) +ServiceWorkerThread::ServiceWorkerThread(ServiceWorkerContextData&& contextData, ServiceWorkerData&& workerData, String&& userAgent, WorkerThreadMode workerThreadMode, const Settings::Values& settingsValues, WorkerLoaderProxy& loaderProxy, WorkerDebuggerProxy& debuggerProxy, WorkerBadgeProxy& badgeProxy, IDBClient::IDBConnectionProxy* idbConnectionProxy, SocketProvider* socketProvider, std::unique_ptr&& notificationClient, PAL::SessionID sessionID, std::optional noiseInjectionHashSalt, OptionSet advancedPrivacyProtections) + : WorkerThread(generateWorkerParameters(contextData, WTFMove(userAgent), workerThreadMode, settingsValues, sessionID, advancedPrivacyProtections, noiseInjectionHashSalt), contextData.script, loaderProxy, debuggerProxy, DummyServiceWorkerThreadProxy::shared(), badgeProxy, WorkerThreadStartMode::Normal, contextData.registration.key.topOrigin().securityOrigin().get(), idbConnectionProxy, socketProvider, JSC::RuntimeFlags::createAllEnabled()) , m_serviceWorkerIdentifier(contextData.serviceWorkerIdentifier) , m_jobDataIdentifier(contextData.jobDataIdentifier) , m_contextData(crossThreadCopy(WTFMove(contextData))) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.h index e5544e91574..cc3ee154681 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThread.h @@ -36,6 +36,7 @@ #include "Settings.h" #include "Timer.h" #include "WorkerThread.h" +#include #include namespace WebCore { @@ -50,6 +51,8 @@ struct MessageWithMessagePorts; struct NotificationData; struct NotificationPayload; +enum class AdvancedPrivacyProtections : uint16_t; + class ServiceWorkerThread : public WorkerThread, public CanMakeWeakPtr { public: template static Ref create(Args&&... args) @@ -98,7 +101,7 @@ class ServiceWorkerThread : public WorkerThread, public CanMakeWeakPtr&&, PAL::SessionID, std::optional); + WEBCORE_EXPORT ServiceWorkerThread(ServiceWorkerContextData&&, ServiceWorkerData&&, String&& userAgent, WorkerThreadMode, const Settings::Values&, WorkerLoaderProxy&, WorkerDebuggerProxy&, WorkerBadgeProxy&, IDBClient::IDBConnectionProxy*, SocketProvider*, std::unique_ptr&&, PAL::SessionID, std::optional, OptionSet); ASCIILiteral threadName() const final { return "WebCore: ServiceWorker"_s; } void finishedEvaluatingScript() final; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp index 575c196ffb7..c98b2323fa5 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp @@ -70,7 +70,7 @@ ServiceWorkerThreadProxy::ServiceWorkerThreadProxy(Ref&& page, ServiceWork #if ENABLE(REMOTE_INSPECTOR) , m_remoteDebuggable(makeUnique(*this, contextData)) #endif - , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), workerThreadMode, m_document->settingsValues(), *this, *this, *this, idbConnectionProxy(m_document), m_document->socketProvider(), WTFMove(notificationClient), m_page->sessionID(), m_document->noiseInjectionHashSalt())) + , m_serviceWorkerThread(ServiceWorkerThread::create(WTFMove(contextData), WTFMove(workerData), WTFMove(userAgent), workerThreadMode, m_document->settingsValues(), *this, *this, *this, idbConnectionProxy(m_document), m_document->socketProvider(), WTFMove(notificationClient), m_page->sessionID(), m_document->noiseInjectionHashSalt(), m_document->advancedPrivacyProtections())) , m_cacheStorageProvider(cacheStorageProvider) , m_inspectorProxy(*this) { diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.cpp index 1ce8416d1ba..b1914b6dc75 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "SWServer.h" +#include "AdvancedPrivacyProtections.h" #include "BackgroundFetchEngine.h" #include "BackgroundFetchInformation.h" #include "BackgroundFetchOptions.h" @@ -743,19 +744,30 @@ void SWServer::matchAll(SWServerWorker& worker, const ServiceWorkerClientQueryOp callback(WTFMove(matchingClients)); } -void SWServer::forEachClientForOrigin(const ClientOrigin& origin, const Function& apply) +template +void forEachClientForOriginImpl(const Vector& identifiers, ClientsByIDType& clientsById, const Function& apply) { - auto iterator = m_clientIdentifiersPerOrigin.find(origin); - if (iterator == m_clientIdentifiersPerOrigin.end()) - return; - - for (auto& clientIdentifier : iterator->value.identifiers) { - auto clientIterator = m_clientsById.find(clientIdentifier); - ASSERT(clientIterator != m_clientsById.end()); + for (auto& clientIdentifier : identifiers) { + auto clientIterator = clientsById.find(clientIdentifier); + ASSERT(clientIterator != clientsById.end()); apply(clientIterator->value); } } +void SWServer::forEachClientForOrigin(const ClientOrigin& origin, const Function& apply) const +{ + auto iterator = m_clientIdentifiersPerOrigin.find(origin); + if (iterator != m_clientIdentifiersPerOrigin.end()) + forEachClientForOriginImpl(iterator->value.identifiers, m_clientsById, apply); +} + +void SWServer::forEachClientForOrigin(const ClientOrigin& origin, const Function& apply) +{ + auto iterator = m_clientIdentifiersPerOrigin.find(origin); + if (iterator != m_clientIdentifiersPerOrigin.end()) + forEachClientForOriginImpl(iterator->value.identifiers, m_clientsById, apply); +} + std::optional SWServer::claim(SWServerWorker& worker) { RefPtr registration = worker.registration(); @@ -893,6 +905,15 @@ void SWServer::terminateContextConnectionWhenPossible(const RegistrableDomain& r contextConnection->terminateWhenPossible(); } +OptionSet SWServer::advancedPrivacyProtectionsFromClient(const ClientOrigin& origin) const +{ + OptionSet result; + forEachClientForOrigin(origin, [&result](auto& clientData) { + result.add(clientData.advancedPrivacyProtections); + }); + return result; +} + void SWServer::installContextData(const ServiceWorkerContextData& data) { ASSERT_WITH_MESSAGE(!data.loadedFromDisk, "Workers we just read from disk should only be launched as needed"); @@ -916,7 +937,7 @@ void SWServer::installContextData(const ServiceWorkerContextData& data) auto result = m_runningOrTerminatingWorkers.add(data.serviceWorkerIdentifier, worker.copyRef()); ASSERT_UNUSED(result, result.isNewEntry); - connection->installServiceWorkerContext(data, worker->data(), userAgent, worker->workerThreadMode()); + connection->installServiceWorkerContext(data, worker->data(), userAgent, worker->workerThreadMode(), advancedPrivacyProtectionsFromClient(worker->registrationKey().clientOrigin())); } void SWServer::runServiceWorkerIfNecessary(ServiceWorkerIdentifier identifier, RunServiceWorkerCallback&& callback) @@ -993,7 +1014,7 @@ bool SWServer::runServiceWorker(SWServerWorker& worker) CheckedPtr contextConnection = worker.contextConnection(); ASSERT(contextConnection); - contextConnection->installServiceWorkerContext(worker.contextData(), worker.data(), worker.userAgent(), worker.workerThreadMode()); + contextConnection->installServiceWorkerContext(worker.contextData(), worker.data(), worker.userAgent(), worker.workerThreadMode(), advancedPrivacyProtectionsFromClient(worker.registrationKey().clientOrigin())); return true; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.h index 1ebc34a09d5..a5514ff85cb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServer.h @@ -65,6 +65,7 @@ class SWServerRegistration; class SWServerToContextConnection; class Timer; +enum class AdvancedPrivacyProtections : uint16_t; enum class NotificationEventType : bool; struct BackgroundFetchInformation; @@ -271,6 +272,7 @@ class SWServer : public RefCounted, public CanMakeWeakPtr { std::optional clientIdentifierToControllingRegistration(ScriptExecutionContextIdentifier) const; WEBCORE_EXPORT void forEachClientForOrigin(const ClientOrigin&, const Function&); + void forEachClientForOrigin(const ClientOrigin&, const Function&) const; struct GatheredClientData { ClientOrigin clientOrigin; @@ -290,6 +292,8 @@ class SWServer : public RefCounted, public CanMakeWeakPtr { WEBCORE_EXPORT void postMessageToServiceWorkerClient(ScriptExecutionContextIdentifier, const MessageWithMessagePorts&, ServiceWorkerIdentifier, const String&, const Function&); + WEBCORE_EXPORT OptionSet advancedPrivacyProtectionsFromClient(const ClientOrigin&) const; + private: SWServer(SWServerDelegate&, UniqueRef&&, bool processTerminationDelayEnabled, String&& registrationDatabaseDirectory, PAL::SessionID, bool shouldRunServiceWorkersOnMainThreadForTesting, bool hasServiceWorkerEntitlement, std::optional overrideServiceWorkerRegistrationCountTestingValue, ServiceWorkerIsInspectable); diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServerToContextConnection.h b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServerToContextConnection.h index 2fbf2b6dd70..5e801ff9e04 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServerToContextConnection.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/service/server/SWServerToContextConnection.h @@ -41,6 +41,7 @@ namespace WebCore { +enum class AdvancedPrivacyProtections : uint16_t; struct BackgroundFetchInformation; struct NotificationData; struct NotificationPayload; @@ -65,7 +66,7 @@ class SWServerToContextConnection: public CanMakeWeakPtr) = 0; virtual void updateAppInitiatedValue(ServiceWorkerIdentifier, LastNavigationWasAppInitiated) = 0; virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0; virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0; diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/SharedWorkerScriptLoader.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/SharedWorkerScriptLoader.cpp index 5b6b23a5c4d..fd8419ee959 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/SharedWorkerScriptLoader.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/SharedWorkerScriptLoader.cpp @@ -70,6 +70,7 @@ void SharedWorkerScriptLoader::notifyFinished() m_completionHandler(WTFMove(fetchResult), WorkerInitializationData { m_loader->takeServiceWorkerData(), m_loader->clientIdentifier(), + m_loader->advancedPrivacyProtections(), m_loader->userAgentForSharedWorker() }); // deletes this. } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp b/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp index 9775b084f6f..4be8f015fbe 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/workers/shared/context/SharedWorkerThreadProxy.cpp @@ -81,6 +81,7 @@ static WorkerParameters generateWorkerParameters(const WorkerFetchResult& worker *document.sessionID(), WTFMove(initializationData.serviceWorkerData), *initializationData.clientIdentifier, + document.advancedPrivacyProtections(), document.noiseInjectionHashSalt() }; } diff --git a/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletGlobalScope.cpp b/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletGlobalScope.cpp index f5acfe94878..2371b8f9a91 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletGlobalScope.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletGlobalScope.cpp @@ -50,7 +50,7 @@ WTF_MAKE_ISO_ALLOCATED_IMPL(WorkletGlobalScope); static std::atomic gNumberOfWorkletGlobalScopes { 0 }; WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, Ref&& vm, const WorkletParameters& parameters) - : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, parameters.sessionID, WTFMove(vm), parameters.referrerPolicy, &thread, parameters.noiseInjectionHashSalt) + : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, parameters.sessionID, WTFMove(vm), parameters.referrerPolicy, &thread, parameters.noiseInjectionHashSalt, parameters.advancedPrivacyProtections) , m_topOrigin(SecurityOrigin::createOpaque()) , m_url(parameters.windowURL) , m_jsRuntimeFlags(parameters.jsRuntimeFlags) @@ -64,7 +64,7 @@ WorkletGlobalScope::WorkletGlobalScope(WorkerOrWorkletThread& thread, Ref&& vm, ScriptSourceCode&& code) - : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, *document.sessionID(), WTFMove(vm), document.referrerPolicy(), nullptr, document.noiseInjectionHashSalt()) + : WorkerOrWorkletGlobalScope(WorkerThreadType::Worklet, *document.sessionID(), WTFMove(vm), document.referrerPolicy(), nullptr, document.noiseInjectionHashSalt(), document.advancedPrivacyProtections()) , m_document(document) , m_topOrigin(SecurityOrigin::createOpaque()) , m_url(code.url()) diff --git a/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletParameters.h b/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletParameters.h index 8942891b681..88a8303490d 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletParameters.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/worklets/WorkletParameters.h @@ -25,6 +25,7 @@ #pragma once +#include "AdvancedPrivacyProtections.h" #include "Settings.h" #include #include @@ -40,10 +41,11 @@ struct WorkletParameters { Settings::Values settingsValues; ReferrerPolicy referrerPolicy; bool isAudioContextRealTime; + OptionSet advancedPrivacyProtections; std::optional noiseInjectionHashSalt; - WorkletParameters isolatedCopy() const & { return { windowURL.isolatedCopy(), jsRuntimeFlags, sampleRate, identifier.isolatedCopy(), sessionID, settingsValues.isolatedCopy(), referrerPolicy, isAudioContextRealTime, noiseInjectionHashSalt }; } - WorkletParameters isolatedCopy() && { return { WTFMove(windowURL).isolatedCopy(), jsRuntimeFlags, sampleRate, WTFMove(identifier).isolatedCopy(), sessionID, WTFMove(settingsValues).isolatedCopy(), referrerPolicy, isAudioContextRealTime, WTFMove(noiseInjectionHashSalt) }; } + WorkletParameters isolatedCopy() const & { return { windowURL.isolatedCopy(), jsRuntimeFlags, sampleRate, identifier.isolatedCopy(), sessionID, settingsValues.isolatedCopy(), referrerPolicy, isAudioContextRealTime, advancedPrivacyProtections, noiseInjectionHashSalt }; } + WorkletParameters isolatedCopy() && { return { WTFMove(windowURL).isolatedCopy(), jsRuntimeFlags, sampleRate, WTFMove(identifier).isolatedCopy(), sessionID, WTFMove(settingsValues).isolatedCopy(), referrerPolicy, isAudioContextRealTime, advancedPrivacyProtections, WTFMove(noiseInjectionHashSalt) }; } }; } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathFunctions.cpp b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathFunctions.cpp index f5d2bbfdbac..0fa552c3feb 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathFunctions.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathFunctions.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Frerich Raabe - * Copyright (C) 2006, 2009, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * Copyright (C) 2019 Google Inc. All rights reserved. * Copyright (C) 2007 Alexey Proskuryakov * @@ -68,157 +68,157 @@ class Interval { class FunLast final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } public: FunLast() { setIsContextSizeSensitive(true); } }; class FunPosition final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } public: FunPosition() { setIsContextPositionSensitive(true); } }; class FunCount final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } }; class FunId final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NodeSetValue; } + Value::Type resultType() const override { return Value::Type::NodeSet; } }; class FunLocalName final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } public: FunLocalName() { setIsContextNodeSensitive(true); } // local-name() with no arguments uses context node. }; class FunNamespaceURI final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } public: FunNamespaceURI() { setIsContextNodeSensitive(true); } // namespace-uri() with no arguments uses context node. }; class FunName final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } public: FunName() { setIsContextNodeSensitive(true); } // name() with no arguments uses context node. }; class FunString final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } public: FunString() { setIsContextNodeSensitive(true); } // string() with no arguments uses context node. }; class FunConcat final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } }; class FunStartsWith final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunContains final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunSubstringBefore final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } }; class FunSubstringAfter final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } }; class FunSubstring final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } }; class FunStringLength final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } public: FunStringLength() { setIsContextNodeSensitive(true); } // string-length() with no arguments uses context node. }; class FunNormalizeSpace final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } public: FunNormalizeSpace() { setIsContextNodeSensitive(true); } // normalize-space() with no arguments uses context node. }; class FunTranslate final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } }; class FunBoolean final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunNot : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunTrue final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunFalse final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } }; class FunLang final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::BooleanValue; } + Value::Type resultType() const override { return Value::Type::Boolean; } public: FunLang() { setIsContextNodeSensitive(true); } // lang() always works on context node. }; class FunNumber final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } public: FunNumber() { setIsContextNodeSensitive(true); } // number() with no arguments uses context node. }; class FunSum final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } }; class FunFloor final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } }; class FunCeiling final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } }; class FunRound final : public Function { Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } public: static double round(double); }; @@ -784,5 +784,5 @@ std::unique_ptr Function::create(const String& name, Vector - * Copyright (C) 2006, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * Copyright (C) 2019 Google Inc. All rights reserved. * Copyright (C) 2007 Alexey Proskuryakov * @@ -47,16 +47,22 @@ namespace XPath { struct Parser::Token { int type; - String string; - Step::Axis axis; - NumericOp::Opcode numericOpcode; - EqTestOp::Opcode equalityTestOpcode; - - Token(int type) : type(type) { } - Token(int type, const String& string) : type(type), string(string) { } - Token(int type, Step::Axis axis) : type(type), axis(axis) { } - Token(int type, NumericOp::Opcode opcode) : type(type), numericOpcode(opcode) { } - Token(int type, EqTestOp::Opcode opcode) : type(type), equalityTestOpcode(opcode) { } + using TokenValue = std::variant; + TokenValue value; + + Token() = delete; + + Token(int type) + : type(type) + { } + Token(int type, TokenValue&& value) + : type(type), value(WTFMove(value)) + { } + + String& string() { return std::get(value); } + Step::Axis axis() const { return std::get(value); } + NumericOp::Opcode numericOpcode() const { return std::get(value); } + EqTestOp::Opcode equalityTestOpcode() const { return std::get(value); } }; enum XMLCat { NameStart, NameCont, NotPartOfName }; @@ -409,14 +415,14 @@ int Parser::lex(YYSTYPE& yylval) switch (token.type) { case AXISNAME: - yylval.axis = token.axis; + yylval.axis = token.axis(); break; case MULOP: - yylval.numericOpcode = token.numericOpcode; + yylval.numericOpcode = token.numericOpcode(); break; case RELOP: case EQOP: - yylval.equalityTestOpcode = token.equalityTestOpcode; + yylval.equalityTestOpcode = token.equalityTestOpcode(); break; case NODETYPE: case FUNCTIONNAME: @@ -424,7 +430,7 @@ int Parser::lex(YYSTYPE& yylval) case VARIABLEREFERENCE: case NUMBER: case NAMETEST: - yylval.string = token.string.releaseImpl().leakRef(); + yylval.string = token.string().releaseImpl().leakRef(); break; } @@ -465,4 +471,5 @@ ExceptionOr> Parser::parseStatement(const String& st return WTFMove(parser.m_result); } -} } +} // namespace XPath +} // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPath.h b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPath.h index 6f5961ad9a3..6872663f078 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPath.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPath.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Frerich Raabe - * Copyright (C) 2006, 2009, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,24 +29,24 @@ #include "XPathExpressionNode.h" namespace WebCore { - namespace XPath { +namespace XPath { - class Step; +class Step; - class Filter final : public Expression { - public: +class Filter final : public Expression { +public: Filter(std::unique_ptr, Vector> predicates); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NodeSetValue; } + Value::Type resultType() const override { return Value::Type::NodeSet; } std::unique_ptr m_expression; Vector> m_predicates; - }; +}; - class LocationPath final : public Expression { - public: +class LocationPath final : public Expression { +public: LocationPath(); void setAbsolute() { m_isAbsolute = true; setIsContextNodeSensitive(false); } @@ -56,25 +56,25 @@ namespace WebCore { void appendStep(std::unique_ptr); void prependStep(std::unique_ptr); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NodeSetValue; } + Value::Type resultType() const override { return Value::Type::NodeSet; } Vector> m_steps; bool m_isAbsolute; - }; +}; - class Path final : public Expression { - public: +class Path final : public Expression { +public: Path(std::unique_ptr filter, std::unique_ptr); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NodeSetValue; } + Value::Type resultType() const override { return Value::Type::NodeSet; } std::unique_ptr m_filter; std::unique_ptr m_path; - }; +}; - } // namespace XPath +} // namespace XPath } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.cpp b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.cpp index 11b8455f287..47a04ca2037 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.cpp @@ -1,6 +1,6 @@ /* * Copyright 2005 Frerich Raabe - * Copyright (C) 2006, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * Copyright (C) 2007 Alexey Proskuryakov * * Redistribution and use in source and binary forms, with or without @@ -297,8 +297,8 @@ bool evaluatePredicate(const Expression& expression) bool predicateIsContextPositionSensitive(const Expression& expression) { - return expression.isContextPositionSensitive() || expression.resultType() == Value::NumberValue; + return expression.isContextPositionSensitive() || expression.resultType() == Value::Type::Number; } -} -} +} // namespace XPath +} // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.h b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.h index aae181c8026..c7faf1c8898 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathPredicate.h @@ -1,6 +1,6 @@ /* * Copyright 2005 Frerich Raabe - * Copyright (C) 2006, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,88 +29,88 @@ #include "XPathExpressionNode.h" namespace WebCore { - namespace XPath { +namespace XPath { - class Number final : public Expression { - public: +class Number final : public Expression { +public: explicit Number(double); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } Value m_value; - }; +}; - class StringExpression final : public Expression { - public: +class StringExpression final : public Expression { +public: explicit StringExpression(String&&); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::StringValue; } + Value::Type resultType() const override { return Value::Type::String; } Value m_value; - }; +}; - class Negative final : public Expression { - public: +class Negative final : public Expression { +public: explicit Negative(std::unique_ptr); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } - }; + Value::Type resultType() const override { return Value::Type::Number; } +}; - class NumericOp final : public Expression { - public: +class NumericOp final : public Expression { +public: enum Opcode { OP_Add, OP_Sub, OP_Mul, OP_Div, OP_Mod }; NumericOp(Opcode, std::unique_ptr lhs, std::unique_ptr rhs); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NumberValue; } + Value::Type resultType() const override { return Value::Type::Number; } Opcode m_opcode; - }; +}; - class EqTestOp final : public Expression { - public: +class EqTestOp final : public Expression { +public: enum Opcode { OP_EQ, OP_NE, OP_GT, OP_LT, OP_GE, OP_LE }; EqTestOp(Opcode, std::unique_ptr lhs, std::unique_ptr rhs); Value evaluate() const override; - private: - Value::Type resultType() const override { return Value::BooleanValue; } +private: + Value::Type resultType() const override { return Value::Type::Boolean; } bool compare(const Value&, const Value&) const; Opcode m_opcode; - }; +}; - class LogicalOp final : public Expression { - public: +class LogicalOp final : public Expression { +public: enum Opcode { OP_And, OP_Or }; LogicalOp(Opcode, std::unique_ptr lhs, std::unique_ptr rhs); - private: - Value::Type resultType() const override { return Value::BooleanValue; } +private: + Value::Type resultType() const override { return Value::Type::Boolean; } bool shortCircuitOn() const; Value evaluate() const override; Opcode m_opcode; - }; +}; - class Union final : public Expression { - public: +class Union final : public Expression { +public: Union(std::unique_ptr, std::unique_ptr); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { return Value::NodeSetValue; } - }; + Value::Type resultType() const override { return Value::Type::NodeSet; } +}; - bool evaluatePredicate(const Expression&); - bool predicateIsContextPositionSensitive(const Expression&); +bool evaluatePredicate(const Expression&); +bool predicateIsContextPositionSensitive(const Expression&); - } // namespace XPath +} // namespace XPath } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathResult.cpp b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathResult.cpp index 5da71f692a9..1dddf8be164 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathResult.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathResult.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2005 Frerich Raabe - * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,16 +36,16 @@ XPathResult::XPathResult(Document& document, const XPath::Value& value) : m_value(value) { switch (m_value.type()) { - case XPath::Value::BooleanValue: + case XPath::Value::Type::Boolean: m_resultType = BOOLEAN_TYPE; return; - case XPath::Value::NumberValue: + case XPath::Value::Type::Number: m_resultType = NUMBER_TYPE; return; - case XPath::Value::StringValue: + case XPath::Value::Type::String: m_resultType = STRING_TYPE; return; - case XPath::Value::NodeSetValue: + case XPath::Value::Type::NodeSet: m_resultType = UNORDERED_NODE_ITERATOR_TYPE; m_nodeSetPosition = 0; m_nodeSet = m_value.toNodeSet(); @@ -180,4 +180,4 @@ ExceptionOr XPathResult::snapshotItem(unsigned index) return nodes[index]; } -} +} // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.cpp b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.cpp index 809a634d011..50ac0359f31 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.cpp +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.cpp @@ -1,6 +1,6 @@ /* * Copyright 2005 Frerich Raabe - * Copyright (C) 2006, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,20 +59,20 @@ NodeSet& Value::modifiableNodeSet() if (!m_data) m_data = Data::create(); - m_type = NodeSetValue; + m_type = Type::NodeSet; return m_data->nodeSet; } bool Value::toBoolean() const { switch (m_type) { - case NodeSetValue: + case Type::NodeSet: return !m_data->nodeSet.isEmpty(); - case BooleanValue: + case Type::Boolean: return m_bool; - case NumberValue: + case Type::Number: return m_number && !std::isnan(m_number); - case StringValue: + case Type::String: return !m_data->string.isEmpty(); } ASSERT_NOT_REACHED(); @@ -82,11 +82,11 @@ bool Value::toBoolean() const double Value::toNumber() const { switch (m_type) { - case NodeSetValue: + case Type::NodeSet: return Value(toString()).toNumber(); - case NumberValue: + case Type::Number: return m_number; - case StringValue: { + case Type::String: { const String& str = m_data->string.simplifyWhiteSpace(deprecatedIsSpaceOrNewline); // String::toDouble() supports exponential notation, which is not allowed in XPath. @@ -103,7 +103,7 @@ double Value::toNumber() const return value; return std::numeric_limits::quiet_NaN(); } - case BooleanValue: + case Type::Boolean: return m_bool; } @@ -114,21 +114,21 @@ double Value::toNumber() const String Value::toString() const { switch (m_type) { - case NodeSetValue: + case Type::NodeSet: if (m_data->nodeSet.isEmpty()) return emptyString(); return stringValue(m_data->nodeSet.firstNode()); - case StringValue: + case Type::String: return m_data->string; - case NumberValue: + case Type::Number: if (std::isnan(m_number)) return "NaN"_s; - if (m_number == 0) + if (!m_number) return "0"_s; if (std::isinf(m_number)) return std::signbit(m_number) ? "-Infinity"_s : "Infinity"_s; return String::number(m_number); - case BooleanValue: + case Type::Boolean: return m_bool ? trueAtom() : falseAtom(); } @@ -136,5 +136,5 @@ String Value::toString() const return String(); } -} -} +} // namespace XPath +} // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.h b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.h index a46291615d3..9980e34c048 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathValue.h @@ -1,6 +1,6 @@ /* * Copyright 2005 Frerich Raabe - * Copyright (C) 2006, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,35 +29,47 @@ #include "XPathNodeSet.h" namespace WebCore { - namespace XPath { - - class Value { - public: - enum Type { NodeSetValue, BooleanValue, NumberValue, StringValue }; - - Value(bool value) : m_type(BooleanValue), m_bool(value) { } - Value(unsigned value) : m_type(NumberValue), m_number(value) { } - Value(double value) : m_type(NumberValue), m_number(value) { } - - Value(const String& value) : m_type(StringValue), m_data(Data::create(value)) { } - Value(const char* value) : m_type(StringValue), m_data(Data::create(String::fromLatin1(value))) { } +namespace XPath { + +class Value { +public: + enum class Type : uint8_t { NodeSet, Boolean, Number, String }; + + Value() = delete; + + Value(bool value) + : m_type(Type::Boolean), m_bool(value) + { } + Value(unsigned value) + : m_type(Type::Number), m_number(value) + { } + Value(double value) + : m_type(Type::Number), m_number(value) + { } + + Value(const String& value) + : m_type(Type::String), m_data(Data::create(value)) + { } + Value(const char* value) + : m_type(Type::String), m_data(Data::create(String::fromLatin1(value))) + { } explicit Value(NodeSet&& value) - : m_type(NodeSetValue), m_data(Data::create(WTFMove(value))) + : m_type(Type::NodeSet), m_data(Data::create(WTFMove(value))) { } explicit Value(Node* value) - : m_type(NodeSetValue), m_data(Data::create(value)) + : m_type(Type::NodeSet), m_data(Data::create(value)) { } explicit Value(RefPtr&& value) - : m_type(NodeSetValue), m_data(Data::create(WTFMove(value))) + : m_type(Type::NodeSet), m_data(Data::create(WTFMove(value))) { } Type type() const { return m_type; } - bool isNodeSet() const { return m_type == NodeSetValue; } - bool isBoolean() const { return m_type == BooleanValue; } - bool isNumber() const { return m_type == NumberValue; } - bool isString() const { return m_type == StringValue; } + bool isNodeSet() const { return m_type == Type::NodeSet; } + bool isBoolean() const { return m_type == Type::Boolean; } + bool isNumber() const { return m_type == Type::Number; } + bool isString() const { return m_type == Type::String; } const NodeSet& toNodeSet() const; bool toBoolean() const; @@ -67,7 +79,7 @@ namespace WebCore { // Note that the NodeSet is shared with other Values that this one was copied from or that are copies of this one. NodeSet& modifiableNodeSet(); - private: +private: // This constructor creates ambiguity so that we don't accidentally call the boolean overload for pointer types. Value(void*) = delete; @@ -94,10 +106,10 @@ namespace WebCore { }; Type m_type; - bool m_bool; - double m_number; + bool m_bool { false }; + double m_number { 0 }; RefPtr m_data; - }; +}; - } // namespace XPath +} // namespace XPath } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathVariableReference.h b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathVariableReference.h index ff35064f834..b915443ec88 100644 --- a/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathVariableReference.h +++ b/modules/javafx.web/src/main/native/Source/WebCore/xml/XPathVariableReference.h @@ -1,5 +1,6 @@ /* * Copyright 2005 Frerich Raabe + * Copyright (C) 2006-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,17 +29,17 @@ #include "XPathExpressionNode.h" namespace WebCore { - namespace XPath { +namespace XPath { - // Variable references are not used with XPathEvaluator. - class VariableReference : public Expression { - public: +// Variable references are not used with XPathEvaluator. +class VariableReference : public Expression { +public: explicit VariableReference(const String& name); - private: +private: Value evaluate() const override; - Value::Type resultType() const override { ASSERT_NOT_REACHED(); return Value::NumberValue; } + Value::Type resultType() const override { ASSERT_NOT_REACHED(); return Value::Type::Number; } String m_name; - }; +}; - } // namespace XPath +} // namespace XPath } // namespace WebCore diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h b/modules/javafx.web/src/main/native/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h index 13c8826f334..c366851f8e2 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/Storage/WebStorageNamespaceProvider.h @@ -58,7 +58,7 @@ class WebStorageNamespaceProvider final : public WebCore::StorageNamespaceProvid void copySessionStorageNamespace(WebCore::Page&, WebCore::Page&) final; const String m_localStorageDatabasePath; - SingleThreadWeakHashMap>> m_sessionStorageNamespaces; + WeakHashMap>> m_sessionStorageNamespaces; }; } // namespace WebKit diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/WebCoreSupport/PageStorageSessionProvider.h b/modules/javafx.web/src/main/native/Source/WebKitLegacy/WebCoreSupport/PageStorageSessionProvider.h index b0097638034..f20c2b549e3 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/WebCoreSupport/PageStorageSessionProvider.h +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/WebCoreSupport/PageStorageSessionProvider.h @@ -48,5 +48,5 @@ class PageStorageSessionProvider final : public WebCore::StorageSessionProvider } private: - SingleThreadWeakPtr m_page; + WeakPtr m_page; }; diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/BackForwardList.cpp b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/BackForwardList.cpp index 1fc26872260..37d5d0df2d0 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/BackForwardList.cpp +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/BackForwardList.cpp @@ -179,7 +179,8 @@ JNIEXPORT jstring JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetURL(JNIE // entry.getTitle() JNIEXPORT jstring JNICALL Java_com_sun_webkit_BackForwardList_bflItemGetTitle(JNIEnv* env, jclass, jlong jitem) { - String title= ""_s; + HistoryItem* item = getItem(jitem); + String title = item->title(); return title.toJavaString(env).releaseLocal(); } diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.cpp b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.cpp index c70640c59f7..044d3157ece 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.cpp +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.cpp @@ -643,7 +643,7 @@ void EditorClientJava::discardedComposition(const Document&) { } -DOMPasteAccessResponse EditorClientJava::requestDOMPasteAccess(DOMPasteAccessCategory, const String& originIdentifier) +DOMPasteAccessResponse EditorClientJava::requestDOMPasteAccess(DOMPasteAccessCategory, FrameIdentifier, const String& originIdentifier) { return DOMPasteAccessResponse::DeniedForGesture; } diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.h b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.h index 344892d0706..51e688b60cf 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.h +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/EditorClientJava.h @@ -73,7 +73,7 @@ class EditorClientJava final : public EditorClient, public TextCheckerClient { void getClientPasteboardData(const std::optional&, Vector& pasteboardTypes, Vector >& pasteboardData) override; void didUpdateComposition() override { } - DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, const String& originIdentifier) override; + DOMPasteAccessResponse requestDOMPasteAccess(DOMPasteAccessCategory, FrameIdentifier, const String& originIdentifier) override; void discardedComposition(const Document&) override; void canceledComposition() override; diff --git a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/WebPage.cpp b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/WebPage.cpp index 4d49a497161..1f1f073ee24 100644 --- a/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/WebPage.cpp +++ b/modules/javafx.web/src/main/native/Source/WebKitLegacy/java/WebCoreSupport/WebPage.cpp @@ -808,7 +808,7 @@ class WebStorageNamespaceProviderJava final : public WebCore::StorageNamespacePr } private: String m_localStorageDatabasePath; - SingleThreadWeakHashMap>> m_sessionStorageNamespaces; + WeakHashMap>> m_sessionStorageNamespaces; RefPtr sessionStorageNamespace(const SecurityOrigin& topLevelOrigin, Page& page, ShouldCreateNamespace shouldCreate) override{ if (m_sessionStorageNamespaces.find(page) == m_sessionStorageNamespaces.end()) { diff --git a/modules/javafx.web/src/main/native/Tools/Scripts/webkitdirs.pm b/modules/javafx.web/src/main/native/Tools/Scripts/webkitdirs.pm index 7f7f740e2f2..612aa16c490 100644 --- a/modules/javafx.web/src/main/native/Tools/Scripts/webkitdirs.pm +++ b/modules/javafx.web/src/main/native/Tools/Scripts/webkitdirs.pm @@ -733,11 +733,18 @@ sub determineNumberOfCPUs if (defined($ENV{NUMBER_OF_PROCESSORS})) { $numberOfCPUs = $ENV{NUMBER_OF_PROCESSORS}; } elsif (isLinux()) { - # First try the nproc utility, if it exists. If we get no - # results fall back to just interpretting /proc directly. - chomp($numberOfCPUs = `nproc --all 2> /dev/null`); + use POSIX; + $numberOfCPUs = POSIX::sysconf(83); # _SC_NPROCESSORS_ONLN = 83 if ($numberOfCPUs eq "") { - $numberOfCPUs = (grep /processor/, `cat /proc/cpuinfo`); + $numberOfCPUs = 0; + open CPUINFO, "/proc/cpuinfo"; + while () { + if (/[Pp]rocessor\s/) { $numberOfCPUs++; } + } + close CPUINFO; + } + if ($numberOfCPUs == 0) { + $numberOfCPUs = 1; } } elsif (isAnyWindows()) { # Assumes cygwin