LibWeb+LibGC: Import GC swift module into LibWeb and an initial user

Start work on a speculative HTML Parser in Swift. This component will
walk ahead of the normal HTML parser looking for fetch() requests to
make while the normal parser is blocked. This work exposed many holes in
the Swift C++ interop component, which have been reported upstream.
This commit is contained in:
Andrew Kaster 2025-03-22 19:12:30 -06:00
parent 744c04d830
commit 82b91a606f
5 changed files with 70 additions and 4 deletions

View file

@ -999,7 +999,8 @@ if (ENABLE_SWIFT)
HTML/Parser/HTMLToken.swift
HTML/Parser/HTMLTokenizer.swift
HTML/Parser/HTMLTokenizerHelpers.cpp
HTML/Parser/SpeculativeHTMLParser.swift
)
target_link_libraries(LibWeb PRIVATE AK Collections)
add_swift_target_properties(LibWeb LAGOM_LIBRARIES AK LibGfx)
add_swift_target_properties(LibWeb LAGOM_LIBRARIES AK LibGfx LibGC COMPILE_DEFINITIONS LIBGC_WORKAROUND_BOOL_BITFIELD)
endif()

View file

@ -214,10 +214,14 @@ private:
GC::Ptr<DOM::Text> m_character_insertion_node;
StringBuilder m_character_insertion_builder;
};
} SWIFT_UNSAFE_REFERENCE;
RefPtr<CSS::CSSStyleValue> parse_dimension_value(StringView);
RefPtr<CSS::CSSStyleValue> parse_nonzero_dimension_value(StringView);
Optional<Color> parse_legacy_color_value(StringView);
// Swift interop
using HTMLParserGCPtr = GC::Ptr<HTMLParser>;
using HTMLParserGCRef = GC::Ref<HTMLParser>;
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2025, Andrew Kaster <andrew@ladybird.org>>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
import AK
import Collections
import Foundation
import GC
@_exported import WebCxx
// Workaround for https://github.com/swiftlang/swift/issues/80231
// If any line of this changes, the whole thing breaks though
extension GC.Cell.Visitor {
public func visit(_ parser: Web.HTML.HTMLParserGCPtr) {
if let parser = parser.ptr() {
let cell: GC.Cell = cxxCast(parser)
visit(cell)
}
}
}
struct SpeculativeMockElement {
let name: Swift.String
let localName: Swift.String
let attributes: [HTMLToken.Attribute]
var children: [SpeculativeMockElement]
init(name: Swift.String, localName: Swift.String, attributes: [HTMLToken.Attribute]) {
self.name = name
self.localName = localName
self.attributes = attributes
self.children = []
}
mutating func appendChild(_ child: consuming SpeculativeMockElement) {
children.append(child)
}
}
public final class SpeculativeHTMLParser: HeapAllocatable {
var parser = Web.HTML.HTMLParserGCPtr() // FIXME: Want HTMLParserGCRef here, but how to initialize it?
public init(cell: GC.Cell) {
self.cell = cell
}
public var cell: GC.Cell
public static func create(on heap: GC.Heap, `for` parser: Web.HTML.HTMLParserGCPtr) -> GC.Cell {
precondition(heap.is_gc_deferred())
let _self = allocate(on: heap)
_self.pointee.parser = parser
return _self.pointee.cell
}
public func visitEdges(_ visitor: GC.Cell.Visitor) {
visitor.visit(parser)
}
}

View file

@ -9,6 +9,7 @@
#include <AK/ByteString.h>
#include <AK/Error.h>
#include <AK/Function.h>
#include <AK/Swift.h>
namespace Web {
@ -22,6 +23,6 @@ public:
private:
ByteString m_path {};
};
} SWIFT_UNSAFE_REFERENCE; // FIXME: This type is actually move-only, not unsafe
}

View file

@ -29,6 +29,6 @@ if (ENABLE_SWIFT)
target_sources(TestLibWebSwift PRIVATE ../Resources/SwiftTestMain.swift)
set_target_properties(TestLibWebSwift PROPERTIES SUFFIX .swift-testing)
target_link_libraries(TestLibWebSwift PRIVATE AK LibWeb SwiftTesting::SwiftTesting)
target_link_libraries(TestLibWebSwift PRIVATE AK LibWeb LibGC SwiftTesting::SwiftTesting)
add_test(NAME TestLibWebSwift COMMAND TestLibWebSwift)
endif()