Everywhere: Abandon Swift adoption
After making no progress on this for a very long time, let's acknowledge it's not going anywhere and remove it from the codebase.
This commit is contained in:
parent
b3231ea2a0
commit
e87f889e31
84 changed files with 22 additions and 4747 deletions
45
.github/actions/setup/action.yml
vendored
45
.github/actions/setup/action.yml
vendored
|
|
@ -74,51 +74,6 @@ runs:
|
|||
with:
|
||||
xcode-version: 26.2
|
||||
|
||||
- name: 'Install Swift toolchain'
|
||||
if: ${{ inputs.toolchain == 'Swift' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -e
|
||||
|
||||
export SWIFTLY_HOME_DIR=${{ github.workspace }}/.swiftly/share
|
||||
export SWIFTLY_BIN_DIR=${{ github.workspace }}/.swiftly/bin
|
||||
|
||||
echo "$SWIFTLY_BIN_DIR" >> $GITHUB_PATH
|
||||
echo "SWIFTLY_HOME_DIR=$SWIFTLY_HOME_DIR" >> $GITHUB_ENV
|
||||
echo "SWIFTLY_BIN_DIR=$SWIFTLY_BIN_DIR" >> $GITHUB_ENV
|
||||
|
||||
export PATH=$SWIFTLY_BIN_DIR:$PATH
|
||||
|
||||
mkdir -p $SWIFTLY_HOME_DIR
|
||||
mkdir -p $SWIFTLY_BIN_DIR
|
||||
|
||||
if ${{ inputs.os == 'Linux' }} ; then
|
||||
curl -O https://download.swift.org/swiftly/linux/swiftly-${{ inputs.arch }}.tar.gz
|
||||
file swiftly-${{ inputs.arch }}.tar.gz
|
||||
tar -xzf swiftly-${{ inputs.arch }}.tar.gz -C $SWIFTLY_BIN_DIR
|
||||
rm swiftly-${{ inputs.arch }}.tar.gz
|
||||
else
|
||||
# FIXME: https://github.com/swiftlang/swiftly/issues/271
|
||||
# Why does this drop files in $HOME? That's not very CI-friendly
|
||||
curl -O https://download.swift.org/swiftly/darwin/swiftly.pkg
|
||||
installer -pkg swiftly.pkg -target CurrentUserHomeDirectory
|
||||
cp ~/.swiftly/bin/swiftly $SWIFTLY_BIN_DIR
|
||||
rm swiftly.pkg
|
||||
fi
|
||||
|
||||
swiftly init \
|
||||
--no-modify-profile \
|
||||
--quiet-shell-followup \
|
||||
--assume-yes \
|
||||
--skip-install \
|
||||
--verbose
|
||||
|
||||
echo "swiftly version: $(swiftly --version)" >&2
|
||||
|
||||
# installs version listed in .swift-version
|
||||
swiftly install
|
||||
swiftly list
|
||||
|
||||
- name: 'Install Dependencies'
|
||||
if: ${{ inputs.os == 'macOS' || inputs.os == 'Android' }}
|
||||
shell: bash
|
||||
|
|
|
|||
6
.github/workflows/lagom-template.yml
vendored
6
.github/workflows/lagom-template.yml
vendored
|
|
@ -66,11 +66,7 @@ jobs:
|
|||
id: 'build-parameters'
|
||||
run: |
|
||||
CMAKE_OPTIONS="-DENABLE_CI_BASELINE_CPU=ON"
|
||||
if ${{ inputs.toolchain == 'Swift' }} ; then
|
||||
echo "host_cc=$(swiftly use --print-location)/usr/bin/clang" >> "$GITHUB_OUTPUT"
|
||||
echo "host_cxx=$(swiftly use --print-location)/usr/bin/clang++" >> "$GITHUB_OUTPUT"
|
||||
CMAKE_OPTIONS="$CMAKE_OPTIONS -DENABLE_SWIFT=ON"
|
||||
elif ${{ inputs.os_name == 'Linux' }} ; then
|
||||
if ${{ inputs.os_name == 'Linux' }} ; then
|
||||
# FIXME: https://github.com/WebAssembly/wabt/issues/2533
|
||||
# wabt doesn't have binary releases for arm64 Linux
|
||||
if ${{ inputs.arch == 'arm64' }} ; then
|
||||
|
|
|
|||
2
.github/workflows/lint-code.yml
vendored
2
.github/workflows/lint-code.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
run: |
|
||||
set -e
|
||||
|
||||
brew install curl llvm@20 ninja optipng ruff shellcheck swift-format unzip
|
||||
brew install curl llvm@20 ninja optipng ruff shellcheck unzip
|
||||
|
||||
# Note: gn isn't available in homebrew :(
|
||||
# Corresponds to https://gn.googlesource.com/gn/+/225e90c5025bf74f41dbee60d9cde4512c846fe7
|
||||
|
|
|
|||
14
.github/workflows/nightly-lagom.yml
vendored
14
.github/workflows/nightly-lagom.yml
vendored
|
|
@ -47,20 +47,6 @@ jobs:
|
|||
clang_plugins: false
|
||||
runner_labels: '["blacksmith-8vcpu-ubuntu-2404-arm"]'
|
||||
|
||||
- os_name: 'Linux'
|
||||
arch: 'x86_64'
|
||||
build_preset: 'Sanitizer'
|
||||
toolchain: 'Swift'
|
||||
clang_plugins: false
|
||||
runner_labels: '["blacksmith-8vcpu-ubuntu-2404"]'
|
||||
|
||||
- os_name: 'macOS'
|
||||
arch: 'arm64'
|
||||
build_preset: 'Sanitizer'
|
||||
toolchain: 'Swift'
|
||||
clang_plugins: false
|
||||
runner_labels: '["macos-15", "self-hosted"]'
|
||||
|
||||
- os_name: 'Windows'
|
||||
arch: 'x86_64'
|
||||
build_preset: 'Sanitizer'
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"indentation": {
|
||||
"spaces": 4
|
||||
},
|
||||
"tabWidth": 4,
|
||||
"lineLength": 320
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
main-snapshot-2025-06-22
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
@_exported import AKCxx
|
||||
import Foundation
|
||||
|
||||
extension Swift.String {
|
||||
public init?(akString: AK.String) {
|
||||
let bytes = akString.__bytes_as_string_viewUnsafe().bytes()
|
||||
let data = Foundation.Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: bytes.data()), count: bytes.size(), deallocator: .none)
|
||||
|
||||
self.init(data: data, encoding: .utf8)
|
||||
}
|
||||
|
||||
public init?(akStringView: AK.StringView) {
|
||||
let bytes = akStringView.bytes()
|
||||
let data = Foundation.Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: bytes.data()), count: bytes.size(), deallocator: .none)
|
||||
|
||||
self.init(data: data, encoding: .utf8)
|
||||
}
|
||||
}
|
||||
|
||||
extension AK.String {
|
||||
public init(swiftString: consuming Swift.String) {
|
||||
self.init() // Create empty string first, using default constructor
|
||||
swiftString.withUTF8 { buffer in
|
||||
self = AK.String.from_utf8_without_validation(AK.ReadonlyBytes(buffer.baseAddress!, buffer.count))
|
||||
}
|
||||
}
|
||||
}
|
||||
extension AK.StringView: ExpressibleByStringLiteral {
|
||||
public typealias StringLiteralType = Swift.StaticString
|
||||
|
||||
public init(stringLiteral value: StringLiteralType) {
|
||||
self.init(value.utf8Start, value.utf8CodeUnitCount)
|
||||
}
|
||||
|
||||
public func endsWith(_ suffix: AK.StringView) -> Bool {
|
||||
if suffix.length() == 1 {
|
||||
return self.ends_with(suffix[0])
|
||||
}
|
||||
return self.ends_with(suffix, AK.CaseSensitivity.sensitive)
|
||||
}
|
||||
}
|
||||
|
|
@ -68,11 +68,9 @@ endif()
|
|||
configure_file(Backtrace.h.in Backtrace.h @ONLY)
|
||||
|
||||
find_package(simdutf REQUIRED)
|
||||
swizzle_target_properties_for_swift(simdutf::simdutf)
|
||||
target_link_libraries(AK PRIVATE simdutf::simdutf)
|
||||
|
||||
find_package(FastFloat CONFIG REQUIRED)
|
||||
swizzle_target_properties_for_swift(FastFloat::fast_float)
|
||||
target_link_libraries(AK PRIVATE FastFloat::fast_float)
|
||||
|
||||
# FIXME: Make this generic for all imported shared library dependencies and apply globally
|
||||
|
|
@ -83,16 +81,6 @@ if (BUILD_SHARED_LIBS AND NOT CMAKE_SKIP_INSTALL_RULES AND NOT "${VCPKG_INSTALLE
|
|||
)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
generate_clang_module_map(AK
|
||||
GENERATED_FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Backtrace.h"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/Debug.h"
|
||||
)
|
||||
target_sources(AK PRIVATE AK+Swift.swift)
|
||||
add_swift_target_properties(AK)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# FIXME: Windows on ARM
|
||||
target_link_libraries(AK PRIVATE clang_rt.builtins-x86_64.lib)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/Span.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <AK/Types.h>
|
||||
|
||||
|
|
@ -380,7 +379,7 @@ private:
|
|||
static constexpr size_t inline_capacity = 4 * sizeof(void*);
|
||||
|
||||
alignas(inline_alignment) u8 m_storage[inline_capacity];
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
47
AK/Swift.h
47
AK/Swift.h
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __has_include(<swift/bridging>)
|
||||
# include <swift/bridging>
|
||||
// FIXME: Workaround for Xcode 14/15. When swif becomes required, we should bump the
|
||||
// required Xcode version to one that supports all the features we are using.
|
||||
# ifndef SWIFT_UNCHECKED_SENDABLE
|
||||
# define SWIFT_UNCHECKED_SENDABLE
|
||||
# define SWIFT_NONCOPYABLE
|
||||
# define SWIFT_NONESCAPABLE
|
||||
# define SWIFT_ESCAPABLE
|
||||
# define SWIFT_ESCAPABLE_IF(...)
|
||||
# define SWIFT_RETURNS_RETAINED
|
||||
# define SWIFT_RETURNS_UNRETAINED
|
||||
# endif
|
||||
#else
|
||||
# define SWIFT_SELF_CONTAINED
|
||||
# define SWIFT_RETURNS_INDEPENDENT_VALUE
|
||||
# define SWIFT_SHARED_REFERENCE(retain, release)
|
||||
# define SWIFT_IMMORTAL_REFERENCE
|
||||
# define SWIFT_UNSAFE_REFERENCE
|
||||
# define SWIFT_NAME(name)
|
||||
# define SWIFT_CONFORMS_TO_PROTOCOL(protocol)
|
||||
# define SWIFT_COMPUTED_PROPERTY
|
||||
# define SWIFT_MUTATING
|
||||
# define SWIFT_UNCHECKED_SENDABLE
|
||||
# define SWIFT_NONCOPYABLE
|
||||
# define SWIFT_NONESCAPABLE
|
||||
# define SWIFT_ESCAPABLE
|
||||
# define SWIFT_ESCAPABLE_IF(...)
|
||||
# define SWIFT_RETURNS_RETAINED
|
||||
# define SWIFT_RETURNS_UNRETAINED
|
||||
#endif
|
||||
|
||||
// FIXME: This needs to be in the global namespace for reasons
|
||||
// https://github.com/swiftlang/swift/issues/80231
|
||||
template<class From, class To>
|
||||
To cxxCast(From i)
|
||||
{
|
||||
return static_cast<To>(i);
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
#include <AK/Diagnostics.h>
|
||||
#include <AK/Platform.h>
|
||||
|
||||
#ifdef AK_OS_WINDOWS // needed for Swift
|
||||
#ifdef AK_OS_WINDOWS
|
||||
# define timeval dummy_timeval
|
||||
# include <ntstatus.h>
|
||||
# include <winsock2.h>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ endif()
|
|||
include("Meta/CMake/use_linker.cmake")
|
||||
|
||||
if (APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
if (ENABLE_SWIFT)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 15.0)
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 14.0)
|
||||
endif()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 14.0)
|
||||
endif()
|
||||
|
||||
# Pass additional information to vcpkg toolchain files if we are using vcpkg.
|
||||
|
|
|
|||
|
|
@ -187,61 +187,3 @@ After you’ve finished debugging your code changes with that build, you can rev
|
|||
|
||||
That will restore your git environment to the state it was in before you patched the build file.
|
||||
|
||||
## Building with Swift support
|
||||
|
||||
There is experimental Swift 6 support in the Ladybird codebase. This experiment intends to determine whether Swift 6 and
|
||||
its improved C++ interoperability is a good choice for new memory-safe and concurrent code for Ladybird.
|
||||
|
||||
Building with Swift 6 support requires a main snapshot toolchain. The Ladybird team is actively working with the Swift
|
||||
team to improve the C++ interop features to meet the needs of our project.
|
||||
|
||||
The best way to get started is with `swiftly`. After setting up a `swiftly` toolchain, any of the existing build presets
|
||||
can be modified to use the Swift toolchain. However, note that in order to build Swift support into the project, the
|
||||
build must use a version of Clang that is built from an LLVM fork with Swift support. The two places this can be found
|
||||
are from the swift.org snapshot/release toolchains, and Xcode toolchains. Upstream llvm.org Clang does not support
|
||||
Swift, and GCC does not support Swift either.
|
||||
|
||||
### Get Swiftly
|
||||
|
||||
`swiftly` is a tool that helps you manage Swift toolchains. It can be installed from https://www.swift.org/install/linux/
|
||||
or https://www.swift.org/install/macos/ as applicable. After following the instructions on the swift.org install page,
|
||||
`swiftly` installs the latest release toolchain. If you wish to save space, add the `--skip-install` flag to the `swiftly
|
||||
init` invocation. If you wish to avoid `swiftly` messing with your shellrc files, add `--no-modify-profile`. On some Linux
|
||||
platforms, it may be necessary to add a `--platform` flag to the `swiftly init` invocation to instruct `swiftly` on which
|
||||
supported platform to masquerade as. This is especially necessary on Fedora or other non-Debian based distributions.
|
||||
|
||||
Note that while `$SWIFTLY_HOME_DIR` and `$SWIFTLY_BIN_DIR` can be used
|
||||
to set the installed location of the `swiftly` binary and its associated files, the install location of toolchains is not
|
||||
nearly as customizable. On Linux they will always be placed in `$XDG_DATA_HOME/swiftly/toolchains`, and on macOS they will always be
|
||||
placed in `$HOME/Library/Developer/Toolchains`. On macOS, the `.pkg` file will always drop temporary files in `$HOME/.swiftly`,
|
||||
so be sure to clear them out if you change the default home/bin directories.
|
||||
|
||||
### Build with Swift
|
||||
|
||||
The simplest way to enable Swift is to use the `Swift_Release` preset and `ladybird.py`.
|
||||
|
||||
```bash
|
||||
./Meta/ladybird.py build --preset Swift_Release
|
||||
```
|
||||
|
||||
Note that because building with Swift support requires use of `clang` and `clang++` from a Swift toolchain, a standard
|
||||
install of Clang or GCC will not work. Additional IDE settings are be required to ensure that the IDE uses the correct
|
||||
compiler paths. Trying to use just `clang` or `$SWIFTLY_BIN_DIR/clang` will both fail, due to https://github.com/swiftlang/swiftly/issues/272.
|
||||
|
||||
The full paths that must be configured for the C and C++ compilers in your IDE are
|
||||
`$(swiftly use --print-location)/usr/bin/clang` and `$(swiftly use --print-location)/usr/bin/clang++`. These paths
|
||||
will change depending on the version of the Swift toolchain specified in `.swift-version`.
|
||||
|
||||
As another note, the main-snapshot toolchains from swift.org are `+assertion` builds. This means that both `clang` and
|
||||
`swiftc` are built with extra assertions that will cause compile-times to be longer than a standard release build.
|
||||
|
||||
To configure the build preset manually, you must first install the specified Swift toolchain, and then set the C and C++
|
||||
compiler paths manually.
|
||||
|
||||
```bash
|
||||
swiftly install
|
||||
|
||||
cmake --preset Swift_Release \
|
||||
-DCMAKE_C_COMPILER=$(swiftly use --print-location)/usr/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=$(swiftly use --print-location)/usr/bin/clang++
|
||||
```
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ Here’s a short timeline:
|
|||
|
||||
## Do you have some general details about the code and basic architecture?
|
||||
|
||||
- C++ while selectively migrating parts to Swift and while keeping an eye on things like Sean Baxter’s [Circle](https://github.com/seanbaxter/circle) & [Safe C++](https://safecpp.org/draft.html).
|
||||
- Some use of third-party libraries (e.g., Harfbuzz, Skia, [simdutf](https://github.com/simdutf/simdutf), libcurl).
|
||||
- Performance optimizing is not yet a super-high priority (but performance-boosting changes are regularly getting made).
|
||||
- Code size:
|
||||
|
|
|
|||
|
|
@ -149,27 +149,3 @@ endif()
|
|||
if (ANDROID)
|
||||
target_link_libraries(LibCore PRIVATE log)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
if(WIN32)
|
||||
list(APPEND SWIFT_EXCLUDE_HEADERS "EventLoopImplementationUnix.h")
|
||||
else()
|
||||
list(APPEND SWIFT_EXCLUDE_HEADERS "EventLoopImplementationWindows.h")
|
||||
endif()
|
||||
if (NOT APPLE)
|
||||
list(APPEND SWIFT_EXCLUDE_HEADERS
|
||||
IOSurface.h
|
||||
MachPort.h
|
||||
MachMessageTypes.h
|
||||
ProcessStatisticsMach.h
|
||||
)
|
||||
endif()
|
||||
|
||||
generate_clang_module_map(LibCore EXCLUDE_FILES ${SWIFT_EXCLUDE_HEADERS})
|
||||
target_sources(LibCore PRIVATE
|
||||
EventSwift.mm
|
||||
EventLoopExecutor.swift)
|
||||
set_source_files_properties(EventSwift.mm PRIVATE PROPERTIES COMPILE_FLAGS -fblocks)
|
||||
target_link_libraries(LibCore PRIVATE AK)
|
||||
add_swift_target_properties(LibCore LAGOM_LIBRARIES AK)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <AK/Function.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibCore/Forward.h>
|
||||
|
|
@ -99,7 +98,7 @@ public:
|
|||
private:
|
||||
NonnullOwnPtr<EventLoopImplementation> m_impl;
|
||||
RefPtr<WeakEventLoopReference> m_weak;
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
};
|
||||
|
||||
class StrongEventLoopReference;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
@_exported import CoreCxx
|
||||
|
||||
extension Core.EventLoop: Equatable {
|
||||
func deferred_invoke(_ task: @escaping () -> Void) {
|
||||
Core.deferred_invoke_block(self, task)
|
||||
}
|
||||
|
||||
public static func == (lhs: Core.EventLoop, rhs: Core.EventLoop) -> Bool {
|
||||
Unmanaged.passUnretained(lhs).toOpaque() == Unmanaged.passUnretained(rhs).toOpaque()
|
||||
}
|
||||
}
|
||||
|
||||
public class EventLoopExecutor: SerialExecutor, TaskExecutor, @unchecked Sendable {
|
||||
nonisolated private let eventLoop: Core.EventLoop
|
||||
|
||||
public init() {
|
||||
eventLoop = Core.EventLoop.current()
|
||||
}
|
||||
|
||||
public init(eventLoop: Core.EventLoop) {
|
||||
self.eventLoop = eventLoop
|
||||
}
|
||||
|
||||
public nonisolated func enqueue(_ job: consuming ExecutorJob) {
|
||||
let job = UnownedJob(job)
|
||||
eventLoop.deferred_invoke { [self, job] in
|
||||
job.runSynchronously(
|
||||
isolatedTo: self.asUnownedSerialExecutor(),
|
||||
taskExecutor: self.asUnownedTaskExecutor())
|
||||
}
|
||||
}
|
||||
|
||||
public func checkIsolated() {
|
||||
precondition(Core.EventLoop.current() == eventLoop)
|
||||
}
|
||||
}
|
||||
|
||||
public protocol EventLoopActor: Actor {
|
||||
nonisolated var executor: EventLoopExecutor { get } // impl with a let
|
||||
}
|
||||
|
||||
extension EventLoopActor {
|
||||
public nonisolated var unownedExecutor: UnownedSerialExecutor {
|
||||
executor.asUnownedSerialExecutor()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/EventSwift.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
void deferred_invoke_block(EventLoop& event_loop, void (^invokee)(void))
|
||||
{
|
||||
event_loop.deferred_invoke(invokee);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ set(SOURCES
|
|||
Cell.cpp
|
||||
CellAllocator.cpp
|
||||
ConservativeVector.cpp
|
||||
ForeignCell.cpp
|
||||
Root.cpp
|
||||
RootHashMap.cpp
|
||||
RootVector.cpp
|
||||
|
|
@ -16,15 +15,6 @@ set(SOURCES
|
|||
ladybird_lib(LibGC gc EXPLICIT_SYMBOL_EXPORT)
|
||||
target_link_libraries(LibGC PRIVATE LibCore)
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
generate_clang_module_map(LibGC)
|
||||
target_sources(LibGC PRIVATE
|
||||
Heap+Swift.swift
|
||||
)
|
||||
target_link_libraries(LibGC PRIVATE AK)
|
||||
add_swift_target_properties(LibGC LAGOM_LIBRARIES AK)
|
||||
endif()
|
||||
|
||||
# TODO: Use lagom_generate_export_header and annotate entire LibGC with export macros
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(LibGC EXPORT_MACRO_NAME GC_API EXPORT_FILE_NAME "Export.h")
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <AK/Noncopyable.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/Weakable.h>
|
||||
#include <LibGC/Forward.h>
|
||||
#include <LibGC/Internals.h>
|
||||
|
|
@ -72,17 +71,17 @@ public:
|
|||
visit_impl(*cell);
|
||||
}
|
||||
|
||||
void visit(Cell& cell) SWIFT_NAME(visitRef(_:))
|
||||
void visit(Cell& cell)
|
||||
{
|
||||
visit_impl(cell);
|
||||
}
|
||||
|
||||
void visit(Cell const* cell) SWIFT_NAME(visitConst(_:))
|
||||
void visit(Cell const* cell)
|
||||
{
|
||||
visit(const_cast<Cell*>(cell));
|
||||
}
|
||||
|
||||
void visit(Cell const& cell) SWIFT_NAME(visitConstRef(_:))
|
||||
void visit(Cell const& cell)
|
||||
{
|
||||
visit(const_cast<Cell&>(cell));
|
||||
}
|
||||
|
|
@ -185,7 +184,7 @@ public:
|
|||
visit(optional.value());
|
||||
}
|
||||
|
||||
void visit(NanBoxedValue const& value) SWIFT_NAME(visitValue(_:));
|
||||
void visit(NanBoxedValue const& value);
|
||||
|
||||
// Allow explicitly ignoring a GC-allocated member in a visit_edges implementation instead
|
||||
// of just not using it.
|
||||
|
|
@ -200,7 +199,7 @@ public:
|
|||
virtual void visit_impl(Cell&) = 0;
|
||||
virtual void visit_impl(ReadonlySpan<NanBoxedValue>) = 0;
|
||||
virtual ~Visitor() = default;
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
};
|
||||
|
||||
MUST_UPCALL virtual void visit_edges(Visitor&) { }
|
||||
|
||||
|
|
@ -220,7 +219,7 @@ protected:
|
|||
private:
|
||||
bool m_mark { false };
|
||||
State m_state { State::Live };
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Swift.h>
|
||||
#include <LibGC/Heap.h>
|
||||
|
||||
namespace GC {
|
||||
|
|
@ -26,6 +25,6 @@ public:
|
|||
|
||||
private:
|
||||
Heap& m_heap;
|
||||
} SWIFT_NONCOPYABLE;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGC/DeferGC.h>
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibGC/Heap.h>
|
||||
|
||||
namespace GC {
|
||||
|
||||
void* ForeignCell::foreign_data()
|
||||
{
|
||||
// !!!
|
||||
auto offset = round_up_to_power_of_two(sizeof(ForeignCell), m_vtable.alignment);
|
||||
return static_cast<void*>(reinterpret_cast<u8*>(this) + offset);
|
||||
}
|
||||
|
||||
ForeignCell::ForeignCell(ForeignCell::Vtable vtable)
|
||||
: m_vtable(move(vtable))
|
||||
{
|
||||
if (m_vtable.initialize)
|
||||
m_vtable.initialize(foreign_data(), m_vtable.class_metadata_pointer, *this);
|
||||
}
|
||||
|
||||
ForeignCell::~ForeignCell()
|
||||
{
|
||||
if (m_vtable.destroy)
|
||||
m_vtable.destroy(foreign_data(), m_vtable.class_metadata_pointer);
|
||||
}
|
||||
|
||||
Ref<ForeignCell> ForeignCell::create(Heap& heap, size_t size, ForeignCell::Vtable vtable)
|
||||
{
|
||||
// NOTE: GC must be deferred so that a collection during allocation doesn't get tripped
|
||||
// up looking for the Cell pointer on the stack or in a register when it might only exist in the heap.
|
||||
// We can't guarantee that the ForeignCell will be stashed in a proper ForeignRef/ForeignPtr or similar
|
||||
// foreign type until after all the dust has settled on both sides of the FFI boundary.
|
||||
VERIFY(heap.is_gc_deferred());
|
||||
VERIFY(is_power_of_two(vtable.alignment));
|
||||
auto& allocator = heap.allocator_for_size(sizeof(ForeignCell) + round_up_to_power_of_two(size, vtable.alignment));
|
||||
auto* memory = allocator.allocate_cell(heap);
|
||||
auto* foreign_cell = new (memory) ForeignCell(move(vtable));
|
||||
return *foreign_cell;
|
||||
}
|
||||
|
||||
void ForeignCell::finalize()
|
||||
{
|
||||
Base::finalize();
|
||||
if (m_vtable.finalize)
|
||||
m_vtable.finalize(foreign_data(), m_vtable.class_metadata_pointer);
|
||||
}
|
||||
|
||||
void ForeignCell::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
if (m_vtable.visit_edges)
|
||||
m_vtable.visit_edges(foreign_data(), m_vtable.class_metadata_pointer, visitor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibGC/Cell.h>
|
||||
#include <LibGC/DeferGC.h>
|
||||
|
||||
namespace GC {
|
||||
|
||||
template<typename T>
|
||||
struct ForeignRef;
|
||||
|
||||
template<typename T>
|
||||
struct ForeignPtr;
|
||||
|
||||
#define FOREIGN_CELL(class_, base_class) \
|
||||
using Base = base_class; \
|
||||
friend class GC::Heap;
|
||||
|
||||
class GC_API ForeignCell : public Cell {
|
||||
FOREIGN_CELL(ForeignCell, Cell);
|
||||
|
||||
public:
|
||||
static constexpr bool OVERRIDES_FINALIZE = true;
|
||||
|
||||
struct Vtable {
|
||||
// Holds a pointer to the foreign vtable information such as
|
||||
// a jclass in Java, or a Swift type metadata pointer
|
||||
void* class_metadata_pointer = nullptr;
|
||||
|
||||
// FIXME: FlyString? The class name must be owned by the ForeignCell so it can vend StringViews
|
||||
// We should properly cache the name and class info pointer to avoid string churn
|
||||
String class_name;
|
||||
|
||||
size_t alignment { 1 };
|
||||
|
||||
void (*initialize)(void* thiz, void* clazz, Ref<Cell>);
|
||||
void (*destroy)(void* thiz, void* clazz);
|
||||
void (*finalize)(void* thiz, void* clazz);
|
||||
void (*visit_edges)(void* thiz, void* clazz, Cell::Visitor&);
|
||||
};
|
||||
static Ref<ForeignCell> create(Heap&, size_t size, Vtable);
|
||||
|
||||
void* foreign_data() SWIFT_RETURNS_INDEPENDENT_VALUE; // technically lying to swift, but it's fiiiiine
|
||||
|
||||
// ^Cell
|
||||
virtual void finalize() override;
|
||||
virtual void visit_edges(Cell::Visitor& visitor) override;
|
||||
virtual StringView class_name() const override { return m_vtable.class_name; }
|
||||
|
||||
~ForeignCell();
|
||||
|
||||
private:
|
||||
ForeignCell(Vtable vtable);
|
||||
|
||||
Vtable m_vtable;
|
||||
} SWIFT_IMMORTAL_REFERENCE;
|
||||
|
||||
template<typename T>
|
||||
struct ForeignRef {
|
||||
friend struct ForeignPtr<T>;
|
||||
|
||||
template<typename... Args>
|
||||
static ForeignRef allocate(Heap& heap, Args... args)
|
||||
{
|
||||
DeferGC const defer_gc(heap);
|
||||
auto* cell = T::create(&heap, forward<Args>(args)...);
|
||||
if constexpr (IsSame<decltype(cell), Cell*>) {
|
||||
return ForeignRef(*as<ForeignCell>(cell));
|
||||
} else {
|
||||
static_assert(IsSame<decltype(cell), void*>);
|
||||
auto* cast_cell = static_cast<Cell*>(cell);
|
||||
return ForeignRef(*as<ForeignCell>(cast_cell));
|
||||
}
|
||||
}
|
||||
|
||||
ForeignRef() = delete;
|
||||
|
||||
// This constructor should only be called directly after allocating a foreign cell by calling an FFI create method
|
||||
ForeignRef(ForeignCell& cell)
|
||||
: m_cell(cell)
|
||||
{
|
||||
// FIXME: This is super dangerous. How can we assert that the cell is actually a T?
|
||||
m_data = static_cast<T*>(m_cell->foreign_data());
|
||||
}
|
||||
|
||||
~ForeignRef() = default;
|
||||
ForeignRef(ForeignRef const& other) = default;
|
||||
ForeignRef& operator=(ForeignRef const& other) = default;
|
||||
|
||||
RETURNS_NONNULL T* operator->() const { return m_data; }
|
||||
[[nodiscard]] T& operator*() const { return *m_data; }
|
||||
|
||||
RETURNS_NONNULL T* ptr() const { return m_data; }
|
||||
RETURNS_NONNULL operator T*() const { return m_data; }
|
||||
|
||||
operator T&() const { return *m_data; }
|
||||
|
||||
Ref<ForeignCell> cell() const { return m_cell; }
|
||||
|
||||
void visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
visitor.visit(m_cell);
|
||||
}
|
||||
|
||||
private:
|
||||
Ref<ForeignCell> m_cell;
|
||||
T* m_data { nullptr };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ForeignPtr {
|
||||
constexpr ForeignPtr() = default;
|
||||
|
||||
// This constructor should only be called directly after allocating a foreign cell by calling an FFI create method
|
||||
ForeignPtr(ForeignCell& cell)
|
||||
: m_cell(&cell)
|
||||
{
|
||||
// FIXME: This is super dangerous. How can we assert that the cell is actually a T?
|
||||
m_data = static_cast<T*>(m_cell->foreign_data());
|
||||
}
|
||||
|
||||
// This constructor should only be called directly after allocating a foreign cell by calling an FFI create method
|
||||
ForeignPtr(ForeignCell* cell)
|
||||
: m_cell(cell)
|
||||
{
|
||||
// FIXME: This is super dangerous. How can we assert that the cell is actually a T?
|
||||
m_data = m_cell ? static_cast<T*>(m_cell->foreign_data()) : nullptr;
|
||||
}
|
||||
|
||||
ForeignPtr(ForeignRef<T> const& other)
|
||||
: m_cell(other.m_cell)
|
||||
, m_data(other.m_data)
|
||||
{
|
||||
}
|
||||
|
||||
ForeignPtr(nullptr_t)
|
||||
: m_cell(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
ForeignPtr(ForeignPtr const& other) = default;
|
||||
ForeignPtr& operator=(ForeignPtr const& other) = default;
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
ASSERT(m_cell && m_data);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
[[nodiscard]] T& operator*() const
|
||||
{
|
||||
ASSERT(m_cell && m_data);
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
operator T*() const { return m_data; }
|
||||
T* ptr() const { return m_data; }
|
||||
|
||||
explicit operator bool() const { return !!m_cell; }
|
||||
bool operator!() const { return !m_cell; }
|
||||
|
||||
Ptr<ForeignCell> cell() const { return m_cell; }
|
||||
|
||||
void visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
visitor.visit(m_cell);
|
||||
}
|
||||
|
||||
private:
|
||||
Ptr<ForeignCell> m_cell;
|
||||
T* m_data { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ namespace GC {
|
|||
class Cell;
|
||||
class CellAllocator;
|
||||
class DeferGC;
|
||||
class ForeignCell;
|
||||
class RootImpl;
|
||||
class Heap;
|
||||
class HeapBlock;
|
||||
|
|
|
|||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
@_exported import GCCxx
|
||||
|
||||
extension GC.Heap {
|
||||
public func withDeferredGC<R, E>(_ body: () throws(E) -> R) throws(E) -> R {
|
||||
let deferredRAII = GC.DeferGC(self)
|
||||
_ = deferredRAII
|
||||
return try body()
|
||||
}
|
||||
}
|
||||
|
||||
public protocol HeapAllocatable {
|
||||
static func allocate(on heap: GC.Heap) -> UnsafeMutablePointer<Self>
|
||||
|
||||
init(cell: GC.Cell)
|
||||
|
||||
func finalize()
|
||||
func visitEdges(_ visitor: GC.Cell.Visitor)
|
||||
|
||||
var cell: GC.Cell { get }
|
||||
}
|
||||
|
||||
// Here be dragons
|
||||
|
||||
func asTypeMetadataPointer(_ type: Any.Type) -> UnsafeMutableRawPointer {
|
||||
unsafeBitCast(type, to: UnsafeMutableRawPointer.self)
|
||||
}
|
||||
|
||||
func asHeapAllocatableType(_ typeMetadata: UnsafeMutableRawPointer) -> any HeapAllocatable.Type {
|
||||
let typeObject = unsafeBitCast(typeMetadata, to: Any.Type.self)
|
||||
guard let type = typeObject as? any HeapAllocatable.Type else {
|
||||
fatalError("Passed foreign class but it wasn't a Swift type!")
|
||||
}
|
||||
return type
|
||||
}
|
||||
|
||||
extension HeapAllocatable {
|
||||
fileprivate static func initializeFromFFI(at this: UnsafeMutableRawPointer, cell: GC.Cell) {
|
||||
this.assumingMemoryBound(to: Self.self).initialize(to: Self.self.init(cell: cell))
|
||||
}
|
||||
|
||||
fileprivate static func destroyFromFFI(at this: UnsafeMutableRawPointer) {
|
||||
this.assumingMemoryBound(to: Self.self).deinitialize(count: 1)
|
||||
}
|
||||
|
||||
fileprivate static func finalizeFromFFI(at this: UnsafeMutableRawPointer) {
|
||||
this.assumingMemoryBound(to: Self.self).pointee.finalize()
|
||||
}
|
||||
|
||||
fileprivate static func visitEdgesFromFFI(at this: UnsafeMutableRawPointer, visitor: GC.Cell.Visitor) {
|
||||
this.assumingMemoryBound(to: Self.self).pointee.visitEdges(visitor)
|
||||
}
|
||||
|
||||
public static func allocate(on heap: GC.Heap) -> UnsafeMutablePointer<Self> {
|
||||
let vtable = GC.ForeignCell.Vtable(
|
||||
class_metadata_pointer: asTypeMetadataPointer(Self.self),
|
||||
class_name: AK.String(swiftString: Swift.String(describing: Self.self)),
|
||||
alignment: MemoryLayout<Self>.alignment,
|
||||
initialize: { this, typeMetadata, cell in
|
||||
asHeapAllocatableType(typeMetadata!).initializeFromFFI(at: this!, cell: cell.ptr())
|
||||
},
|
||||
destroy: { this, typeMetadata in
|
||||
asHeapAllocatableType(typeMetadata!).destroyFromFFI(at: this!)
|
||||
},
|
||||
finalize: { this, typeMetadata in
|
||||
asHeapAllocatableType(typeMetadata!).finalizeFromFFI(at: this!)
|
||||
},
|
||||
visit_edges: nil
|
||||
)
|
||||
let cell = GC.ForeignCell.create(heap, MemoryLayout<Self>.stride, vtable)
|
||||
return cell.pointee.foreign_data().assumingMemoryBound(to: Self.self)
|
||||
}
|
||||
|
||||
public func finalize() {}
|
||||
public func visitEdges(_ visitor: GC.Cell.Visitor) {}
|
||||
}
|
||||
|
|
@ -12,7 +12,6 @@
|
|||
#include <AK/Noncopyable.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/StackInfo.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/Forward.h>
|
||||
|
|
@ -90,7 +89,6 @@ private:
|
|||
friend class MarkingVisitor;
|
||||
friend class GraphConstructorVisitor;
|
||||
friend class DeferGC;
|
||||
friend class ForeignCell;
|
||||
|
||||
void defer_gc();
|
||||
void undefer_gc();
|
||||
|
|
@ -179,7 +177,7 @@ private:
|
|||
|
||||
WeakBlock::List m_usable_weak_blocks;
|
||||
WeakBlock::List m_full_weak_blocks;
|
||||
} SWIFT_IMMORTAL_REFERENCE;
|
||||
};
|
||||
|
||||
inline void Heap::did_create_root(Badge<RootImpl>, RootImpl& impl)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,14 +61,6 @@ set(SOURCES
|
|||
YUVData.cpp
|
||||
)
|
||||
|
||||
set(SWIFT_EXCLUDE_HEADERS
|
||||
FilterImpl.h
|
||||
GlobalFontConfig.h
|
||||
MetalContext.h
|
||||
VulkanContext.h
|
||||
SkiaUtils.h
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND SOURCES MetalContext.mm)
|
||||
endif()
|
||||
|
|
@ -157,15 +149,6 @@ else()
|
|||
target_link_libraries(LibGfx PRIVATE libjxl::libjxl hwy::hwy)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
generate_clang_module_map(LibGfx GENERATED_FILES ${generated_headers} EXCLUDE_FILES ${SWIFT_EXCLUDE_HEADERS})
|
||||
target_sources(LibGfx PRIVATE
|
||||
Color.swift
|
||||
)
|
||||
target_link_libraries(LibGfx PRIVATE AK)
|
||||
add_swift_target_properties(LibGfx LAGOM_LIBRARIES AK)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(LibCore PUBLIC "-framework Metal")
|
||||
target_link_libraries(LibCore PUBLIC "-framework Accelerate")
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/StringConversions.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <AK/Utf16String.h>
|
||||
#include <AK/Utf16View.h>
|
||||
#include <AK/Vector.h>
|
||||
|
|
@ -19,10 +18,6 @@
|
|||
#include <LibIPC/Encoder.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef LIBGFX_USE_SWIFT
|
||||
# include <LibGfx-Swift.h>
|
||||
#endif
|
||||
|
||||
namespace Gfx {
|
||||
|
||||
namespace {
|
||||
|
|
@ -355,15 +350,6 @@ Optional<Color> Color::from_named_css_color_string(StringView string)
|
|||
return {};
|
||||
}
|
||||
|
||||
#if defined(LIBGFX_USE_SWIFT)
|
||||
static Optional<Color> hex_string_to_color(StringView string)
|
||||
{
|
||||
auto color = parseHexString(string);
|
||||
if (color.getCount() == 0)
|
||||
return {};
|
||||
return color[0];
|
||||
}
|
||||
#else
|
||||
static Optional<Color> hex_string_to_color(StringView string)
|
||||
{
|
||||
auto hex_nibble_to_u8 = [](char nibble) -> Optional<u8> {
|
||||
|
|
@ -414,7 +400,6 @@ static Optional<Color> hex_string_to_color(StringView string)
|
|||
|
||||
return Color(r.value(), g.value(), b.value(), a.value());
|
||||
}
|
||||
#endif
|
||||
|
||||
Optional<Color> Color::from_string(StringView string)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
@_exported import GfxCxx
|
||||
|
||||
// FIXME: Do this without extending String with an index operation that was explicitly deleted :^)
|
||||
extension Swift.String {
|
||||
subscript(_ index: Int) -> Character {
|
||||
return self[self.index(self.startIndex, offsetBy: index)]
|
||||
}
|
||||
}
|
||||
|
||||
private func hexNibbleToUInt8(_ nibble: Character) -> UInt8? {
|
||||
guard nibble.isHexDigit else {
|
||||
return nil
|
||||
}
|
||||
return UInt8(nibble.hexDigitValue!)
|
||||
}
|
||||
|
||||
private func hexNibblesToUInt8(_ nib1: Character, _ nib2: Character) -> UInt8? {
|
||||
guard let n1 = hexNibbleToUInt8(nib1) else {
|
||||
return nil
|
||||
}
|
||||
guard let n2 = hexNibbleToUInt8(nib2) else {
|
||||
return nil
|
||||
}
|
||||
return n1 << 4 | n2
|
||||
}
|
||||
|
||||
// FIXME: Return Gfx.Color? When swift ABI bug is fixed
|
||||
public func parseHexString(_ rawString: AK.StringView) -> [Gfx.Color] {
|
||||
guard let string = Swift.String(akStringView: rawString) else {
|
||||
return []
|
||||
}
|
||||
|
||||
assert(string.hasPrefix("#"))
|
||||
|
||||
switch string.count {
|
||||
case 4:
|
||||
let r = hexNibbleToUInt8(string[1])
|
||||
let g = hexNibbleToUInt8(string[2])
|
||||
let b = hexNibbleToUInt8(string[3])
|
||||
|
||||
guard r != nil && g != nil && b != nil else {
|
||||
return []
|
||||
}
|
||||
|
||||
return [Gfx.Color(r! * 17, g! * 17, b! * 17)]
|
||||
case 5:
|
||||
let r = hexNibbleToUInt8(string[1])
|
||||
let g = hexNibbleToUInt8(string[2])
|
||||
let b = hexNibbleToUInt8(string[3])
|
||||
let a = hexNibbleToUInt8(string[4])
|
||||
|
||||
guard r != nil && g != nil && b != nil && a != nil else {
|
||||
return []
|
||||
}
|
||||
|
||||
return [Gfx.Color(r! * 17, g! * 17, b! * 17, a! * 17)]
|
||||
case 6: return []
|
||||
case 7:
|
||||
let r = hexNibblesToUInt8(string[1], string[2])
|
||||
let g = hexNibblesToUInt8(string[3], string[4])
|
||||
let b = hexNibblesToUInt8(string[5], string[6])
|
||||
|
||||
guard r != nil && g != nil && b != nil else {
|
||||
return []
|
||||
}
|
||||
|
||||
return [Gfx.Color(r!, g!, b!, UInt8(255))]
|
||||
case 8: return []
|
||||
case 9:
|
||||
let r = hexNibblesToUInt8(string[1], string[2])
|
||||
let g = hexNibblesToUInt8(string[3], string[4])
|
||||
let b = hexNibblesToUInt8(string[5], string[6])
|
||||
let a = hexNibblesToUInt8(string[7], string[8])
|
||||
|
||||
guard r != nil && g != nil && b != nil && a != nil else {
|
||||
return []
|
||||
}
|
||||
|
||||
return [Gfx.Color(r!, g!, b!, a!)]
|
||||
default: return []
|
||||
}
|
||||
}
|
||||
|
|
@ -1210,23 +1210,3 @@ target_link_libraries(LibWeb PRIVATE LibCore LibCompress LibCrypto LibJS LibHTTP
|
|||
target_include_directories(LibWeb PRIVATE ${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/include)
|
||||
|
||||
generate_js_bindings(LibWeb)
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
include(collections)
|
||||
|
||||
set(generated_headers ${GENERATED_SOURCES})
|
||||
list(FILTER generated_headers INCLUDE REGEX "\\.h$")
|
||||
list(TRANSFORM generated_headers PREPEND "${CMAKE_CURRENT_BINARY_DIR}/")
|
||||
list(APPEND LIBWEB_ALL_GENERATED_HEADERS ${generated_headers})
|
||||
|
||||
generate_clang_module_map(LibWeb GENERATED_FILES ${LIBWEB_ALL_GENERATED_HEADERS})
|
||||
|
||||
target_sources(LibWeb PRIVATE
|
||||
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 LibGC)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -51,10 +51,6 @@
|
|||
#include <LibWeb/SVG/SVGScriptElement.h>
|
||||
#include <LibWeb/SVG/TagNames.h>
|
||||
|
||||
#ifdef LIBWEB_USE_SWIFT
|
||||
# include <LibWeb-Swift.h>
|
||||
#endif
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(HTMLParser);
|
||||
|
|
@ -205,10 +201,6 @@ void HTMLParser::visit_edges(Cell::Visitor& visitor)
|
|||
void HTMLParser::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
|
||||
#if defined(LIBWEB_USE_SWIFT)
|
||||
m_speculative_parser = GC::ForeignRef<Web::SpeculativeHTMLParser>::allocate(realm.heap(), this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void HTMLParser::run(HTMLTokenizer::StopAtInsertionPoint stop_at_insertion_point)
|
||||
|
|
|
|||
|
|
@ -15,16 +15,6 @@
|
|||
#include <LibWeb/HTML/Parser/StackOfOpenElements.h>
|
||||
#include <LibWeb/MimeSniff/MimeType.h>
|
||||
|
||||
#ifdef LIBWEB_USE_SWIFT
|
||||
# include <LibGC/ForeignCell.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class SpeculativeHTMLParser;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
#define ENUMERATE_INSERTION_MODES \
|
||||
|
|
@ -221,22 +211,14 @@ private:
|
|||
GC::Ptr<HTMLFormElement> m_form_element;
|
||||
GC::Ptr<DOM::Element> m_context_element;
|
||||
|
||||
#ifdef LIBWEB_USE_SWIFT
|
||||
GC::ForeignPtr<Web::SpeculativeHTMLParser> m_speculative_parser;
|
||||
#endif
|
||||
|
||||
Vector<HTMLToken> m_pending_table_character_tokens;
|
||||
|
||||
GC::Ptr<DOM::Text> m_character_insertion_node;
|
||||
StringBuilder m_character_insertion_builder { StringBuilder::Mode::UTF16 };
|
||||
} SWIFT_UNSAFE_REFERENCE;
|
||||
};
|
||||
|
||||
RefPtr<CSS::StyleValue const> parse_dimension_value(StringView);
|
||||
RefPtr<CSS::StyleValue const> parse_nonzero_dimension_value(StringView);
|
||||
Optional<Color> parse_legacy_color_value(StringView);
|
||||
|
||||
// Swift interop
|
||||
using HTMLParserGCPtr = GC::Ptr<HTMLParser>;
|
||||
using HTMLParserGCRef = GC::Ref<HTMLParser>;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
@_exported import WebCxx
|
||||
|
||||
public class HTMLToken {
|
||||
public struct Position: Equatable {
|
||||
var line = UInt()
|
||||
var column = UInt()
|
||||
var byteOffset = UInt()
|
||||
}
|
||||
|
||||
public struct Attribute: Equatable {
|
||||
public var prefix: Swift.String? = nil
|
||||
public var localName: Swift.String
|
||||
public var namespace_: Swift.String? = nil
|
||||
public var value: Swift.String
|
||||
public var nameStartPosition = Position()
|
||||
public var nameEndPosition = Position()
|
||||
public var valueStartPosition = Position()
|
||||
public var valueEndPosition = Position()
|
||||
|
||||
public init(localName: Swift.String, value: Swift.String) {
|
||||
self.localName = localName
|
||||
self.value = value
|
||||
}
|
||||
}
|
||||
|
||||
public enum TokenType: Equatable {
|
||||
case Invalid
|
||||
case DOCTYPE(
|
||||
name: Swift.String?,
|
||||
publicIdentifier: Swift.String?,
|
||||
systemIdentifier: Swift.String?,
|
||||
forceQuirksMode: Bool)
|
||||
case StartTag(
|
||||
tagName: Swift.String,
|
||||
selfClosing: Bool = false,
|
||||
selfClosingAcknowledged: Bool = false,
|
||||
attributes: [Attribute] = [])
|
||||
case EndTag(
|
||||
tagName: Swift.String,
|
||||
selfClosing: Bool = false,
|
||||
selfClosingAcknowledged: Bool = false,
|
||||
attributes: [Attribute] = [])
|
||||
case Comment(data: Swift.String)
|
||||
case Character(codePoint: Character)
|
||||
case EndOfFile
|
||||
}
|
||||
|
||||
public func isCharacter() -> Bool {
|
||||
if case .Character(_) = self.type {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func isEndTag() -> Bool {
|
||||
if case .EndTag(_, _, _, _) = self.type {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func isStartTag() -> Bool {
|
||||
if case .StartTag(_, _, _, _) = self.type {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func isTag() -> Bool {
|
||||
return isStartTag() || isEndTag()
|
||||
}
|
||||
|
||||
public func isParserWhitespace() -> Bool {
|
||||
precondition(isCharacter(), "isParserWhitespace() called on non-character token")
|
||||
|
||||
// NOTE: The parser considers '\r' to be whitespace, while the tokenizer does not.
|
||||
switch self.type {
|
||||
case .Character(codePoint: "\t"),
|
||||
.Character(codePoint: "\n"),
|
||||
.Character(codePoint: "\u{000C}"), // \f
|
||||
.Character(codePoint: "\r"),
|
||||
.Character(codePoint: " "):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public var type = TokenType.Invalid
|
||||
public var startPosition = Position()
|
||||
public var endPosition = Position()
|
||||
|
||||
// Is in-place mutating enums a thing? Seems not https://forums.swift.org/t/in-place-mutation-of-an-enum-associated-value/11747
|
||||
public var attributes: [Attribute] {
|
||||
get {
|
||||
switch self.type {
|
||||
case .StartTag(_, _, _, let attributes):
|
||||
return attributes
|
||||
case .EndTag(_, _, _, let attributes):
|
||||
return attributes
|
||||
default:
|
||||
preconditionFailure("attributes called on non-tag token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .StartTag(let tagName, let selfClosing, let selfClosingAcknowledged, attributes: _):
|
||||
self.type = .StartTag(tagName: tagName, selfClosing: selfClosing, selfClosingAcknowledged: selfClosingAcknowledged, attributes: newValue)
|
||||
case .EndTag(let tagName, let selfClosing, let selfClosingAcknowledged, attributes: _):
|
||||
self.type = .EndTag(tagName: tagName, selfClosing: selfClosing, selfClosingAcknowledged: selfClosingAcknowledged, attributes: newValue)
|
||||
default:
|
||||
preconditionFailure("attributes= called on non-tag token")
|
||||
}
|
||||
}
|
||||
}
|
||||
public var tagName: Swift.String {
|
||||
get {
|
||||
switch self.type {
|
||||
case .StartTag(let tagName, _, _, _):
|
||||
return tagName
|
||||
case .EndTag(let tagName, _, _, _):
|
||||
return tagName
|
||||
default:
|
||||
preconditionFailure("tagName called on non-tag token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .StartTag(tagName: _, let selfClosing, let selfClosingAcknowledged, let attributes):
|
||||
self.type = .StartTag(tagName: newValue, selfClosing: selfClosing, selfClosingAcknowledged: selfClosingAcknowledged, attributes: attributes)
|
||||
case .EndTag(tagName: _, let selfClosing, let selfClosingAcknowledged, let attributes):
|
||||
self.type = .EndTag(tagName: newValue, selfClosing: selfClosing, selfClosingAcknowledged: selfClosingAcknowledged, attributes: attributes)
|
||||
default:
|
||||
preconditionFailure("tagName= called on non-tag token")
|
||||
}
|
||||
}
|
||||
}
|
||||
public var selfClosing: Bool {
|
||||
get {
|
||||
switch self.type {
|
||||
case .StartTag(_, let selfClosing, _, _):
|
||||
return selfClosing
|
||||
case .EndTag(_, let selfClosing, _, _):
|
||||
return selfClosing
|
||||
default:
|
||||
preconditionFailure("selfClosing called on non-tag token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .StartTag(let tagName, _, let selfClosingAcknowledged, let attributes):
|
||||
self.type = .StartTag(tagName: tagName, selfClosing: newValue, selfClosingAcknowledged: selfClosingAcknowledged, attributes: attributes)
|
||||
case .EndTag(let tagName, _, let selfClosingAcknowledged, let attributes):
|
||||
self.type = .EndTag(tagName: tagName, selfClosing: newValue, selfClosingAcknowledged: selfClosingAcknowledged, attributes: attributes)
|
||||
default:
|
||||
preconditionFailure("selfClosing= called on non-tag token")
|
||||
}
|
||||
}
|
||||
}
|
||||
public var name: Swift.String? {
|
||||
get {
|
||||
switch self.type {
|
||||
case .DOCTYPE(let name, _, _, _):
|
||||
return name
|
||||
default:
|
||||
preconditionFailure("doctypeName called on non-doctype token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .DOCTYPE(_, let publicIdentifier, let systemIdentifier, let forceQuirksMode):
|
||||
self.type = .DOCTYPE(name: newValue, publicIdentifier: publicIdentifier, systemIdentifier: systemIdentifier, forceQuirksMode: forceQuirksMode)
|
||||
default:
|
||||
preconditionFailure("doctypeName= called on non-doctype token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var forceQuirks: Bool {
|
||||
get {
|
||||
switch self.type {
|
||||
case .DOCTYPE(_, _, _, let forceQuirksMode):
|
||||
return forceQuirksMode
|
||||
default:
|
||||
preconditionFailure("forceQuirks called on non-doctype token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .DOCTYPE(let name, let publicIdentifier, let systemIdentifier, _):
|
||||
self.type = .DOCTYPE(name: name, publicIdentifier: publicIdentifier, systemIdentifier: systemIdentifier, forceQuirksMode: newValue)
|
||||
default:
|
||||
preconditionFailure("forceQuirks= called on non-doctype token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var publicIdentifier: Swift.String? {
|
||||
get {
|
||||
switch self.type {
|
||||
case .DOCTYPE(_, let publicIdentifier, _, _):
|
||||
return publicIdentifier
|
||||
default:
|
||||
preconditionFailure("publicIdentifier called on non-doctype token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .DOCTYPE(let name, _, let systemIdentifier, let forceQuirksMode):
|
||||
self.type = .DOCTYPE(name: name, publicIdentifier: newValue, systemIdentifier: systemIdentifier, forceQuirksMode: forceQuirksMode)
|
||||
default:
|
||||
preconditionFailure("publicIdentifier= called on non-doctype token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var systemIdentifier: Swift.String? {
|
||||
get {
|
||||
switch self.type {
|
||||
case .DOCTYPE(_, _, let systemIdentifier, _):
|
||||
return systemIdentifier
|
||||
default:
|
||||
preconditionFailure("systemIdentifier called on non-doctype token")
|
||||
}
|
||||
}
|
||||
set {
|
||||
switch self.type {
|
||||
case .DOCTYPE(let name, let publicIdentifier, _, let forceQuirksMode):
|
||||
self.type = .DOCTYPE(name: name, publicIdentifier: publicIdentifier, systemIdentifier: newValue, forceQuirksMode: forceQuirksMode)
|
||||
default:
|
||||
preconditionFailure("systemIdentifier= called on non-doctype token")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public init() {}
|
||||
public init(type: TokenType) {
|
||||
self.type = type
|
||||
}
|
||||
}
|
||||
|
||||
extension HTMLToken.Position: CustomStringConvertible {
|
||||
public var description: Swift.String {
|
||||
return "\(self.line):\(self.column)"
|
||||
}
|
||||
}
|
||||
|
||||
extension HTMLToken.TokenType: CustomStringConvertible {
|
||||
// FIXME: Print attributes for start/end tags
|
||||
public var description: Swift.String {
|
||||
switch self {
|
||||
case .Invalid:
|
||||
return "Invalid"
|
||||
case .DOCTYPE(let name, let publicIdentifier, let systemIdentifier, let forceQuirksMode):
|
||||
return "DOCTYPE(name: \(name ?? "nil"), publicIdentifier: \(publicIdentifier ?? "nil"), systemIdentifier: \(systemIdentifier ?? "nil"), forceQuirksMode: \(forceQuirksMode))"
|
||||
case .StartTag(let tagName, let selfClosing, let selfClosingAcknowledged, let attributes):
|
||||
return "StartTag(tagName: \(tagName), selfClosing: \(selfClosing), selfClosingAcknowledged: \(selfClosingAcknowledged), attributes: \(attributes))"
|
||||
case .EndTag(let tagName, let selfClosing, let selfClosingAcknowledged, let attributes):
|
||||
return "EndTag(tagName: \(tagName), selfClosing: \(selfClosing), selfClosingAcknowledged: \(selfClosingAcknowledged), attributes: \(attributes))"
|
||||
case .Comment(let data):
|
||||
return "Comment(data: \(data))"
|
||||
case .Character(let codePoint):
|
||||
return "Character(codePoint: \(codePoint))"
|
||||
case .EndOfFile:
|
||||
return "EndOfFile"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension HTMLToken: CustomStringConvertible {
|
||||
public var description: Swift.String {
|
||||
if self.startPosition == Position() {
|
||||
return "HTMLToken(type: \(self.type))"
|
||||
} else if self.endPosition == Position() {
|
||||
return "HTMLToken(type: \(self.type))@\(self.startPosition)"
|
||||
} else {
|
||||
return "HTMLToken(type: \(self.type))@\(self.startPosition)-\(self.endPosition)"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibTextCodec/Decoder.h>
|
||||
#include <LibWeb/HTML/Parser/Entities.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLTokenizerHelpers.h>
|
||||
#include <LibWeb/HTML/Parser/NamedCharacterReferences.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
OptionalString decode_to_utf8(StringView text, StringView encoding)
|
||||
{
|
||||
auto decoder = TextCodec::decoder_for(encoding);
|
||||
if (!decoder.has_value())
|
||||
return std::nullopt;
|
||||
auto decoded_or_error = decoder.value().to_utf8(text);
|
||||
if (decoded_or_error.is_error())
|
||||
return std::nullopt;
|
||||
return decoded_or_error.release_value();
|
||||
}
|
||||
|
||||
OptionalEntityMatch match_entity_for_named_character_reference(StringView entity)
|
||||
{
|
||||
NamedCharacterReferenceMatcher matcher;
|
||||
int consumed_length = 0;
|
||||
for (auto c : entity) {
|
||||
if (!matcher.try_consume_ascii_char(c))
|
||||
break;
|
||||
consumed_length++;
|
||||
}
|
||||
|
||||
auto codepoints = matcher.code_points();
|
||||
if (codepoints.has_value()) {
|
||||
EntityMatch match;
|
||||
auto matched_length = consumed_length - matcher.overconsumed_code_points();
|
||||
auto matched_string_view = entity.substring_view(0, matched_length);
|
||||
auto second_codepoint = named_character_reference_second_codepoint_value(codepoints.value().second);
|
||||
if (second_codepoint.has_value()) {
|
||||
match = { { codepoints.value().first, second_codepoint.release_value() }, matched_string_view };
|
||||
} else {
|
||||
match = { { codepoints.value().first }, matched_string_view };
|
||||
}
|
||||
return match;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <optional>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
// FIXME: This is a temporary stop-gap solution, and it should be removed once the C++
|
||||
// NamedCharacterReference state implementation is implemented in Swift.
|
||||
struct EntityMatch {
|
||||
Vector<u32, 2> code_points;
|
||||
StringView entity;
|
||||
};
|
||||
|
||||
// Swift-friendly wrapper for TextCodec::Decoder::to_utf8
|
||||
using OptionalString = std::optional<String>;
|
||||
OptionalString decode_to_utf8(StringView text, StringView encoding);
|
||||
|
||||
// Swift-friendly wrapper for HTML::code_points_from_entity
|
||||
// FIXME: This is a temporary stop-gap solution, and it should be removed once the C++
|
||||
// NamedCharacterReference state implementation is implemented in Swift.
|
||||
using OptionalEntityMatch = std::optional<EntityMatch>;
|
||||
OptionalEntityMatch match_entity_for_named_character_reference(StringView entity);
|
||||
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <LibWeb/Export.h>
|
||||
|
||||
namespace Web {
|
||||
|
|
@ -24,6 +23,6 @@ public:
|
|||
|
||||
private:
|
||||
ByteString m_path {};
|
||||
} SWIFT_UNSAFE_REFERENCE; // FIXME: This type is actually move-only, not unsafe
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <AK/LexicalPath.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Swift.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibDatabase/Forward.h>
|
||||
|
|
@ -268,7 +267,7 @@ private:
|
|||
OwnPtr<DevTools::DevToolsServer> m_devtools;
|
||||
|
||||
mutable HashMap<u64, u64> m_navigation_listener_ids;
|
||||
} SWIFT_IMMORTAL_REFERENCE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
# Finds the BlocksRuntime library
|
||||
# On Apple platforms, this does not exist and is folded into other System libraries
|
||||
|
||||
find_library(BLOCKS_RUNTIME NAMES BlocksRuntime
|
||||
PATHS ${SWIFT_LIBRARY_SEARCH_PATHS}
|
||||
)
|
||||
find_library(BLOCKS_RUNTIME NAMES BlocksRuntime)
|
||||
if (BLOCKS_RUNTIME)
|
||||
if (NOT TARGET BlocksRuntime::BlocksRuntime)
|
||||
add_library(BlocksRuntime::BlocksRuntime IMPORTED UNKNOWN)
|
||||
|
|
@ -12,7 +10,7 @@ if (BLOCKS_RUNTIME)
|
|||
set_target_properties(BlocksRuntime::BlocksRuntime PROPERTIES
|
||||
IMPORTED_LOCATION "${BLOCKS_RUNTIME}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_BLOCKS_RUNTIME_DIR}"
|
||||
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:C,CXX>:-fblocks>;SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc -fblocks>"
|
||||
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:C,CXX>:-fblocks>"
|
||||
)
|
||||
endif()
|
||||
set(BlocksRuntime_FOUND TRUE)
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
# Finds the swift-testing library
|
||||
# On Apple platforms, this is a framework included in the Xcode release
|
||||
include_guard()
|
||||
|
||||
if (NOT TARGET SwiftTesting::SwiftTesting)
|
||||
cmake_policy(PUSH)
|
||||
if (POLICY CMP0152)
|
||||
cmake_policy(SET CMP0152 NEW)
|
||||
endif()
|
||||
|
||||
set(_SEARCH_PATHS "")
|
||||
set(_PLUGIN_PATHS "")
|
||||
foreach(path IN LISTS SWIFT_LIBRARY_SEARCH_PATHS)
|
||||
file(REAL_PATH ${path} real_path)
|
||||
if (EXISTS ${real_path})
|
||||
list(APPEND _SEARCH_PATHS ${real_path})
|
||||
if (EXISTS "${real_path}/testing")
|
||||
list(APPEND _SEARCH_PATHS "${real_path}/testing")
|
||||
endif()
|
||||
endif()
|
||||
if (EXISTS "${real_path}/../host/plugins")
|
||||
file(REAL_PATH "${real_path}/../host/plugins" plugin_path)
|
||||
list(APPEND _PLUGIN_PATHS ${plugin_path})
|
||||
if (EXISTS "${plugin_path}/testing")
|
||||
list(APPEND _PLUGIN_PATHS "${plugin_path}/testing")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES _SEARCH_PATHS)
|
||||
list(REMOVE_DUPLICATES _PLUGIN_PATHS)
|
||||
|
||||
find_library(SWIFT_TESTING NAMES Testing
|
||||
PATHS ${_SEARCH_PATHS}
|
||||
)
|
||||
if (SWIFT_TESTING)
|
||||
add_library(SwiftTesting::SwiftTesting IMPORTED UNKNOWN)
|
||||
message(STATUS "Found SwiftTesting: ${SWIFT_TESTING}")
|
||||
cmake_path(GET SWIFT_TESTING PARENT_PATH _SWIFT_TESTING_DIR)
|
||||
|
||||
find_library(SWIFT_TESTING_MACROS NAMES TestingMacros
|
||||
PATHS ${_PLUGIN_PATHS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if (NOT SWIFT_TESTING_MACROS)
|
||||
message(FATAL_ERROR "Could not find associated TestingMacros plugin for ${SWIFT_TESTING}")
|
||||
else()
|
||||
message(VERBOSE "Found SwiftTesting macros: ${SWIFT_TESTING_MACROS}")
|
||||
endif()
|
||||
|
||||
set_target_properties(SwiftTesting::SwiftTesting PROPERTIES
|
||||
IMPORTED_LOCATION "${SWIFT_TESTING}"
|
||||
INTERFACE_LINK_DIRECTORIES "${_SWIFT_TESTING_DIR}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_SWIFT_TESTING_DIR}"
|
||||
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:Swift>:SHELL:-load-plugin-library ${SWIFT_TESTING_MACROS}>"
|
||||
INTERFACE_LINK_OPTIONS "-load-plugin-library;${SWIFT_TESTING_MACROS}"
|
||||
)
|
||||
set(SwiftTesting_FOUND TRUE)
|
||||
endif()
|
||||
cmake_policy(POP)
|
||||
endif()
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
# This source file is part of the Swift open source project
|
||||
#
|
||||
# Copyright (c) 2023 Apple Inc. and the Swift project authors.
|
||||
# Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
#
|
||||
# See https://swift.org/LICENSE.txt for license information
|
||||
|
||||
|
||||
# Generate the bridging header from Swift to C++
|
||||
#
|
||||
# target: the name of the target to generate headers for.
|
||||
# This target must build swift source files.
|
||||
# header: the name of the header file to generate.
|
||||
#
|
||||
# NOTE: This logic will eventually be unstreamed into CMake.
|
||||
function(_swift_generate_cxx_header target header)
|
||||
if(NOT TARGET ${target})
|
||||
message(FATAL_ERROR "Target ${target} not defined.")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_Swift_COMPILER)
|
||||
message(WARNING "Swift not enabled in project. Cannot generate headers for Swift files.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
cmake_parse_arguments(PARSE_ARGV 2 "ARG" "" "MODULE_NAME;CXX_STD_VERSION" "SEARCH_PATHS;COMPILE_OPTIONS")
|
||||
|
||||
if(NOT ARG_MODULE_NAME)
|
||||
set(target_module_name $<TARGET_PROPERTY:${target},Swift_MODULE_NAME>)
|
||||
set(ARG_MODULE_NAME $<IF:$<BOOL:${target_module_name}>,${target_module_name},${target}>)
|
||||
endif()
|
||||
|
||||
if(ARG_SEARCH_PATHS)
|
||||
list(TRANSFORM ARG_SEARCH_PATHS PREPEND "-I")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(SDK_FLAGS "-sdk" "${CMAKE_OSX_SYSROOT}")
|
||||
list(APPEND SDK_FLAGS "-target" "${CMAKE_Swift_COMPILER_TARGET}")
|
||||
elseif(WIN32)
|
||||
set(SDK_FLAGS "-sdk" "$ENV{SDKROOT}")
|
||||
elseif(DEFINED ${CMAKE_SYSROOT})
|
||||
set(SDK_FLAGS "-sdk" "${CMAKE_SYSROOT}")
|
||||
list(APPEND SDK_FLAGS "-target" "${CMAKE_Swift_COMPILER_TARGET}")
|
||||
endif()
|
||||
|
||||
cmake_path(APPEND CMAKE_CURRENT_BINARY_DIR include
|
||||
OUTPUT_VARIABLE base_path)
|
||||
|
||||
cmake_path(APPEND base_path ${header}
|
||||
OUTPUT_VARIABLE header_path)
|
||||
|
||||
if (NOT ARG_CXX_STD_VERSION)
|
||||
set(ARG_CXX_STD_VERSION "14")
|
||||
get_target_property(CxxFeatures ${target} COMPILE_FEATURES)
|
||||
list(FILTER CxxFeatures INCLUDE REGEX "cxx_std_[0-9]+$")
|
||||
if (NOT "${CxxFeatures}" STREQUAL "")
|
||||
string(SUBSTRING ${CxxFeatures} 8 2 ARG_CXX_STD_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CXX_STD_FLAGS -Xcc -std=c++${ARG_CXX_STD_VERSION})
|
||||
|
||||
set(_AllSources $<TARGET_PROPERTY:${target},SOURCES>)
|
||||
set(_SwiftSources $<FILTER:${_AllSources},INCLUDE,\\.swift$>)
|
||||
add_custom_command(OUTPUT ${header_path}
|
||||
DEPENDS ${_SwiftSources}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMAND
|
||||
${CMAKE_Swift_COMPILER} -frontend -typecheck
|
||||
${ARG_SEARCH_PATHS}
|
||||
${_SwiftSources}
|
||||
${SDK_FLAGS}
|
||||
${CXX_STD_FLAGS}
|
||||
${ARG_COMPILE_OPTIONS}
|
||||
-Xcc -Wno-unqualified-std-cast-call
|
||||
-Xcc -Wno-user-defined-literals
|
||||
-Xcc -Wno-unknown-warning-option
|
||||
-Xcc -Wno-invalid-offsetof
|
||||
-module-name "${ARG_MODULE_NAME}"
|
||||
-cxx-interoperability-mode=default
|
||||
-emit-clang-header-path ${header_path}
|
||||
COMMENT
|
||||
"Generating '${header_path}'"
|
||||
COMMAND_EXPAND_LISTS)
|
||||
|
||||
# Added to public interface for dependees to find.
|
||||
target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${base_path}>)
|
||||
# Added to the target to ensure target rebuilds if header changes and is used
|
||||
# by sources in the target.
|
||||
target_sources(${target} PRIVATE ${header_path})
|
||||
endfunction()
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
# This source file is part of the Swift open source project
|
||||
#
|
||||
# Copyright (c) 2023 Apple Inc. and the Swift project authors.
|
||||
# Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
#
|
||||
# See https://swift.org/LICENSE.txt for license information
|
||||
|
||||
# Compute the name of the architecture directory on Windows from the CMake
|
||||
# system processor name.
|
||||
function(_swift_windows_arch_name output_variable_name target_arch)
|
||||
if(NOT WIN32)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if("${target_arch}" STREQUAL "AMD64")
|
||||
set("${output_variable_name}" "x86_64" PARENT_SCOPE)
|
||||
elseif("${target_arch}" STREQUAL "ARM64")
|
||||
set("${output_variable_name}" "aarch64" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown windows architecture: ${target_arch}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Compute flags and search paths
|
||||
# NOTE: This logic will eventually move to CMake
|
||||
function(_setup_swift_paths)
|
||||
# If we haven't set the swift library search paths, do that now
|
||||
if(NOT SWIFT_LIBRARY_SEARCH_PATHS OR NOT SWIFT_INCLUDE_PATHS OR (APPLE AND NOT SWIFT_TARGET_TRIPLE))
|
||||
if(APPLE)
|
||||
set(SDK_FLAGS "-sdk" "${CMAKE_OSX_SYSROOT}")
|
||||
endif()
|
||||
|
||||
# Note: This does not handle cross-compiling correctly.
|
||||
# To handle it correctly, we would need to pass the target triple and
|
||||
# flags to this compiler invocation.
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_Swift_COMPILER} ${SDK_FLAGS} -print-target-info
|
||||
OUTPUT_VARIABLE SWIFT_TARGET_INFO
|
||||
)
|
||||
|
||||
# FIXME: https://gitlab.kitware.com/cmake/cmake/-/issues/26174
|
||||
if (APPLE)
|
||||
if (CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
set(SWIFT_TARGET_TRIPLE "${CMAKE_SYSTEM_PROCESSOR}-apple-macosx${CMAKE_OSX_DEPLOYMENT_TARGET}" CACHE STRING "Swift target triple")
|
||||
else()
|
||||
string(JSON SWIFT_TARGET_TARGET GET ${SWIFT_TARGET_INFO} "target")
|
||||
string(JSON SWIFT_TARGET_TARGET_TRIPLE GET ${SWIFT_TARGET_TARGET} "triple")
|
||||
set(SWIFT_TARGET_TRIPLE ${SWIFT_TARGET_TARGET_TRIPLE} CACHE STRING "Swift target triple")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# extract search paths from swift driver response
|
||||
string(JSON SWIFT_TARGET_PATHS GET ${SWIFT_TARGET_INFO} "paths")
|
||||
|
||||
string(JSON SWIFT_TARGET_LIBRARY_PATHS GET ${SWIFT_TARGET_PATHS} "runtimeLibraryPaths")
|
||||
string(JSON SWIFT_TARGET_LIBRARY_PATHS_LENGTH LENGTH ${SWIFT_TARGET_LIBRARY_PATHS})
|
||||
math(EXPR SWIFT_TARGET_LIBRARY_PATHS_LENGTH "${SWIFT_TARGET_LIBRARY_PATHS_LENGTH} - 1 ")
|
||||
|
||||
string(JSON SWIFT_TARGET_LIBRARY_IMPORT_PATHS GET ${SWIFT_TARGET_PATHS} "runtimeLibraryImportPaths")
|
||||
string(JSON SWIFT_TARGET_LIBRARY_IMPORT_PATHS_LENGTH LENGTH ${SWIFT_TARGET_LIBRARY_IMPORT_PATHS})
|
||||
math(EXPR SWIFT_TARGET_LIBRARY_IMPORT_PATHS_LENGTH "${SWIFT_TARGET_LIBRARY_IMPORT_PATHS_LENGTH} - 1 ")
|
||||
|
||||
string(JSON SWIFT_SDK_IMPORT_PATH ERROR_VARIABLE errno GET ${SWIFT_TARGET_PATHS} "sdkPath")
|
||||
|
||||
foreach(JSON_ARG_IDX RANGE ${SWIFT_TARGET_LIBRARY_PATHS_LENGTH})
|
||||
string(JSON SWIFT_LIB GET ${SWIFT_TARGET_LIBRARY_PATHS} ${JSON_ARG_IDX})
|
||||
list(APPEND SWIFT_SEARCH_PATHS ${SWIFT_LIB})
|
||||
endforeach()
|
||||
|
||||
foreach(JSON_ARG_IDX RANGE ${SWIFT_TARGET_LIBRARY_IMPORT_PATHS_LENGTH})
|
||||
string(JSON SWIFT_LIB GET ${SWIFT_TARGET_LIBRARY_IMPORT_PATHS} ${JSON_ARG_IDX})
|
||||
list(APPEND SWIFT_SEARCH_PATHS ${SWIFT_LIB})
|
||||
endforeach()
|
||||
|
||||
if(SWIFT_SDK_IMPORT_PATH)
|
||||
list(APPEND SWIFT_SEARCH_PATHS ${SWIFT_SDK_IMPORT_PATH})
|
||||
endif()
|
||||
|
||||
# Save the swift library search paths
|
||||
set(SWIFT_LIBRARY_SEARCH_PATHS ${SWIFT_SEARCH_PATHS} CACHE FILEPATH "Swift driver search paths")
|
||||
|
||||
string(JSON SWIFT_RUNTIME_RESOURCE_PATH GET ${SWIFT_TARGET_PATHS} "runtimeResourcePath")
|
||||
set(SWIFT_TOOLCHAIN_INCLUDE_DIR "${SWIFT_RUNTIME_RESOURCE_PATH}/../../include")
|
||||
cmake_path(ABSOLUTE_PATH SWIFT_TOOLCHAIN_INCLUDE_DIR NORMALIZE)
|
||||
if (NOT IS_DIRECTORY "${SWIFT_TOOLCHAIN_INCLUDE_DIR}")
|
||||
message(WARNING "Expected toolchain include dir ${SWIFT_TOOLCHAIN_INCLUDE_DIR} does not exist")
|
||||
endif()
|
||||
set(SWIFT_INCLUDE_PATHS ${SWIFT_TOOLCHAIN_INCLUDE_DIR} CACHE FILEPATH "Swift interop include paths")
|
||||
endif()
|
||||
|
||||
link_directories(${SWIFT_LIBRARY_SEARCH_PATHS})
|
||||
include_directories(${SWIFT_INCLUDE_PATHS})
|
||||
|
||||
if(WIN32)
|
||||
_swift_windows_arch_name(SWIFT_WIN_ARCH_DIR "${CMAKE_SYSTEM_PROCESSOR}")
|
||||
set(SWIFT_SWIFTRT_FILE "$ENV{SDKROOT}/usr/lib/swift/windows/${SWIFT_WIN_ARCH_DIR}/swiftrt.obj")
|
||||
add_link_options("$<$<LINK_LANGUAGE:Swift>:${SWIFT_SWIFTRT_FILE}>")
|
||||
elseif(NOT APPLE)
|
||||
find_file(SWIFT_SWIFTRT_FILE
|
||||
swiftrt.o
|
||||
PATHS ${SWIFT_LIBRARY_SEARCH_PATHS}
|
||||
NO_CACHE
|
||||
REQUIRED
|
||||
NO_DEFAULT_PATH)
|
||||
add_link_options("$<$<LINK_LANGUAGE:Swift>:${SWIFT_SWIFTRT_FILE}>")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
_setup_swift_paths()
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
enable_language(Swift)
|
||||
|
||||
if (CMAKE_Swift_COMPILER_VERSION VERSION_LESS 6.0)
|
||||
message(FATAL_ERROR "Swift 6.0 or newer is required to parse C++ headers in C++23 mode")
|
||||
endif()
|
||||
|
||||
# Check for a Swift-aware clang
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles([=[
|
||||
struct __attribute__((swift_name("CxxS"))) __attribute__((swift_attr("~Copyable"))) S { int& x; };
|
||||
int main() {}
|
||||
]=] CXX_COMPILER_SUPPORTS_SWIFT_ATTRS)
|
||||
if (NOT CXX_COMPILER_SUPPORTS_SWIFT_ATTRS)
|
||||
message(FATAL_ERROR "A Swift-aware C++ compiler is required to build with Swift interop enabled")
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/InitializeSwift.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/GenerateSwiftHeader.cmake)
|
||||
|
||||
find_package(SwiftTesting REQUIRED)
|
||||
|
||||
# FIXME: https://gitlab.kitware.com/cmake/cmake/-/issues/26174
|
||||
if (APPLE)
|
||||
set(CMAKE_Swift_COMPILER_TARGET "${SWIFT_TARGET_TRIPLE}")
|
||||
endif()
|
||||
|
||||
add_compile_options("SHELL:$<$<COMPILE_LANGUAGE:Swift>:-enable-experimental-feature Extern>")
|
||||
|
||||
set(VFS_OVERLAY_DIRECTORY "${CMAKE_BINARY_DIR}/vfs_overlays" CACHE PATH "Directory to put VFS overlays in")
|
||||
|
||||
# FIXME: https://gitlab.kitware.com/cmake/cmake/-/issues/26195
|
||||
# For now, we'll just manually massage the flags.
|
||||
function(swizzle_target_properties_for_swift target_name)
|
||||
get_property(compile_options TARGET ${target_name} PROPERTY INTERFACE_COMPILE_OPTIONS)
|
||||
set(munged_properties "")
|
||||
foreach(property IN LISTS compile_options)
|
||||
set(cxx_property "$<$<COMPILE_LANGUAGE:C,CXX,ASM>:${property}>")
|
||||
set(swift_property "SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc ${property}>")
|
||||
list(APPEND munged_properties "${cxx_property}" "${swift_property}")
|
||||
endforeach()
|
||||
set_property(TARGET ${target_name} PROPERTY INTERFACE_COMPILE_OPTIONS ${munged_properties})
|
||||
endfunction()
|
||||
|
||||
function(add_swift_target_properties target_name)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 SWIFT_TARGET "" "" "LAGOM_LIBRARIES;COMPILE_DEFINITIONS;COMPILE_OPTIONS")
|
||||
|
||||
target_compile_features(${target_name} PUBLIC cxx_std_${CMAKE_CXX_STANDARD})
|
||||
target_compile_options(${target_name} PUBLIC "SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc -std=c++23 -cxx-interoperability-mode=default>")
|
||||
|
||||
string(REPLACE "Lib" "" module_name ${target_name})
|
||||
|
||||
string(TOUPPER ${target_name} TARGET_NAME_UPPER)
|
||||
target_compile_definitions(${target_name} PRIVATE "${TARGET_NAME_UPPER}_USE_SWIFT")
|
||||
set_target_properties(${target_name} PROPERTIES Swift_MODULE_NAME ${module_name})
|
||||
|
||||
# FIXME: These should be pulled automatically from interface compile options for the target
|
||||
set(VFS_OVERLAY_OPTIONS "-Xcc" "-ivfsoverlay${VFS_OVERLAY_DIRECTORY}/${target_name}_vfs_overlay.yaml")
|
||||
foreach(internal_library IN LISTS SWIFT_TARGET_LAGOM_LIBRARIES)
|
||||
list(APPEND VFS_OVERLAY_OPTIONS "-Xcc" "-ivfsoverlay${VFS_OVERLAY_DIRECTORY}/${internal_library}_vfs_overlay.yaml")
|
||||
endforeach()
|
||||
|
||||
get_target_property(_NATIVE_DIRS ${target_name} INCLUDE_DIRECTORIES)
|
||||
list(APPEND _NATIVE_DIRS ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
# Swift-testing in swift.org toolchains on macOS has its .swiftmodule in a testing/ subdirectory of
|
||||
# the swift compiler's built-in lib dirs.
|
||||
get_target_property(DEPENDENCIES ${target_name} LINK_LIBRARIES)
|
||||
if (SwiftTesting::SwiftTesting IN_LIST DEPENDENCIES)
|
||||
get_target_property(SWIFT_TESTING_INCLUDE_DIRS SwiftTesting::SwiftTesting INTERFACE_INCLUDE_DIRECTORIES)
|
||||
list(APPEND _NATIVE_DIRS ${SWIFT_TESTING_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
set(EXTRA_COMPILE_DEFINITIONS "")
|
||||
foreach (compile_definition IN LISTS SWIFT_TARGET_COMPILE_DEFINITIONS)
|
||||
list(APPEND EXTRA_COMPILE_DEFINITIONS "-Xcc" "-D${compile_definition}")
|
||||
endforeach()
|
||||
|
||||
_swift_generate_cxx_header(${target_name} "${target_name}-Swift.h"
|
||||
SEARCH_PATHS ${_NATIVE_DIRS}
|
||||
COMPILE_OPTIONS ${VFS_OVERLAY_OPTIONS} ${EXTRA_COMPILE_DEFINITIONS} ${SWIFT_TARGET_COMPILE_OPTIONS}
|
||||
)
|
||||
endfunction()
|
||||
|
|
@ -23,40 +23,6 @@ function(embed_as_string name source_file output source_variable_name)
|
|||
add_dependencies(ladybird_codegen_accumulator "generate_${name}")
|
||||
endfunction()
|
||||
|
||||
function(generate_clang_module_map target_name)
|
||||
cmake_parse_arguments(PARSE_ARGV 1 MODULE_MAP "" "DIRECTORY" "GENERATED_FILES;EXCLUDE_FILES")
|
||||
if (NOT MODULE_MAP_DIRECTORY)
|
||||
set(MODULE_MAP_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
string(REPLACE "Lib" "" module_name ${target_name})
|
||||
set(module_name "${module_name}Cxx")
|
||||
|
||||
set(module_map_file "${CMAKE_CURRENT_BINARY_DIR}/module/module.modulemap")
|
||||
set(vfs_overlay_file "${VFS_OVERLAY_DIRECTORY}/${target_name}_vfs_overlay.yaml")
|
||||
|
||||
find_package(Python3 REQUIRED COMPONENTS Interpreter)
|
||||
# FIXME: Make this depend on the public headers of the target
|
||||
add_custom_command(
|
||||
OUTPUT "${module_map_file}"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${SerenityOS_SOURCE_DIR}/Meta/generate_clang_module_map.py"
|
||||
"${MODULE_MAP_DIRECTORY}"
|
||||
--module-name "${module_name}"
|
||||
--module-map "${module_map_file}"
|
||||
--vfs-map ${vfs_overlay_file}
|
||||
--exclude-files ${MODULE_MAP_EXCLUDE_FILES}
|
||||
--generated-files ${MODULE_MAP_GENERATED_FILES}
|
||||
VERBATIM
|
||||
DEPENDS "${SerenityOS_SOURCE_DIR}/Meta/generate_clang_module_map.py"
|
||||
)
|
||||
|
||||
add_custom_target("generate_${target_name}_module_map" DEPENDS "${module_map_file}")
|
||||
add_dependencies(ladybird_codegen_accumulator "generate_${target_name}_module_map")
|
||||
add_dependencies("${target_name}" "generate_${target_name}_module_map")
|
||||
|
||||
target_compile_options(${target_name} PUBLIC "SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc -ivfsoverlay${vfs_overlay_file}>")
|
||||
endfunction()
|
||||
|
||||
function(compile_ipc source output)
|
||||
if (NOT IS_ABSOLUTE ${source})
|
||||
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${source})
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
include_guard(GLOBAL)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
set(FETCHCONTENT_TRY_FIND_PACKAGE_MODE OPT_IN)
|
||||
FetchContent_Declare(SwiftCollections
|
||||
GIT_REPOSITORY https://github.com/apple/swift-collections.git
|
||||
GIT_TAG 1.1.2
|
||||
PATCH_COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/patches/git-patch.cmake"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/patches/swift-collections/0001-CMake-Remove-top-level-binary-module-locations.patch"
|
||||
OVERRIDE_FIND_PACKAGE
|
||||
)
|
||||
|
||||
set(BUILD_TESTING_SAVE ${BUILD_TESTING})
|
||||
set(BUILD_TESTING OFF)
|
||||
set(BUILD_EXAMPLES OFF)
|
||||
|
||||
# FIXME: https://github.com/apple/swift-collections/issues/440
|
||||
set(BUILD_SHARED_LIBS_SAVE ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
FetchContent_MakeAvailable(SwiftCollections)
|
||||
|
||||
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVE})
|
||||
set(BUILD_TESTING ${BUILD_TESTING_SAVE})
|
||||
|
|
@ -11,7 +11,6 @@ macro(add_cxx_compile_options)
|
|||
set(args "")
|
||||
foreach(arg ${ARGN})
|
||||
string(APPEND args ${arg}$<SEMICOLON>)
|
||||
add_compile_options("SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc ${arg}>")
|
||||
endforeach()
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX,ASM>:${args}>)
|
||||
endmacro()
|
||||
|
|
@ -20,7 +19,6 @@ macro(add_cxx_compile_definitions)
|
|||
set(args "")
|
||||
foreach(arg ${ARGN})
|
||||
string(APPEND args ${arg}$<SEMICOLON>)
|
||||
add_compile_options("SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xcc -D${arg}>")
|
||||
endforeach()
|
||||
add_compile_definitions($<$<COMPILE_LANGUAGE:C,CXX,ASM>:${args}>)
|
||||
endmacro()
|
||||
|
|
@ -33,22 +31,6 @@ macro(add_cxx_link_options)
|
|||
add_link_options($<$<LINK_LANGUAGE:C,CXX>:${args}>)
|
||||
endmacro()
|
||||
|
||||
macro(add_swift_compile_options)
|
||||
set(args "")
|
||||
foreach(arg ${ARGN})
|
||||
string(APPEND args ${arg}$<SEMICOLON>)
|
||||
endforeach()
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:Swift>:${args}>)
|
||||
endmacro()
|
||||
|
||||
macro(add_swift_link_options)
|
||||
set(args "")
|
||||
foreach(arg ${ARGN})
|
||||
string(APPEND args ${arg}$<SEMICOLON>)
|
||||
endforeach()
|
||||
add_link_options($<$<LINK_LANGUAGE:Swift>:${args}>)
|
||||
endmacro()
|
||||
|
||||
include(CheckLinkerFlag)
|
||||
include(CMakePushCheckState)
|
||||
function(add_cxx_link_option_if_supported option)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,6 @@ if (POLICY CMP0116)
|
|||
cmake_policy(SET CMP0116 NEW)
|
||||
endif()
|
||||
|
||||
# Enable better flags for configuring swift compilation mode
|
||||
if (POLICY CMP0157)
|
||||
cmake_policy(SET CMP0157 NEW)
|
||||
set(CMAKE_Swift_COMPILATION_MODE "$<IF:$<CONFIG:Release>,wholemodule,incremental>")
|
||||
endif()
|
||||
|
||||
# Check arguments to return()
|
||||
if (POLICY CMP0140)
|
||||
cmake_policy(SET CMP0140 NEW)
|
||||
|
|
@ -39,7 +33,6 @@ endif()
|
|||
ladybird_option(ENABLE_GUI_TARGETS ON CACHE BOOL "Enable building GUI targets")
|
||||
ladybird_option(ENABLE_INSTALL_HEADERS ON CACHE BOOL "Enable installing headers")
|
||||
ladybird_option(ENABLE_INSTALL_FREEDESKTOP_FILES ${freedesktop_files_default} CACHE BOOL "Enable installing .desktop and .service files")
|
||||
ladybird_option(ENABLE_SWIFT OFF CACHE BOOL "Enable building Swift files")
|
||||
ladybird_option(LADYBIRD_ENABLE_CPPTRACE ON CACHE BOOL "Enable use of cpptrace as the default library for stacktraces. If not available falls back to backtrace.h")
|
||||
ladybird_option(ENABLE_CI_BASELINE_CPU OFF CACHE BOOL "Use a baseline CPU target for improved ccache sharing")
|
||||
|
||||
|
|
@ -48,10 +41,6 @@ if (ENABLE_FUZZERS_LIBFUZZER)
|
|||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY CACHE STRING "Type of target to use for try_compile()" FORCE)
|
||||
endif()
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/Swift/swift-settings.cmake)
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
set(BLOCKS_REQUIRED_LIBRARIES "")
|
||||
if (NOT APPLE)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${IN_BUILD_PREFIX}${CMAK
|
|||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${IN_BUILD_PREFIX}${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${IN_BUILD_PREFIX}${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
# FIXME: Stop setting this when we have a good way to retrieve the directory that has the swift module
|
||||
# file for use by the swift frontend's header generator
|
||||
set(CMAKE_Swift_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/${IN_BUILD_PREFIX}swift")
|
||||
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
|
||||
if ("${VCPKG_INSTALLED_DIR}" STREQUAL "")
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Kaster <andrew@ladybird.org>
|
||||
Date: Thu, 22 Aug 2024 20:51:38 -0600
|
||||
Subject: [PATCH] CMake: Remove top-level binary/module locations
|
||||
|
||||
---
|
||||
CMakeLists.txt | 13 +++++--------
|
||||
Sources/BitCollections/CMakeLists.txt | 2 --
|
||||
Sources/CMakeLists.txt | 2 --
|
||||
Sources/Collections/CMakeLists.txt | 4 ++--
|
||||
Sources/DequeModule/CMakeLists.txt | 2 --
|
||||
Sources/HashTreeCollections/CMakeLists.txt | 2 --
|
||||
Sources/HeapModule/CMakeLists.txt | 2 --
|
||||
Sources/InternalCollectionsUtilities/CMakeLists.txt | 2 --
|
||||
Sources/OrderedCollections/CMakeLists.txt | 2 --
|
||||
Sources/RopeModule/CMakeLists.txt | 2 --
|
||||
10 files changed, 7 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 939a29e48ee386c0dac32350c6f6dfb4c4279170..2692814e02971e1469fc236a89c825a5c1547932 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -11,22 +11,19 @@ if(POLICY CMP0091)
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
endif()
|
||||
|
||||
+if(POLICY CMP0157)
|
||||
+ cmake_policy(SET CMP0157 OLD)
|
||||
+endif()
|
||||
+
|
||||
+
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(SwiftCollections
|
||||
LANGUAGES C Swift)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
|
||||
-set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
|
||||
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
|
||||
|
||||
-set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
|
||||
-set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
|
||||
-
|
||||
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
-
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows OR CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
diff --git a/Sources/BitCollections/CMakeLists.txt b/Sources/BitCollections/CMakeLists.txt
|
||||
index c5becdeec08a91978aa8b00dc2fc272299ca16b0..3f52e47220362de9c47e3e2527a2b78260d6f45e 100644
|
||||
--- a/Sources/BitCollections/CMakeLists.txt
|
||||
+++ b/Sources/BitCollections/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_BIT_SOURCES})
|
||||
target_link_libraries(BitCollections PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(BitCollections PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(BitCollections)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS BitCollections)
|
||||
diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt
|
||||
index ad39dd9be70a3d3fd7f3176e9a607c6fa1413d82..a54e494c81a552282735bd926a05cb3d9527b169 100644
|
||||
--- a/Sources/CMakeLists.txt
|
||||
+++ b/Sources/CMakeLists.txt
|
||||
@@ -24,8 +24,6 @@ if(COLLECTIONS_SINGLE_MODULE)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${COLLECTIONS_MODULE_NAME} PRIVATE COLLECTIONS_SINGLE_MODULE)
|
||||
- set_target_properties(${COLLECTIONS_MODULE_NAME} PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
if(COLLECTIONS_FOUNDATION_TOOLCHAIN_MODULE)
|
||||
get_swift_host_os(swift_os)
|
||||
diff --git a/Sources/Collections/CMakeLists.txt b/Sources/Collections/CMakeLists.txt
|
||||
index 9f534a46c80475e2ef39ba39d386be00d25b7c30..6be24ce21145f14718e90d67247d2ea56c21ffd4 100644
|
||||
--- a/Sources/Collections/CMakeLists.txt
|
||||
+++ b/Sources/Collections/CMakeLists.txt
|
||||
@@ -15,9 +15,9 @@ target_link_libraries(Collections PRIVATE
|
||||
HeapModule
|
||||
OrderedCollections
|
||||
HashTreeCollections
|
||||
+ InternalCollectionsUtilities
|
||||
)
|
||||
-set_target_properties(Collections PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(Collections)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS Collections)
|
||||
+
|
||||
diff --git a/Sources/DequeModule/CMakeLists.txt b/Sources/DequeModule/CMakeLists.txt
|
||||
index 07364b66e32257c098edfbfdd3204206dee56709..da1a79becc36893a90d797bee610b973c3c12853 100644
|
||||
--- a/Sources/DequeModule/CMakeLists.txt
|
||||
+++ b/Sources/DequeModule/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_DEQUE_SOURCES})
|
||||
target_link_libraries(DequeModule PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(DequeModule PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(DequeModule)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS DequeModule)
|
||||
diff --git a/Sources/HashTreeCollections/CMakeLists.txt b/Sources/HashTreeCollections/CMakeLists.txt
|
||||
index 0329fe664fd103348f55ce34dee71da9f437dfd6..56566f36a63c834f0c7d40f787504adede820808 100644
|
||||
--- a/Sources/HashTreeCollections/CMakeLists.txt
|
||||
+++ b/Sources/HashTreeCollections/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_HASHTREE_SOURCES})
|
||||
target_link_libraries(HashTreeCollections PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(HashTreeCollections PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(HashTreeCollections)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS HashTreeCollections)
|
||||
diff --git a/Sources/HeapModule/CMakeLists.txt b/Sources/HeapModule/CMakeLists.txt
|
||||
index a1cc57a63b5bcd140ea207298fbd0c6d48f784de..6bf9edeed5bfdeb9120869dfdbaed21a2376e3c3 100644
|
||||
--- a/Sources/HeapModule/CMakeLists.txt
|
||||
+++ b/Sources/HeapModule/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_HEAP_SOURCES})
|
||||
target_link_libraries(HeapModule PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(HeapModule PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(HeapModule)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS HeapModule)
|
||||
diff --git a/Sources/InternalCollectionsUtilities/CMakeLists.txt b/Sources/InternalCollectionsUtilities/CMakeLists.txt
|
||||
index 808e36c2eb43f26f8009d4982e5cd095c3a3639d..f25f3da067e8d6ce540ba911a3df43d6e3b5b561 100644
|
||||
--- a/Sources/InternalCollectionsUtilities/CMakeLists.txt
|
||||
+++ b/Sources/InternalCollectionsUtilities/CMakeLists.txt
|
||||
@@ -13,8 +13,6 @@ else()
|
||||
set(module_name InternalCollectionsUtilities)
|
||||
add_library(InternalCollectionsUtilities
|
||||
${COLLECTIONS_UTILITIES_SOURCES})
|
||||
- set_target_properties(InternalCollectionsUtilities PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(InternalCollectionsUtilities)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS InternalCollectionsUtilities)
|
||||
diff --git a/Sources/OrderedCollections/CMakeLists.txt b/Sources/OrderedCollections/CMakeLists.txt
|
||||
index 017113861101c5acfb3f77a8feca86f1b9a6fd50..16e63aec3d0e317191b59637ef02aba9b0e76a76 100644
|
||||
--- a/Sources/OrderedCollections/CMakeLists.txt
|
||||
+++ b/Sources/OrderedCollections/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_ORDERED_SOURCES})
|
||||
target_link_libraries(OrderedCollections PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(OrderedCollections PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(OrderedCollections)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS OrderedCollections)
|
||||
diff --git a/Sources/RopeModule/CMakeLists.txt b/Sources/RopeModule/CMakeLists.txt
|
||||
index d33fac9213f939fcfccb1f702039b421814d3dfd..19e08d235a14348dac983cb4bf1972a039ea3fbb 100644
|
||||
--- a/Sources/RopeModule/CMakeLists.txt
|
||||
+++ b/Sources/RopeModule/CMakeLists.txt
|
||||
@@ -15,8 +15,6 @@ else()
|
||||
${COLLECTIONS_ROPE_SOURCES})
|
||||
target_link_libraries(_RopeModule PRIVATE
|
||||
InternalCollectionsUtilities)
|
||||
- set_target_properties(_RopeModule PROPERTIES
|
||||
- INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
|
||||
|
||||
_install_target(_RopeModule)
|
||||
set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS _RopeModule)
|
||||
|
|
@ -96,25 +96,6 @@
|
|||
"ENABLE_FUZZERS_LIBFUZZER": "ON",
|
||||
"ENABLE_ADDRESS_SANITIZER": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"hidden": true,
|
||||
"name": "Swift_Release_base",
|
||||
"displayName": "Swift Release Config",
|
||||
"description": "Swift-enabled release build",
|
||||
"binaryDir": "$env{LADYBIRD_SOURCE_DIR}/Build/swift",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||
"VCPKG_OVERLAY_TRIPLETS": "$env{LADYBIRD_SOURCE_DIR}/Meta/CMake/vcpkg/release-triplets",
|
||||
"ENABLE_SWIFT": "ON",
|
||||
"CMAKE_C_COMPILER": "MustBeSetManually",
|
||||
"CMAKE_CXX_COMPILER": "MustBeSetManually++"
|
||||
},
|
||||
"vendor": {
|
||||
"jetbrains.com/clion": {
|
||||
"toolchain": "Swift"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
|
|
|
|||
|
|
@ -55,13 +55,6 @@
|
|||
"unix_base",
|
||||
"All_Debug_base"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Swift_Release",
|
||||
"inherits": [
|
||||
"unix_base",
|
||||
"Swift_Release_base"
|
||||
]
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
|
|
@ -71,13 +64,6 @@
|
|||
"configurePreset": "Distribution",
|
||||
"displayName": "Distribution Build",
|
||||
"description": "Build the project for distribution"
|
||||
},
|
||||
{
|
||||
"name": "Swift_Release",
|
||||
"inherits": "base",
|
||||
"configurePreset": "Swift_Release",
|
||||
"displayName": "Swift Release Build",
|
||||
"description": "Build the project for Swift release on Unix"
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
|
|
@ -85,11 +71,6 @@
|
|||
"name": "Distribution",
|
||||
"inherits": "base",
|
||||
"configurePreset": "Distribution"
|
||||
},
|
||||
{
|
||||
"name": "Swift_Release",
|
||||
"inherits": "base",
|
||||
"configurePreset": "Swift_Release"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ if (ENABLE_ADDRESS_SANITIZER)
|
|||
else()
|
||||
add_cxx_compile_options(-fsanitize=address -fno-omit-frame-pointer)
|
||||
add_cxx_link_options(-fsanitize=address)
|
||||
add_swift_compile_options(-sanitize=address)
|
||||
add_swift_link_options(-sanitize=address)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
@ -31,7 +29,7 @@ if (ENABLE_UNDEFINED_SANITIZER)
|
|||
add_cxx_compile_options(-fsanitize=undefined)
|
||||
# FIXME: Windows on ARM
|
||||
link_libraries(clang_rt.ubsan_standalone-x86_64.lib clang_rt.ubsan_standalone_cxx-x86_64.lib)
|
||||
elseif (APPLE OR NOT ENABLE_SWIFT)
|
||||
else()
|
||||
add_cxx_compile_options(-fsanitize=undefined -fno-omit-frame-pointer)
|
||||
if (UNDEFINED_BEHAVIOR_IS_FATAL)
|
||||
add_cxx_compile_options(-fno-sanitize-recover=undefined)
|
||||
|
|
@ -40,7 +38,5 @@ if (ENABLE_UNDEFINED_SANITIZER)
|
|||
add_cxx_compile_options(-fno-sanitize=function)
|
||||
endif()
|
||||
add_cxx_link_options(-fsanitize=undefined)
|
||||
add_swift_compile_options(-sanitize=undefined)
|
||||
add_swift_link_options(-sanitize=undefined)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -40,5 +40,4 @@ else()
|
|||
set(SKIA_TARGET PkgConfig::skia)
|
||||
set_property(TARGET PkgConfig::skia APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SKCMS_DLL")
|
||||
endif()
|
||||
swizzle_target_properties_for_swift(${SKIA_TARGET})
|
||||
add_library(skia ALIAS ${SKIA_TARGET})
|
||||
|
|
|
|||
|
|
@ -203,8 +203,3 @@ function(add_lagom_library_install_rules target_name)
|
|||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
if (NOT COMMAND swizzle_target_properties_for_swift)
|
||||
function(swizzle_target_properties_for_swift target)
|
||||
endfunction()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -757,9 +757,6 @@ static std::optional<CellTypeWithOrigin> find_cell_type_with_origin(clang::CXXRe
|
|||
if (base_name == "GC::Cell")
|
||||
return CellTypeWithOrigin { *base_record, LibJSCellMacro::Type::GCCell };
|
||||
|
||||
if (base_name == "GC::ForeignCell")
|
||||
return CellTypeWithOrigin { *base_record, LibJSCellMacro::Type::ForeignCell };
|
||||
|
||||
if (base_name == "JS::Object")
|
||||
return CellTypeWithOrigin { *base_record, LibJSCellMacro::Type::JSObject };
|
||||
|
||||
|
|
@ -782,9 +779,6 @@ static std::optional<CellTypeWithOrigin> find_cell_type_with_origin(clang::CXXRe
|
|||
|
||||
LibJSGCVisitor::CellMacroExpectation LibJSGCVisitor::get_record_cell_macro_expectation(clang::CXXRecordDecl const& record)
|
||||
{
|
||||
if (record.getQualifiedNameAsString() == "GC::ForeignCell")
|
||||
return { LibJSCellMacro::Type::ForeignCell, "Cell" };
|
||||
|
||||
auto origin = find_cell_type_with_origin(record);
|
||||
assert(origin.has_value());
|
||||
|
||||
|
|
@ -921,8 +915,6 @@ char const* LibJSCellMacro::type_name(Type type)
|
|||
switch (type) {
|
||||
case Type::GCCell:
|
||||
return "GC_CELL";
|
||||
case Type::ForeignCell:
|
||||
return "FOREIGN_CELL";
|
||||
case Type::JSObject:
|
||||
return "JS_OBJECT";
|
||||
case Type::JSEnvironment:
|
||||
|
|
@ -951,7 +943,6 @@ void LibJSPPCallbacks::MacroExpands(clang::Token const& name_token, clang::Macro
|
|||
if (auto* ident_info = name_token.getIdentifierInfo()) {
|
||||
static llvm::StringMap<LibJSCellMacro::Type> libjs_macro_types {
|
||||
{ "GC_CELL", LibJSCellMacro::Type::GCCell },
|
||||
{ "FOREIGN_CELL", LibJSCellMacro::Type::ForeignCell },
|
||||
{ "JS_OBJECT", LibJSCellMacro::Type::JSObject },
|
||||
{ "JS_ENVIRONMENT", LibJSCellMacro::Type::JSEnvironment },
|
||||
{ "JS_PROTOTYPE_OBJECT", LibJSCellMacro::Type::JSPrototypeObject },
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
struct LibJSCellMacro {
|
||||
enum class Type {
|
||||
GCCell,
|
||||
ForeignCell,
|
||||
JSObject,
|
||||
JSEnvironment,
|
||||
JSPrototypeObject,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import re
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
RE_RELEVANT_FILE_EXTENSION = re.compile("\\.(cpp|h|mm|swift|gml|html|js|css|sh|py|json|txt|cmake|gn|gni)$")
|
||||
RE_RELEVANT_FILE_EXTENSION = re.compile("\\.(cpp|h|mm|gml|html|js|css|sh|py|json|txt|cmake|gn|gni)$")
|
||||
|
||||
|
||||
def should_check_file(filename):
|
||||
|
|
|
|||
|
|
@ -165,34 +165,6 @@ def pick_host_compiler(platform: Platform, cc: str, cxx: str) -> tuple[str, str]
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
def pick_swift_compilers(platform: Platform, project_root: Path) -> tuple[Path, Path, Path]:
|
||||
if platform.host_system == HostSystem.Windows:
|
||||
print("Swift builds are not supported on Windows", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if not shutil.which("swiftly"):
|
||||
print("swiftly is required to manage Swift toolchains", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
swiftly_toolchain_path = run_command(["swiftly", "use", "--print-location"], return_output=True, cwd=project_root)
|
||||
if not swiftly_toolchain_path:
|
||||
run_command(["swiftly", "install"], exit_on_failure=True, cwd=project_root)
|
||||
|
||||
swiftly_toolchain_path = run_command(
|
||||
["swiftly", "use", "--print-location"], return_output=True, exit_on_failure=True, cwd=project_root
|
||||
)
|
||||
assert swiftly_toolchain_path
|
||||
|
||||
swiftly_toolchain_path = Path(swiftly_toolchain_path.strip())
|
||||
swiftly_bin_dir = swiftly_toolchain_path.joinpath("usr", "bin")
|
||||
|
||||
if not swiftly_toolchain_path.exists() or not swiftly_bin_dir.exists():
|
||||
print(f"swiftly toolchain path {swiftly_toolchain_path} does not exist", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return swiftly_bin_dir / "clang", swiftly_bin_dir / "clang++", swiftly_bin_dir / "swiftc"
|
||||
|
||||
|
||||
def main():
|
||||
platform = Platform()
|
||||
(default_cc, default_cxx) = platform.default_compiler()
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generates a clang module map for a given directory
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def write_file_if_not_same(file_path, content):
|
||||
try:
|
||||
with open(file_path, "r") as f:
|
||||
if f.read() == content:
|
||||
return
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
with open(file_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(epilog=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
parser.add_argument("directory", help="source directory to generate module map for")
|
||||
parser.add_argument("--module-name", help="top-level module name")
|
||||
parser.add_argument("--module-map", required=True, help="output module map file")
|
||||
parser.add_argument("--vfs-map", required=True, help="output VFS map file")
|
||||
parser.add_argument("--exclude-files", nargs="*", required=False, help="files to exclude in the module map")
|
||||
parser.add_argument("--generated-files", nargs="*", help="extra files to include in the module map")
|
||||
args = parser.parse_args()
|
||||
|
||||
root = pathlib.Path(args.directory)
|
||||
if not root.is_dir():
|
||||
print(f"Error: {args.directory} is not a directory", file=sys.stderr)
|
||||
return 1
|
||||
pathlib.Path(args.module_map).parent.mkdir(parents=True, exist_ok=True)
|
||||
pathlib.Path(args.vfs_map).parent.mkdir(parents=True, exist_ok=True)
|
||||
exclude_files = set(args.exclude_files) if args.exclude_files else set()
|
||||
|
||||
header_files = [f for f in root.rglob("**/*.h") if f.is_file() and f.name not in exclude_files]
|
||||
module_name = args.module_name if args.module_name else root.name
|
||||
|
||||
module_map = f"module {module_name} {{\n"
|
||||
for header_file in header_files:
|
||||
module_map += f' header "{header_file.relative_to(root)}"\n'
|
||||
for generated_file in args.generated_files:
|
||||
module_map += f' header "{generated_file}"\n'
|
||||
module_map += " requires cplusplus\n"
|
||||
module_map += " export *\n"
|
||||
module_map += "}\n"
|
||||
|
||||
vfs_map = {
|
||||
"version": 0,
|
||||
"use-external-names": False,
|
||||
"roots": [
|
||||
{
|
||||
"name": f"{root}/module.modulemap",
|
||||
"type": "file",
|
||||
"external-contents": f"{args.module_map}",
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
write_file_if_not_same(args.module_map, module_map)
|
||||
write_file_if_not_same(args.vfs_map, yaml.dump(vfs_map))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -177,7 +177,6 @@ shared_library("AK") {
|
|||
"StringUtils.h",
|
||||
"StringView.cpp",
|
||||
"StringView.h",
|
||||
"Swift.h",
|
||||
"TemporaryChange.h",
|
||||
"Time.cpp",
|
||||
"Time.h",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ source_set("Parser") {
|
|||
"HTMLParser.cpp",
|
||||
"HTMLToken.cpp",
|
||||
"HTMLTokenizer.cpp",
|
||||
"HTMLTokenizerHelpers.cpp",
|
||||
"ListOfActiveFormattingElements.cpp",
|
||||
"StackOfOpenElements.cpp",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ from typing import Optional
|
|||
sys.path.append(str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from Meta.find_compiler import pick_host_compiler
|
||||
from Meta.find_compiler import pick_swift_compilers
|
||||
from Meta.host_platform import HostArchitecture
|
||||
from Meta.host_platform import HostSystem
|
||||
from Meta.host_platform import Platform
|
||||
|
|
@ -194,14 +193,9 @@ def configure_main(platform: Platform, preset: str, cc: str, cxx: str) -> Path:
|
|||
if build_preset_dir.joinpath("build.ninja").exists() or build_preset_dir.joinpath("ladybird.sln").exists():
|
||||
return build_preset_dir
|
||||
|
||||
swiftc: Optional[str] = None
|
||||
validate_cmake_version()
|
||||
|
||||
if "Swift" in preset:
|
||||
compilers = pick_swift_compilers(platform, ladybird_source_dir)
|
||||
(cc, cxx, swiftc) = tuple(map(str, compilers))
|
||||
else:
|
||||
(cc, cxx) = pick_host_compiler(platform, cc, cxx)
|
||||
(cc, cxx) = pick_host_compiler(platform, cc, cxx)
|
||||
|
||||
config_args = [
|
||||
"cmake",
|
||||
|
|
@ -215,9 +209,6 @@ def configure_main(platform: Platform, preset: str, cc: str, cxx: str) -> Path:
|
|||
f"-DCMAKE_CXX_COMPILER={cxx}",
|
||||
]
|
||||
|
||||
if swiftc:
|
||||
config_args.append(f"-DCMAKE_Swift_COMPILER={swiftc}")
|
||||
|
||||
if platform.host_system == HostSystem.Linux and platform.host_architecture == HostArchitecture.AArch64:
|
||||
config_args.extend(configure_skia_jemalloc())
|
||||
|
||||
|
|
@ -273,7 +264,6 @@ def configure_build_env(platform: Platform, preset: str) -> tuple[Path, Path]:
|
|||
"Distribution": build_root_dir / "distribution",
|
||||
"Release": build_root_dir / "release",
|
||||
"Sanitizer": build_root_dir / "sanitizers",
|
||||
"Swift_Release": build_root_dir / "swift",
|
||||
}
|
||||
|
||||
build_preset_dir = known_presets.get(preset, None)
|
||||
|
|
|
|||
|
|
@ -52,11 +52,4 @@ else
|
|||
((FAILURES+=1))
|
||||
fi
|
||||
|
||||
if Meta/lint-swift.sh "$@" && git diff --exit-code -- ':*.swift'; then
|
||||
echo -e "[${GREEN}OK${NC}]: Meta/lint-swift.sh"
|
||||
else
|
||||
echo -e "[${BOLD_RED}FAIL${NC}]: Meta/lint-swift.sh"
|
||||
((FAILURES+=1))
|
||||
fi
|
||||
|
||||
exit "${FAILURES}"
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
script_path=$(cd -P -- "$(dirname -- "$0")" && pwd -P)
|
||||
cd "${script_path}/.." || exit 1
|
||||
|
||||
if [ "$#" -eq "0" ]; then
|
||||
files=()
|
||||
while IFS= read -r file; do
|
||||
files+=("$file")
|
||||
done < <(
|
||||
git ls-files '*.swift'
|
||||
)
|
||||
else
|
||||
files=()
|
||||
for file in "$@"; do
|
||||
if [[ "${file}" == *".swift" ]] ; then
|
||||
files+=("${file}")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if (( ${#files[@]} )); then
|
||||
if ! command -v swift-format >/dev/null 2>&1 ; then
|
||||
echo "swift-format is not available, but Swift files need linting! Either skip this script, or install swift-format."
|
||||
exit 1
|
||||
fi
|
||||
swift-format -i "${files[@]}"
|
||||
echo "Maybe some files have changed. Sorry, but swift-format doesn't indicate what happened."
|
||||
else
|
||||
echo "No .swift files to check."
|
||||
fi
|
||||
|
|
@ -114,12 +114,3 @@ endif()
|
|||
|
||||
target_link_libraries(TestString PRIVATE LibUnicode)
|
||||
target_link_libraries(TestUtf16String PRIVATE LibUnicode)
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
|
||||
# FIXME: Convert to use swift-testing after resolving https://github.com/LadybirdBrowser/ladybird/issues/1201
|
||||
add_executable(TestAKBindings TestAKBindings.swift)
|
||||
target_link_libraries(TestAKBindings PRIVATE AK)
|
||||
target_compile_options(TestAKBindings PRIVATE -parse-as-library)
|
||||
add_test(NAME TestAKBindings COMMAND TestAKBindings)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
import Foundation
|
||||
|
||||
protocol ConformanceMarker {}
|
||||
enum CxxSequenceMarker<T: ~Copyable> {}
|
||||
extension CxxSequenceMarker: ConformanceMarker where T: CxxSequence {}
|
||||
private func isCxxSequenceType<T: ~Copyable>(_ type: borrowing T.Type) -> Bool {
|
||||
return CxxSequenceMarker<T>.self is ConformanceMarker.Type
|
||||
}
|
||||
|
||||
class StandardError: TextOutputStream {
|
||||
func write(_ string: Swift.String) {
|
||||
try! FileHandle.standardError.write(contentsOf: Data(string.utf8))
|
||||
}
|
||||
}
|
||||
|
||||
@main
|
||||
struct TestAKBindings {
|
||||
static func testSequenceTypesAreBound() {
|
||||
var standardError = StandardError()
|
||||
print("Testing CxxSequence types...", to: &standardError)
|
||||
|
||||
//precondition(isCxxSequenceType(AK.StringView.self))
|
||||
precondition(isCxxSequenceType(AK.Bytes.self))
|
||||
precondition(isCxxSequenceType(AK.ReadonlyBytes.self))
|
||||
precondition(!isCxxSequenceType(AK.Utf16View.self))
|
||||
|
||||
// FIXME: Not bound for some reason
|
||||
//precondition(isCxxSequenceType(AK.Utf16String.self))
|
||||
precondition(!isCxxSequenceType(AK.String.self))
|
||||
|
||||
precondition(!isCxxSequenceType(AK.Error.self))
|
||||
|
||||
print("CxxSequence types pass", to: &standardError)
|
||||
}
|
||||
|
||||
static func main() {
|
||||
var standardError = StandardError()
|
||||
print("Starting test suite...", to: &standardError)
|
||||
testSequenceTypesAreBound()
|
||||
|
||||
print("All tests pass", to: &standardError)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ add_subdirectory(LibCrypto)
|
|||
add_subdirectory(LibDatabase)
|
||||
add_subdirectory(LibDiff)
|
||||
add_subdirectory(LibDNS)
|
||||
add_subdirectory(LibGC)
|
||||
add_subdirectory(LibHTTP)
|
||||
add_subdirectory(LibJS)
|
||||
add_subdirectory(LibRegex)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
// RUN: %clang++ -Xclang -verify %plugin_opts% -c %s -o %t 2>&1
|
||||
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibJS/Runtime/PrototypeObject.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
|
||||
|
|
@ -14,10 +13,6 @@
|
|||
class TestCellClass : JS::Cell {
|
||||
};
|
||||
|
||||
// expected-error@+1 {{Expected record to have a FOREIGN_CELL macro invocation}}
|
||||
class TestForeignCellClass : GC::ForeignCell {
|
||||
};
|
||||
|
||||
// expected-error@+1 {{Expected record to have a JS_OBJECT macro invocation}}
|
||||
class TestObjectClass : JS::Object {
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
// RUN: %clang++ -Xclang -verify %plugin_opts% -c %s -o %t 2>&1
|
||||
// expected-no-diagnostics
|
||||
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibJS/Runtime/PrototypeObject.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
|
||||
|
|
@ -15,10 +14,6 @@ class TestCellClass : JS::Cell {
|
|||
GC_CELL(TestCellClass, JS::Cell);
|
||||
};
|
||||
|
||||
class TestForeignCellClass : GC::ForeignCell {
|
||||
FOREIGN_CELL(TestForeignCellClass, GC::ForeignCell);
|
||||
};
|
||||
|
||||
class TestObjectClass : JS::Object {
|
||||
JS_OBJECT(TestObjectClass, JS::Object);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
// RUN: %clang++ -Xclang -verify %plugin_opts% -c %s -o %t 2>&1
|
||||
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/PrototypeObject.h>
|
||||
|
||||
|
|
@ -35,16 +34,6 @@ class ObjectWithEnvironmentMacro : JS::Object {
|
|||
JS_ENVIRONMENT(ObjectWithEnvironmentMacro, JS::Object);
|
||||
};
|
||||
|
||||
class CellWithForeignCellMacro : GC::Cell {
|
||||
// expected-error@+1 {{Invalid GC-CELL-like macro invocation; expected GC_CELL}}
|
||||
FOREIGN_CELL(CellWithForeignCellMacro, GC::Cell);
|
||||
};
|
||||
|
||||
class ObjectWithForeignCellMacro : JS::Object {
|
||||
// expected-error@+1 {{Invalid GC-CELL-like macro invocation; expected JS_OBJECT}}
|
||||
FOREIGN_CELL(ObjectWithForeignCellMacro, JS::Object);
|
||||
};
|
||||
|
||||
// JS_PROTOTYPE_OBJECT can only be used in the JS namespace
|
||||
namespace JS {
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
// RUN: %clang++ -Xclang -verify %plugin_opts% -c %s -o %t 2>&1
|
||||
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibJS/Runtime/PrototypeObject.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
|
||||
|
|
@ -17,11 +16,6 @@ class TestCellClass : JS::Cell {
|
|||
GC_CELL(bad, JS::Cell);
|
||||
};
|
||||
|
||||
class TestForeignCellClass : GC::ForeignCell {
|
||||
// expected-error@+1 {{Expected first argument of FOREIGN_CELL macro invocation to be TestForeignCellClass}}
|
||||
FOREIGN_CELL(bad, GC::ForeignCell);
|
||||
};
|
||||
|
||||
class TestObjectClass : JS::Object {
|
||||
// expected-error@+1 {{Expected first argument of JS_OBJECT macro invocation to be TestObjectClass}}
|
||||
JS_OBJECT(bad, JS::Object);
|
||||
|
|
|
|||
|
|
@ -29,20 +29,3 @@ if(NOT WIN32)
|
|||
endif()
|
||||
|
||||
target_link_libraries(TestLibCoreSharedSingleProducerCircularQueue PRIVATE LibThreading)
|
||||
|
||||
if(ENABLE_SWIFT)
|
||||
find_package(SwiftTesting REQUIRED)
|
||||
|
||||
add_executable(TestCoreSwift
|
||||
TestEventLoopActor.swift
|
||||
TestEventLoop.cpp
|
||||
)
|
||||
|
||||
# FIXME: Swift doesn't seem to like object libraries for @main
|
||||
target_sources(TestCoreSwift PRIVATE ../Resources/SwiftTestMain.swift)
|
||||
|
||||
set_target_properties(TestCoreSwift PROPERTIES SUFFIX .swift-testing)
|
||||
target_include_directories(TestCoreSwift PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(TestCoreSwift PRIVATE AK LibCore SwiftTesting::SwiftTesting)
|
||||
add_test(NAME TestCoreSwift COMMAND TestCoreSwift)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
import Core
|
||||
import CoreTesting
|
||||
import Testing
|
||||
|
||||
actor TestEventLoopActor: EventLoopActor {
|
||||
nonisolated public let executor: EventLoopExecutor
|
||||
|
||||
init() {
|
||||
install_thread_local_event_loop()
|
||||
executor = EventLoopExecutor()
|
||||
}
|
||||
|
||||
nonisolated func submit(action: @escaping @Sendable () async -> Void) {
|
||||
Task(executorPreference: self.executor) {
|
||||
await action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suite
|
||||
struct TestEventLoop {
|
||||
@Test
|
||||
func testEventLoopActor() async {
|
||||
// Creates an executor around EventLoop::current()
|
||||
let actor = TestEventLoopActor()
|
||||
|
||||
let ev = Core.EventLoop.current()
|
||||
print("Event loop at \(Unmanaged.passUnretained(ev).toOpaque())")
|
||||
|
||||
let (stream, continuation) = AsyncStream<Int>.makeStream()
|
||||
var iterator = stream.makeAsyncIterator()
|
||||
|
||||
actor.submit {
|
||||
#expect(ev == Core.EventLoop.current(), "Closure is executed on event loop")
|
||||
print("Hello from event loop at \(Unmanaged.passUnretained(Core.EventLoop.current()).toOpaque())")
|
||||
|
||||
continuation.yield(42)
|
||||
}
|
||||
|
||||
actor.submit {
|
||||
#expect(ev == Core.EventLoop.current(), "Closure is executed on event loop")
|
||||
Core.EventLoop.current().quit(4)
|
||||
|
||||
continuation.yield(1234)
|
||||
continuation.finish()
|
||||
}
|
||||
|
||||
let rc = ev.exec()
|
||||
#expect(rc == 4)
|
||||
// Values not available until event loop has processed tasks
|
||||
#expect(await iterator.next() == 42)
|
||||
#expect(await iterator.next() == 1234)
|
||||
|
||||
#expect(ev == Core.EventLoop.current(), "Event loop exists until end of function")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
if (ENABLE_SWIFT)
|
||||
find_package(SwiftTesting REQUIRED)
|
||||
|
||||
add_executable(TestGCSwift
|
||||
TestGCBindings.swift
|
||||
TestHeap.cpp
|
||||
TestInterop.cpp
|
||||
)
|
||||
# FIXME: Swift doesn't seem to like object libraries for @main
|
||||
target_sources(TestGCSwift PRIVATE ../Resources/SwiftTestMain.swift)
|
||||
|
||||
generate_clang_module_map(TestGCSwift)
|
||||
|
||||
set_target_properties(TestGCSwift PROPERTIES SUFFIX .swift-testing)
|
||||
target_include_directories(TestGCSwift PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(TestGCSwift PRIVATE AK LibGC SwiftTesting::SwiftTesting)
|
||||
|
||||
get_property(testing_compile_options TARGET SwiftTesting::SwiftTesting PROPERTY INTERFACE_LINK_OPTIONS)
|
||||
|
||||
add_swift_target_properties(TestGCSwift
|
||||
LAGOM_LIBRARIES AK LibGC
|
||||
COMPILE_OPTIONS ${testing_compile_options} -enable-experimental-feature Extern
|
||||
)
|
||||
add_test(NAME TestGCSwift COMMAND TestGCSwift)
|
||||
endif()
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
import GC
|
||||
@_exported import TestGCSwiftCxx
|
||||
import Testing
|
||||
|
||||
public struct HeapString: HeapAllocatable {
|
||||
public var string: Swift.String
|
||||
|
||||
public init(cell: GC.Cell) {
|
||||
self.cell = cell
|
||||
self.string = ""
|
||||
}
|
||||
|
||||
public static func create(on heap: GC.Heap, string: Swift.String) -> GC.Cell {
|
||||
// NOTE: GC must be deferred so that a collection during allocation doesn't get tripped
|
||||
// up looking for the Cell pointer on the stack or in a register when it might only exist in the heap
|
||||
precondition(heap.is_gc_deferred())
|
||||
let heapString = allocate(on: heap)
|
||||
heapString.pointee.string = string
|
||||
return heapString.pointee.cell
|
||||
}
|
||||
|
||||
public var cell: GC.Cell
|
||||
}
|
||||
|
||||
@Suite(.serialized)
|
||||
struct TestGCSwiftBindings {
|
||||
|
||||
@Test func createBoundString() {
|
||||
let heap = test_gc_heap()
|
||||
let string = heap.withDeferredGC {
|
||||
return HeapString.allocate(on: heap)
|
||||
}
|
||||
#expect(string.pointee.string == "")
|
||||
heap.collect_garbage(GC.Heap.CollectionType.CollectGarbage)
|
||||
|
||||
string.pointee.string = "Hello, World!"
|
||||
heap.collect_garbage(GC.Heap.CollectionType.CollectGarbage)
|
||||
#expect(string.pointee.string == "Hello, World!")
|
||||
|
||||
heap.collect_garbage(GC.Heap.CollectionType.CollectEverything)
|
||||
}
|
||||
|
||||
@Test func testInterop() {
|
||||
test_interop()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "TestHeap.h"
|
||||
#include <LibGC/Heap.h>
|
||||
|
||||
GC::Heap& test_gc_heap()
|
||||
{
|
||||
// FIXME: The GC heap should become thread aware!
|
||||
thread_local GC::Heap heap(nullptr, [](auto&) { });
|
||||
return heap;
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGC/Forward.h>
|
||||
|
||||
GC::Heap& test_gc_heap();
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "TestInterop.h"
|
||||
#include "TestHeap.h"
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibGC/ForeignCell.h>
|
||||
#include <LibGC/Heap.h>
|
||||
#include <TestGCSwift-Swift.h>
|
||||
|
||||
#define COLLECT heap.collect_garbage(GC::Heap::CollectionType::CollectGarbage)
|
||||
#define COLLECT_ALL heap.collect_garbage(GC::Heap::CollectionType::CollectEverything)
|
||||
|
||||
void test_interop()
|
||||
{
|
||||
auto& heap = test_gc_heap();
|
||||
|
||||
COLLECT_ALL;
|
||||
|
||||
auto string = GC::ForeignRef<TestGCSwift::HeapString>::allocate(heap, "Hello, World!");
|
||||
|
||||
COLLECT;
|
||||
|
||||
auto strings_string = std::string(string->getString());
|
||||
VERIFY(strings_string == "Hello, World!");
|
||||
|
||||
COLLECT;
|
||||
|
||||
auto* cell = string->getCell();
|
||||
VERIFY(cell == static_cast<GC::Cell*>(string.cell()));
|
||||
|
||||
COLLECT;
|
||||
|
||||
strings_string = std::string(string->getString());
|
||||
|
||||
COLLECT;
|
||||
|
||||
VERIFY(strings_string == "Hello, World!");
|
||||
|
||||
COLLECT_ALL;
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void test_interop();
|
||||
|
|
@ -21,20 +21,4 @@ endforeach()
|
|||
target_link_libraries(TestContentFilter PRIVATE LibURL)
|
||||
target_link_libraries(TestFetchURL PRIVATE LibURL)
|
||||
|
||||
if (ENABLE_SWIFT)
|
||||
find_package(SwiftTesting REQUIRED)
|
||||
|
||||
add_executable(TestLibWebSwift
|
||||
TestLibWebSwiftBindings.swift
|
||||
TestHTMLTokenizerSwift.swift
|
||||
)
|
||||
|
||||
# FIXME: Swift doesn't seem to like object libraries for @main
|
||||
target_sources(TestLibWebSwift PRIVATE ../Resources/SwiftTestMain.swift)
|
||||
|
||||
set_target_properties(TestLibWebSwift PROPERTIES SUFFIX .swift-testing)
|
||||
target_link_libraries(TestLibWebSwift PRIVATE AK LibWeb LibGC SwiftTesting::SwiftTesting)
|
||||
add_test(NAME TestLibWebSwift COMMAND TestLibWebSwift)
|
||||
endif()
|
||||
|
||||
add_subdirectory("test-web")
|
||||
|
|
|
|||
|
|
@ -1,314 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
import Testing
|
||||
import Web
|
||||
|
||||
@Suite
|
||||
struct TestHTMLTokenizerSwift {
|
||||
|
||||
@Test func tokenTypes() {
|
||||
let default_token = HTMLToken()
|
||||
default_token.type = .Character(codePoint: "a")
|
||||
#expect(default_token.isCharacter())
|
||||
|
||||
#expect("\(default_token)" == "HTMLToken(type: Character(codePoint: a))")
|
||||
}
|
||||
|
||||
@Test func parserWhitespace() {
|
||||
for codePoint: Character in ["\t", "\n", "\r", "\u{000C}", " "] {
|
||||
let token = HTMLToken(type: .Character(codePoint: codePoint))
|
||||
#expect(token.isParserWhitespace())
|
||||
}
|
||||
|
||||
for codePoint: Character in ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] {
|
||||
let token = HTMLToken(type: .Character(codePoint: codePoint))
|
||||
#expect(!token.isParserWhitespace())
|
||||
}
|
||||
}
|
||||
|
||||
@Test func dataStateNoInput() {
|
||||
let tokenizer = HTMLTokenizer()
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .EndOfFile)
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2 == nil)
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data)
|
||||
}
|
||||
|
||||
@Test func dataStateSingleChar() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "X") else {
|
||||
Issue.record("Failed to create tokenizer for 'X'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: "X"))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3 == nil)
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data)
|
||||
}
|
||||
|
||||
@Test func dataStateAmpersand() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "&") else {
|
||||
Issue.record("Failed to create tokenizer for '&'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: "&"))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3 == nil)
|
||||
}
|
||||
|
||||
@Test func tagOpenOnly() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<") else {
|
||||
Issue.record("Failed to create tokenizer for '<'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: "<"))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.TagOpen)
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3 == nil)
|
||||
}
|
||||
|
||||
@Test func dataStateNulChar() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "H\0I") else {
|
||||
Issue.record("Failed to create tokenizer for 'H\\0I'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: "H"))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .Character(codePoint: "\u{FFFD}"))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .Character(codePoint: "I"))
|
||||
|
||||
let token4 = tokenizer.nextToken()
|
||||
#expect(token4?.type == .EndOfFile)
|
||||
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data)
|
||||
}
|
||||
|
||||
@Test func scriptTagWithAttributes() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<script type=\"text/javascript\">") else {
|
||||
Issue.record("Failed to create tokenizer for '<script type=\"text/javascript\">'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "script", attributes: [HTMLToken.Attribute(localName: "type", value: "text/javascript")]))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data)
|
||||
}
|
||||
|
||||
@Test func scriptWithContent() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<script>var x = 1;</script>") else {
|
||||
Issue.record("Failed to create tokenizer for '<script>var x = 1;</script>'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "script", attributes: []))
|
||||
|
||||
for codePoint in "var x = 1;" {
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: codePoint))
|
||||
}
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndTag(tagName: "script"))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func simpleDivWithContent() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<div>hi</div>") else {
|
||||
Issue.record("Failed to create tokenizer for '<div>hi</div>'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "div", attributes: []))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .Character(codePoint: "h"))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .Character(codePoint: "i"))
|
||||
|
||||
let token4 = tokenizer.nextToken()
|
||||
#expect(token4?.type == .EndTag(tagName: "div"))
|
||||
|
||||
let token5 = tokenizer.nextToken()
|
||||
#expect(token5?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func simpleDivWithContentAndAttributes() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<div class=\"foo\">hi</div>") else {
|
||||
Issue.record("Failed to create tokenizer for '<div class=\"foo\">hi</div>'")
|
||||
return
|
||||
}
|
||||
#expect(tokenizer.state == HTMLTokenizer.State.Data) // initial state
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "div", attributes: [HTMLToken.Attribute(localName: "class", value: "foo")]))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .Character(codePoint: "h"))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .Character(codePoint: "i"))
|
||||
|
||||
let token4 = tokenizer.nextToken()
|
||||
#expect(token4?.type == .EndTag(tagName: "div"))
|
||||
|
||||
let token5 = tokenizer.nextToken()
|
||||
#expect(token5?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func severalDivsWithAttributesAndContent() {
|
||||
// Explicitly use unquoted and single quotes for attribute values
|
||||
guard let tokenizer = HTMLTokenizer(input: "<div class=foo>hi</div><div class='bar'>bye</div>") else {
|
||||
Issue.record("Failed to create tokenizer for '<div class=\"foo\">hi</div><div class=\"bar\">bye</div>'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "div", attributes: [HTMLToken.Attribute(localName: "class", value: "foo")]))
|
||||
|
||||
for codePoint in "hi" {
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: codePoint))
|
||||
}
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndTag(tagName: "div"))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .StartTag(tagName: "div", attributes: [HTMLToken.Attribute(localName: "class", value: "bar")]))
|
||||
|
||||
for codePoint in "bye" {
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: codePoint))
|
||||
}
|
||||
|
||||
let token4 = tokenizer.nextToken()
|
||||
#expect(token4?.type == .EndTag(tagName: "div"))
|
||||
|
||||
let token5 = tokenizer.nextToken()
|
||||
#expect(token5?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func startTagWithMultipleAttributes() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<div class=\"foo\" id=\"bar\">hi</div attr=endTagAttributeWhee>") else {
|
||||
Issue.record("Failed to create tokenizer for '<div class=\"foo\" id=\"bar\">hi</div>'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .StartTag(tagName: "div", attributes: [HTMLToken.Attribute(localName: "class", value: "foo"), HTMLToken.Attribute(localName: "id", value: "bar")]))
|
||||
|
||||
for codePoint in "hi" {
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: codePoint))
|
||||
}
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndTag(tagName: "div", attributes: [HTMLToken.Attribute(localName: "attr", value: "endTagAttributeWhee")]))
|
||||
|
||||
let token3 = tokenizer.nextToken()
|
||||
#expect(token3?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func xmlDeclaration() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>") else {
|
||||
Issue.record("Failed to create tokenizer for '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Comment(data: "?xml version=\"1.0\" encoding=\"UTF-8\"?"))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func simpleComment() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<!-- comment -->") else {
|
||||
Issue.record("Failed to create tokenizer for '<!-- comment -->'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Comment(data: " comment "))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func nestedComment() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<!-- <!-- nested --> -->") else {
|
||||
Issue.record("Failed to create tokenizer for '<!-- <!-- nested --> -->'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Comment(data: " <!-- nested "))
|
||||
|
||||
for codePoint in " -->" {
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Character(codePoint: codePoint))
|
||||
}
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
}
|
||||
|
||||
@Test func commentWithScriptTagInside() {
|
||||
guard let tokenizer = HTMLTokenizer(input: "<!-- <script>var x = 1;</script> -->") else {
|
||||
Issue.record("Failed to create tokenizer for '<!-- <script>var x = 1;</script> -->'")
|
||||
return
|
||||
}
|
||||
|
||||
let token = tokenizer.nextToken()
|
||||
#expect(token?.type == .Comment(data: " <script>var x = 1;</script> "))
|
||||
|
||||
let token2 = tokenizer.nextToken()
|
||||
#expect(token2?.type == .EndOfFile)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import AK
|
||||
import Testing
|
||||
import Web
|
||||
|
||||
@Suite
|
||||
struct TestLibWebSwiftBindings {
|
||||
|
||||
@Test func enumsAreBound() {
|
||||
#expect(Web.DOM.NodeType.ELEMENT_NODE.rawValue == 1)
|
||||
|
||||
#expect(Web.Bindings.NavigationType.Push.rawValue == 0)
|
||||
|
||||
let end = Web.Bindings.idl_enum_to_string(Web.Bindings.ScrollLogicalPosition.End)
|
||||
let end_string = Swift.String(akString: end)!
|
||||
|
||||
#expect(end_string == "end")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
typealias EntryPoint = @convention(thin) @Sendable (_ configurationJSON: UnsafeRawBufferPointer?, _ recordHandler: @escaping @Sendable (_ recordJSON: UnsafeRawBufferPointer) -> Void) async throws -> Bool
|
||||
|
||||
@_extern(c, "swt_abiv0_getEntryPoint")
|
||||
func swt_abiv0_getEntryPoint() -> UnsafeRawPointer
|
||||
|
||||
@main struct Runner {
|
||||
static func main() async throws {
|
||||
nonisolated(unsafe) let configurationJSON: UnsafeRawBufferPointer? = nil
|
||||
let recordHandler: @Sendable (UnsafeRawBufferPointer) -> Void = { _ in }
|
||||
|
||||
let entryPoint = unsafeBitCast(swt_abiv0_getEntryPoint(), to: EntryPoint.self)
|
||||
|
||||
if try await entryPoint(configurationJSON, recordHandler) {
|
||||
exit(EXIT_SUCCESS)
|
||||
} else {
|
||||
exit(EXIT_FAILURE)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue