Revision control

Copy as Markdown

Other Tools

# Introduction to WebKit
## What is WebKit?
[WebKit](https://webkit.org/) is an open-source Web browser engine.
It’s a framework in macOS and iOS, and used by many first party and third party applications including Safari, Mail, Notes, Books, News, and App Store.
The WebKit codebase is mostly written in C++ with bits of C and assembly, primarily in JavaScriptCore, and some Objective-C to integrate with Cocoa platforms.
It primarily consists of the following components, each inside its own directory in [Source](https://github.com/WebKit/WebKit/tree/main/Source):
* **bmalloc** - WebKit’s malloc implementation as a bump pointer allocator. It provides an important security feature, called IsoHeap,
which segregates each type of object into its own page to prevent type confusion attacks upon use-after-free.
* **WTF** - Stands for Web Template Framework. WebKit’s template library.
The rest of the WebKit codebase is built using this template library in addition to, and often in place of, similar class templates in the C++ standard library.
It contains common container classes such as Vector, HashMap (unordered), HashSet, and smart pointer types such as Ref, RefPtr, and WeakPtr used throughout the rest of WebKit.
* **JavaScriptCore** - WebKit’s JavaScript engine; often abbreviated as JSC.
JSC parses JavaScript and generates byte code, which is then executed by one of the following four tiers.
Many tiers are needed to balance between compilation time and execution time.
Also see Phil's blog post about [Speculation in JavaScriptCore](https://webkit.org/blog/10308/speculation-in-javascriptcore/).
* **Interpreter** - This tier reads and executes instructions in byte code in C++.
* **Baseline JIT** - The first Just In Time compiler tier serves as the profiler as well as a significant speed up from the interpreter.
* **DFG JIT** - Data Flow Graph Just In Time compiler uses the data flow analysis to generate optimized machine code.
* **FTL JIT** - Faster than Light Just In Time compiler which uses [B3 backend](https://webkit.org/blog/5852/introducing-the-b3-jit-compiler/).
It’s the fastest tier of JSC.
JavaScriptCode also implements JavaScriptCore API for macOS and iOS applications.
* **WebCore** - The largest component of WebKit, this layer implements most of the Web APIs and their behaviors.
Most importantly, this component implements HTML, XML, and CSS parsers and implements HTML, SVG, and MathML elements as well as CSS.
It also implements [CSS JIT](https://webkit.org/blog/3271/webkit-css-selector-jit-compiler/), the only Just In Time compiler for CSS in existence.
It works with a few tree data structures:
* **Document Object Model** - This is the tree data structure we create from parsing HTML.
* **Render Tree** - This tree represents the visual representation of each element in DOM tree computed from CSS and also stores the geometric layout information of each element.
* **WebCore/PAL and WebCore/platform** - Whilst technically a part of WebCore, this is a platform abstraction layer for WebCore
so that the rest of WebCore code can remain platform independent / agnostic across all the platforms WebKit can run on: macOS, iOS, Windows, Linux, etc...
Historically, most of this code resided in WebCore/platform.
There is an ongoing multi-year project to slowly migrate code to PAL as we remove the reverse dependencies to WebCore.
* **WebKitLegacy** (a.k.a. WebKit1) - This layer interfaces WebCore with the rest of operating systems in single process and implements WebView on macOS and UIWebView on iOS.
* **WebKit** (a.k.a. WebKit2) - This layer implements the multi-process architecture of WebKit, and implements WKWebView on macOS and iOS.
WebKit’s multi-process architecture consists of the following processes:
* **UI process** - This is the application process. e.g. Safari and Mail
* **WebContent process** - This process loads & runs code loaded from websites.
Each tab in Safari typically has its own WebContent process.
This is important to keep each tab responsive and protect websites from one another.
* **Networking process** - This process is responsible for handling network requests as well as storage management.
All WebContent processes in a single session (default vs. private browsing) share a single networking session in the networking process.
* **WebInspector / WebDriver** - WebKit’s developer tool & automation tool for Web developers.
## Contributing to WebKit
There are many ways to get involved and contribute to the WebKit Project.
Filing a new bug, fixing a bug, or adding a new feature.
There are three different kinds of contributors in the WebKit project.
* Contributor - This category encompasses everyone. Anyone who files a bug or contributes a code change or reviews a code change is considered as a contributor
* Committer - A committer is someone who has write access to [WebKit's repository](https://github.com/WebKit/WebKit).
* Reviewer - A reviewer is someone who has the right to review and approve code changes other contributors proposed.
See [Commit and Review Policy](https://webkit.org/commit-and-review-policy/) for more details on how to become a committer or a reviewer.
### Staying in Touch
Before getting in touch with WebKit developers using any of the avenues below, make sure that you have checked our page on how to ask [questions about WebKit](https://webkit.org/asking-questions/).
You can find WebKit developers, testers, and other interested parties on the [#WebKit Slack workspace](https://webkit.slack.com/).
and stay in touch.
## Bug tracking in WebKit
[bugs.webkit.org](https://bugs.webkit.org/) hosted is the primary bug tracking tool we use.
When making a code change, we post a code change (patch) on this website.
### Filing a bug and editing bugs
To [file a new WebKit bug](https://bugs.webkit.org/enter_bug.cgi), see [reporting bugs](https://webkit.org/reporting-bugs/).
To edit an existing bug, you may need [editbug-bits](https://webkit.org/bugzilla-bits/).
### Code review
Code reviews are done on GitHub when a pull request is made. See [Submitting a pull request](#submitting-a-pull-request).
### Security Bugs in bugs.webkit.org
Security bugs have their own components in [bugs.webkit.org](https://bugs.webkit.org/).
We’re also working on a new policy to delay publishing tests for security fixes until after the fixes have been widely deployed.
_***Do not post a patch or describe a security bug in a bug that is not in security component of bugs.webkit.org.***_
## Getting started with WebKit
### Getting Code
### Adding Tools to PATH
For convenience, you can add `Tools/Scripts/` to your path as follows in `~/.zshrc` like so:
```sh
export PATH=$PATH:/Volumes/Data/webkit/Tools/Scripts/
```
where `/Volumes/Data/webkit` is the path to a WebKit checkout.
This will allow you to run various tools you by name instead of typing the full path of the script.
### Updating checkouts
There is a script to update a WebKit checkout: `Tools/Scripts/update-webkit`.
### Building WebKit
### Getting setup to contribute
If you've followed the steps above, get setup to contribute by running:
```Bash
git webkit setup
```
The `setup` checks that your environment is optimally configured to contribute, and may prompt you for some additional information.
### Submitting a pull request
Firstly, please make sure you [file a bug](https://bugs.webkit.org) for the thing you are adding or fixing! Or, find a bug that you think is relevant to the fix you are making.
Assuming you are working off "main" branch, once your patch is working and [tests are passing](#correctness-testing-in-webkit), simply run:
```Bash
git webkit pr --issue <your bug number here>
```
That will pull down the details from [bugs.webkit.org](https://bugs.webkit.org), create a new git branch, and generate a commit message for you.
If necessary, please add additional details describing what you've added, modified, or fixed.
Once your pull request is on GitHub, the Early Warning System (a.k.a. EWS) will automatically build and run tests against your code change.
This allows contributors to find build or test failures before committing code changes to the WebKit’s repository.
Note, if you'd like to submit a draft pull request, you can do so by running:
```Bash
git webkit pr --draft
```
## Addressing review feedback
After you receive review feedback on GitHub, you should collaborate with the reviewer to address the feedback.
Once done, you can update your pull request to include the changes by again simply running:
```Bash
git webkit pr
```
That will replace your old pull request with a new one with the new changes, while also updating the pull request's description with your current commit message.
### Fixing mysterious build or runtime errors after Xcode upgrades
If you see mysterious build failures or if you’ve switched to a new version of
macOS or Xcode, delete the `WebKitBuild` directory.
`make clean` may not delete all the relevant files,
and building after doing that without deleting the `WebKitBuild` directory may result in mysterious build or dyld errors.
### Building with Address Sanitizer to investigate memory corruption bugs
To build [Address Sanitizer](https://en.wikipedia.org/wiki/AddressSanitizer) or ASan builds to analyze security bugs,
run `Tools/Scripts/set-webkit-configuration --asan --release`.
This will enable ASan build. If want to attach a debugger, you can also specify `--debug` instead of `--release`.
Once you don’t need to build or run ASan anymore, you can specify `--no-asan` in place of `--asan` to disable ASan.
Note that this configuration is saved by creating a file called Asan in the WebKitBuild directory,
so if you are trying to do a clean Asan build by deleting the build directory you need to rerun this command.
### Using Xcode
You can also use Xcode to build & debug WebKit. Open `WebKit.xcworkspace` at the top level directory.
In order to make Xcode use build files built by `make` command above,
go to File > Workspace Settings... > Advanced... > Custom > Relative to Workspace
and adjust the relative paths of Products and Intermediates to point to `WebKitBuild` directory.
![Screenshot of Xcode Workspace Settings](resources/xcode-workspace-settings.png)
![Screenshot of Xcode Workspace Settings - Advanced Build Location](resources/xcode-workspace-build-location.png)
Note that debugging WebCore code typically requires attaching to the relevant WebContent process,
not the application process, which is mostly running code in [Source/WebKit/UIProcess](https://github.com/WebKit/WebKit/tree/main/Source/WebKit/UIProcess).
Depending on what you’re debugging, you’d have to attach & debug different processes in the coalition.
You may find it useful to use the debug helpers under `Tools/lldb/lldb_webkit.py`.
This can be added to `~/.lldbinit` for automatic loading into LLDB on launch by adding the line `command script import {Path to WebKit}/Tools/lldb/lldb_webkit.py`.
For more details, see the Wiki article on [lldb formatters](https://trac.webkit.org/wiki/lldb%20formatters).
When debugging a debug build in LLDB, there are also a few functions that can be called on objects that will dump debugging info.
* RenderObject
* showNodeTree()
* showLineTree()
* showRenderTree()
* Node
* showTree()
* showNodePath()
* showTreeForThis()
* showNodePathForThis()
Debugging child processes such as GPU process, "Child Process Debuggability" internal feature must be in use. For the test runner, you can
specify `run-webkit-tests --internal-feature=ChildProcessDebuggabilityEnabled`. For MiniBrowser, set the Debug > Internal > Child Process Debuggability
menu item and restart.
## Correctness Testing in WebKit
WebKit is really big on test driven development, we have many types of tests.
* **JavaScript tests** - Resides in top-level [JSTests](https://github.com/WebKit/WebKit/tree/main/JSTests) directory.
This is the primary method of testing JavaScriptCore. Use `Tools/Scripts/run-javascriptcore-tests` to run these tests.
* **Layout tests** - Resides in top-level [LayoutTests](https://github.com/WebKit/WebKit/tree/main/LayoutTests) directory.
This is the primary method of testing WebCore.
If you’re making code changes to WebCore, you typically run these tests. Use `Tools/Scripts/run-webkit-tests` to run these.
Pass `-1` to run tests using WebKitLegacy (a.k.a. WebKit1).
[WebKitTestRunner](https://github.com/WebKit/WebKit/tree/main/Tools/WebKitTestRunner) is used to run these tests for WebKit2,
and [DumpRenderTree](https://github.com/WebKit/WebKit/tree/main/Tools/DumpRenderTree) is used to these tests for WebKit1.
There are a few styles of layout tests but all of them have a test file and expected result (ends with -expected.txt),
and the test passes if the test file’s output matches that of the expected result.
* **API tests** - Reside in [Tools/TestWebKitAPI](https://github.com/WebKit/WebKit/tree/main/Tools/TestWebKitAPI),
these are [GTests](https://en.wikipedia.org/wiki/Google_Test) that test APIs exposed by JavaScriptCore,
WebKitLegacy, and WebKit layers as well as unit tests for selected WTF classes.
WebKit does not use [XCTests](https://developer.apple.com/documentation/xctest).
Use `Tools/Scripts/run-api-tests` to run these tests.
Because these API tests are sequentially, it’s preferable to write layout tests when possible.
* **Bindings tests** - Reside in [Source/WebCore/bindings/scripts/test](https://github.com/WebKit/WebKit/tree/main/Source/WebCore/bindings/scripts/test),
these are tests for WebCore’s binding code generator.
Use `Tools/Scripts/run-bindings-tests` to run these tests.
* **webkitpy tests** - Tests for WebKit’s various Python scripts in [Tools/Scripts/webkitpy](https://github.com/WebKit/WebKit/tree/main/Tools/Scripts/webkitpy).
Use `Tools/Scripts/test-webkitpy` to run these tests.
* **webkitperl tests** - Tests for WebKit’s various Perl scripts in [Tools/Scripts/webkitperl](https://github.com/WebKit/WebKit/tree/main/Tools/Scripts/webkitperl).
Use `Tools/Scripts/test-webkitperl` to run these tests.
## Performance Testing in WebKit
The WebKit project has a "no performance regression" policy.
We maintain the performance of the following of the benchmarks and are located under [PerformanceTests](https://github.com/WebKit/WebKit/tree/main/PerformanceTests).
If your patch regresses one of these benchmarks even slightly (less than 1%), it will get reverted.
* **JetStream2** - Measures JavaScript and WASM performance.
* **MotionMark** - Measures graphics performance.
* **Speedometer 2** - Measures WebKit’s performance for complex web apps.
The following are benchmarks maintained by Apple's WebKit team but not available to other open source contributors
since Apple doesn't have the right to redistribute the content.
If your WebKit patch regresses one of these tests, your patch may still get reverted.
* **RAMification** - Apple's internal JavaScript memory benchmark.
* **ScrollPerf** - Apple's internal scrolling performance tests.
* **PLT** - Apple's internal page load time tests.
* **Membuster / PLUM** - Apple's internal memory tests. Membuster for macOS and PLUM for iOS and iPadOS.
## Contributing code to WebKit
WebKit has a rigorous code contribution process and policy in place to maintain the quality of code.
### Coding style
Code you write must follow WebKit’s [coding style guideline](https://webkit.org/contributing-code/#code-style-guidelines).
You can run `Tools/Scripts/check-webkit-style` to check whether your code follows the coding guidelines or not
(it can report false positives or false negatives).
If you use `Tools/Scripts/webkit-patch upload` to upload your patch,
it automatically runs the style checker against the code you changed so there is no need to run `check-webkit-style` separately.
Some older parts of the codebase do not follow these guidelines.
If you are modifying such code, it is generally best to clean it up to comply with the current guidelines.
### Convenience Tools
`Tools/Scripts/webkit-patch` provides a lot of utility functions like applying the latest patch on [bugs.webkit.org](https://bugs.webkit.org/) (`apply-from-bug`)
and uploading a patch (`upload --git-commit=<commit hash>`) to a [bugs.webkit.org](https://bugs.webkit.org/) bug.
Use `--all-commands` to the list of all commands this tool supports.
### Licensing
Much of the code we inherited from [KHTML](https://en.wikipedia.org/wiki/KHTML) is licensed under [LGPL](https://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License).
New code contributed to WebKit will use the [two clause BSD license](https://github.com/WebKit/WebKit/blob/main/Source/WebCore/LICENSE-APPLE).
When contributing new code, update the copyright date.
When moving the existing code, you need to include the original copyright notice for the moved code
and you should also not change the license, which may be BSD or LGPL depending on a file, without the permission of the copyright holders.
### Regression Tests
Once you have made a code change, you need to run the aforementioned tests (layout tests, API tests, etc...)
to make sure your code change doesn’t break existing functionality.
These days, uploading a patch on [bugs.webkit.org](https://bugs.webkit.org/) triggers the Early Warning System (a.k.a. EWS)
For any bug fix or a feature addition, there should be a new test demonstrating the behavior change caused by the code change.
If no such test can be written in a reasonable manner (e.g. the fix for a hard-to-reproduce race condition),
then the reason writing a tests is impractical should be explained in the accompanying commit message.